1 /*
2 * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
3 * Copyright © 2015 Red Hat
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 /**
26 * ARB_gpu_shader_fp64 + ARB_transform_feedback3 test.
27 *
28 * Test writing interleaved vertex attribs into a buffer object.
29 * Writing unaligned doubles is undefined so if we want to have a float
30 * follow a double we need to use ARB_tf3
31 *
32 * "If capturing a mix of single- and double-precision components, it might
33 * be necessary to use the "gl_SkipComponents1" variable from
34 * ARB_transform_feedback3 to force proper alignment."
35 */
36
37 #include "piglit-util-gl.h"
38
39 PIGLIT_GL_TEST_CONFIG_BEGIN
40
41 config.supports_gl_core_version = 32;
42 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
43 config.khr_no_error_support = PIGLIT_NO_ERRORS;
44
45 PIGLIT_GL_TEST_CONFIG_END
46
47 static const char *vstext = {
48 "#version 150\n"
49 "#extension GL_ARB_gpu_shader_fp64 : require\n"
50 "in vec4 vertex;"
51 "out vec4 color;"
52 "out float tf;"
53 "out dvec3 v3;"
54 "out dvec2 v2;"
55 "void main() {"
56 " gl_Position = vertex;"
57 " color = vec4(1.0, 0.9, 0.8, 0.7);"
58 " tf = 0.5;"
59 " v2 = dvec2(0.2lf, 0.7lf);"
60 " v3 = dvec3(0.55lf, 0.66lf, 0.77lf);"
61 "}"
62 };
63
64 static const char *varyings[] = {"tf", "gl_SkipComponents1", "v3", "color", "v2"};
65 GLuint buf;
66 GLuint prog;
67 GLuint vao, vbo;
68
69 #define NUM_COMPONENTS 16
70 #define TOTAL_BUF_COMPONENTS (NUM_COMPONENTS*6)
71
72 static uint32_t dbl_components = (0x3f << 2) | (0xf << 12);
piglit_init(int argc,char ** argv)73 void piglit_init(int argc, char **argv)
74 {
75 GLuint vs, i;
76 GLint maxcomps;
77 float *ptr;
78
79 /* Check the driver. */
80 piglit_require_transform_feedback();
81 piglit_require_extension("GL_ARB_gpu_shader_fp64");
82 piglit_require_extension("GL_ARB_transform_feedback3");
83
84 glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT, &maxcomps);
85 if (maxcomps < 18) {
86 fprintf(stderr, "Not enough interleaved components supported by transform feedback.\n");
87 piglit_report_result(PIGLIT_SKIP);
88 }
89
90 /* Create shaders. */
91 vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
92 prog = glCreateProgram();
93 glAttachShader(prog, vs);
94 glTransformFeedbackVaryings(prog, sizeof(varyings)/sizeof(varyings[0]),
95 varyings, GL_INTERLEAVED_ATTRIBS_EXT);
96 glLinkProgram(prog);
97 if (!piglit_link_check_status(prog)) {
98 glDeleteProgram(prog);
99 piglit_report_result(PIGLIT_FAIL);
100 }
101
102 /* Set up the transform feedback buffer. */
103 glGenBuffers(1, &buf);
104 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, buf);
105 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER_EXT,
106 TOTAL_BUF_COMPONENTS*sizeof(float), NULL, GL_STREAM_READ);
107 ptr = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, GL_WRITE_ONLY);
108 for (i = 0; i < TOTAL_BUF_COMPONENTS; i++) {
109 ptr[i] = 0.123456;
110 }
111 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT);
112 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, 0, buf);
113
114 if (!piglit_check_gl_error(GL_NO_ERROR))
115 piglit_report_result(PIGLIT_FAIL);
116
117 glClearColor(0.2, 0.2, 0.2, 1.0);
118 }
119
piglit_display(void)120 enum piglit_result piglit_display(void)
121 {
122 GLboolean pass = GL_TRUE;
123 float *ptr;
124 double *dptr;
125 unsigned i;
126 static const float verts[] = {
127 10, 10,
128 10, 20,
129 20, 20,
130 20, 10
131 };
132 static const unsigned indices[] = {
133 0, 1, 3, 1, 2, 3
134 };
135 static const float expected[] = {
136 0.5, 0.123456,
137 0.550000, 0.0, 0.660000, 0.0, 0.770000, 0.0,
138 1.000000, 0.900000, 0.800000, 0.700000,
139 0.200000, 0.0, 0.700000, 0.0,
140 };
141
142 glClear(GL_COLOR_BUFFER_BIT);
143
144 glGenVertexArrays(1, &vao);
145 glBindVertexArray(vao);
146
147 glGenBuffers(1, &vbo);
148 glBindBuffer(GL_ARRAY_BUFFER, vbo);
149 glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
150 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid const *)0);
151
152 /* Render into TFBO. */
153 glUseProgram(prog);
154 glEnable(GL_RASTERIZER_DISCARD);
155 glBeginTransformFeedback(GL_TRIANGLES);
156 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
157 glEndTransformFeedback();
158 glDisable(GL_RASTERIZER_DISCARD);
159
160 if (!piglit_check_gl_error(GL_NO_ERROR))
161 piglit_report_result(PIGLIT_FAIL);
162
163 ptr = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, GL_READ_ONLY);
164 dptr = (double *)ptr;
165 for (i = 0; i < TOTAL_BUF_COMPONENTS; i++) {
166 float expect = expected[i % NUM_COMPONENTS];
167 if ((dbl_components) & (1 << (i % NUM_COMPONENTS))) {
168 if ((i % 2) == 0) {
169 if (fabs(dptr[i/2] - expect) > 0.01) {
170 printf("Bufferd[%i]: %f, Expected: %f\n", i, dptr[i/2], expect);
171 pass = GL_FALSE;
172 } else {
173 printf("Bufferd[%i]: %f, Expected: %f -- OK\n", i, dptr[i/2], expect);
174 }
175 }
176 } else {
177 //printf("%f, ", ptr[i]); continue;
178 if (fabs(ptr[i] - expect) > 0.01) {
179 printf("Buffer[%i]: %f, Expected: %f\n", i, ptr[i], expect);
180 pass = GL_FALSE;
181 } else {
182 printf("Buffer[%i]: %f, Expected: %f -- OK\n", i, ptr[i], expect);
183 }
184 }
185 }
186 //puts("");
187 glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT);
188
189 if (!piglit_check_gl_error(GL_NO_ERROR))
190 piglit_report_result(PIGLIT_FAIL);
191
192 piglit_present_results();
193
194 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
195 }
196