1 /*
2 * Copyright © 2015 Intel Corporation
3 *
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:
10 *
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.
14 *
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 DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Neil Roberts <neil@linux.intel.com>
25 *
26 */
27
28 /** @file zero-tex-coord.c
29 *
30 * Tests various texture sampling functions using constant 0 values
31 * for the arguments. The i965 driver has optimisations for trailing 0
32 * arguments to sampler messages so the intention is to test these
33 * code paths.
34 */
35
36 #include "piglit-util-gl.h"
37
38 PIGLIT_GL_TEST_CONFIG_BEGIN
39
40 config.supports_gl_compat_version = 10;
41 config.supports_gl_core_version = 31;
42
43 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
44 config.khr_no_error_support = PIGLIT_NO_ERRORS;
45
46 PIGLIT_GL_TEST_CONFIG_END
47
48 struct sample_function {
49 const char *name;
50 const char *snippet;
51 int glsl_version;
52 const char *extension;
53 };
54
55 static const struct sample_function
56 sample_functions[] = {
57 { "texture2D", "texture2D(tex, vec2(0.0))", 0 },
58 { "bias", "texture2D(tex, vec2(0.0), 0.0)", 0 },
59 { "textureGrad",
60 "textureGrad(tex, vec2(0.0), vec2(0.0), vec2(0.0))",
61 130 },
62 { "texelFetch", "texelFetch(tex, ivec2(0), 0)", 130 },
63 { "textureLod",
64 "textureLod(tex, vec2(0.0), 0.0)",
65 130 },
66 { "textureSize",
67 "textureSize(tex, 0) == ivec2(4) ? "
68 "vec4(0.0, 1.0, 0.0, 1.0) : "
69 "vec4(1.0, 0.0, 0.0, 1.0)",
70 130 },
71 { "textureQueryLOD",
72 "textureQueryLOD(tex, vec2(0.0)).x == 0.0 ? "
73 "vec4(0.0, 1.0, 0.0, 1.0) : "
74 "vec4(1.0, 0.0, 0.0, 1.0)",
75 0, "GL_ARB_texture_query_lod" },
76 { "textureGather",
77 "textureGather(tex, vec2(0.0), 0) == vec4(0.0) ? "
78 "vec4(0.0, 1.0, 0.0, 1.0) : "
79 "vec4(1.0, 0.0, 0.0, 1.0)",
80 130, "GL_ARB_gpu_shader5" },
81 };
82
83 static const char
84 vertex_source[] =
85 "attribute vec2 piglit_vertex;\n"
86 "\n"
87 "void\n"
88 "main()\n"
89 "{\n"
90 " gl_Position = vec4(piglit_vertex, 0.0, 1.0);\n"
91 "}\n";
92
93 static const char
94 fragment_source[] =
95 "uniform sampler2D tex;\n"
96 "\n"
97 "void\n"
98 "main()\n"
99 "{\n"
100 " gl_FragColor = SNIPPET;\n"
101 "}\n";
102
103 const struct sample_function *
104 sample_function = sample_functions;
105
106 static const GLfloat
107 green[] = { 0.0f, 1.0f, 0.0f, 1.0f };
108
109 static GLuint
make_tex(void)110 make_tex(void)
111 {
112 /* Make a fully mipmapped texture with a green texel on at the
113 * 0,0 position on the largest mip image and a red texel for
114 * all of the other positions */
115
116 GLuint tex;
117 int size = 4;
118 int level = 0;
119 GLubyte *image, *p;
120 int y, x;
121
122 glGenTextures(1, &tex);
123 glBindTexture(GL_TEXTURE_2D, tex);
124 glTexParameteri(GL_TEXTURE_2D,
125 GL_TEXTURE_MIN_FILTER,
126 GL_NEAREST_MIPMAP_NEAREST);
127 glTexParameteri(GL_TEXTURE_2D,
128 GL_TEXTURE_MAG_FILTER,
129 GL_NEAREST);
130 glTexParameteri(GL_TEXTURE_2D,
131 GL_TEXTURE_WRAP_S,
132 GL_CLAMP_TO_EDGE);
133 glTexParameteri(GL_TEXTURE_2D,
134 GL_TEXTURE_WRAP_T,
135 GL_CLAMP_TO_EDGE);
136
137 while (size >= 1) {
138 p = image = malloc(size * size * 4);
139
140 for (y = 0; y < size; y++) {
141 for (x = 0; x < size; x++) {
142 if (level == 0 && y == 0 && x == 0) {
143 *(p++) = 0x00;
144 *(p++) = 0xff;
145 } else {
146 *(p++) = 0xff;
147 *(p++) = 0x00;
148 }
149 *(p++) = 0x00;
150 *(p++) = 0x00;
151 }
152 }
153
154 glTexImage2D(GL_TEXTURE_2D,
155 level,
156 GL_RGBA,
157 size, size,
158 0, /* border */
159 GL_RGBA, GL_UNSIGNED_BYTE,
160 image);
161
162 free(image);
163
164 size /= 2;
165 level++;
166 }
167
168 return tex;
169 }
170
171 static GLuint
make_program(void)172 make_program(void)
173 {
174 const char *snippet = sample_function->snippet;
175 int glsl_version = sample_function->glsl_version;
176 int snippet_length = strlen(snippet);
177 int snippet_pos = strstr(fragment_source, "SNIPPET") - fragment_source;
178 GLuint program;
179 char source[1000], *p = source;
180
181 if (glsl_version > 0) {
182 p += sprintf(p, "#version %i\n", glsl_version);
183 piglit_require_GLSL_version(glsl_version);
184 }
185
186 if (sample_function->extension) {
187 p += sprintf(p,
188 "#extension %s : require\n",
189 sample_function->extension);
190 piglit_require_extension(sample_function->extension);
191 }
192
193 memcpy(p, fragment_source, snippet_pos);
194 p += snippet_pos;
195 memcpy(p, snippet, snippet_length);
196 p += snippet_length;
197 memcpy(p,
198 fragment_source + snippet_pos + 7,
199 sizeof fragment_source - snippet_pos - 7);
200
201 program = piglit_build_simple_program(vertex_source, source);
202
203 return program;
204 }
205
206 enum piglit_result
piglit_display(void)207 piglit_display(void)
208 {
209 GLboolean pass = GL_TRUE;
210 GLuint program, tex;
211 GLint tex_location;
212
213 tex = make_tex();
214 program = make_program();
215
216 glUseProgram(program);
217 tex_location = glGetUniformLocation(program, "tex");
218 glUniform1i(tex_location, 0);
219
220 piglit_draw_rect(-1.0f, -1.0f, 2.0f, 2.0f);
221
222 glUseProgram(0);
223
224 glDeleteTextures(1, &tex);
225 glDeleteProgram(program);
226
227 pass = piglit_probe_rect_rgb(0, 0,
228 piglit_width, piglit_height,
229 green) && pass;
230
231 piglit_present_results();
232
233 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
234 }
235
236 void
piglit_init(int argc,char ** argv)237 piglit_init(int argc, char **argv)
238 {
239 int i;
240
241 if (argc > 1) {
242 for (i = 0; i < ARRAY_SIZE(sample_functions); i++) {
243 if (!strcmp(sample_functions[i].name, argv[1])) {
244 sample_function = sample_functions + i;
245 goto found;
246 }
247 }
248
249 fprintf(stderr, "Unknown function: %s\n", argv[1]);
250 piglit_report_result(PIGLIT_FAIL);
251
252 found:
253 (void) 0;
254 }
255
256 piglit_require_GLSL();
257 }
258