progs/tests: added new blitfb.c test
authorBrian Paul <brianp@vmware.com>
Tue, 27 Oct 2009 22:46:07 +0000 (16:46 -0600)
committerBrian Paul <brianp@vmware.com>
Tue, 27 Oct 2009 23:00:31 +0000 (17:00 -0600)
Tests glBlitFramebuffer() between two texture/renderbuffer surfaces.
In particular, blit from level[1] of a cube map face to a 2D texture.

Used to find/fix bug in intel do_copy_texsubimage().
See commit aef1ab1073f3e30d699b99dae17518ed48b57c72

progs/tests/Makefile
progs/tests/SConscript
progs/tests/blitfb.c [new file with mode: 0644]

index 2b93aa5464f0e491feb57a1b6860fe6196c90f6c..197e14d5b00a0cc1f7425f57a769d28c7166b9a6 100644 (file)
@@ -29,6 +29,7 @@ SOURCES = \
        blendminmax.c \
        blendsquare.c \
        blendxor.c \
+       blitfb.c \
        bufferobj.c \
        bumpmap.c \
        bug_3050.c \
index bb6a1d2b8a99bcb1f8edbb7d541204cf30567d2e..3a0da62717c193a84f38bc7e1683baa7fb7adc2e 100644 (file)
@@ -52,6 +52,7 @@ progs = [
     'blendminmax',
     'blendsquare',
     'blendxor',
+    'blitfb',
     'bufferobj',
     'bug_3050',
     'bug_3101',
diff --git a/progs/tests/blitfb.c b/progs/tests/blitfb.c
new file mode 100644 (file)
index 0000000..18c8380
--- /dev/null
@@ -0,0 +1,259 @@
+/**
+ * Test glFramebufferBlit()
+ * Brian Paul
+ * 27 Oct 2009
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glew.h>
+#include <GL/glut.h>
+
+
+static int Win;
+static int WinWidth = 1100, WinHeight = 600;
+
+static int SrcWidth = 512, SrcHeight = 512;
+static int DstWidth = 512, DstHeight = 512;
+
+static GLuint SrcFB, DstFB;
+static GLuint SrcTex, DstTex;
+
+#if 0
+static GLenum SrcTexTarget = GL_TEXTURE_2D, SrcTexFace = GL_TEXTURE_2D;
+#else
+static GLenum SrcTexTarget = GL_TEXTURE_CUBE_MAP, SrcTexFace = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+#endif
+
+static GLenum DstTexTarget = GL_TEXTURE_2D, DstTexFace = GL_TEXTURE_2D;
+
+static GLuint SrcTexLevel = 01, DstTexLevel = 0;
+
+
+static void
+Draw(void)
+{
+   GLboolean rp = GL_FALSE;
+   GLubyte *buf;
+   GLint srcWidth = SrcWidth >> SrcTexLevel;
+   GLint srcHeight = SrcHeight >> SrcTexLevel;
+   GLint dstWidth = DstWidth >> DstTexLevel;
+   GLint dstHeight = DstHeight >> DstTexLevel;
+   GLenum status;
+
+   /* clear window */
+   glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
+   glClearColor(0.5, 0.5, 0.5, 1.0);
+   glClear(GL_COLOR_BUFFER_BIT);
+
+
+   /* clear src buf */
+   glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
+   status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+   assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
+   glClearColor(0, 1, 0, 0);
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   /* clear dst buf */
+   glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
+   status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+   assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
+   glClearColor(1, 0, 0, 0);
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   /* blit src -> dst */
+   glBindFramebufferEXT(GL_READ_FRAMEBUFFER, SrcFB);
+   glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, DstFB);
+   glBlitFramebufferEXT(0, 0, srcWidth, srcHeight,
+                        0, 0, dstWidth, dstHeight,
+                        GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+#if 01
+   /* read src results */
+   buf = malloc(4 * srcWidth * srcHeight);
+   memset(buf, 0x88, 4 * srcWidth * srcHeight);
+   glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
+   if (rp)
+      glReadPixels(0, 0, srcWidth, srcHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+   else {
+      glBindTexture(SrcTexTarget, SrcTex);
+      glGetTexImage(SrcTexFace, SrcTexLevel, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+   }
+
+   /* draw dst in window */
+   glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
+   glWindowPos2i(0, 0);
+   glDrawPixels(srcWidth, srcHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+
+   printf("Src Pix[0] = %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3]);
+   free(buf);
+#endif
+
+   glFinish();
+
+   /* read dst results */
+   buf = malloc(4 * dstWidth * dstHeight);
+   memset(buf, 0x88, 4 * dstWidth * dstHeight);
+   glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
+   if (rp)
+      glReadPixels(0, 0, dstWidth, dstHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+   else {
+      glBindTexture(DstTexTarget, DstTex);
+      glGetTexImage(DstTexFace, DstTexLevel, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+   }
+
+   /* draw dst in window */
+   glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
+   glWindowPos2i(srcWidth + 2, 0);
+   glDrawPixels(dstWidth, dstHeight, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+
+   printf("Dst Pix[0] = %d %d %d %d\n", buf[0], buf[1], buf[2], buf[3]);
+   free(buf);
+
+   glFinish();
+
+   glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+   WinWidth = width;
+   WinHeight = height;
+   glViewport(0, 0, width, height);
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+   glTranslatef(0.0, 0.0, -15.0);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+   case 27:
+      glutDestroyWindow(Win);
+      exit(0);
+      break;
+   }
+   glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+   (void) x;
+   (void) y;
+   switch (key) {
+   }
+   glutPostRedisplay();
+}
+
+
+static void
+InitFBOs(void)
+{
+   GLuint w, h, lvl;
+
+   /* Src */
+   glGenTextures(1, &SrcTex);
+   glBindTexture(SrcTexTarget, SrcTex);
+   w = SrcWidth;
+   h = SrcHeight;
+   lvl = 0;
+   for (lvl = 0; ; lvl++) {
+      if (SrcTexTarget == GL_TEXTURE_CUBE_MAP) {
+         GLuint f;
+         for (f = 0; f < 6; f++) {
+            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, lvl, GL_RGBA8,
+                         w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+         }
+      }
+      else {
+         /* single face */
+         glTexImage2D(SrcTexFace, lvl, GL_RGBA8, w, h, 0,
+                      GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+      }
+      if (w == 1 && h == 1)
+         break;
+      if (w > 1)
+         w /= 2;
+      if (h > 1)
+         h /= 2;
+   }
+
+   glGenFramebuffersEXT(1, &SrcFB);
+   glBindFramebufferEXT(GL_FRAMEBUFFER, SrcFB);
+   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                             SrcTexFace, SrcTex, SrcTexLevel);
+
+   /* Dst */
+   glGenTextures(1, &DstTex);
+   glBindTexture(DstTexTarget, DstTex);
+   w = DstWidth;
+   h = DstHeight;
+   lvl = 0;
+   for (lvl = 0; ; lvl++) {
+      glTexImage2D(DstTexFace, lvl, GL_RGBA8, w, h, 0,
+                   GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+      if (w == 1 && h == 1)
+         break;
+      if (w > 1)
+         w /= 2;
+      if (h > 1)
+         h /= 2;
+   }
+
+   glGenFramebuffersEXT(1, &DstFB);
+   glBindFramebufferEXT(GL_FRAMEBUFFER, DstFB);
+   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+                             DstTexFace, DstTex, DstTexLevel);
+}
+
+
+static void
+Init(void)
+{
+   if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
+      fprintf(stderr, "This test requires GL_EXT_framebuffer_object\n");
+      exit(1);
+   }
+
+   if (!glutExtensionSupported("GL_EXT_framebuffer_blit")) {
+      fprintf(stderr, "This test requires GL_EXT_framebuffer_blit,\n");
+      exit(1);
+   }
+
+   InitFBOs();
+
+   printf("Left rect = src FBO, Right rect = dst FBO.\n");
+   printf("Both should be green.\n");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+   glutInit(&argc, argv);
+   glutInitWindowSize(WinWidth, WinHeight);
+   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+   Win = glutCreateWindow(argv[0]);
+   glewInit();
+   glutReshapeFunc(Reshape);
+   glutKeyboardFunc(Key);
+   glutSpecialFunc(SpecialKey);
+   glutDisplayFunc(Draw);
+   Init();
+   glutMainLoop();
+   return 0;
+}