ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_framebuffer_srgb / srgb_pbo.c
blob86ade0b26d15ad0f0c52cdb92b8e8145d993fea1
1 /*
2 * Copyright © 2016 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
13 * Software.
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
21 * IN THE SOFTWARE.
23 * Authors:
24 * Neha Bhende <bhenden@vmware.com>
27 /**
28 * \file srgb-pbo.c
30 * To test a bug in glClear() with GL_FRAMEBUFFER_SRGB enabled on nVidia GPUs.
31 * nVidia GPUs seems to disable GL_FRAMEBUFFER_SRGB after using a PBO to
32 * define a GL_BGRA4 texture.
33 * This test creates fbo and the clear it with GL_FRAMEBUFFER_SRGB.
34 * Before reading fbo pixels, test performs some PBO operations and creates
35 * GL_RGBA4 texture. So when we readback fbo pixels, it has GL_FRAMEBUFFER_SRGB
36 * disabled values.
37 * For example, we clear the framebuffer with (R, G, B, A)=(0, 0, 127, 0)
38 * with GL_FRAMEBUFFER_SRGB enabled, we should get (0, 0, 187, 0) but we get
39 * (0, 0, 127, 0).
42 #include <stdio.h>
43 #include <inttypes.h>
44 #include <math.h>
45 #include "piglit-util-gl.h"
48 PIGLIT_GL_TEST_CONFIG_BEGIN
49 config.supports_gl_compat_version = 13;
50 config.window_visual = PIGLIT_GL_VISUAL_RGB;
51 PIGLIT_GL_TEST_CONFIG_END
53 const unsigned int texWidth = 256;
54 const unsigned int texHeight = 256;
55 const unsigned int level = 0;
56 const unsigned int numLevels = 1;
57 const GLenum texFormat = GL_BGRA;
58 const GLenum texInternalFormat = GL_SRGB8_ALPHA8;
59 const GLenum texType = GL_UNSIGNED_INT_8_8_8_8_REV;
61 struct BGRA4
63 unsigned blue:4;
64 unsigned green:4;
65 unsigned red:4;
66 unsigned alpha:4;
69 struct BGRA8
71 unsigned char blue;
72 unsigned char green;
73 unsigned char red;
74 unsigned char alpha;
78 static GLuint
79 createTexture2D(const GLenum internalFormat, unsigned int numMipmapLevels,
80 unsigned int width, unsigned int height)
82 GLuint tex;
84 glGenTextures(1, &tex);
85 glBindTexture(GL_TEXTURE_2D, tex);
87 glTexStorage2D(GL_TEXTURE_2D, numMipmapLevels, internalFormat,
88 width, height);
89 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
90 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
91 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
92 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
93 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
94 return tex;
98 enum piglit_result
99 test2dTexelAt(const GLuint tex2D, unsigned int mipLevel, unsigned int x,
100 unsigned int y, struct BGRA8 expected, unsigned int width,
101 unsigned int height)
103 struct BGRA8 *texData = (struct BGRA8 *)
104 malloc(width * height *sizeof(struct BGRA8));
105 enum piglit_result status = PIGLIT_PASS;
107 glBindTexture(GL_TEXTURE_2D, tex2D);
108 glPixelStorei(GL_PACK_ROW_LENGTH, width);
109 glPixelStorei(GL_PACK_IMAGE_HEIGHT, height);
110 glPixelStorei(GL_PACK_ALIGNMENT, 1);
112 glGetTexImage(GL_TEXTURE_2D, mipLevel, texFormat, texType, texData);
114 const unsigned int offset = y * width + x;
115 struct BGRA8 pixel = texData[offset];
117 if (memcmp(&expected, &pixel, sizeof(struct BGRA8))) {
118 status = PIGLIT_FAIL;
119 fprintf(stdout," texel mismatch at position (%u, %u): \n", x,y);
120 fprintf(stdout, "expected {%u, %u, %u, %u},"
121 " found {%u, %u, %u, %u}\n",
122 expected.red, expected.green,
123 expected.blue, expected.alpha,
124 pixel.red, pixel.green, pixel.blue, pixel.alpha);
127 free(texData);
128 return status;
132 /** Borrowed from Mesa */
133 static float
134 linear_to_srgb(float cl)
136 if (cl <= 0.0f)
137 return 0.0f;
138 else if (cl < 0.0031308f)
139 return 12.92f * cl;
140 else if (cl < 1.0f)
141 return 1.055f * powf(cl, 0.41666f) - 0.055f;
142 else
143 return 1.0f;
147 enum piglit_result
148 piglit_display(void)
150 /* not reached */
151 return PIGLIT_FAIL;
155 void
156 piglit_init(int argc, char **argv)
158 piglit_require_extension("GL_ARB_texture_storage");
159 piglit_require_extension("GL_ARB_framebuffer_object");
160 piglit_require_extension("GL_ARB_pixel_buffer_object");
161 piglit_require_extension("GL_ARB_framebuffer_sRGB");
163 GLuint tex2D = createTexture2D(texInternalFormat, numLevels,
164 texWidth, texHeight);
165 const struct BGRA8 clearVal = { 127, 63, 192, 0 };
166 struct BGRA8 sRGBVal;
168 /* compute expected sRGB value */
169 sRGBVal.red = (unsigned) (255 * linear_to_srgb(clearVal.red / 255.0));
170 sRGBVal.green = (unsigned) (255 * linear_to_srgb(clearVal.green / 255.0));
171 sRGBVal.blue = (unsigned) (255 * linear_to_srgb(clearVal.blue / 255.0));
172 sRGBVal.alpha = 0;
174 const unsigned int numPixels = texWidth * texHeight;
175 GLuint fbo;
176 enum piglit_result status = PIGLIT_PASS;
178 /* Create a FBO */
179 glGenFramebuffers(1, &fbo);
180 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
182 /* using 2D texture as frame buffer texture */
183 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
184 GL_TEXTURE_2D, tex2D, level);
185 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
186 GL_FRAMEBUFFER_COMPLETE) {
187 fprintf(stdout, "Error: Cannot attach tex2D to FBO!\n");
188 piglit_report_result(PIGLIT_FAIL);
191 glDrawBuffer(GL_COLOR_ATTACHMENT0);
192 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
193 GL_FRAMEBUFFER_COMPLETE) {
194 fprintf(stderr, "Error: Cannot set Draw Buffer!\n");
195 piglit_report_result(PIGLIT_FAIL);
198 /* clearing texture tex2D with GL_FRAMEBUFFER_SRGB */
199 glViewport(0, 0, texWidth, texHeight);
200 glEnable(GL_FRAMEBUFFER_SRGB);
201 glClearColor(clearVal.red / 255.0f, clearVal.green / 255.0f,
202 clearVal.blue / 255.0f, clearVal.alpha / 255.0f);
203 glClear(GL_COLOR_BUFFER_BIT);
205 /* following code basically triggers the issue.
206 * We have sRGB fbo. PBO operations are done and GL_RGBA4
207 * texture is created, before readback.
208 * When we readback framebuffer pixels, it doesn't have expected
209 * sRGB values.
212 GLuint tex;
213 tex = createTexture2D(GL_RGBA4, 1, texWidth, texHeight);
215 /* Create a PBO and initialize it to zeros */
216 GLuint unpackPbo;
217 const unsigned int texDataLength = numPixels * sizeof(struct BGRA4);
219 glGenBuffers(1, &unpackPbo);
220 glBindBuffer(GL_COPY_READ_BUFFER, unpackPbo);
221 glBufferData(GL_COPY_READ_BUFFER, texDataLength, 0, GL_STREAM_DRAW);
222 void *ptr =
223 glMapBufferRange(GL_COPY_READ_BUFFER, 0, texDataLength,
224 GL_MAP_WRITE_BIT);
226 if (!ptr) {
227 fprintf(stderr, "Error: Failed to map PBO!\n");
228 piglit_report_result(PIGLIT_FAIL);
230 memset(ptr, 0, texDataLength);
231 glUnmapBuffer(GL_COPY_READ_BUFFER);
233 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackPbo);
235 glBindTexture(GL_TEXTURE_2D, tex);
236 glPixelStorei(GL_UNPACK_ROW_LENGTH, texWidth);
237 glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, texHeight);
238 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
240 glTexSubImage2D(GL_TEXTURE_2D, level,
241 0, 0,
242 texWidth, texHeight,
243 GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV,
246 /* now recheck 2D texture tex2D data */
247 status = test2dTexelAt(tex2D, level, 0, 0, sRGBVal,
248 texWidth, texHeight);
250 piglit_report_result(status);