1 /*
2  * Copyright 2013 VMware, Inc.
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
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 /**
25  * \file fs-textureOffset-2D.c
26  *
27  * Tests the built-in function textureLodOffset() in the fragment shader.
28  *
29  * Creates a mipmapped 64x32 2D texture and draws a series of squares whose
30  * color contains a texel fetched from each quadrant of the rgbw texture.
31  *
32  * Author: Roland Scheidegger
33  */
34 #include "piglit-util-gl.h"
35 
36 PIGLIT_GL_TEST_CONFIG_BEGIN
37 
38 	config.supports_gl_compat_version = 10;
39 
40 	config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
41 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
42 
43 PIGLIT_GL_TEST_CONFIG_END
44 
45 const int tex_size = 64;
46 
47 static int pos_location, lod_location;
48 
49 static const char vert[] =
50 "#version 130\n"
51 "void main()\n"
52 "{\n"
53 "	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
54 "}\n";
55 
56 static const char fragtexlodoffset[] =
57 "#version 130\n"
58 "uniform vec2 pos;\n"
59 "uniform float lod;\n"
60 "uniform sampler2D tex;\n"
61 "void main()\n"
62 "{\n"
63 "       const ivec2 offset = ivec2(-2, 2);\n"
64 "       vec4 texel = textureLodOffset(tex, pos, lod, offset);\n"
65 "	gl_FragColor = texel;\n"
66 "}\n";
67 
max(float x,float y)68 static float max(float x, float y) { return (x > y) ? x : y; }
69 
70 enum piglit_result
piglit_display(void)71 piglit_display(void)
72 {
73 	int l, q;
74 	bool pass = true;
75 	float red[4]   = {1.0, 0.0, 0.0, 1.0};
76 	float green[4]   = {0.0, 1.0, 0.0, 1.0};
77 	float blue[4]  = {0.0, 0.0, 1.0, 1.0};
78 	float white[4]  = {1.0, 1.0, 1.0, 1.0};
79 	float undefined[4] = {0.0, 0.0, 0.0, 0.0};
80 
81 	piglit_ortho_projection(piglit_width, piglit_height, false);
82 
83 	glClearColor(0.5, 0.5, 0.5, 1.0);
84 	glClear(GL_COLOR_BUFFER_BIT);
85 
86 	/* TODO: test other wrap modes */
87 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
88 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
89 
90 	for (l = 0; (tex_size >> l) > 0; l++) {
91 		const int width = tex_size >> l;
92 		const int height = max(width / 2, 1);
93 		const int y = 10 + 20 * l;
94 
95 		glUniform1f(lod_location, (float)l);
96 
97 		/* Draw 4 squares with a color sample for each quad */
98 		for (q = 0; q < 4; q++) {
99 			const float tex_x = (q / 2) * 0.5f + 0.25f;
100 			const float tex_y = (q % 2) * 0.5f + 0.25f;
101 			float *c = undefined;
102 			const int x = 10+20*q;
103 
104 			if (((q / 2) * 0.5f + 0.25f) * width + (-2.0f) < 0.5f * width) {
105 				if (((q % 2) * 0.5f + 0.25f) * height + (+2.0f) < 0.5f * height)
106 					c = red;
107 				else
108 					c = blue;
109 			}
110 			else {
111 				if (((q % 2) * 0.5f + 0.25f) * height + (+2.0f) < 0.5f * height)
112 					c = green;
113 				else
114 					c = white;
115 			}
116 
117 			glUniform2f(pos_location, tex_x, tex_y);
118 			piglit_draw_rect(x, y, 10, 10);
119 
120 			if (width > 2 && c != undefined) /* below 1 wide no test */
121 				pass &= piglit_probe_rect_rgba(x, y, 10, 10, c);
122 		}
123 	}
124 
125 	piglit_present_results();
126 
127 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
128 }
129 
130 void
piglit_init(int argc,char ** argv)131 piglit_init(int argc, char **argv)
132 {
133 	int prog;
134 
135 	piglit_require_GLSL_version(130);
136 
137 	glActiveTexture(GL_TEXTURE0);
138 	/* TODO: test npot sizes, other samplers, ... */
139 	piglit_rgbw_texture(GL_RGBA, tex_size, tex_size / 2, true, false,
140 			    GL_UNSIGNED_NORMALIZED);
141 
142 	/* TODO: test other texture instructions */
143 	prog = piglit_build_simple_program(vert, fragtexlodoffset);
144 
145 	lod_location = glGetUniformLocation(prog, "lod");
146 	pos_location = glGetUniformLocation(prog, "pos");
147 
148 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
149 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
150 
151 	glUseProgram(prog);
152 }
153