From 498fcfd315325365a7c58520ea956f298d6bc94c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 27 Oct 2009 16:46:07 -0600 Subject: [PATCH] progs/tests: added new blitfb.c test 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 | 1 + progs/tests/SConscript | 1 + progs/tests/blitfb.c | 259 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 progs/tests/blitfb.c diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 4d9b4e8388c..8c310df0954 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -28,6 +28,7 @@ SOURCES = \ blendminmax.c \ blendsquare.c \ blendxor.c \ + blitfb.c \ bufferobj.c \ bumpmap.c \ bug_3050.c \ diff --git a/progs/tests/SConscript b/progs/tests/SConscript index bb6a1d2b8a9..3a0da62717c 100644 --- a/progs/tests/SConscript +++ b/progs/tests/SConscript @@ -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 index 00000000000..18c8380a5e2 --- /dev/null +++ b/progs/tests/blitfb.c @@ -0,0 +1,259 @@ +/** + * Test glFramebufferBlit() + * Brian Paul + * 27 Oct 2009 + */ + +#include +#include +#include +#include +#include +#include +#include + + +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; +} -- 2.30.2