summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@users.sourceforge.net>2008-01-01 19:55:49 +0000
committerBrian Paul <brianp@users.sourceforge.net>2008-01-01 19:55:49 +0000
commit158ed9377b3f3e9c237d0f1f763637f6db73d5f3 (patch)
tree8f2df6ee7a140f22445f95e9645e19234bd1e986
parent5e5f942f610d773ad28e343fa31b1d217be0bae9 (diff)
new GL_EXT_pixel_buffer_object test (Shuang He, Intel)
-rw-r--r--doc/html/changes.html1
-rw-r--r--src/glean/tpbo.cpp1240
-rw-r--r--src/glean/tpbo.h86
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__