+ {"GL_UNSIGNED_BYTE", GL_UNSIGNED_BYTE, false, 1},
+ {"GL_BYTE", GL_BYTE, false, 1},
+ {"GL_UNSIGNED_SHORT", GL_UNSIGNED_SHORT, false, 2},
+ {"GL_SHORT", GL_SHORT, false, 2},
+ {"GL_UNSIGNED_INT", GL_UNSIGNED_INT, false, 4},
+ {"GL_INT", GL_INT, false, 4},
+ {"GL_FLOAT", GL_FLOAT, false, 4},
+ {"GL_UNSIGNED_BYTE_3_3_2", GL_UNSIGNED_BYTE_3_3_2, true, 1},
+ {"GL_UNSIGNED_BYTE_2_3_3_REV", GL_UNSIGNED_BYTE_2_3_3_REV, true, 1},
+ {"GL_UNSIGNED_SHORT_5_6_5", GL_UNSIGNED_SHORT_5_6_5, true, 2},
+ {"GL_UNSIGNED_SHORT_5_6_5_REV", GL_UNSIGNED_SHORT_5_6_5_REV, true, 2},
+ {"GL_UNSIGNED_SHORT_4_4_4_4", GL_UNSIGNED_SHORT_4_4_4_4, true, 2},
+ {"GL_UNSIGNED_SHORT_4_4_4_4_REV", GL_UNSIGNED_SHORT_4_4_4_4_REV, true, 2},
+ {"GL_UNSIGNED_SHORT_5_5_5_1", GL_UNSIGNED_SHORT_5_5_5_1, true, 2},
+ {"GL_UNSIGNED_SHORT_1_5_5_5_REV", GL_UNSIGNED_SHORT_1_5_5_5_REV, true, 2},
+ {"GL_UNSIGNED_INT_8_8_8_8", GL_UNSIGNED_INT_8_8_8_8, true, 4},
+ {"GL_UNSIGNED_INT_8_8_8_8_REV", GL_UNSIGNED_INT_8_8_8_8_REV, true, 4},
+ {"GL_UNSIGNED_INT_10_10_10_2", GL_UNSIGNED_INT_10_10_10_2, true, 4},
+ {"GL_UNSIGNED_INT_2_10_10_10_REV", GL_UNSIGNED_INT_2_10_10_10_REV, true, 4},
+};
+
+/** parse the type string */
+GLenum
+parseType(char *typestr)
+{
+ GLenum ogltype;
+ int i;
+
+ for (i=0; i<(sizeof(parse_type_table)/sizeof(struct gl_parse_type)); i++) {
+ }
+ perf_printf("]\n");
+ exit(0);
+ } else {
+ perf_printf("Unrecognized argument: %s\n", key);
+ exit(1);
+ }
+ }
+
+ g_texelsize = determineTexelSize(g_texfmt, g_texsrctype);
+
+ for (i = 0; i < TEST_COUNT; i++) {
+ if (test_enable[i] == GL_TRUE)
+ break;
+ }
+ if (i == TEST_COUNT) {
+ /* No tests were enabled, so enable all of them */
+ for (i = 0; i < TEST_COUNT; i++) {
+ test_enable[i] = GL_TRUE;
+ }
+ }
+
+ /* if internal format not provided, set to source format */
+ if (g_texintfmt == 0) {
+ g_texintfmt = g_texfmt;
+ }
+
+ /* generate config name for output */
+ sprintf(configName, "%s/%s/%s", formatName, internalformatName, typeName);
+ if (g_csvstyle == CSV_STYLE_OFF && g_verbose)
+ perf_printf("config name (fmt/intfmt/type): %s\n", configName);
+
+ /* print out values using for this test run */
+ if (g_verbose) {
+ perf_printf("running benchmark with the following options:\n");
+ perf_printf(" type: %s:%d\n", typeName, g_texsrctype);
+ perf_printf(" format: %s:%d\n", formatName, g_texfmt);
+ perf_printf(" internalformat: %s:%d\n", internalformatName,
g_texintfmt);
+ perf_printf(" level: %d\n", g_level);
+ perf_printf(" width: %d\n", g_width);
+ perf_printf(" height: %d\n", g_height);
+ perf_printf(" texel size: %d\n", g_texelsize);
+ perf_printf(" draw point?: %d\n", g_drawpoint);
+ }
+
+ return;
+
+}
/** Called from test harness/main */
void
@@ -91,15 +421,20 @@ PerfInit(int argc, char *argv[])
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEnable(GL_TEXTURE_2D);
-}
-
-
+ /* parse config file */
+ parseCommands(argc, argv);
+}
static void
CreateUploadTexImage2D(unsigned count)
{
unsigned i;
+
+ if (g_verbose) {
+ perf_printf("CreateUploadTexImage2D count: %d\n", count);
+ }
+
for (i = 0; i < count; i++) {
if (TexObj)
glDeleteTextures(1, &TexObj);
@@ -109,68 +444,135 @@ CreateUploadTexImage2D(unsigned count)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
- TexSize, TexSize, 0,
- TexSrcFormat, TexSrcType, TexImage);
+ glTexImage2D(GL_TEXTURE_2D, g_level, g_texintfmt,
+ g_width, g_height, 0,
+ g_texfmt, g_texsrctype, TexImage);
- if (DrawPoint)
+ if (g_drawpoint)
glDrawArrays(GL_POINTS, 0, 1);
}
glFinish();
}
-
static void
UploadTexImage2D(unsigned count)
{
unsigned i;
+
+ if (g_verbose) {
+ perf_printf("UploadTexImage2D count: %d\n", count);
+ }
+
for (i = 0; i < count; i++) {
- /* XXX is this equivalent to a glTexSubImage call since we're
- * always specifying the same image size? That case isn't optimized
- * in Mesa but may be optimized in other drivers. Note sure how
- * much difference that might make.
- */
- glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
- TexSize, TexSize, 0,
- TexSrcFormat, TexSrcType, TexImage);
- if (DrawPoint)
+ glTexImage2D(GL_TEXTURE_2D, g_level, g_texintfmt,
+ g_width, g_height, 0,
+ g_texfmt, g_texsrctype, TexImage);
+ if (g_drawpoint)
glDrawArrays(GL_POINTS, 0, 1);
}
glFinish();
}
+GLuint
+GenerateMipmapImages(void)
+{
+ GLuint w, h;
+ GLint bytesPerImage, mallocSize, bytesPerLevel;
+ GLubyte *levelPtr;
+ w = g_width;
+ h = g_height;
+ bytesPerImage = 0;
+ mallocSize = 0;
+
+ /* compute totals first */
+ while ((w > 1) || (h > 1)) {
+ bytesPerLevel = w * h * g_texelsize;
+ bytesPerImage += bytesPerLevel;
+ /* Add 64 so that we can align the data to 64 byte boundary */
+ mallocSize += bytesPerLevel + 0x40;
+
+ if (w > 1) {
+ w = w / 2;
+ }
+ if (h > 1) {
+ h = h / 2;
+ }
+ }
+
+ TexImage = malloc(mallocSize);
+ levelPtr = TexImage;
+
+ w = g_width;
+ h = g_height;
+ /* generate the mipmap images */
+ while ((w > 1) || (h > 1)) {
+ bytesPerLevel = w * h * g_texelsize;
+
+ /* Round to the next higher 64byte boundary.
+ * That is generally better for today's HW and
+ * easy for an app to do if they care.
+ */
+ levelPtr = (GLubyte *) ALIGN_PTR(levelPtr, 64);
+
+ /* set memory to "simulate" loading an image */
+ memset(levelPtr, g_numLevel, bytesPerLevel);
+
+ g_mipmapimgs[g_numLevel] = levelPtr;
+ g_mmwidths[g_numLevel] = w;
+ g_mmheights[g_numLevel] = h;
+ g_numLevel = g_numLevel + 1;
+
+ /* Advance pointer to next free area */
+ levelPtr += bytesPerLevel;
+
+ if (w > 1) {
+ w = w / 2;
+ }
+ if (h > 1) {
+ h = h / 2;
+ }
+ }
+ if (g_verbose) {
+ perf_printf("GenerateMipmapImages: generated %d mipmaps\n", g_numLevel);
+ }
+
+ return bytesPerImage;
+
+}
static void
UploadTexSubImage2D(unsigned count)
{
unsigned i;
for (i = 0; i < count; i++) {
- if (TexSubImage4) {
- GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2;
- GLsizei halfPos = TexSize - halfSize;
+ if (g_subtexquad) {
+ GLsizei halfSizeW = (g_width == 1) ? 1 : g_width / 2;
+ GLsizei halfPosX = g_width - halfSizeW;
+ GLsizei halfSizeH = (g_height == 1) ? 1 : g_height / 2;
+ GLsizei halfPosY = g_height - halfSizeH;
/* do glTexSubImage2D in four pieces */
/* lower-left */
- glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, g_width);
glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, 0, halfSize, halfSize,
- TexSrcFormat, TexSrcType, TexImage);
+ 0, 0, halfSizeW, halfSizeH,
+ g_texfmt, g_texsrctype, TexImage);
/* lower-right */
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPosX);
glTexSubImage2D(GL_TEXTURE_2D, 0,
- halfPos, 0, halfSize, halfSize,
- TexSrcFormat, TexSrcType, TexImage);
+ halfPosX, 0, halfSizeW, halfSizeH,
+ g_texfmt, g_texsrctype, TexImage);
/* upper-left */
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPosY);
glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, halfPos, halfSize, halfSize,
- TexSrcFormat, TexSrcType, TexImage);
+ 0, halfPosY, halfSizeW, halfSizeH,
+ g_texfmt, g_texsrctype, TexImage);
/* upper-right */
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPosX);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPosY);
glTexSubImage2D(GL_TEXTURE_2D, 0,
- halfPos, halfPos, halfSize, halfSize,
- TexSrcFormat, TexSrcType, TexImage);
+ halfPosX, halfPosY, halfSizeW, halfSizeH,
+ g_texfmt, g_texsrctype, TexImage);
/* reset the unpacking state */
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
@@ -179,46 +581,52 @@ UploadTexSubImage2D(unsigned count)
else {
/* replace whole texture image at once */
glTexSubImage2D(GL_TEXTURE_2D, 0,
- 0, 0, TexSize, TexSize,
- TexSrcFormat, TexSrcType, TexImage);
+ 0, 0, g_width, g_height,
+ g_texfmt, g_texsrctype, TexImage);
}
- if (DrawPoint)
+ if (g_drawpoint)
glDrawArrays(GL_POINTS, 0, 1);
}
glFinish();
}
-
static void
GetTexImage2D(unsigned count)
{
unsigned i;
- GLubyte *buf = (GLubyte *) malloc(TexSize * TexSize * 4);
+ GLubyte *buf = (GLubyte *) malloc(g_width * g_height * g_texelsize);
for (i = 0; i < count; i++) {
glGetTexImage(GL_TEXTURE_2D, 0,
- TexSrcFormat, TexSrcType, buf);
+ g_texfmt, g_texsrctype, buf);
}
glFinish();
free(buf);
}
+static void
+UploadTexImage2DMipmap(unsigned count)
+{
+ unsigned i, j;
-/* XXX any other formats to measure? */
-static const struct {
- GLenum format, type;
- GLenum internal_format;
- const char *name;
- GLuint texel_size;
- GLboolean full_test;
-} SrcFormats[] = {
- { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, "RGBA/ubyte", 4, GL_TRUE },
- { GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, "RGB/ubyte", 3, GL_FALSE },
- { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, "RGB/565", 2, GL_FALSE },
- { GL_BGRA, GL_UNSIGNED_BYTE, GL_RGBA, "BGRA/ubyte", 4, GL_FALSE },
- { GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, "L/ubyte", 1, GL_FALSE },
- { 0, 0, 0, NULL, 0, 0 }
-};
+ /* ?? make this configurable ?? */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST_MIPMAP_NEAREST);
+ /* mipmaps previously generated, call glTexImage2D for all levels */
+ for (i = 0; i < count; i++) {
+ for (j = 0; j < g_numLevel; j++) {
+ if (g_verbose) {
+ perf_printf("mipmap glTexImage2D - level: %d, width: %d, height:
%d\n",
+ j, g_mmwidths[j], g_mmheights[j]);
+ }
+ glTexImage2D(GL_TEXTURE_2D, j, g_texintfmt, g_mmwidths[j],
+ g_mmheights[j], 0, g_texfmt, g_texsrctype,
g_mipmapimgs[j]);
+ if (g_drawpoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ }
+ glFinish();
+
+}
/** Called from test harness/main */
void
@@ -226,104 +634,102 @@ PerfNextRound(void)
{
}
-
/** Called from test harness/main */
void
PerfDraw(void)
{
GLint maxSize;
double rate;
- GLint fmt, mode;
+ GLint test;
+ double mbPerSec; // Megabytes per second
+ double mTPerSec; // MegaTexels per second
+ GLint bytesPerImage;
+
+ if (g_csvstyle == CSV_STYLE_FULL) {
+ perf_printf("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
+ "ID", "Test", "width", "height", "level", "type",
+ "texelsize", "format", "internalformat",
+ "images/sec", "MB/sec", "MT/sec");
+ }
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
+ /* TODO - check for max size exceeded?? */
+
+ /* loop over glTexImage */
+ for (test = 0; test < TEST_COUNT; test++) {
+
+ if (test_enable[test] == GL_FALSE) continue;
+
+ switch (test) {
+ case TEST_TEXIMAGE:
+ bytesPerImage = g_width * g_height * g_texelsize;
+ TexImage = malloc(bytesPerImage);
+ rate = PerfMeasureRate(UploadTexImage2D);
+ break;
+
+ case TEST_CREATE_TEXIMAGE:
+ bytesPerImage = g_width * g_height * g_texelsize;
+ TexImage = malloc(bytesPerImage);
+ rate = PerfMeasureRate(CreateUploadTexImage2D);
+ break;
+
+ case TEST_TEXIMAGE_MIPMAP:
+ g_initialwidth = g_width;
+ g_initialheight = g_height;
+ bytesPerImage = GenerateMipmapImages();
+ rate = PerfMeasureRate(UploadTexImage2DMipmap);
+ /* ?? each mipmap has a different bytes per image, is mb/s and mt/s
+ calculation below correct? ?? */
+ break;
+
+ case TEST_TEXSUBIMAGE:
+ /* create initial, empty texture */
+ bytesPerImage = g_width * g_height * g_texelsize;
+ TexImage = malloc(bytesPerImage);
+ glTexImage2D(GL_TEXTURE_2D, 0, g_texintfmt,
+ g_width, g_height, 0,
+ g_texfmt, g_texsrctype, NULL);
+ rate = PerfMeasureRate(UploadTexSubImage2D);
+ break;
+
+ case TEST_GETTEXIMAGE:
+ bytesPerImage = g_width * g_height * g_texelsize;
+ TexImage = malloc(bytesPerImage);
+ glTexImage2D(GL_TEXTURE_2D, 0, g_texintfmt,
+ g_width, g_height, 0,
+ g_texfmt, g_texsrctype, TexImage);
+ rate = PerfMeasureRate(GetTexImage2D);
+ break;
+
+ default:
+ exit(1);
+ }
- /* loop over source data formats */
- for (fmt = 0; SrcFormats[fmt].format; fmt++) {
- TexIntFormat = SrcFormats[fmt].internal_format;
- TexSrcFormat = SrcFormats[fmt].format;
- TexSrcType = SrcFormats[fmt].type;
-
- /* loop over glTexImage, glTexSubImage */
- for (mode = 0; mode < MODE_COUNT; mode++) {
- GLuint minsz, maxsz;
-
- if (SrcFormats[fmt].full_test) {
- minsz = 16;
- maxsz = 4096;
- }
- else {
- minsz = maxsz = 256;
- if (mode == MODE_CREATE_TEXIMAGE)
- continue;
- }
-
- /* loop over a defined range of texture sizes, test only the
- * ones which are legal for this driver.
- */
- for (TexSize = minsz; TexSize <= maxsz; TexSize *= 4) {
- double mbPerSec;
-
- if (TexSize <= maxSize) {
- GLint bytesPerImage;
-
- bytesPerImage = TexSize * TexSize * SrcFormats[fmt].texel_size;
- TexImage = malloc(bytesPerImage);
-
- switch (mode) {
- case MODE_TEXIMAGE:
- rate = PerfMeasureRate(UploadTexImage2D);
- break;
-
- case MODE_CREATE_TEXIMAGE:
- rate = PerfMeasureRate(CreateUploadTexImage2D);
- break;
-
- case MODE_TEXSUBIMAGE:
- /* create initial, empty texture */
- glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
- TexSize, TexSize, 0,
- TexSrcFormat, TexSrcType, NULL);
- rate = PerfMeasureRate(UploadTexSubImage2D);
- break;
-
- case MODE_GETTEXIMAGE:
- glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
- TexSize, TexSize, 0,
- TexSrcFormat, TexSrcType, TexImage);
- rate = PerfMeasureRate(GetTexImage2D);
- break;
-
- default:
- exit(1);
- }
-
- mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
- free(TexImage);
-
-
- {
- unsigned err;
- err = glGetError();
- if (err) {
- perf_printf("non-zero glGetError() %d\n", err);
- exit(1);
- }
- }
-
- }
- else {
- rate = 0;
- mbPerSec = 0;
- }
+ mbPerSec = (rate * bytesPerImage) / (1024.0 * 1024.0);
+ mTPerSec = (rate * g_width * g_height) / (1024.0 * 1024.0);
+ free(TexImage);
- perf_printf(" %s(%s %d x %d): "
- "%.1f images/sec, %.1f MB/sec\n",
- mode_name[mode],
- SrcFormats[fmt].name, TexSize, TexSize, rate,
mbPerSec);
+ {
+ unsigned err;
+ err = glGetError();
+ if (err) {
+ perf_printf("non-zero glGetError() %d\n", err);
+ exit(1);
}
+ }
- if (SrcFormats[fmt].full_test)
- perf_printf("\n");
+ if (g_csvstyle == CSV_STYLE_DATA || g_csvstyle == CSV_STYLE_FULL) {
+ /* print a unique name to add in spreadsheet computations */
+ perf_printf("%s-%d-%d-%d-%s-%d-%s-%s, ",
+ test_name[test], g_width, g_height, g_level,
+ typeName, g_texelsize, formatName, internalformatName);
+ perf_printf("%s, %d, %d, %d, %s, %d, %s, %s, %.1f, %.1f, %.1f\n",
+ test_name[test], g_width, g_height, g_level, typeName,
g_texelsize, formatName,
+ internalformatName, rate, mbPerSec, mTPerSec);
+ } else {
+ perf_printf("%s(%s %dx%d): " "%.1f images/sec, %.1f MB/sec\n",
+ test_name[test],
+ configName, g_width, g_height, rate, mbPerSec);
}
}