@@ -1,133 +1,133 @@ | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure drawing overhead | |||
* | |||
* This is the first in a series of simple performance benchmarks. | |||
* The code in this file should be as simple as possible to make it | |||
* easily portable to other APIs. | |||
* | |||
* All the window-system stuff should be contained in glmain.c (or TBDmain.c). | |||
* All the re-usable, generic code should be in common.c (XXX not done yet). | |||
* | |||
* Brian Paul | |||
* 15 Sep 2009 | |||
*/ | |||
#include "glmain.h" | |||
#include "common.h" | |||
int WinWidth = 100, WinHeight = 100; | |||
static GLuint VBO; | |||
struct vertex | |||
{ | |||
GLfloat x, y; | |||
}; | |||
static const struct vertex vertices[4] = { | |||
{ -1.0, -1.0 }, | |||
{ 1.0, -1.0 }, | |||
{ 1.0, 1.0 }, | |||
{ -1.0, 1.0 } | |||
}; | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
/* setup VBO w/ vertex data */ | |||
glGenBuffersARB(1, &VBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); | |||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, | |||
sizeof(vertices), vertices, GL_STATIC_DRAW_ARB); | |||
glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), (void *) 0); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
/* misc GL state */ | |||
glAlphaFunc(GL_ALWAYS, 0.0); | |||
} | |||
static void | |||
DrawNoStateChange(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
glDrawArrays(GL_POINTS, 0, 4); | |||
} | |||
glFinish(); | |||
} | |||
static void | |||
DrawNopStateChange(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
glDisable(GL_ALPHA_TEST); | |||
glDrawArrays(GL_POINTS, 0, 4); | |||
} | |||
glFinish(); | |||
} | |||
static void | |||
DrawStateChange(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
if (i & 1) | |||
glEnable(GL_TEXTURE_GEN_S); | |||
else | |||
glDisable(GL_TEXTURE_GEN_S); | |||
glDrawArrays(GL_POINTS, 0, 4); | |||
} | |||
glFinish(); | |||
} | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
double rate0, rate1, rate2, overhead; | |||
rate0 = PerfMeasureRate(DrawNoStateChange); | |||
printf(" Draw only: %.1f draws/second\n", rate0); | |||
rate1 = PerfMeasureRate(DrawNopStateChange); | |||
overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0); | |||
printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n", | |||
rate1, overhead); | |||
rate2 = PerfMeasureRate(DrawStateChange); | |||
overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0); | |||
printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n", | |||
rate2, overhead); | |||
exit(0); | |||
} | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure drawing overhead | |||
* | |||
* This is the first in a series of simple performance benchmarks. | |||
* The code in this file should be as simple as possible to make it | |||
* easily portable to other APIs. | |||
* | |||
* All the window-system stuff should be contained in glmain.c (or TBDmain.c). | |||
* All the re-usable, generic code should be in common.c (XXX not done yet). | |||
* | |||
* Brian Paul | |||
* 15 Sep 2009 | |||
*/ | |||
#include "glmain.h" | |||
#include "common.h" | |||
int WinWidth = 100, WinHeight = 100; | |||
static GLuint VBO; | |||
struct vertex | |||
{ | |||
GLfloat x, y; | |||
}; | |||
static const struct vertex vertices[4] = { | |||
{ -1.0, -1.0 }, | |||
{ 1.0, -1.0 }, | |||
{ 1.0, 1.0 }, | |||
{ -1.0, 1.0 } | |||
}; | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
/* setup VBO w/ vertex data */ | |||
glGenBuffersARB(1, &VBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); | |||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, | |||
sizeof(vertices), vertices, GL_STATIC_DRAW_ARB); | |||
glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), (void *) 0); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
/* misc GL state */ | |||
glAlphaFunc(GL_ALWAYS, 0.0); | |||
} | |||
static void | |||
DrawNoStateChange(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
glDrawArrays(GL_POINTS, 0, 4); | |||
} | |||
glFinish(); | |||
} | |||
static void | |||
DrawNopStateChange(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
glDisable(GL_ALPHA_TEST); | |||
glDrawArrays(GL_POINTS, 0, 4); | |||
} | |||
glFinish(); | |||
} | |||
static void | |||
DrawStateChange(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
if (i & 1) | |||
glEnable(GL_TEXTURE_GEN_S); | |||
else | |||
glDisable(GL_TEXTURE_GEN_S); | |||
glDrawArrays(GL_POINTS, 0, 4); | |||
} | |||
glFinish(); | |||
} | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
double rate0, rate1, rate2, overhead; | |||
rate0 = PerfMeasureRate(DrawNoStateChange); | |||
printf(" Draw only: %.1f draws/second\n", rate0); | |||
rate1 = PerfMeasureRate(DrawNopStateChange); | |||
overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0); | |||
printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n", | |||
rate1, overhead); | |||
rate2 = PerfMeasureRate(DrawStateChange); | |||
overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0); | |||
printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n", | |||
rate2, overhead); | |||
exit(0); | |||
} | |||
@@ -1,210 +1,210 @@ | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure glTexSubImage2D rate | |||
* | |||
* Brian Paul | |||
* 16 Sep 2009 | |||
*/ | |||
#include "glmain.h" | |||
#include "common.h" | |||
int WinWidth = 100, WinHeight = 100; | |||
static GLuint VBO; | |||
static GLuint TexObj = 0; | |||
static GLubyte *TexImage = NULL; | |||
static GLsizei TexSize; | |||
static GLenum TexSrcFormat, TexSrcType; | |||
static const GLboolean DrawPoint = GL_TRUE; | |||
static const GLboolean TexSubImage4 = GL_TRUE; | |||
struct vertex | |||
{ | |||
GLfloat x, y, s, t; | |||
}; | |||
static const struct vertex vertices[1] = { | |||
{ 0.0, 0.0, 0.5, 0.5 }, | |||
}; | |||
#define VOFFSET(F) ((void *) offsetof(struct vertex, F)) | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
/* setup VBO w/ vertex data */ | |||
glGenBuffersARB(1, &VBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); | |||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, | |||
sizeof(vertices), vertices, GL_STATIC_DRAW_ARB); | |||
glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x)); | |||
glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s)); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
glEnableClientState(GL_TEXTURE_COORD_ARRAY); | |||
/* texture */ | |||
glGenTextures(1, &TexObj); | |||
glBindTexture(GL_TEXTURE_2D, TexObj); | |||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |||
glEnable(GL_TEXTURE_2D); | |||
} | |||
static void | |||
UploadTexImage2D(unsigned count) | |||
{ | |||
unsigned i; | |||
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, GL_RGBA, | |||
TexSize, TexSize, 0, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
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; | |||
/* do glTexSubImage2D in four pieces */ | |||
/* lower-left */ | |||
glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
0, 0, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* lower-right */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
halfPos, 0, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* upper-left */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | |||
glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
0, halfPos, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* upper-right */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); | |||
glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
halfPos, halfPos, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* reset the unpacking state */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | |||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); | |||
} | |||
else { | |||
/* replace whole texture image at once */ | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
0, 0, TexSize, TexSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
} | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
/* XXX any other formats to measure? */ | |||
static const struct { | |||
GLenum format, type; | |||
const char *name; | |||
} SrcFormats[] = { | |||
{ GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" }, | |||
{ GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" }, | |||
{ 0, 0, NULL } | |||
}; | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
GLint maxSize; | |||
double rate; | |||
GLint fmt, subImage; | |||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); | |||
/* loop over source data formats */ | |||
for (fmt = 0; SrcFormats[fmt].format; fmt++) { | |||
TexSrcFormat = SrcFormats[fmt].format; | |||
TexSrcType = SrcFormats[fmt].type; | |||
/* loop over glTexImage, glTexSubImage */ | |||
for (subImage = 0; subImage < 2; subImage++) { | |||
/* loop over texture sizes */ | |||
for (TexSize = 16; TexSize <= maxSize; TexSize *= 2) { | |||
GLint bytesPerImage; | |||
double mbPerSec; | |||
bytesPerImage = TexSize * TexSize * 4; | |||
TexImage = malloc(bytesPerImage); | |||
if (subImage) { | |||
/* create initial, empty texture */ | |||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
TexSize, TexSize, 0, | |||
TexSrcFormat, TexSrcType, NULL); | |||
rate = PerfMeasureRate(UploadTexSubImage2D); | |||
} | |||
else { | |||
rate = PerfMeasureRate(UploadTexImage2D); | |||
} | |||
mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0); | |||
printf(" glTex%sImage2D(%s %d x %d): " | |||
"%.1f images/sec, %.1f MB/sec\n", | |||
(subImage ? "Sub" : ""), | |||
SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec); | |||
free(TexImage); | |||
} | |||
} | |||
} | |||
exit(0); | |||
} | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure glTexSubImage2D rate | |||
* | |||
* Brian Paul | |||
* 16 Sep 2009 | |||
*/ | |||
#include "glmain.h" | |||
#include "common.h" | |||
int WinWidth = 100, WinHeight = 100; | |||
static GLuint VBO; | |||
static GLuint TexObj = 0; | |||
static GLubyte *TexImage = NULL; | |||
static GLsizei TexSize; | |||
static GLenum TexSrcFormat, TexSrcType; | |||
static const GLboolean DrawPoint = GL_TRUE; | |||
static const GLboolean TexSubImage4 = GL_TRUE; | |||
struct vertex | |||
{ | |||
GLfloat x, y, s, t; | |||
}; | |||
static const struct vertex vertices[1] = { | |||
{ 0.0, 0.0, 0.5, 0.5 }, | |||
}; | |||
#define VOFFSET(F) ((void *) offsetof(struct vertex, F)) | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
/* setup VBO w/ vertex data */ | |||
glGenBuffersARB(1, &VBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); | |||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, | |||
sizeof(vertices), vertices, GL_STATIC_DRAW_ARB); | |||
glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x)); | |||
glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s)); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
glEnableClientState(GL_TEXTURE_COORD_ARRAY); | |||
/* texture */ | |||
glGenTextures(1, &TexObj); | |||
glBindTexture(GL_TEXTURE_2D, TexObj); | |||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |||
glEnable(GL_TEXTURE_2D); | |||
} | |||
static void | |||
UploadTexImage2D(unsigned count) | |||
{ | |||
unsigned i; | |||
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, GL_RGBA, | |||
TexSize, TexSize, 0, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
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; | |||
/* do glTexSubImage2D in four pieces */ | |||
/* lower-left */ | |||
glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
0, 0, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* lower-right */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
halfPos, 0, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* upper-left */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | |||
glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
0, halfPos, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* upper-right */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); | |||
glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
halfPos, halfPos, halfSize, halfSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
/* reset the unpacking state */ | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | |||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | |||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); | |||
} | |||
else { | |||
/* replace whole texture image at once */ | |||
glTexSubImage2D(GL_TEXTURE_2D, 0, | |||
0, 0, TexSize, TexSize, | |||
TexSrcFormat, TexSrcType, TexImage); | |||
} | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
/* XXX any other formats to measure? */ | |||
static const struct { | |||
GLenum format, type; | |||
const char *name; | |||
} SrcFormats[] = { | |||
{ GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" }, | |||
{ GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" }, | |||
{ 0, 0, NULL } | |||
}; | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
GLint maxSize; | |||
double rate; | |||
GLint fmt, subImage; | |||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); | |||
/* loop over source data formats */ | |||
for (fmt = 0; SrcFormats[fmt].format; fmt++) { | |||
TexSrcFormat = SrcFormats[fmt].format; | |||
TexSrcType = SrcFormats[fmt].type; | |||
/* loop over glTexImage, glTexSubImage */ | |||
for (subImage = 0; subImage < 2; subImage++) { | |||
/* loop over texture sizes */ | |||
for (TexSize = 16; TexSize <= maxSize; TexSize *= 2) { | |||
GLint bytesPerImage; | |||
double mbPerSec; | |||
bytesPerImage = TexSize * TexSize * 4; | |||
TexImage = malloc(bytesPerImage); | |||
if (subImage) { | |||
/* create initial, empty texture */ | |||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |||
TexSize, TexSize, 0, | |||
TexSrcFormat, TexSrcType, NULL); | |||
rate = PerfMeasureRate(UploadTexSubImage2D); | |||
} | |||
else { | |||
rate = PerfMeasureRate(UploadTexImage2D); | |||
} | |||
mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0); | |||
printf(" glTex%sImage2D(%s %d x %d): " | |||
"%.1f images/sec, %.1f MB/sec\n", | |||
(subImage ? "Sub" : ""), | |||
SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec); | |||
free(TexImage); | |||
} | |||
} | |||
} | |||
exit(0); | |||
} |
@@ -1,138 +1,138 @@ | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure VBO upload speed. | |||
* That is, measure glBufferDataARB() and glBufferSubDataARB(). | |||
* | |||
* Brian Paul | |||
* 16 Sep 2009 | |||
*/ | |||
#include <string.h> | |||
#include "glmain.h" | |||
#include "common.h" | |||
int WinWidth = 100, WinHeight = 100; | |||
static GLuint VBO; | |||
static GLsizei VBOSize = 0; | |||
static GLubyte *VBOData = NULL; | |||
static const GLboolean DrawPoint = GL_TRUE; | |||
static const GLboolean BufferSubDataInHalves = GL_TRUE; | |||
static const GLfloat Vertex0[2] = { 0.0, 0.0 }; | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
/* setup VBO */ | |||
glGenBuffersARB(1, &VBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); | |||
glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
} | |||
static void | |||
UploadVBO(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
static void | |||
UploadSubVBO(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
if (BufferSubDataInHalves) { | |||
GLsizei half = VBOSize / 2; | |||
glBufferSubDataARB(GL_ARRAY_BUFFER, 0, half, VBOData); | |||
glBufferSubDataARB(GL_ARRAY_BUFFER, half, half, VBOData + half); | |||
} | |||
else { | |||
glBufferSubDataARB(GL_ARRAY_BUFFER, 0, VBOSize, VBOData); | |||
} | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
static const GLsizei Sizes[] = { | |||
64, | |||
1024, | |||
16*1024, | |||
256*1024, | |||
1024*1024, | |||
16*1024*1024, | |||
0 /* end of list */ | |||
}; | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
double rate, mbPerSec; | |||
int sub, sz; | |||
/* loop over whole/sub buffer upload */ | |||
for (sub = 0; sub < 2; sub++) { | |||
/* loop over VBO sizes */ | |||
for (sz = 0; Sizes[sz]; sz++) { | |||
VBOSize = Sizes[sz]; | |||
VBOData = malloc(VBOSize); | |||
memcpy(VBOData, Vertex0, sizeof(Vertex0)); | |||
if (sub) | |||
rate = PerfMeasureRate(UploadSubVBO); | |||
else | |||
rate = PerfMeasureRate(UploadVBO); | |||
mbPerSec = rate * VBOSize / (1024.0 * 1024.0); | |||
printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", | |||
(sub ? "Sub" : ""), VBOSize, mbPerSec); | |||
free(VBOData); | |||
} | |||
} | |||
exit(0); | |||
} | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure VBO upload speed. | |||
* That is, measure glBufferDataARB() and glBufferSubDataARB(). | |||
* | |||
* Brian Paul | |||
* 16 Sep 2009 | |||
*/ | |||
#include <string.h> | |||
#include "glmain.h" | |||
#include "common.h" | |||
int WinWidth = 100, WinHeight = 100; | |||
static GLuint VBO; | |||
static GLsizei VBOSize = 0; | |||
static GLubyte *VBOData = NULL; | |||
static const GLboolean DrawPoint = GL_TRUE; | |||
static const GLboolean BufferSubDataInHalves = GL_TRUE; | |||
static const GLfloat Vertex0[2] = { 0.0, 0.0 }; | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
/* setup VBO */ | |||
glGenBuffersARB(1, &VBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); | |||
glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
} | |||
static void | |||
UploadVBO(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
static void | |||
UploadSubVBO(unsigned count) | |||
{ | |||
unsigned i; | |||
for (i = 0; i < count; i++) { | |||
if (BufferSubDataInHalves) { | |||
GLsizei half = VBOSize / 2; | |||
glBufferSubDataARB(GL_ARRAY_BUFFER, 0, half, VBOData); | |||
glBufferSubDataARB(GL_ARRAY_BUFFER, half, half, VBOData + half); | |||
} | |||
else { | |||
glBufferSubDataARB(GL_ARRAY_BUFFER, 0, VBOSize, VBOData); | |||
} | |||
if (DrawPoint) | |||
glDrawArrays(GL_POINTS, 0, 1); | |||
} | |||
glFinish(); | |||
} | |||
static const GLsizei Sizes[] = { | |||
64, | |||
1024, | |||
16*1024, | |||
256*1024, | |||
1024*1024, | |||
16*1024*1024, | |||
0 /* end of list */ | |||
}; | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
double rate, mbPerSec; | |||
int sub, sz; | |||
/* loop over whole/sub buffer upload */ | |||
for (sub = 0; sub < 2; sub++) { | |||
/* loop over VBO sizes */ | |||
for (sz = 0; Sizes[sz]; sz++) { | |||
VBOSize = Sizes[sz]; | |||
VBOData = malloc(VBOSize); | |||
memcpy(VBOData, Vertex0, sizeof(Vertex0)); | |||
if (sub) | |||
rate = PerfMeasureRate(UploadSubVBO); | |||
else | |||
rate = PerfMeasureRate(UploadVBO); | |||
mbPerSec = rate * VBOSize / (1024.0 * 1024.0); | |||
printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", | |||
(sub ? "Sub" : ""), VBOSize, mbPerSec); | |||
free(VBOData); | |||
} | |||
} | |||
exit(0); | |||
} |
@@ -1,271 +1,271 @@ | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure simple vertex processing rate via: | |||
* - immediate mode | |||
* - vertex arrays | |||
* - VBO vertex arrays | |||
* - glDrawElements | |||
* - VBO glDrawElements | |||
* - glDrawRangeElements | |||
* - VBO glDrawRangeElements | |||
* | |||
* Brian Paul | |||
* 16 Sep 2009 | |||
*/ | |||
#include <assert.h> | |||
#include <string.h> | |||
#include "glmain.h" | |||
#include "common.h" | |||
#define MAX_VERTS (100 * 100) | |||
/** glVertex2/3/4 size */ | |||
#define VERT_SIZE 4 | |||
int WinWidth = 500, WinHeight = 500; | |||
static GLuint VertexBO, ElementBO; | |||
static unsigned NumVerts = MAX_VERTS; | |||
static unsigned VertBytes = VERT_SIZE * sizeof(float); | |||
static float *VertexData = NULL; | |||
static unsigned NumElements = MAX_VERTS; | |||
static GLuint *Elements = NULL; | |||
/** | |||
* Load VertexData buffer with a 2-D grid of points in the range [-1,1]^2. | |||
*/ | |||
static void | |||
InitializeVertexData(void) | |||
{ | |||
unsigned i; | |||
float x = -1.0, y = -1.0; | |||
float dx = 2.0 / 100; | |||
float dy = 2.0 / 100; | |||
VertexData = (float *) malloc(NumVerts * VertBytes); | |||
for (i = 0; i < NumVerts; i++) { | |||
VertexData[i * VERT_SIZE + 0] = x; | |||
VertexData[i * VERT_SIZE + 1] = y; | |||
VertexData[i * VERT_SIZE + 2] = 0.0; | |||
VertexData[i * VERT_SIZE + 3] = 1.0; | |||
x += dx; | |||
if (x > 1.0) { | |||
x = -1.0; | |||
y += dy; | |||
} | |||
} | |||
Elements = (GLuint *) malloc(NumVerts * sizeof(GLuint)); | |||
for (i = 0; i < NumVerts; i++) { | |||
Elements[i] = NumVerts - i - 1; | |||
} | |||
} | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
InitializeVertexData(); | |||
/* setup VertexBO */ | |||
glGenBuffersARB(1, &VertexBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBO); | |||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, | |||
NumVerts * VertBytes, VertexData, GL_STATIC_DRAW_ARB); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
/* setup ElementBO */ | |||
glGenBuffersARB(1, &ElementBO); | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ElementBO); | |||
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, | |||
NumElements * sizeof(GLuint), Elements, GL_STATIC_DRAW_ARB); | |||
} | |||
static void | |||
DrawImmediate(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
for (i = 0; i < count; i++) { | |||
unsigned j; | |||
glBegin(GL_POINTS); | |||
for (j = 0; j < NumVerts; j++) { | |||
#if VERT_SIZE == 4 | |||
glVertex4fv(VertexData + j * 4); | |||
#elif VERT_SIZE == 3 | |||
glVertex3fv(VertexData + j * 3); | |||
#elif VERT_SIZE == 2 | |||
glVertex2fv(VertexData + j * 2); | |||
#else | |||
abort(); | |||
#endif | |||
} | |||
glEnd(); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawArraysMem(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData); | |||
for (i = 0; i < count; i++) { | |||
glDrawArrays(GL_POINTS, 0, NumVerts); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawArraysVBO(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, VertexBO); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0); | |||
for (i = 0; i < count; i++) { | |||
glDrawArrays(GL_POINTS, 0, NumVerts); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawElementsMem(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData); | |||
for (i = 0; i < count; i++) { | |||
glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, Elements); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawElementsBO(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER, VertexBO); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0); | |||
for (i = 0; i < count; i++) { | |||
glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, (void *) 0); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawRangeElementsMem(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData); | |||
for (i = 0; i < count; i++) { | |||
glDrawRangeElements(GL_POINTS, 0, NumVerts - 1, | |||
NumVerts, GL_UNSIGNED_INT, Elements); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawRangeElementsBO(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER, VertexBO); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0); | |||
for (i = 0; i < count; i++) { | |||
glDrawRangeElements(GL_POINTS, 0, NumVerts - 1, | |||
NumVerts, GL_UNSIGNED_INT, (void *) 0); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
double rate; | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE); | |||
rate = PerfMeasureRate(DrawImmediate); | |||
rate *= NumVerts; | |||
printf(" Immediate mode: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawArraysMem); | |||
rate *= NumVerts; | |||
printf(" glDrawArrays: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawArraysVBO); | |||
rate *= NumVerts; | |||
printf(" VBO glDrawArrays: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawElementsMem); | |||
rate *= NumVerts; | |||
printf(" glDrawElements: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawElementsBO); | |||
rate *= NumVerts; | |||
printf(" VBO glDrawElements: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawRangeElementsMem); | |||
rate *= NumVerts; | |||
printf(" glDrawRangeElements: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawRangeElementsBO); | |||
rate *= NumVerts; | |||
printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate); | |||
exit(0); | |||
} | |||
/* | |||
* Copyright (C) 2009 VMware, Inc. All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included | |||
* in all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
*/ | |||
/** | |||
* Measure simple vertex processing rate via: | |||
* - immediate mode | |||
* - vertex arrays | |||
* - VBO vertex arrays | |||
* - glDrawElements | |||
* - VBO glDrawElements | |||
* - glDrawRangeElements | |||
* - VBO glDrawRangeElements | |||
* | |||
* Brian Paul | |||
* 16 Sep 2009 | |||
*/ | |||
#include <assert.h> | |||
#include <string.h> | |||
#include "glmain.h" | |||
#include "common.h" | |||
#define MAX_VERTS (100 * 100) | |||
/** glVertex2/3/4 size */ | |||
#define VERT_SIZE 4 | |||
int WinWidth = 500, WinHeight = 500; | |||
static GLuint VertexBO, ElementBO; | |||
static unsigned NumVerts = MAX_VERTS; | |||
static unsigned VertBytes = VERT_SIZE * sizeof(float); | |||
static float *VertexData = NULL; | |||
static unsigned NumElements = MAX_VERTS; | |||
static GLuint *Elements = NULL; | |||
/** | |||
* Load VertexData buffer with a 2-D grid of points in the range [-1,1]^2. | |||
*/ | |||
static void | |||
InitializeVertexData(void) | |||
{ | |||
unsigned i; | |||
float x = -1.0, y = -1.0; | |||
float dx = 2.0 / 100; | |||
float dy = 2.0 / 100; | |||
VertexData = (float *) malloc(NumVerts * VertBytes); | |||
for (i = 0; i < NumVerts; i++) { | |||
VertexData[i * VERT_SIZE + 0] = x; | |||
VertexData[i * VERT_SIZE + 1] = y; | |||
VertexData[i * VERT_SIZE + 2] = 0.0; | |||
VertexData[i * VERT_SIZE + 3] = 1.0; | |||
x += dx; | |||
if (x > 1.0) { | |||
x = -1.0; | |||
y += dy; | |||
} | |||
} | |||
Elements = (GLuint *) malloc(NumVerts * sizeof(GLuint)); | |||
for (i = 0; i < NumVerts; i++) { | |||
Elements[i] = NumVerts - i - 1; | |||
} | |||
} | |||
/** Called from test harness/main */ | |||
void | |||
PerfInit(void) | |||
{ | |||
InitializeVertexData(); | |||
/* setup VertexBO */ | |||
glGenBuffersARB(1, &VertexBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBO); | |||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, | |||
NumVerts * VertBytes, VertexData, GL_STATIC_DRAW_ARB); | |||
glEnableClientState(GL_VERTEX_ARRAY); | |||
/* setup ElementBO */ | |||
glGenBuffersARB(1, &ElementBO); | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ElementBO); | |||
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, | |||
NumElements * sizeof(GLuint), Elements, GL_STATIC_DRAW_ARB); | |||
} | |||
static void | |||
DrawImmediate(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
for (i = 0; i < count; i++) { | |||
unsigned j; | |||
glBegin(GL_POINTS); | |||
for (j = 0; j < NumVerts; j++) { | |||
#if VERT_SIZE == 4 | |||
glVertex4fv(VertexData + j * 4); | |||
#elif VERT_SIZE == 3 | |||
glVertex3fv(VertexData + j * 3); | |||
#elif VERT_SIZE == 2 | |||
glVertex2fv(VertexData + j * 2); | |||
#else | |||
abort(); | |||
#endif | |||
} | |||
glEnd(); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawArraysMem(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData); | |||
for (i = 0; i < count; i++) { | |||
glDrawArrays(GL_POINTS, 0, NumVerts); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawArraysVBO(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, VertexBO); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0); | |||
for (i = 0; i < count; i++) { | |||
glDrawArrays(GL_POINTS, 0, NumVerts); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawElementsMem(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData); | |||
for (i = 0; i < count; i++) { | |||
glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, Elements); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawElementsBO(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER, VertexBO); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0); | |||
for (i = 0; i < count; i++) { | |||
glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, (void *) 0); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawRangeElementsMem(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0); | |||
glBindBufferARB(GL_ARRAY_BUFFER, 0); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData); | |||
for (i = 0; i < count; i++) { | |||
glDrawRangeElements(GL_POINTS, 0, NumVerts - 1, | |||
NumVerts, GL_UNSIGNED_INT, Elements); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
static void | |||
DrawRangeElementsBO(unsigned count) | |||
{ | |||
unsigned i; | |||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO); | |||
glBindBufferARB(GL_ARRAY_BUFFER, VertexBO); | |||
glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0); | |||
for (i = 0; i < count; i++) { | |||
glDrawRangeElements(GL_POINTS, 0, NumVerts - 1, | |||
NumVerts, GL_UNSIGNED_INT, (void *) 0); | |||
} | |||
glFinish(); | |||
PerfSwapBuffers(); | |||
} | |||
/** Called from test harness/main */ | |||
void | |||
PerfDraw(void) | |||
{ | |||
double rate; | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE); | |||
rate = PerfMeasureRate(DrawImmediate); | |||
rate *= NumVerts; | |||
printf(" Immediate mode: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawArraysMem); | |||
rate *= NumVerts; | |||
printf(" glDrawArrays: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawArraysVBO); | |||
rate *= NumVerts; | |||
printf(" VBO glDrawArrays: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawElementsMem); | |||
rate *= NumVerts; | |||
printf(" glDrawElements: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawElementsBO); | |||
rate *= NumVerts; | |||
printf(" VBO glDrawElements: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawRangeElementsMem); | |||
rate *= NumVerts; | |||
printf(" glDrawRangeElements: %.1f verts/sec\n", rate); | |||
rate = PerfMeasureRate(DrawRangeElementsBO); | |||
rate *= NumVerts; | |||
printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate); | |||
exit(0); | |||
} |