2 * Copyright © 2015 Intel Corporation
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
21 * DEALINGS IN THE SOFTWARE.
25 * \file fast-clear-blend.c
27 * Enables GL_FRAMEBUFFER_SRGB, clears the buffer to a color and then
28 * blends it with a rectangle in another color before verifying the
29 * result. This is mainly to test fast clears on SKL in the i965
30 * driver because in that case fast clears can't be used with
31 * GL_FRAMEBUFFER_SRGB so it internally needs to resolve the color
35 #include "piglit-util-gl.h"
37 PIGLIT_GL_TEST_CONFIG_BEGIN
39 config
.supports_gl_compat_version
= 21;
40 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
42 PIGLIT_GL_TEST_CONFIG_END
46 "attribute vec4 piglit_vertex;\n"
51 " gl_Position = piglit_vertex;\n"
56 "uniform vec4 color;\n"
61 " gl_FragColor = color;\n"
66 static GLint color_location
;
70 { 0.0f
, 0.0f
, 0.0f
, 0.0f
},
71 { 1.0f
, 1.0f
, 1.0f
, 1.0f
},
72 { 0.0f
, 0.0f
, 1.0f
, 0.0f
},
73 { 1.0f
, 0.0f
, 0.0f
, 1.0f
},
75 { 0.25f
, 0.5f
, 0.75f
, 1.0f
},
76 { 0.75f
, 0.5f
, 0.25f
, 0.0f
},
77 { 0.5f
, 0.25f
, 0.75f
, 0.5f
},
81 probe_srgb_color(int x
, int y
, int w
, int h
,
84 GLfloat srgb_color
[4];
87 /* The value in the framebuffer is stored in SRGB space so we
88 * need to convert to that.
90 for (i
= 0; i
< 3; i
++)
91 srgb_color
[i
] = piglit_linear_to_srgb(color
[i
]);
92 srgb_color
[3] = color
[3];
94 return piglit_probe_rect_rgba(x
, y
, w
, h
, srgb_color
);
98 test_color(bool srgb_before_clear
,
99 const GLfloat
*clear_color
)
101 static const GLfloat rect_color
[] = {
102 0.0f
, 0.75f
, 1.0f
, 0.5f
104 GLfloat expected_color
[4];
109 printf("Clear to %f,%f,%f,%f - SRGB enabled %s clear\n",
114 srgb_before_clear
? "before" : "after");
116 if (srgb_before_clear
)
117 glEnable(GL_FRAMEBUFFER_SRGB
);
119 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
120 glClearColor(clear_color
[0],
124 glClear(GL_COLOR_BUFFER_BIT
);
126 if (!srgb_before_clear
)
127 glEnable(GL_FRAMEBUFFER_SRGB
);
130 glUniform4fv(color_location
, 1, rect_color
);
133 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
135 /* Blend a rectangle into the right-hand half of the framebuffer */
136 piglit_draw_rect(0.0f
, -1.0f
, 1.0f
, 2.0f
);
139 glDisable(GL_FRAMEBUFFER_SRGB
);
141 /* Sanity check that the blend didn't affect the left-hand
142 * side of the framebuffer where the rectangle wasn't drawn.
144 if (srgb_before_clear
) {
145 pass
= probe_srgb_color(0, 0,
146 piglit_width
/ 2, piglit_height
,
147 clear_color
) && pass
;
149 pass
= piglit_probe_rect_rgba(0, 0,
150 piglit_width
/ 2, piglit_height
,
151 clear_color
) && pass
;
154 /* Calculate the expected blended color. The blending will be
155 * done in linear space so if GL_FRAMEBUFFER_SRGB was enabled
156 * before the clear then the SRGB conversions cancel out and
157 * don't affect the result. However if it wasn't enabled then
158 * the clear color will go through an SRGB→linear conversion
159 * before being used as one of the sources for the blend.
161 for (i
= 0; i
< 4; i
++) {
162 if (i
>= 3 || srgb_before_clear
)
163 fb_color
= clear_color
[i
];
165 fb_color
= piglit_srgb_to_linear(clear_color
[i
]);
167 expected_color
[i
] = (fb_color
* (1.0f
- rect_color
[3]) +
168 rect_color
[i
] * rect_color
[3]);
171 pass
= probe_srgb_color(piglit_width
/ 2, 0,
172 piglit_width
/ 2, piglit_height
,
173 expected_color
) && pass
;
175 /* Copy the test framebuffer into the winsys framebuffer so
176 * that something will be visible */
177 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fbo
);
178 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
179 glBlitFramebuffer(0, 0, piglit_width
, piglit_height
,
180 0, 0, piglit_width
, piglit_height
,
184 glBindFramebuffer(GL_FRAMEBUFFER
, piglit_winsys_fbo
);
186 piglit_present_results();
197 for (i
= 0; i
< ARRAY_SIZE(clear_colors
); i
++) {
198 pass
= test_color(false, /* srgb_before_clear */
199 clear_colors
[i
]) && pass
;
200 pass
= test_color(true, /* srgb_before_clear */
201 clear_colors
[i
]) && pass
;
204 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
208 piglit_init(int argc
, char **argv
)
212 piglit_require_extension("GL_EXT_framebuffer_sRGB");
213 piglit_require_extension("GL_ARB_framebuffer_sRGB");
215 prog
= piglit_build_simple_program(vertex_source
, fragment_source
);
217 color_location
= glGetUniformLocation(prog
, "color");
219 glGenFramebuffers(1, &fbo
);
220 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
221 glGenRenderbuffers(1, &rb
);
222 glBindRenderbuffer(GL_RENDERBUFFER
, rb
);
223 glRenderbufferStorage(GL_RENDERBUFFER
,
225 piglit_width
, piglit_height
);
226 glFramebufferRenderbuffer(GL_FRAMEBUFFER
,
227 GL_COLOR_ATTACHMENT0
,
231 if (glCheckFramebufferStatus(GL_FRAMEBUFFER
) !=
232 GL_FRAMEBUFFER_COMPLETE
) {
233 fprintf(stderr
, "FBO incomplete\n");
234 piglit_report_result(PIGLIT_SKIP
);
237 glBindFramebuffer(GL_FRAMEBUFFER
, piglit_winsys_fbo
);