2 * Copyright © 2013 LunarG, 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
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
23 * Author: Jon Ashburn <jon@lunarg.com>
27 * Draws quads into a single framebuffer surface with multiple viewports
28 * via a geometry shader. Each different viewport has a different DepthRange.
29 * The fragment shader outputs a color based on the depthRange, z, and viewport
30 * index. Confirm that each quad has the correct color and therefore has
31 * the correct depthRange for that viewport index.
32 * From the OpenGL 4.3 Core3 Profile Spec section 13.6:
33 * "DepthRangeIndexed specifies the depth range for a single viewport and
34 * is equivalent (assuming no errors are generated) to:
35 * double v[] = { n, f };
36 * DepthRangeArrayv(index, 1, v);"
37 * "DepthRange sets the depth range for all viewports to the same values
38 * and is equivalent (assuming no errors are generated) to:
39 * for (uint i = 0; i < MAX_VIEWPORTS; i++)
40 * DepthRangeIndexed(i, n, f );"
42 #include "piglit-util-gl.h"
44 PIGLIT_GL_TEST_CONFIG_BEGIN
46 config
.supports_gl_compat_version
= 32;
47 config
.supports_gl_core_version
= 32;
48 config
.supports_gl_es_version
= 31;
50 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
51 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
53 PIGLIT_GL_TEST_CONFIG_END
55 #ifdef PIGLIT_USE_OPENGL
56 #define GLSL_VERSION "150"
58 #define GLSL_VERSION "310 es"
61 const char *vsSource
= {
62 "#version " GLSL_VERSION
"\n"
63 "in vec4 piglit_vertex;\n"
65 " gl_Position = piglit_vertex;\n"
69 const char *gsSource
= {
70 "#version " GLSL_VERSION
"\n"
71 "#extension GL_ARB_viewport_array : enable\n"
72 "#extension GL_OES_viewport_array : enable\n"
73 "#extension GL_EXT_geometry_shader : enable\n"
74 "#extension GL_OES_geometry_shader : enable\n"
75 "layout(triangles) in;\n"
76 "layout(triangle_strip, max_vertices = 3) out;\n"
78 "flat out int ViewportIndex;\n"
82 " gl_ViewportIndex = idx;\n"
83 " ViewportIndex = idx;\n"
84 " for(int i = 0; i < gl_in.length(); i++) {\n"
85 " gl_Position = gl_in[i].gl_Position;\n"
92 const char *fsSource
= {
93 "#version " GLSL_VERSION
"\n"
95 "precision highp float;\n"
97 "uniform vec3 color;\n"
98 "flat in int ViewportIndex;\n"
101 " float idx = float(ViewportIndex) / 10.0;\n"
102 " c = vec4(gl_FragCoord.z, gl_DepthRange.far, idx, 1.0);\n"
106 static GLint colorLoc
;
107 static GLint vpIndexLoc
;
113 * Draws a single quad into multiple viewport each with a different
114 * depthRange and fixed Z plane. Reads back the expected color (which is a
115 * a function (funcOf(Z, depthRange, viewportIndex)) to test if the drawing
116 * with different depthRanges per viewport index is correct.
117 * From GLSL 4.30.6 Spec section 7.4:
118 * "Depth range in window coordinates,
119 * section 13.6.1 “Controlling the Viewport” in the
120 * OpenGL Graphics System Specification.
121 * Note: Depth-range state is only for viewport 0."
125 draw_multi_viewport(void)
129 GLfloat w
= (GLfloat
) piglit_width
/ (GLfloat
) DIVX
;
130 GLfloat h
= (GLfloat
) piglit_height
/ (GLfloat
) DIVY
;
131 GLfloat zVal
= 0.25f
;
132 GLfloat drFar
= 0.6f
;
133 GLfloat colors
[DIVX
* DIVY
][4];
134 #ifdef PIGLIT_USE_OPENGL
135 const GLdouble depthRange
[][2] =
137 const GLfloat depthRange
[][2] =
148 assert(ARRAY_SIZE(depthRange
) == DIVX
*DIVY
);
150 glViewport(0, 0, piglit_width
, piglit_height
); /* for glClear() */
152 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
153 glEnable(GL_DEPTH_TEST
);
154 #ifdef PIGLIT_USE_OPENGL
155 glDepthRangeIndexed(0, 0.4, drFar
);
157 glDepthRangeIndexedfOES(0, 0.4, drFar
);
159 glDepthFunc(GL_ALWAYS
);
161 /* initialize expected colors
162 * Frag shader uses FragCoord.z for the Red, DepthRange[0].far for
163 * Green color, and Blue is viewportIndex / 10.0
165 for (i
= 0; i
< DIVX
* DIVY
; i
++) {
166 GLfloat nearZ
= (GLfloat
) depthRange
[i
][0];
167 GLfloat farZ
= (GLfloat
) depthRange
[i
][1];
168 colors
[i
][0] = (((farZ
- nearZ
) * zVal
) + nearZ
+ farZ
) / 2.0f
;
169 colors
[i
][1] = drFar
;
170 colors
[i
][2] = (GLfloat
) (i
+ 1) / 10.0f
;
174 /* draw with varying viewports and depth ranges */
175 for (i
= 0; i
< DIVX
; i
++) {
176 for (j
= 0; j
< DIVY
; j
++) {
178 /* start at index 1 instead of zero, since index 0
179 * contains the Frag Shader gl_DepthRange value
181 idx
= j
+ 1 + i
*DIVY
;
182 glUniform3fv(colorLoc
, 1, &colors
[idx
-1][0]);
183 glUniform1i(vpIndexLoc
, idx
);
184 glViewportIndexedf(idx
, i
* w
, j
* h
, w
, h
);
185 #ifdef PIGLIT_USE_OPENGL
186 glDepthRangeIndexed(idx
, depthRange
[idx
-1][0],
187 depthRange
[idx
-1][1]);
189 glDepthRangeIndexedfOES(idx
, depthRange
[idx
-1][0],
190 depthRange
[idx
-1][1]);
192 piglit_draw_rect_z(zVal
, -1.0, -1.0, 2.0, 2.0);
193 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
194 p
= piglit_probe_pixel_rgba(i
* w
+ w
/2, j
* h
+ h
/2,
196 piglit_present_results();
198 printf("Wrong color for viewport i,j %d %d\n",
212 pass
= draw_multi_viewport();
213 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
214 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
218 piglit_init(int argc
, char **argv
)
222 #ifdef PIGLIT_USE_OPENGL
223 piglit_require_extension("GL_ARB_viewport_array");
225 piglit_require_extension("GL_OES_viewport_array");
228 program
= piglit_build_simple_program_multiple_shaders(
229 GL_VERTEX_SHADER
, vsSource
,
230 GL_GEOMETRY_SHADER
, gsSource
,
231 GL_FRAGMENT_SHADER
, fsSource
,
233 glUseProgram(program
);
234 colorLoc
= glGetUniformLocation(program
, "color");
235 vpIndexLoc
= glGetUniformLocation(program
, "idx");