2 * Copyright 2017 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.
24 /** @file compare-framebuffer-parameter-with-get.
26 * OpenGL 4.5 spec introduced new valid pnames for
27 * GetFramebufferParameter. From OpenGL 4.5 spec, Section 9.2.3
28 * "Framebuffer Object Queries":
30 * "pname may also be one of DOUBLEBUFFER, IMPLEMENTATION_COLOR_-
31 * READ_FORMAT, IMPLEMENTATION_COLOR_READ_TYPE, SAMPLES,
32 * SAMPLE_BUFFERS, or STEREO, indicating the corresponding
33 * framebuffer-dependent state from table 23.73. Values of
34 * framebuffer-dependent state are identical to those that would be
35 * obtained were the framebuffer object bound and queried using the
36 * simple state queries in that table. These values may be queried
37 * from either a framebuffer object or a default framebuffer."
39 * That "simple state queries in that table" are either glGetBooleanv
42 * 4.5 also defines a new method, available on previous versions
43 * through the direct state access extension,
44 * GetNamedFramebufferParameteriv:
46 * "For GetFramebufferParameteriv, the framebuffer object is that
49 * "For GetNamedFramebufferParameteriv, framebuffer may be zero,
50 * indicating the default draw framebuffer, or the name of the
51 * framebuffer object."
53 * So with the Named version, you can query the same info, but you can
54 * query for a framebuffer not bound at that moment.
56 * This test checks that the behaviour of GetFramebufferParameter,
57 * GetNamedFramebufferParameter and glGetX is the same for the bound
58 * framebuffer (default or user defined). Behaviour in the sense of
59 * same value returned or same error generated. For *Named* we will
60 * explicitly bound to a different framebuffer, to ensure that it
61 * works when the queried framebuffer is not bound at that moment.
63 * Note that we will not check if the error or the value is correct,
64 * just that are the same. Value and error correctness should be
65 * evaluated by other tests.
69 #include "piglit-util-gl.h"
71 PIGLIT_GL_TEST_CONFIG_BEGIN
73 config
.supports_gl_core_version
= 45;
75 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
|
76 PIGLIT_GL_VISUAL_DOUBLE
;
78 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
80 PIGLIT_GL_TEST_CONFIG_END
83 * Values of table 23.73, defined on 4.5 spec, allowed on
84 * GetFramebufferParameteriv (so the full table minus SAMPLE_POSITION)
86 static const GLenum table_23_73_allowed
[] = {
87 GL_IMPLEMENTATION_COLOR_READ_FORMAT
,
88 GL_IMPLEMENTATION_COLOR_READ_TYPE
,
95 GLuint framebuffers
[3];
96 bool filter_pname
= false;
98 bool filter_framebuffer
= false;
99 int global_framebuffer
;
102 * Returns if any of the table_23_73 enums is a boolean or not
105 is_boolean(GLenum pname
)
108 case GL_DOUBLEBUFFER
:
119 printf("Usage: gl-4.5-compare-framebuffer-parameter-with-get <pname> <framebuffer>\n");
120 printf("\tpname: only test this pname from table 23.73 (minus "
121 "SAMPLE_POSITION) to use. Optional. \n");
122 printf("\tframebuffer: only test this framebuffer. Optional. Allowed values:\n "
123 "\t\t 0 (default framebuffer)\n"
124 "\t\t 1 (incomplete framebuffer)\n"
125 "\t\t 2 (complete framebuffer)\n");
129 parse_args(int argc
, char **argv
)
135 printf("Only two possible params supported\n");
143 /* Note that this call will abort if the enum is not recognized */
144 global_pname
= piglit_get_gl_enum_from_name(argv
[1]);
145 for (i
= 0; i
< ARRAY_SIZE(table_23_73_allowed
); i
++) {
146 if (global_pname
== table_23_73_allowed
[i
]) {
153 printf("pname %s is not valid for this test\n", argv
[1]);
160 filter_framebuffer
= true;
161 global_framebuffer
= atoi(argv
[2]);
162 if (global_framebuffer
< 0 || global_framebuffer
> 2) {
163 printf("Wrong value for framebuffer: %i\n", global_framebuffer
);
170 piglit_report_result(PIGLIT_FAIL
);
174 * This method calls wraps glGetBooleanv and glGetInteger, as
175 * depending of the pname you will call one or the other. It also does
176 * the boolean to integer casting, as GetFramebufferParameteriv
177 * returns always int.
180 call_get_x(GLenum pname
,
184 if (is_boolean(pname
)) {
185 GLboolean local_value
;
186 glGetBooleanv(pname
, &local_value
);
187 *value
= local_value
;
190 glGetIntegerv(pname
, &local_value
);
191 *value
= local_value
;
194 *error
= glGetError();
198 get_framebuffer_name(int index
)
202 return "default framebuffer";
204 return "incomplete framebuffer";
206 return "complete framebuffer";
208 assert(!"unknown framebuffer");
209 return "unknown framebuffer";
214 * Gets a framebuffer and attaches to it renderbuffer and other stuff,
215 * in order to ensure that it is a complete framebuffer.
217 * returns if it was successful.
220 complete_framebuffer(GLint fb
)
224 glBindFramebuffer(GL_FRAMEBUFFER
, fb
);
225 glGenRenderbuffers(1, &rb
);
226 glBindRenderbuffer(GL_RENDERBUFFER
, rb
);
227 glRenderbufferStorage(GL_RENDERBUFFER
, GL_R8
, 1, 2);
228 glFramebufferRenderbuffer(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_RENDERBUFFER
, rb
);
230 if (GL_FRAMEBUFFER_COMPLETE
== glCheckFramebufferStatus(GL_FRAMEBUFFER
) &&
231 glGetError() == GL_NO_ERROR
) {
239 * We pass the index inside the array of available framebuffers,
240 * instead of the fb itself, because we also want to test binding with
241 * a different valid fb.
244 execute_subtest(int index
,
248 GLint parameter_value
;
251 GLenum parameter_error
;
257 fb
= framebuffers
[index
];
258 other_fb
= framebuffers
[(index
+ 1) % ARRAY_SIZE(framebuffers
)];
260 glBindFramebuffer(GL_FRAMEBUFFER
, fb
);
261 glGetFramebufferParameteriv(GL_FRAMEBUFFER
, pname
, ¶meter_value
);
262 parameter_error
= glGetError();
265 * We re-bind to a different (but valid) framebuffer, as we
266 * want to check that NamedFramebufferParameter gets the same
267 * value even if other framebuffer is bound.
269 glBindFramebuffer(GL_FRAMEBUFFER
, other_fb
);
270 glGetNamedFramebufferParameteriv(fb
, pname
, &named_value
);
271 named_error
= glGetError();
273 glBindFramebuffer(GL_FRAMEBUFFER
, fb
);
274 call_get_x(pname
, &get_value
, &get_error
);
276 subtest_pass
= (get_error
== parameter_error
&&
277 get_value
== parameter_value
&&
278 parameter_error
== named_error
&&
279 parameter_value
== named_value
);
282 printf("Different behaviour for pname %s.\n\tGetBooleanv/Integerv"
283 " returns %i and generate the error %s.\n"
284 "\tGetFramebufferParameter returns %i and generate the "
285 "error %s.\n\tGetNamedFramebufferParameter returns %i "
286 "and generate the error %s\n",
287 piglit_get_gl_enum_name(pname
),
288 get_value
, piglit_get_gl_error_name(get_error
),
289 parameter_value
, piglit_get_gl_error_name(parameter_error
),
290 named_value
, piglit_get_gl_error_name(named_error
));
305 piglit_init(int argc
, char **argv
)
308 * We don't check for framebuffer object extension support an
309 * any other, as we are already asking core version 4.5 on
312 parse_args(argc
, argv
);
320 glCreateFramebuffers(2, &framebuffers
[1]);
321 piglit_check_gl_error(GL_NO_ERROR
);
323 if (!complete_framebuffer(framebuffers
[2])) {
324 printf("Not able to allocate a complete framebuffer\n");
326 piglit_report_result(PIGLIT_FAIL
);
329 for (c
= 0; c
< ARRAY_SIZE(framebuffers
); c
++) {
331 if (filter_framebuffer
&& global_framebuffer
!= c
)
334 for (i
= 0; i
< ARRAY_SIZE(table_23_73_allowed
); i
++) {
335 GLenum pname
= table_23_73_allowed
[i
];
337 if (filter_pname
&& global_pname
!= pname
)
340 subtest_pass
= execute_subtest(c
, pname
);
342 PIGLIT_SUBTEST_CONDITION(subtest_pass
, pass
, "%s pname %s",
343 get_framebuffer_name(c
),
344 piglit_get_gl_enum_name(pname
));
348 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);