2 * Copyright © 2014 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * With AMD OpenGL drivers, when we draw a point sprite and use
26 * gl_PointCoord in the fragment (pixel) shader, the buggy host driver
27 * will wrongly put gl_PointCoord value into a fragment shader input
28 * variable, e.g., fs_color0, so that the rendering results are all wrong.
29 * We will NOT see this issue if there is no vertex attribute for the
33 * -- Present in : ATI HD 6770M on Mac OS X 10.8.4
34 * -- Fixed in : Mac OS 10.9
38 #include "piglit-util-gl.h"
40 PIGLIT_GL_TEST_CONFIG_BEGIN
42 config
.supports_gl_core_version
= 32;
43 config
.supports_gl_compat_version
= 32;
45 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
46 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
48 PIGLIT_GL_TEST_CONFIG_END
53 #define COLOR_GRAY 0x7F7F7FFF
54 #define CLEAR_COLOR 0x000033FF
55 #define NUM_VERTICES 4
62 test_pointsprite_ps(void)
64 static const float vertArray
[ATTR_SIZE
* NUM_ATTRS
] = {
65 0.0f
, 0.0f
, 0.0f
, 1.0f
,
66 1.0f
, 1.0f
, 1.0f
, 1.0f
,
68 const unsigned int numPixels
= WIDTH
* HEIGHT
;
69 GLuint texData
[WIDTH
* HEIGHT
];
70 GLuint i
, texFbo
, fbo
, vertexArray
, vertexBuf
;
72 const float pointSize
= WIDTH
;
73 const unsigned int expectedTexelColor
= 0xFFFFFFFF;
75 for (i
= 0; i
< numPixels
; ++i
) {
76 texData
[i
] = COLOR_GRAY
;
79 /* Create 2D textures */
80 glGenTextures(1, &texFbo
);
81 glActiveTexture(GL_TEXTURE0
);
82 glBindTexture(GL_TEXTURE_2D
, texFbo
);
83 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA8
, WIDTH
, HEIGHT
, 0,
84 GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8
, texData
);
86 if (!piglit_check_gl_error(GL_NO_ERROR
))
89 /* Setup the vertex attributes */
90 glGenVertexArrays(1, &vertexArray
);
91 glBindVertexArray(vertexArray
);
92 glGenBuffers(1, &vertexBuf
);
93 glBindBuffer(GL_ARRAY_BUFFER
, vertexBuf
);
94 glBufferData(GL_ARRAY_BUFFER
, sizeof(vertArray
), vertArray
,
97 for (i
= 0; i
< NUM_ATTRS
; i
++) {
98 const GLvoid
*offset
=
99 (const GLvoid
*)(i
* ATTR_SIZE
* sizeof(float));
102 snprintf(name
, sizeof name
, "Attr%d", i
);
103 attrLoc
= glGetAttribLocation(prog
, name
);
104 glEnableVertexAttribArray(attrLoc
);
105 glVertexAttribPointer(attrLoc
, ATTR_SIZE
, GL_FLOAT
, GL_FALSE
,
106 ATTR_SIZE
* sizeof(float), offset
);
109 if (!piglit_check_gl_error(GL_NO_ERROR
))
113 glGenFramebuffers(1, &fbo
);
114 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
115 glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
116 GL_TEXTURE_2D
, texFbo
, 0);
117 if (glCheckFramebufferStatus(GL_FRAMEBUFFER
) !=
118 GL_FRAMEBUFFER_COMPLETE
) {
119 printf("incomplete framebuffer at line %d\n", __LINE__
);
123 glDrawBuffer(GL_COLOR_ATTACHMENT0
);
124 if (glCheckFramebufferStatus(GL_FRAMEBUFFER
) !=
125 GL_FRAMEBUFFER_COMPLETE
) {
126 printf("incomplete framebuffer at line %d\n", __LINE__
);
131 glViewport(0, 0, WIDTH
, HEIGHT
);
132 glClearColor(((CLEAR_COLOR
>> 24) & 0xFF) / 255.0f
,
133 ((CLEAR_COLOR
>> 16) & 0xFF) / 255.0f
,
134 ((CLEAR_COLOR
>> 8) & 0xFF) / 255.0f
,
135 ((CLEAR_COLOR
) & 0xFF) / 255.0f
);
136 glClear(GL_COLOR_BUFFER_BIT
);
137 glPointSize(pointSize
);
138 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN
, GL_LOWER_LEFT
);
139 glDrawArrays(GL_POINTS
, 0, 1);
142 glReadBuffer(GL_COLOR_ATTACHMENT0
);
143 if (glCheckFramebufferStatus(GL_FRAMEBUFFER
) !=
144 GL_FRAMEBUFFER_COMPLETE
) {
145 printf("incomplete framebuffer at line %d\n", __LINE__
);
149 /* read color buffer */
150 glPixelStorei(GL_PACK_ROW_LENGTH
, WIDTH
);
151 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
152 memset(texData
, 0, sizeof(texData
));
153 glReadPixels(0, 0, WIDTH
, HEIGHT
,
154 GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8
, texData
);
156 if (texData
[0] != expectedTexelColor
) {
157 printf("At pixel (0,0) expected 0x%x but found 0x%x\n",
158 expectedTexelColor
, texData
[0]);
160 glDeleteTextures(1, &texFbo
);
161 glDeleteFramebuffers(1, &fbo
);
165 if (!piglit_check_gl_error(GL_NO_ERROR
))
168 glDeleteTextures(1, &texFbo
);
169 glDeleteFramebuffers(1, &fbo
);
177 static const char *vsSrc
=
181 "smooth out vec4 fs_color0;"
183 " gl_Position = Attr0;"
184 " fs_color0 = Attr1;"
186 static const char *fsSrc
=
188 "smooth in vec4 fs_color0;"
189 "out vec4 fragColor0;"
191 " vec2 psCoords = gl_PointCoord;"
192 " fragColor0 = fs_color0;"
195 prog
= piglit_build_simple_program(vsSrc
, fsSrc
);
196 glBindFragDataLocation(prog
, 0, "fragColor0");
205 bool pass
= test_pointsprite_ps();
207 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
212 piglit_init(int argc
, char **argv
)