2 * Copyright (c) 2013 VMware, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT. IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * This test exercises an NVIDIA driver bug where using glGetTexImage
28 * to read a cubemap face into a PBO fails. It appears that glGetTexImage
29 * always reads from the +X face.
33 #include "piglit-util-gl.h"
35 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config
.supports_gl_compat_version
= 15;
37 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
;
38 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
39 PIGLIT_GL_TEST_CONFIG_END
46 #define TEX_NUMPIXELS (TEX_WIDTH * TEX_HEIGHT)
49 static const GLuint Colors
[NUMCOLORS
] = {
51 0x00FF00FF, /* green */
52 0x0000FFFF, /* blue */
53 0x00FFFFFF, /* cyan */
54 0xFF00FFFF, /* magenta */
55 0xFFFF00FF, /* yellow */
56 0x7F7F7FFF, /* gray */
61 * Test one cube map face to see if glGetTexImage from a cube face into
62 * a PBO works correctly.
65 test_face(GLuint face
)
67 const GLenum cubeFaceTarget
= GL_TEXTURE_CUBE_MAP_POSITIVE_X
+ face
;
68 const GLuint expectedColor
= Colors
[face
];
69 GLuint texData
[TEX_NUMPIXELS
];
70 GLuint cubeTex
, fbo
, packPBO
;
74 /* Create the cubemap texture. */
75 glGenTextures(1, &cubeTex
);
76 glActiveTextureARB(GL_TEXTURE0
);
77 glBindTexture(GL_TEXTURE_CUBE_MAP
, cubeTex
);
78 glPixelStorei(GL_UNPACK_ROW_LENGTH
, TEX_WIDTH
);
79 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
80 for (f
= 0; f
< 6; ++f
) {
81 for (i
= 0; i
< TEX_NUMPIXELS
; ++i
) {
82 texData
[i
] = Colors
[f
];
84 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X
+ f
, 0,
85 GL_SRGB8_ALPHA8
, TEX_WIDTH
, TEX_HEIGHT
, 0, GL_BGRA
,
86 GL_UNSIGNED_INT_8_8_8_8_REV
, texData
);
90 glGenFramebuffers(1, &fbo
);
91 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
92 glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
93 cubeFaceTarget
, cubeTex
, 0);
94 if (glCheckFramebufferStatus(GL_FRAMEBUFFER
) !=
95 GL_FRAMEBUFFER_COMPLETE
) {
96 printf("Incomplete framebuffer object\n");
99 glDrawBuffer(GL_COLOR_ATTACHMENT0
);
101 /* Read back cubemap face into PBO */
102 glGenBuffers(1, &packPBO
);
103 glBindBuffer(GL_PIXEL_PACK_BUFFER
, packPBO
);
104 glBufferData(GL_PIXEL_PACK_BUFFER
, TEX_NUMPIXELS
* sizeof(GLuint
),
105 NULL
, GL_STREAM_READ
);
106 glPixelStorei(GL_PACK_ROW_LENGTH
, TEX_WIDTH
);
107 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
108 glGetTexImage(cubeFaceTarget
, 0, GL_BGRA
, GL_UNSIGNED_INT_8_8_8_8_REV
,
111 /* Map pack PBO to get results. */
112 ptr
= glMapBuffer(GL_PIXEL_PACK_BUFFER
, GL_READ_ONLY
);
114 printf("failed to map PBO\n");
117 for (i
= 0; i
< TEX_NUMPIXELS
; ++i
) {
118 texData
[i
] = Colors
[6]; /* gray */
121 memcpy(texData
, ptr
, TEX_NUMPIXELS
* sizeof(GLuint
));
123 glUnmapBuffer(GL_PIXEL_PACK_BUFFER
);
125 if (expectedColor
!= texData
[0]) {
126 printf("Colors don't match for face %u\n", face
);
127 printf("Expected 0x%08x but found 0x%08x \n",
128 expectedColor
, texData
[0]);
132 glDeleteTextures(1, &cubeTex
);
133 glDeleteFramebuffers(1, &fbo
);
134 glDeleteBuffers(1, &packPBO
);
136 /* if we get here we passed */
146 for (i
= 0; i
< 6; i
++) {
147 pass
= test_face(i
) && pass
;
149 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
154 piglit_init(int argc
, char *argv
[])
156 piglit_require_extension("GL_ARB_texture_cube_map");
157 piglit_require_extension("GL_ARB_pixel_buffer_object");
158 piglit_require_extension("GL_ARB_framebuffer_object");