2 * Copyright (c) 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
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 rendering-array.c
26 * Test rendering with a UBO containing an array of structs.
27 * We draw four squares with different positions, sizes, rotations and colors
28 * where those parameters come from an array in a UBO. Each draw command
29 * indexes into a different element of that array.
32 #include "piglit-util-gl.h"
34 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config
.supports_gl_compat_version
= 20;
36 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
37 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
38 PIGLIT_GL_TEST_CONFIG_END
41 static const char vert_shader_text
[] =
42 "#extension GL_ARB_uniform_buffer_object : require\n"
44 "layout(std140) uniform;\n"
45 "uniform ub_info { \n"
55 "varying vec4 color; \n"
61 " for (i = 0; i < 4; i++) { \n"
63 " m[0][0] = m[1][1] = cos(info[i].rotation); \n"
64 " m[0][1] = sin(info[i].rotation); \n"
65 " m[1][0] = -m[0][1]; \n"
66 " gl_Position.xy = m * gl_Vertex.xy * vec2(info[i].size) + info[i].pos;\n"
67 " gl_Position.zw = vec2(0, 1);\n"
68 " color = info[i].color; \n"
73 static const char frag_shader_text
[] =
74 "#extension GL_ARB_uniform_buffer_object : require\n"
76 "varying vec4 color; \n"
78 "layout(std140) uniform;\n"
82 " gl_FragColor = color;\n"
88 static GLuint ubo_buffer
;
89 static GLint alignment
;
90 static bool test_buffer_offset
= false;
99 /* This data are copied into the UBO */
100 static const struct object_info obj_info
[NUM_SQUARES
] = {
101 { {-0.5, -0.5}, 0.1, 0.0, {1.0, 0.0, 0.0, 1.0} },
102 { { 0.5, -0.5}, 0.2, 0.1, {0.0, 1.0, 0.0, 1.0} },
103 { {-0.5, 0.5}, 0.3, 0.2, {0.0, 0.0, 1.0, 1.0} },
104 { { 0.5, 0.5}, 0.4, 0.3, {1.0, 1.0, 1.0, 1.0} }
111 static const char *ubo_name
= "ub_info";
112 GLint ubo_index
, ubo_size
;
114 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
, &alignment
);
115 printf("GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = %d\n", alignment
);
117 if (test_buffer_offset
) {
118 printf("Testing buffer offset %d\n", alignment
);
121 /* we use alignment as the offset */
125 glGenBuffers(1, &ubo_buffer
);
127 /* query UBO index */
128 ubo_index
= glGetUniformBlockIndex(prog
, ubo_name
);
131 glGetActiveUniformBlockiv(prog
, ubo_index
,
132 GL_UNIFORM_BLOCK_DATA_SIZE
, &ubo_size
);
134 printf("UBO %s: index = %d, size = %d\n",
135 ubo_name
, ubo_index
, ubo_size
);
137 assert(ubo_size
== sizeof(obj_info
));
139 /* Allocate UBO and put object info into it */
140 glBindBuffer(GL_UNIFORM_BUFFER
, ubo_buffer
);
141 glBufferData(GL_UNIFORM_BUFFER
, alignment
+ sizeof(obj_info
),
142 NULL
, GL_STATIC_DRAW
);
143 glBufferSubData(GL_UNIFORM_BUFFER
, alignment
,
144 sizeof(obj_info
), obj_info
);
147 glBindBufferRange(GL_UNIFORM_BUFFER
, 0, ubo_buffer
,
148 alignment
, /* offset */
150 glUniformBlockBinding(prog
, ubo_index
, 0);
152 if (!piglit_check_gl_error(GL_NO_ERROR
))
153 piglit_report_result(PIGLIT_FAIL
);
158 piglit_init(int argc
, char **argv
)
160 piglit_require_extension("GL_ARB_uniform_buffer_object");
162 if (argc
> 1 && strcmp(argv
[1], "offset") == 0) {
163 test_buffer_offset
= true;
166 prog
= piglit_build_simple_program(vert_shader_text
, frag_shader_text
);
170 uniform_j
= glGetUniformLocation(prog
, "j");
174 glClearColor(0.2, 0.2, 0.2, 0.2);
182 int x0
= piglit_width
/ 4;
183 int x1
= piglit_width
* 3 / 4;
184 int y0
= piglit_height
/ 4;
185 int y1
= piglit_height
* 3 / 4;
188 glViewport(0, 0, piglit_width
, piglit_height
);
190 glClear(GL_COLOR_BUFFER_BIT
);
192 for (i
= 0; i
< NUM_SQUARES
; i
++) {
193 /* Take object parameters from array position [i] */
194 glUniform1i(uniform_j
, i
);
196 if (!piglit_check_gl_error(GL_NO_ERROR
))
199 piglit_draw_rect(-1, -1, 2, 2);
202 pass
= piglit_probe_pixel_rgba(x0
, y0
, obj_info
[0].color
) && pass
;
203 pass
= piglit_probe_pixel_rgba(x1
, y0
, obj_info
[1].color
) && pass
;
204 pass
= piglit_probe_pixel_rgba(x0
, y1
, obj_info
[2].color
) && pass
;
205 pass
= piglit_probe_pixel_rgba(x1
, y1
, obj_info
[3].color
) && pass
;
207 piglit_present_results();
209 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;