1 /*
2  * Copyright (c) 2013 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 
24 /**
25  * @file interpolateAtSample.c
26  *
27  * Test ARB_gpu_shader5 interpolateAtSample builtin
28  *
29  * Tests that interpolateAtSample(x) gives the correct result.
30  *
31  * R, 1-G channels are interesting; a correct implementation should produce
32  * (0,1,0) in all pixels.
33  *
34  * We require 3.2, so the following assumptions are made:
35  * - MAX_SAMPLES >= 4 (although we dont require exactly 4 samples; if only an
36  *   8x mode is supported, the test should still work)
37  * - GLSL 1.50 and Multisample textures are supported.
38  *
39  * This variant exercises a nonconstant sample_num parameter.
40  */
41 
42 
43 #include "piglit-util-gl.h"
44 
45 PIGLIT_GL_TEST_CONFIG_BEGIN
46 
47 	config.supports_gl_core_version = 32;
48 
49 	config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB;
50 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
51 
52 PIGLIT_GL_TEST_CONFIG_END
53 
54 GLuint ms_fbo, vao, bo;
55 GLint draw_prog, test_prog;
56 GLint sample_pos_loc;
57 
58 float green[] = { 0, 1, 0 };
59 float verts[][2] = { { -1, -1 }, { 1, -1 }, { -1, 1 }, { 1, 1 }, };
60 #define GAIN "5"			/* multiplier for absolute difference; make the error more visible. */
61 
62 
63 enum piglit_result
piglit_display(void)64 piglit_display(void)
65 {
66 	bool pass = true;
67 	GLfloat pos[2];
68 	glGetMultisamplefv(GL_SAMPLE_POSITION, 0, pos);
69 	/* API gives us 0..1 sample position; get it into
70 	 * -0.5..0.5 space.
71 	 */
72 	pos[0] -= 0.5f;
73 	pos[1] -= 0.5f;
74 
75 	glViewport(0, 0, 64, 64);
76 
77 	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ms_fbo);
78 	glUseProgram(draw_prog);
79 	glUniform2fv(sample_pos_loc, 1, pos);
80 	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
81 
82 	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
83 	glUseProgram(test_prog);
84 	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
85 
86 	pass = piglit_probe_rect_rgb(0, 0, 64, 64, green) && pass;
87 
88 	piglit_present_results();
89 
90 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
91 }
92 
93 
94 void
piglit_init(int argc,char ** argv)95 piglit_init(int argc, char**argv)
96 {
97 	GLuint tex;
98 	piglit_require_extension("GL_ARB_gpu_shader5");
99 
100 	glGenFramebuffers(1, &ms_fbo);
101 	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ms_fbo);
102 	glGenTextures(1, &tex);
103 	glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
104 	glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4,
105 				GL_RGBA, 64, 64, GL_TRUE);
106 	glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
107 			       GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
108 
109 	if (!piglit_check_gl_error(GL_NO_ERROR)) {
110 		printf("fbo setup failed.\n");
111 		piglit_report_result(PIGLIT_SKIP);
112 	}
113 
114 	/* Test quantity varies from -1 to +1 over 64 pixels --
115 	 * so moving 1px changes its value by 1/32.
116 	 */
117 	draw_prog = piglit_build_simple_program(
118 		"#version 150\n"
119 		"uniform vec2 sample_pos;\n"
120 		"in vec2 p;\n"
121 		"out vec2 test;\n"
122 		"out vec2 ref;\n"
123 		"flat out int sample_id;\n"
124 		"void main() {\n"
125 		"	gl_Position = vec4(p, 0, 1);\n"
126 		"	test = p;\n"
127 		"	ref = p;\n"
128 		"	ref.xy += sample_pos / 32;\n"
129 		"	sample_id = 0;\n"
130 		"}\n",
131 
132 		"#version 150\n"
133 		"#extension GL_ARB_gpu_shader5: require\n"
134 		"flat in int sample_id;\n"
135 		"in vec2 test;\n"
136 		"in vec2 ref;\n"
137 		"void main() {\n"
138 		"	gl_FragColor = vec4(" GAIN " * abs(\n"
139 		"		interpolateAtSample(test, sample_id) - ref), 0, 1);\n"
140 		"}\n");
141 	if (!draw_prog) {
142 		printf("draw_prog compile/link failed\n");
143 		piglit_report_result(PIGLIT_FAIL);
144 	}
145 
146 	test_prog = piglit_build_simple_program(
147 		"#version 150\n"
148 		"in vec2 p;\n"
149 		"void main() {\n"
150 		"	gl_Position = vec4(p, 0, 1);\n"
151 		"}\n",
152 
153 		"#version 150\n"
154 		"uniform sampler2DMS s;\n"
155 		"void main() {\n"
156 		"	vec4 temp = \n"
157 		"		texelFetch(s, ivec2(gl_FragCoord.xy), 0) +\n"
158 		"		texelFetch(s, ivec2(gl_FragCoord.xy), 1) +\n"
159 		"		texelFetch(s, ivec2(gl_FragCoord.xy), 2) +\n"
160 		"		texelFetch(s, ivec2(gl_FragCoord.xy), 3);\n"
161 		"	gl_FragColor = vec4(temp.x, 1-temp.y, temp.z, temp.w);\n"
162 		"}\n");
163 	if (!test_prog) {
164 		printf("test_prog compile/link failed\n");
165 		piglit_report_result(PIGLIT_FAIL);
166 	}
167 
168 	sample_pos_loc = glGetUniformLocation(draw_prog, "sample_pos");
169 
170 	glUseProgram(test_prog);
171 	glUniform1i(glGetUniformLocation(test_prog, "s"), 0);
172 
173 	if (!piglit_check_gl_error(GL_NO_ERROR)) {
174 		printf("shader setup failed\n");
175 		piglit_report_result(PIGLIT_SKIP);
176 	}
177 
178 	glGenVertexArrays(1, &vao);
179 	glBindVertexArray(vao);
180 
181 	glEnableVertexAttribArray(0);
182 	glGenBuffers(1, &bo);
183 	glBindBuffer(GL_ARRAY_BUFFER, bo);
184 	glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
185 	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid const *)0);
186 }
187 
188