ARB_ubo/referenced-by-shader: pass if shader compiler moves UBOs between shaders
[piglit.git] / tests / spec / arb_uniform_buffer_object / rendering-array.c
blobd508635be71857b84fb0e3c0907cf006e99a7d1a
1 /*
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
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
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"
43 "\n"
44 "layout(std140) uniform;\n"
45 "uniform ub_info { \n"
46 " struct { \n"
47 " vec2 pos; \n"
48 " float size; \n"
49 " float rotation; \n"
50 " vec4 color; \n"
51 " } info [4];\n"
52 "};\n"
53 "\n"
54 "uniform int j; \n"
55 "varying vec4 color; \n"
56 "\n"
57 "void main()\n"
58 "{\n"
59 " int i; \n"
60 " mat2 m;\n"
61 " for (i = 0; i < 4; i++) { \n"
62 " if (i == j) { \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"
69 " } \n"
70 " } \n"
71 "}\n";
73 static const char frag_shader_text[] =
74 "#extension GL_ARB_uniform_buffer_object : require\n"
75 "\n"
76 "varying vec4 color; \n"
77 "\n"
78 "layout(std140) uniform;\n"
79 "\n"
80 "void main()\n"
81 "{\n"
82 " gl_FragColor = color;\n"
83 "}\n";
85 #define NUM_SQUARES 4
87 static GLuint prog;
88 static GLuint ubo_buffer;
89 static GLint alignment;
90 static bool test_buffer_offset = false;
91 static int uniform_j;
93 struct object_info {
94 float pos[2];
95 float size, rotation;
96 float color[4];
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} }
108 static void
109 setup_ubos(void)
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);
120 else {
121 /* we use alignment as the offset */
122 alignment = 0;
125 glGenBuffers(1, &ubo_buffer);
127 /* query UBO index */
128 ubo_index = glGetUniformBlockIndex(prog, ubo_name);
130 /* query UBO size */
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);
146 /* Attach UBO */
147 glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo_buffer,
148 alignment, /* offset */
149 ubo_size);
150 glUniformBlockBinding(prog, ubo_index, 0);
152 if (!piglit_check_gl_error(GL_NO_ERROR))
153 piglit_report_result(PIGLIT_FAIL);
157 void
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);
167 assert(prog);
168 glUseProgram(prog);
170 uniform_j = glGetUniformLocation(prog, "j");
172 setup_ubos();
174 glClearColor(0.2, 0.2, 0.2, 0.2);
178 enum piglit_result
179 piglit_display(void)
181 bool pass = true;
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;
186 int i;
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))
197 return PIGLIT_FAIL;
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;