diff options
author | Brian Paul <brianp@users.sourceforge.net> | 2008-01-01 19:55:49 +0000 |
---|---|---|
committer | Brian Paul <brianp@users.sourceforge.net> | 2008-01-01 19:55:49 +0000 |
commit | 158ed9377b3f3e9c237d0f1f763637f6db73d5f3 (patch) | |
tree | 8f2df6ee7a140f22445f95e9645e19234bd1e986 | |
parent | 5e5f942f610d773ad28e343fa31b1d217be0bae9 (diff) |
new GL_EXT_pixel_buffer_object test (Shuang He, Intel)
-rw-r--r-- | doc/html/changes.html | 1 | ||||
-rw-r--r-- | src/glean/tpbo.cpp | 1240 | ||||
-rw-r--r-- | src/glean/tpbo.h | 86 |
3 files changed, 1327 insertions, 0 deletions
diff --git a/doc/html/changes.html b/doc/html/changes.html index 392111d..ea1be01 100644 --- a/doc/html/changes.html +++ b/doc/html/changes.html @@ -28,6 +28,7 @@ descriptions. Added the following new tests: </P> <UL> +<LI>pbo - test the GL_EXT_pixel_buffer_object extension (Shuang He, Intel) <li>occluQry - test GL_ARB_occlusion_query extension (Wei Wang) <LI>api2 - test the OpenGL 2.0 API functions, most of which are related to the OpenGL shading language. (Brian Paul)</LI> diff --git a/src/glean/tpbo.cpp b/src/glean/tpbo.cpp new file mode 100644 index 0000000..130786e --- /dev/null +++ b/src/glean/tpbo.cpp @@ -0,0 +1,1240 @@ +// BEGIN_COPYRIGHT -*- glean -*- +// +// Copyrigth (C) 2007 Intel Corporation +// Copyright (C) 1999 Allen Akin 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 ALLEN AKIN 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. +// +// END_COPYRIGHT +// +// Authors: +// Shuang He <shuang.he@intel.com> +// +// tpbo.cpp: Test OpenGL Extension GL_ARB_pixel_buffer_object + + +#define GL_GLEXT_PROTOTYPES +#include "tpbo.h" +#include <cassert> +#include <math.h> +#include "timer.h" +namespace GLEAN +{ + +static int usePBO; +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +bool PBOTest::setup(void) +{ + glMatrixMode(GL_PROJECTION); + + glLoadIdentity(); + gluOrtho2D(0, 100, 0, 100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDrawBuffer(GL_FRONT); + glReadBuffer(GL_FRONT); + + // compute error tolerances (may need fine-tuning) + int + bufferBits[5]; + + glGetIntegerv(GL_RED_BITS, &bufferBits[0]); + glGetIntegerv(GL_GREEN_BITS, &bufferBits[1]); + glGetIntegerv(GL_BLUE_BITS, &bufferBits[2]); + glGetIntegerv(GL_ALPHA_BITS, &bufferBits[3]); + glGetIntegerv(GL_DEPTH_BITS, &bufferBits[4]); + + tolerance[0] = 2.0 / (1 << bufferBits[0]); + tolerance[1] = 2.0 / (1 << bufferBits[1]); + tolerance[2] = 2.0 / (1 << bufferBits[2]); + if (bufferBits[3]) + tolerance[3] = 2.0 / (1 << bufferBits[3]); + else + tolerance[3] = 1.0; + if (bufferBits[4]) + tolerance[4] = 16.0 / (1 << bufferBits[4]); + else + tolerance[4] = 1.0; + + // Check if GL_ARB_pixel_buffer_object is supported + if (!strstr((char *) glGetString(GL_EXTENSIONS), "GL_ARB_pixel_buffer_object")) { + printf("GL_ARB_pixel_buffer_object is not supported\n"); + usePBO = 0; + return false; + } + else { + printf("GL_ARB_pixel_buffer_object is supported\n"); + usePBO = 1; + } + + return true; +} + + +void +PBOTest::reportFailure(const char *msg, const int line) const +{ + env->log << "FAILURE: " << msg << " (at tpbo.cpp:" << line << ")\n"; +} + +void +PBOTest::reportFailure(const char *msg, const GLenum target, const int line) const +{ + env->log << "FAILURE: " << msg; + if (target == GL_FRAGMENT_SHADER) + env->log << " (fragment)"; + else + env->log << " (vertex)"; + env->log << " (at tpbo.cpp:" << line << ")\n"; +} + +#define REPORT_FAILURE(MSG) reportFailure(MSG, __LINE__) +#define REPORT_FAILURE_T(MSG, TARGET) reportFailure(MSG, TARGET, __LINE__) +// Compare actual and expected colors +bool PBOTest::equalColors(const GLfloat act[3], const GLfloat exp[3]) const +{ + if ((fabsf(act[0] - exp[0]) > tolerance[0]) + || (fabsf(act[1] - exp[1]) > tolerance[1]) + || (fabsf(act[2] - exp[2]) > tolerance[2])) { + return false; + } + else + return true; +} + +bool PBOTest::equalColors1(const GLubyte act[3], const GLubyte exp[3]) const +{ + if ((act[0] != exp[0]) + || (act[1] != exp[1]) + || (act[2] != exp[2])) { + return false; + } + else + return true; +} + + + +#define TEXSIZE 64 + +bool PBOTest::testSanity(void) +{ + GLuint pbs[1]; + GLuint pb_binding; + + if (!usePBO) + return true; + + // Check default binding + glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING_ARB, (GLint *) & pb_binding); + if (pb_binding != 0) { + REPORT_FAILURE("Failed to bind unpack pixel buffer object"); + return false; + } + + glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING_ARB, (GLint *) & pb_binding); + if (pb_binding != 0) { + REPORT_FAILURE("Failed to bind pack pixel buffer object"); + return false; + } + + glGenBuffersARB(1, pbs); + + if (glIsBufferARB(pbs[0]) != GL_TRUE) { + REPORT_FAILURE("Failed to call glIsBuffersARB"); + return false; + } + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbs[0]); + glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING_ARB, (GLint *) & pb_binding); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); + if (pb_binding != pbs[0]) { + REPORT_FAILURE("Failed to bind unpack pixel buffer object"); + return false; + } + + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbs[0]); + glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING_ARB, (GLint *) & pb_binding); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); + if (pb_binding != pbs[0]) { + REPORT_FAILURE("Failed to bind unpack pixel buffer object"); + return false; + } + + glDeleteBuffersARB(1, pbs); + + if (glIsBufferARB(pbs[0]) == GL_TRUE) { + REPORT_FAILURE("Failed to call glIsBuffersARB"); + return false; + } + + return true; +} + + +bool PBOTest::testDrawPixels(void) +{ + int useUnpackBuffer; + int usePackBuffer; + GLuint pb_pack[1]; + GLuint pb_unpack[1]; + GLubyte buf[windowSize * windowSize * 4]; + GLubyte t[TEXSIZE * TEXSIZE * 4]; + int i, j; + GLubyte * pboPackMem = NULL; + GLubyte black[3] = { 0, 0, 0 }; + + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0); + + for (useUnpackBuffer = 0; useUnpackBuffer < usePBO + 1; useUnpackBuffer++) { + for (usePackBuffer = 0; usePackBuffer < usePBO + 1; usePackBuffer++) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + if (useUnpackBuffer) { + glGenBuffersARB(1, pb_unpack); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb_unpack[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, + TEXSIZE * TEXSIZE * 4 * sizeof(GLubyte), NULL, + GL_STREAM_DRAW); + } + GLubyte *pboMem = NULL; + if (useUnpackBuffer) { + pboMem = (GLubyte *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + } + else { + pboMem = t; + } + + for (i = 0; i < TEXSIZE; i++) + for (j = 0; j < TEXSIZE; j++) { + pboMem[4 * (i * TEXSIZE + j)] = i % 256; + pboMem[4 * (i * TEXSIZE + j) + 1] = i % 256; + pboMem[4 * (i * TEXSIZE + j) + 2] = i % 256; + pboMem[4 * (i * TEXSIZE + j) + 3] = 0; + } + + if (useUnpackBuffer) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + + if (useUnpackBuffer) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb_unpack[0]); + glDrawPixels(TEXSIZE, TEXSIZE, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + else + glDrawPixels(TEXSIZE, TEXSIZE, GL_BGRA, GL_UNSIGNED_BYTE, pboMem); + + // Check the result + if (usePackBuffer) { + glGenBuffersARB(1, pb_pack); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pb_pack[0]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + windowSize * windowSize * 4 * + sizeof(GL_UNSIGNED_BYTE), NULL, GL_STREAM_DRAW); + glReadPixels(0, 0, windowSize, windowSize, GL_BGRA, + GL_UNSIGNED_BYTE, NULL); + pboPackMem = (GLubyte *) glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, + GL_READ_ONLY); + } + else { + pboPackMem = buf; + glReadPixels(0, 0, windowSize, windowSize, GL_BGRA, + GL_UNSIGNED_BYTE, pboPackMem); + } + + for (j = 0; j < windowSize; j++) { + for (i = 0; i < windowSize; i++) { + GLubyte exp[3]; + exp[0] = j % 256; + exp[1] = j % 256; + exp[2] = j % 256; + + if (i < TEXSIZE && j < TEXSIZE) { + if (equalColors1(&pboPackMem[(j * windowSize + i) * 4], exp) + != true) { + REPORT_FAILURE("glDrawPixels failed"); + printf(" got (%d, %d) = [%d, %d, %d], ", i, j, + pboPackMem[(j * windowSize + i) * 4], + pboPackMem[(j * windowSize + i) * 4 + 1], + pboPackMem[(j * windowSize + i) * 4 + 2]); + printf("should be [%d, %d, %d]\n", + exp[0], exp[1], exp[2]); + + return false; + } + } + else { + if (equalColors1(&pboPackMem[(j * windowSize + i) * 4], + black) != true) { + REPORT_FAILURE("glDrawPixels failed"); + printf("(%d, %d) = [%d, %d, %d], ", i, j, + pboPackMem[(j * windowSize + i) * 4], + pboPackMem[(j * windowSize + i) * 4 + 1], + pboPackMem[(j * windowSize + i) * 4 + 2]); + printf("should be [0.0, 0.0, 0.0]\n"); + return false; + } + + } + } + } + + + if (usePackBuffer) { + glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pb_pack); + } + + if (useUnpackBuffer) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pb_unpack); + } + + } + } + + return true; +} + + +bool PBOTest::testPixelMap(void) +{ + int useUnpackBuffer; + int usePackBuffer; + GLuint pb_pack[1]; + GLuint pb_unpack[1]; + int i; + int size; + int max; + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + glGetIntegerv(GL_MAX_PIXEL_MAP_TABLE, &max); + + for (usePackBuffer = 0; usePackBuffer < usePBO + 1; usePackBuffer++) { + for (useUnpackBuffer = 0; useUnpackBuffer < usePBO + 1; + useUnpackBuffer++) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + if (useUnpackBuffer) { + glGenBuffersARB(1, pb_unpack); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb_unpack[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, max * sizeof(GLushort), + NULL, GL_STREAM_DRAW); + } + GLushort *pboMem = NULL; + if (useUnpackBuffer) { + pboMem = (GLushort *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + } + else { + pboMem = (GLushort *) malloc(sizeof(GLushort) * max); + } + for (i = 0; i < max; i++) + pboMem[i] = max - i - 1; + + if (useUnpackBuffer) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glPixelMapusv(GL_PIXEL_MAP_R_TO_R, max, NULL); + glPixelMapusv(GL_PIXEL_MAP_G_TO_G, max, NULL); + glPixelMapusv(GL_PIXEL_MAP_B_TO_B, max, NULL); + glPixelMapusv(GL_PIXEL_MAP_A_TO_A, max, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + else { + glPixelMapusv(GL_PIXEL_MAP_R_TO_R, max, pboMem); + glPixelMapusv(GL_PIXEL_MAP_G_TO_G, max, pboMem); + glPixelMapusv(GL_PIXEL_MAP_B_TO_B, max, pboMem); + glPixelMapusv(GL_PIXEL_MAP_A_TO_A, max, pboMem); + free(pboMem); + } + + + glGetIntegerv(GL_PIXEL_MAP_R_TO_R_SIZE, &size); + if (size != max) { + REPORT_FAILURE("glPixelMap failed"); + return false; + } + glPixelTransferi(GL_MAP_COLOR, GL_FALSE); + + // Read back pixel map + if (usePackBuffer) { + glGenBuffersARB(1, pb_pack); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pb_pack[0]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, max * sizeof(GLushort), + NULL, GL_STREAM_DRAW); + glGetPixelMapusv(GL_PIXEL_MAP_R_TO_R, NULL); + pboMem = (GLushort *) glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, + GL_READ_ONLY); + } + else { + pboMem = (GLushort *) malloc(sizeof(GLushort) * max); + glGetPixelMapusv(GL_PIXEL_MAP_R_TO_R, pboMem); + } + + for (i = 0; i < max; i++) { + if (pboMem[i] != (255 - i)) { + REPORT_FAILURE("get PixelMap failed"); + return false; + } + } + + + if (usePackBuffer) { + glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pb_pack); + } + else { + free(pboMem); + } + + if (useUnpackBuffer) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pb_unpack); + } + + } + } + + return true; +} + +bool PBOTest::testBitmap(void) +{ + GLuint pb_unpack[1]; + GLuint pb_pack[1]; + int useUnpackBuffer = usePBO; + int usePackBuffer = 0; + GLubyte bitmap[TEXSIZE * TEXSIZE / 8]; + GLfloat buf[windowSize * windowSize * 3]; + GLfloat white[3] = { 1.0, 1.0, 1.0 }; + GLfloat black[3] = { 0.0, 0.0, 0.0 }; + int i, j; + GLubyte *pboUnpackMem = NULL; + GLfloat *pboPackMem = NULL; + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + for (usePackBuffer = 0; usePackBuffer < usePBO + 1; usePackBuffer++) { + for (useUnpackBuffer = 0; useUnpackBuffer < usePBO + 1; + useUnpackBuffer++) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + if (useUnpackBuffer) { + glGenBuffersARB(1, pb_unpack); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pb_unpack[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, TEXSIZE * TEXSIZE, NULL, + GL_STREAM_DRAW); + pboUnpackMem = (GLubyte *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + } + else { + pboUnpackMem = bitmap; + } + + for (i = 0; i < TEXSIZE * TEXSIZE / 8; i++) { + pboUnpackMem[i] = 0xAA; + } + + + glColor4f(1.0, 1.0, 1.0, 0.0); + glRasterPos2f(0.0, 0.0); + if (useUnpackBuffer) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + else + glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0, pboUnpackMem); + + // Check the result + if (usePackBuffer) { + glGenBuffersARB(1, pb_pack); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pb_pack[0]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, TEXSIZE * TEXSIZE, NULL, + GL_STREAM_DRAW); + glReadPixels(0, 0, windowSize, windowSize, GL_RGB, GL_FLOAT, + NULL); + pboPackMem = + (GLfloat *) glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, + GL_READ_ONLY); + } + else { + pboPackMem = buf; + glReadPixels(0, 0, windowSize, windowSize, GL_RGB, GL_FLOAT, + pboPackMem); + } + + for (j = 0; j < windowSize; j++) { + for (i = 0; i < windowSize; i++) { + const GLfloat *exp; + if ((i & 1)) + exp = black; + else + exp = white; + if (i < TEXSIZE && j < TEXSIZE) { + if (equalColors(&pboPackMem[(j * windowSize + i) * 3], exp) + != true) { + REPORT_FAILURE("glBitmap failed"); + printf(" got (%d, %d) = [%f, %f, %f], ", i, j, + pboPackMem[(j * windowSize + i) * 3], + pboPackMem[(j * windowSize + i) * 3 + 1], + pboPackMem[(j * windowSize + i) * 3 + 2]); + printf("should be [%f, %f, %f]\n", + exp[0], exp[1], exp[2]); + + return false; + } + } + else { + if (equalColors + (&pboPackMem[(j * windowSize + i) * 3], + black) != true) { + REPORT_FAILURE("glBitmap failed"); + printf("(%d, %d) = [%f, %f, %f], ", i, j, + pboPackMem[(j * windowSize + i) * 3], + pboPackMem[(j * windowSize + i) * 3 + 1], + pboPackMem[(j * windowSize + i) * 3 + 2]); + printf("should be [0.0, 0.0, 0.0]\n"); + return false; + } + + } + } + } + if (usePackBuffer) { + glUnmapBuffer(GL_PIXEL_PACK_BUFFER_EXT); + glBindBuffer(GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pb_pack); + } + + if (useUnpackBuffer) { + glBindBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pb_unpack); + } + } + } + return true; +} + + +bool PBOTest::testTexImage(void) +{ + int breakCOWPBO, breakCOWTexture; + int useTexUnpackBuffer, useTexPackBuffer; + GLuint unpack_pb[1]; + GLuint pack_pb[1]; + GLfloat t1[TEXSIZE * TEXSIZE * 3]; + GLfloat t2[TEXSIZE * TEXSIZE * 3]; + GLfloat *pboMem = NULL; + int i, j; + GLfloat green[3] = { 1.0, 1.0, 0.0 }; + GLfloat black[3] = { 0.0, 0.0, 0.0 }; + GLfloat buf[windowSize * windowSize * 3]; + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + for (useTexPackBuffer = 0; useTexPackBuffer < usePBO + 1; + useTexPackBuffer++) { + for (useTexUnpackBuffer = 0; useTexUnpackBuffer < usePBO + 1; + useTexUnpackBuffer++) { + for (breakCOWPBO = 0; breakCOWPBO < useTexUnpackBuffer + 1; + breakCOWPBO++) { + for (breakCOWTexture = 0; + breakCOWTexture < useTexUnpackBuffer + 1; + breakCOWTexture++) { + if (useTexUnpackBuffer) { + glGenBuffersARB(1, unpack_pb); + if (glIsBufferARB(unpack_pb[0]) == false) + return false; + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, unpack_pb[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, + TEXSIZE * TEXSIZE * 3 * sizeof(GLfloat), NULL, + GL_STREAM_DRAW); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + + if (useTexUnpackBuffer) { + pboMem = + (GLfloat *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + } + else { + pboMem = t1; + } + + for (i = 0; i < TEXSIZE * TEXSIZE; i++) { + pboMem[3 * i] = 1.0; + pboMem[3 * i + 1] = 1.0; + pboMem[3 * i + 2] = 0.0; + } + + if (useTexUnpackBuffer) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE, TEXSIZE, 0, + GL_RGB, GL_FLOAT, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + else + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEXSIZE, TEXSIZE, 0, + GL_RGB, GL_FLOAT, pboMem); + + if (useTexUnpackBuffer) { + if (breakCOWPBO) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, unpack_pb[0]); + pboMem = + (GLfloat *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + for (i = 0; i < TEXSIZE * TEXSIZE * 3; i++) + pboMem[i] = 0.2; + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + } + + if (useTexUnpackBuffer) { + if (breakCOWTexture) { + GLfloat temp[1 * 1 * 3]; + for (i = 0; i < 1 * 1 * 3; i++) + temp[i] = 0.8; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGB, + GL_FLOAT, temp); + } + } + + // Check PBO's content + if (useTexUnpackBuffer) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, unpack_pb[0]); + pboMem = (GLfloat *) glMapBuffer(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY); + if (breakCOWPBO) { + for (i = 0; i < TEXSIZE * TEXSIZE * 3; i++) + if (fabsf(pboMem[i] - 0.2) > tolerance[0]) { + REPORT_FAILURE + ("PBO modified by someone else, there must be something wrong"); + return false; + } + } + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + + + // Read texture back + if (useTexPackBuffer) { + glGenBuffersARB(1, pack_pb); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pack_pb[0]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + TEXSIZE * TEXSIZE * 3 * sizeof(GLfloat), NULL, + GL_STREAM_DRAW); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_FLOAT, NULL); + pboMem = (GLfloat *) glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, + GL_READ_ONLY); + } + else { + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_FLOAT, t2); + pboMem = t2; + } + + // Check texture image + for (i = 0; i < TEXSIZE * TEXSIZE; i++) { + if (i == 0 && breakCOWTexture && useTexUnpackBuffer) { + GLfloat exp[3] = { 0.8, 0.8, 0.8 }; + if (equalColors(&pboMem[i * 3], exp) != true) { + REPORT_FAILURE("glGetTexImage failed"); + printf(" got (%d) = [%f, %f, %f], ", i, + pboMem[i * 3], + pboMem[i * 3 + 1], pboMem[i * 3 + 2]); + printf("should be [%f, %f, %f]\n", + exp[0], exp[1], exp[2]); + + return false; + } + } + else { + GLfloat exp[3] = { 1.0, 1.0, 0.0 }; + if (equalColors(&pboMem[i * 3], exp) != true) { + REPORT_FAILURE("glGetTexImage failed"); + printf(" got (%d) = [%f, %f, %f], ", i, + pboMem[i * 3], + pboMem[i * 3 + 1], pboMem[i * 3 + 2]); + printf("should be [%f, %f, %f]\n", + exp[0], exp[1], exp[2]); + + return false; + } + } + } + + if (useTexPackBuffer) { + glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_EXT); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pack_pb); + } + if (useTexUnpackBuffer) { + glDeleteBuffersARB(1, unpack_pb); + } + + glEnable(GL_TEXTURE_2D); + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); + glVertex2f(0, 0); + glTexCoord2f(1, 0); + glVertex2f(TEXSIZE, 0); + glTexCoord2f(1, 1); + glVertex2f(TEXSIZE, TEXSIZE); + glTexCoord2f(0, 1); + glVertex2f(0, TEXSIZE); + glEnd(); + + glReadPixels(0, 0, windowSize, windowSize, GL_RGB, GL_FLOAT, + buf); + for (j = 0; j < windowSize; j++) { + for (i = 0; i < windowSize; i++) { + if (i == 0 && j == 0 && breakCOWTexture + && useTexUnpackBuffer) { + GLfloat exp[3] = { 0.8, 0.8, 0.8 }; + if (equalColors(&buf[(j * windowSize + i) * 3], exp) + != true) { + REPORT_FAILURE("glTexImage failed"); + printf(" got (%d, %d) = [%f, %f, %f], ", i, j, + buf[(j * windowSize + i) * 3], + buf[(j * windowSize + i) * 3 + 1], + buf[(j * windowSize + i) * 3 + 2]); + printf("should be [%f, %f, %f]\n", + exp[0], exp[1], exp[2]); + + return false; + } + } + else if (i < TEXSIZE && j < TEXSIZE) { + if (equalColors(&buf[(j * windowSize + i) * 3], green) + != true) { + REPORT_FAILURE("glTexImage failed"); + printf(" got (%d, %d) = [%f, %f, %f], ", i, j, + buf[(j * windowSize + i) * 3], + buf[(j * windowSize + i) * 3 + 1], + buf[(j * windowSize + i) * 3 + 2]); + printf("should be [%f, %f, %f]\n", + green[0], green[1], green[2]); + + return false; + } + } + else { + if (equalColors(&buf[(j * windowSize + i) * 3], black) + != true) { + REPORT_FAILURE("glTexImage failed"); + printf("(%d, %d) = [%f, %f, %f], ", i, j, + buf[(j * windowSize + i) * 3], + buf[(j * windowSize + i) * 3 + 1], + buf[(j * windowSize + i) * 3 + 2]); + printf("should be [0.0, 0.0, 0.0]\n"); + + return false; + } + } + } + } + } + } + } + } + + return true; +} + +bool PBOTest::testTexSubImage(void) +{ + GLuint pbs[1]; + GLfloat t[TEXSIZE * TEXSIZE * 3]; + int i, j; + int useUnpackBuffer = 0; + GLfloat green[3] = { 0.0, 1.0, 0.0 }; + GLfloat black[3] = { 0.0, 0.0, 0.0 }; + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + for (useUnpackBuffer = 0; useUnpackBuffer < usePBO + 1; useUnpackBuffer++) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + if (useUnpackBuffer) { + glGenBuffersARB(1, pbs); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pbs[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, TEXSIZE * TEXSIZE * 3 * sizeof(GLfloat), + NULL, GL_STREAM_DRAW); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + + 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, GL_RGB, TEXSIZE, TEXSIZE, 0, GL_RGB, + GL_FLOAT, NULL); + + GLfloat *pboMem = NULL; + if (useUnpackBuffer) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, pbs[0]); + pboMem = (GLfloat *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + } + else { + pboMem = t; + } + + for (i = 0; i < TEXSIZE * TEXSIZE; i++) { + pboMem[3 * i] = 0.0; + pboMem[3 * i + 1] = 1.0; + pboMem[3 * i + 2] = 0.0; + } + + if (useUnpackBuffer) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE, TEXSIZE, GL_RGB, + GL_FLOAT, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + } + else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE, TEXSIZE, GL_RGB, + GL_FLOAT, pboMem); + + glEnable(GL_TEXTURE_2D); + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); + glVertex2f(0, 0); + glTexCoord2f(1, 0); + glVertex2f(10, 0); + glTexCoord2f(1, 1); + glVertex2f(10, 10); + glTexCoord2f(0, 1); + glVertex2f(0, 10); + glEnd(); + glDisable(GL_TEXTURE_2D); + + GLfloat buf[windowSize * windowSize * 3]; + + glReadPixels(0, 0, windowSize, windowSize, GL_RGB, GL_FLOAT, buf); + for (j = 0; j < windowSize; j++) { + for (i = 0; i < windowSize; i++) { + if (i < 10 && j < 10) { + if (equalColors(&buf[(j * windowSize + i) * 3], green) != true) { + REPORT_FAILURE("glTexSubImage failed"); + printf(" got (%d, %d) = [%f, %f, %f], ", i, j, + buf[(j * windowSize + i) * 3], + buf[(j * windowSize + i) * 3 + 1], + buf[(j * windowSize + i) * 3 + 2]); + printf("should be [%f, %f, %f]\n", + green[0], green[1], green[2]); + + return false; + } + } + else { + if (equalColors(&buf[(j * windowSize + i) * 3], black) != true) { + REPORT_FAILURE("glTexSubImage failed"); + printf("(%d, %d) = [%f, %f, %f], ", i, j, + buf[(j * windowSize + i) * 3], + buf[(j * windowSize + i) * 3 + 1], + buf[(j * windowSize + i) * 3 + 2]); + printf("should be [0.0, 0.0, 0.0]\n"); + + return false; + } + + } + } + } + } + return true; +} + +bool PBOTest::testPolygonStip(void) +{ + int useUnpackBuffer = 0; + int usePackBuffer = 0; + GLuint unpack_pb[1]; + GLuint pack_pb[1]; + GLubyte t1[32 * 32 / 8]; + GLubyte t2[32 * 32 / 8]; + GLubyte *pboMem = NULL; + int i, j; + GLfloat white[3] = { 1.0, 1.0, 1.0 }; + GLfloat black[3] = { 0.0, 0.0, 0.0 }; + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + for (useUnpackBuffer = 0; useUnpackBuffer < usePBO + 1; useUnpackBuffer++) { + for (usePackBuffer = 0; usePackBuffer < usePBO + 1; usePackBuffer++) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + if (useUnpackBuffer) { + glGenBuffersARB(1, unpack_pb); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, unpack_pb[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, 32 * 32 / 8, NULL, + GL_STREAM_DRAW); + pboMem = (GLubyte *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + } + else { + pboMem = t1; + } + + + // Fill in the stipple pattern + for (i = 0; i < 32 * 32 / 8; i++) { + pboMem[i] = 0xAA; + } + + if (useUnpackBuffer) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glPolygonStipple(NULL); + } + else { + glPolygonStipple(pboMem); + } + + // Read back the stipple pattern + if (usePackBuffer) { + glGenBuffersARB(1, pack_pb); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, pack_pb[0]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, 32 * 32 / 8, NULL, + GL_STREAM_DRAW); + glGetPolygonStipple(NULL); + pboMem = (GLubyte *) glMapBufferARB(GL_PIXEL_PACK_BUFFER_EXT, + GL_READ_ONLY); + } + else { + glGetPolygonStipple(t2); + pboMem = t2; + } + + for (i = 0; i < 32 * 32 / 8; i++) { + if (pboMem[i] != 0xAA) { + REPORT_FAILURE("glGetPolygonStipple failed"); + return false; + } + } + + + if (useUnpackBuffer) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, unpack_pb); + } + if (usePackBuffer) { + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + glDeleteBuffersARB(1, pack_pb); + } + + glEnable(GL_POLYGON_STIPPLE); + glBegin(GL_POLYGON); + glVertex2f(0, 0); + glVertex2f(10, 0); + glVertex2f(10, 10); + glVertex2f(0, 10); + glEnd(); + + glDisable(GL_POLYGON_STIPPLE); + + // Check the result + GLfloat buf[windowSize * windowSize * 3]; + + glReadPixels(0, 0, windowSize, windowSize, GL_RGB, GL_FLOAT, buf); + + for (j = 0; j < windowSize; j++) { + for (i = 0; i < windowSize; i++) { + const GLfloat *exp; + if (i & 1) + exp = black; + else + exp = white; + if (i < 10 && j < 10) { + if (equalColors(&buf[(j * windowSize + i) * 3], exp) != + true) { + REPORT_FAILURE("glGetPolygonStipple failed"); + printf("(%d, %d) = [%f, %f, %f], ", i, j, + buf[(j * windowSize + i) * 3], + buf[(j * windowSize + i) * 3 + 1], + buf[(j * windowSize + i) * 3 + 2]); + printf("should be [1.0, 1.0, 1.0]\n"); + return false; + } + } + else { + if (equalColors(&buf[(j * windowSize + i) * 3], black) != + true) { + REPORT_FAILURE("glGetPolygonStipple failed"); + printf("(%d, %d) = [%f, %f, %f], ", i, j, + buf[(j * windowSize + i) * 3], + buf[(j * windowSize + i) * 3 + 1], + buf[(j * windowSize + i) * 3 + 2]); + printf("should be [0.0, 0.0, 0.0]\n"); + return false; + } + + } + } + } + + } + } + + return true; +} + + +bool PBOTest::testErrorHandling(void) +{ + GLuint fbs[1]; + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + if (usePBO) { + //handle exceed memory size + glGenBuffersARB(1, fbs); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, fbs[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, 32 * 32 * 4, NULL, + GL_STREAM_DRAW); + glDrawPixels(32, 32 + 1, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + if (glGetError() != GL_INVALID_OPERATION) + return false; + + glDeleteBuffersARB(1, fbs); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0); + + glGenBuffersARB(1, fbs); + glBindBufferARB(GL_PIXEL_PACK_BUFFER, fbs[0]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, 32 * 32 * 4, NULL, + GL_STREAM_DRAW); + glReadPixels(0, 0, 32, 32 + 1, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + if (glGetError() != GL_INVALID_OPERATION) + return false; + + glDeleteBuffersARB(1, fbs); + glBindBufferARB(GL_PIXEL_PACK_BUFFER, 0); + } + return true; +} + +bool PBOTest::testFunctionality(MultiTestResult & r) +{ + static SubTestFunc + funcs[] = { + &GLEAN::PBOTest::testSanity, + &GLEAN::PBOTest::testBitmap, + &GLEAN::PBOTest::testDrawPixels, + &GLEAN::PBOTest::testPixelMap, + &GLEAN::PBOTest::testTexImage, + &GLEAN::PBOTest::testTexSubImage, + &GLEAN::PBOTest::testPolygonStip, + &GLEAN::PBOTest::testErrorHandling, + NULL + }; + + for (int i = 0; funcs[i]; i++) + if ((this->*funcs[i]) ()) + r.numPassed++; + else + r.numFailed++; + return true; +} + +enum { + BLACK, + RED, + GREEN, + BLUE, +WHITE }; + +GLfloat colors1[][4] = { + {0.0, 0.0, 0.0, 0.0}, + {1.0, 0.0, 0.0, 1.0}, + {0.0, 1.0, 0.0, 1.0}, + {0.0, 0.0, 1.0, 1.0}, + {1.0, 1.0, 1.0, 1.0} +}; + +#define TEXSIZE1 64 +bool PBOTest::testPerformance(MultiTestResult & r) +{ + GLuint pbs[1]; + GLuint textures[1]; + GLubyte data[TEXSIZE1 * TEXSIZE1 * 4]; + int mode; + int i, j; + Timer t; + double t0, t1, perf[2]; + GLubyte *pboMem = NULL; + + (void) r; + + for (mode = 0; mode < usePBO + 1; mode++) { + t0 = t.getClock(); + + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + if (mode) { + glGenBuffersARB(1, pbs); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, pbs[0]); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER, + TEXSIZE1 * TEXSIZE1 * 4 * sizeof(GLubyte), NULL, + GL_STREAM_DRAW); + } + glGenTextures(1, textures); + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA, TEXSIZE1, + TEXSIZE1, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + for (i = 0; i < 1024; i++) { + if (mode) { + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, pbs[0]); + pboMem = + (GLubyte *) glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, + GL_WRITE_ONLY); + } + else { + pboMem = data; + } + + for (j = 0; j < TEXSIZE1 * TEXSIZE1; j++) { + pboMem[4 * j] = 255; + pboMem[4 * j + 1] = 255; + pboMem[4 * j + 2] = 0; + pboMem[4 * j + 3] = 0; + } + + if (mode) { + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE1, + TEXSIZE1, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0); + } + else { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEXSIZE1, + TEXSIZE1, GL_BGRA, GL_UNSIGNED_BYTE, data); + } + + + // Actually apply the texture + glEnable(GL_TEXTURE_2D); + glColor4fv(colors1[WHITE]); + + glBegin(GL_POLYGON); + glTexCoord2f(0.0, 0.0); + glVertex2f(0, 0); + glTexCoord2f(1.0, 0.0); + glVertex2f(1, 0); + glTexCoord2f(1.0, 1.0); + glVertex2f(1, 1); + glTexCoord2f(0.0, 1.0); + glVertex2f(0, 1); + glEnd(); + glFlush(); + glDisable(GL_TEXTURE_2D); + } + t1 = t.getClock(); + glDeleteTextures(1, textures); + if (mode) + glDeleteBuffersARB(1, pbs); + + perf[mode] = (double) TEXSIZE1 * TEXSIZE1 * 3 * sizeof(GLfloat) / 1024 / (t1 - t0); + + } + + if (perf[1] < perf[0] && usePBO) { + env->log << name << ": NOTE " + << "perf[0] = " << perf[0] << + " MB/s, which is in normal mode" << endl; + env->log << name << ": NOTE " << "perf[1] = " << + perf[1] << " MB/s, which is using PBO" << endl; + } + + return true; +} + + + +// Run all the subtests, incrementing numPassed, numFailed +void +PBOTest::runSubTests(MultiTestResult & r) +{ + static TestFunc funcs[] = { + &GLEAN::PBOTest::testFunctionality, + &GLEAN::PBOTest::testPerformance, + NULL + }; + + for (int i = 0; funcs[i]; i++) + if ((this->*funcs[i]) (r)) + r.numPassed++; + else + r.numFailed++; +} + + +void +PBOTest::runOne(MultiTestResult & r, Window & w) +{ + (void) w; + + if (!setup()) { + r.pass = false; + return; + } + + runSubTests(r); + + r.pass = (r.numFailed == 0); +} + + +// The test object itself: +PBOTest pboTest("pbo", "window, rgb, z", "", // no extension filter + "pbo test: Test OpenGL Extension GL_ARB_pixel_buffer_object\n"); + + + +} // namespace GLEAN diff --git a/src/glean/tpbo.h b/src/glean/tpbo.h new file mode 100644 index 0000000..cda1a49 --- /dev/null +++ b/src/glean/tpbo.h @@ -0,0 +1,86 @@ +// BEGIN_COPYRIGHT -*- glean -*- +// +// Copyrigth (C) 2007 Intel Corporation +// Copyright (C) 1999 Allen Akin 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 ALLEN AKIN 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. +// +// END_COPYRIGHT +// +// Authors: +// Shuang He <shuang.he@intel.com> +// +// tfbo.h: Test OpenGL Extension GL_ARB_pixel_buffer_objec + +#ifndef __pfbo_h__ +#define __pfbo_h__ + +#include "tmultitest.h" + +namespace GLEAN { + +#define windowSize 100 + + +class PBOTest: public MultiTest +{ +public: + PBOTest(const char* testName, const char* filter, + const char *extensions, const char* description): + MultiTest(testName, filter, extensions, description) + { + } + + virtual void runOne(MultiTestResult &r, Window &w); + +private: + typedef bool (PBOTest::*TestFunc)(MultiTestResult &r); + typedef bool (PBOTest::*SubTestFunc)(void); + + GLfloat tolerance[5]; + + bool testFunctionality(MultiTestResult &r); + bool testPerformance(MultiTestResult &r); + bool testSanity(void); + bool testErrorHandling(void); + bool testDrawPixels(void); + bool testPixelMap(void); + bool testBitmap(void); + bool testTexImage(void); + bool testTexSubImage(void); + bool testPolygonStip(void); + + void runSubTests(MultiTestResult &r); + + bool setup(void); + bool checkResult(const GLfloat exp[4], const int depth, const int stencil) const; + bool equalColors(const GLfloat a[4], const GLfloat b[4]) const; + bool equalColors1(const GLubyte a[4], const GLubyte b[4]) const; + + void reportFailure(const char *msg, int line) const; + void reportFailure(const char *msg, GLenum target, int line) const; +}; + +} // namespace GLEAN + +#endif // __tpbo_h__ |