[Piglit] [PATCH 4/4] tests: port tests for arb_shader_viewport_layer_array
Dylan Baker
dylan at pnwbakers.com
Fri Sep 9 23:14:07 UTC 2016
This adds a couple of original compiler tests, and ports the tests for
amd_vertex_shader_layer and amd_vertex_shader_viewport_index to the ARB
extension.
These tests touch the VS, but not the tes eval.
Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
tests/all.py | 8 +
tests/spec/CMakeLists.txt | 1 +
.../CMakeLists.gl.txt | 24 ++
.../arb_shader_viewport_layer_array/CMakeLists.txt | 1 +
.../compiler/write-viewportindex.frag | 15 +
.../compiler/write-viewportindex.tesc | 15 +
.../compiler/write-viewportindex.tese | 17 ++
.../compiler/write-viewportindex.vert | 17 ++
.../layered-2d-texture-render.c | 339 +++++++++++++++++++++
.../layered-depth-texture-render.c | 239 +++++++++++++++
.../spec/arb_shader_viewport_layer_array/render.c | 152 +++++++++
11 files changed, 828 insertions(+)
create mode 100644 tests/spec/arb_shader_viewport_layer_array/CMakeLists.gl.txt
create mode 100644 tests/spec/arb_shader_viewport_layer_array/CMakeLists.txt
create mode 100644 tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.frag
create mode 100644 tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tesc
create mode 100644 tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tese
create mode 100644 tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.vert
create mode 100644 tests/spec/arb_shader_viewport_layer_array/layered-2d-texture-render.c
create mode 100644 tests/spec/arb_shader_viewport_layer_array/layered-depth-texture-render.c
create mode 100644 tests/spec/arb_shader_viewport_layer_array/render.c
diff --git a/tests/all.py b/tests/all.py
index 3961656..edec9d0 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -4749,6 +4749,14 @@ with profile.group_manager(
g(['arb_shader_draw_parameters-drawid-indirect', 'baseinstance'], 'drawid-indirect-baseinstance')
g(['arb_shader_draw_parameters-drawid-indirect', 'vertexid'], 'drawid-indirect-vertexid')
+with profile.group_manager(
+ PiglitGLTest,
+ grouptools.join('spec', 'ARB_shader_viewport_layer_array')) as g:
+ for test in ['layered-depth-texture-render',
+ 'layered-depth-texture-render',
+ 'render-vs']:
+ g(['arb_shader_viewport_layer_array-{}'.format(test)], test)
+
# Group ARB_indirect_parameters
with profile.group_manager(
PiglitGLTest,
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index 9b0f73e..d56c501 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -54,6 +54,7 @@ add_subdirectory (arb_shader_atomic_counters)
add_subdirectory (arb_shader_objects)
add_subdirectory (arb_shader_image_load_store)
add_subdirectory (arb_shader_image_size)
+add_subdirectory (arb_shader_viewport_layer_array)
add_subdirectory (arb_shading_language_420pack/execution)
add_subdirectory (arb_stencil_texturing)
add_subdirectory (arb_sync)
diff --git a/tests/spec/arb_shader_viewport_layer_array/CMakeLists.gl.txt b/tests/spec/arb_shader_viewport_layer_array/CMakeLists.gl.txt
new file mode 100644
index 0000000..ebbca99
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/CMakeLists.gl.txt
@@ -0,0 +1,24 @@
+include_directories(
+ ${GLEXT_INCLUDE_DIR}
+ ${OPENGL_INCLUDE_PATH}
+)
+
+link_libraries (
+ piglitutil_${piglit_target_api}
+ ${OPENGL_gl_LIBRARY}
+)
+
+piglit_add_executable(
+ arb_shader_viewport_layer_array-layered-2d-texture-render
+ layered-2d-texture-render.c
+)
+piglit_add_executable(
+ arb_shader_viewport_layer_array-layered-depth-texture-render
+ layered-depth-texture-render.c
+)
+piglit_add_executable(
+ arb_shader_viewport_layer_array-render-vs
+ render.c
+)
+
+# vim: ft=cmake
diff --git a/tests/spec/arb_shader_viewport_layer_array/CMakeLists.txt b/tests/spec/arb_shader_viewport_layer_array/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.frag b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.frag
new file mode 100644
index 0000000..5acf23c
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.frag
@@ -0,0 +1,15 @@
+/* gl_ViewportIndex should be undefined in a Fragment Shader.
+ *
+ * [config]
+ * expect_result: fail
+ * glsl_version: 4.10
+ * require_extensions: GL_ARB_shader_viewport_layer_array
+ * [end config]
+ */
+
+#version 410
+
+void main()
+{
+ gl_ViewportIndex = 1;
+}
diff --git a/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tesc b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tesc
new file mode 100644
index 0000000..e1d308d
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tesc
@@ -0,0 +1,15 @@
+/* gl_ViewportIndex should be undefined in a Teselation Control Shader.
+ *
+ * [config]
+ * expect_result: fail
+ * glsl_version: 4.10
+ * require_extensions: GL_ARB_shader_viewport_layer_array
+ * [end config]
+ */
+
+#version 410
+
+void main()
+{
+ gl_ViewportIndex = 1;
+}
diff --git a/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tese b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tese
new file mode 100644
index 0000000..5087a30
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.tese
@@ -0,0 +1,17 @@
+/* Tests that the OpenGL special variable gl_ViewportIndex can be set in a
+ * Teselation Evaulation Shader.
+ *
+ * [config]
+ * expect_result: pass
+ * glsl_version: 4.10
+ * require_extensions: GL_ARB_shader_viewport_layer_array
+ * [end config]
+ */
+
+#version 410
+#extension GL_ARB_shader_viewport_layer_array : require
+
+void main()
+{
+ gl_ViewportIndex = 1;
+}
diff --git a/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.vert b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.vert
new file mode 100644
index 0000000..b98580a
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/compiler/write-viewportindex.vert
@@ -0,0 +1,17 @@
+/* Tests that the OpenGL special variable gl_ViewportIndex can be set in a
+ * vertex shader
+ *
+ * [config]
+ * expect_result: pass
+ * glsl_version: 4.10
+ * require_extensions: GL_ARB_shader_viewport_layer_array
+ * [end config]
+ */
+
+#version 410
+#extension GL_ARB_shader_viewport_layer_array : require
+
+void main()
+{
+ gl_ViewportIndex = 1;
+}
diff --git a/tests/spec/arb_shader_viewport_layer_array/layered-2d-texture-render.c b/tests/spec/arb_shader_viewport_layer_array/layered-2d-texture-render.c
new file mode 100644
index 0000000..e5ad56c
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/layered-2d-texture-render.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2013, 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Test 2D array texture rendering with gl_Layer
+ * (ARB_shader_viewport_layer_array)
+ *
+ * This test uses layered rendering (gl_Layer) within the vertex shader.
+ * Support for gl_Layer in VS is added by the ARB_shader_viewport_layer_array
+ * extension.
+ *
+ * This test first draws to a color array texture which is attached to
+ * a framebuffer. The texture has 5 layers and 7 LODs.
+ *
+ * Once colors have been rendered to each array slice & LOD, the test
+ * then uses the texture to draw on the system framebuffer and verifies
+ * that the expected colors appear.
+ */
+
+#include "piglit-util-gl.h"
+
+#define PAD 5
+#define SIZE 64
+#define LAYERS 5
+#define LOD 7
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_core_version = 41;
+ config.supports_gl_compat_version = 41;
+
+ config.window_width = (((SIZE+PAD)*LAYERS)+PAD);
+ config.window_height = (((SIZE+PAD)*2)+PAD);
+ config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static GLuint rectangle_vertices_bo;
+
+/* VS and FS to fill the 2D array texture */
+static const char *fill_tex_vs =
+ "#version 410\n"
+ "#extension GL_ARB_shader_viewport_layer_array: enable\n"
+ "uniform int color_bias;\n"
+ "in vec2 vertex;\n"
+ "out vec3 color;\n"
+ "vec3 get_color(int num)\n"
+ "{\n"
+ " vec3 result = vec3(0.0);\n"
+ " if ((num & 4) != 0) result.r = 1.0;"
+ " if ((num & 2) != 0) result.g = 1.0;"
+ " if ((num & 1) != 0) result.b = 1.0;"
+ " return result;\n"
+ "}\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(vertex, vec2(0.0, 1.0));\n"
+ " gl_Layer = gl_InstanceID;\n"
+ " color = get_color(color_bias + gl_InstanceID);\n"
+ "}\n";
+
+static const char *fill_tex_fs =
+ "#version 410\n"
+ "in vec3 color;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(color, 1.0);\n"
+ "}\n";
+
+/* VS and FS to use and test the 2D array texture */
+static const char *use_tex_vs =
+ "#version 410\n"
+ "in vec2 vertex;\n"
+ "out vec2 coord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(vertex, vec2(0.0, 1.0));\n"
+ " coord = (vertex * 0.5) + 0.5;\n"
+ "}\n";
+
+static const char *use_tex_fs =
+ "#version 410\n"
+ "uniform sampler2DArray tex; \n"
+ "uniform int layer;\n"
+ "uniform int lod;\n"
+ "in vec2 coord;\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = textureLod(tex, vec3(coord, float(layer)), lod);\n"
+ "}\n";
+
+static GLuint fill_tex_program;
+static GLuint use_tex_program;
+
+static int get_x(int layer)
+{
+ return ((SIZE + PAD) * layer) + PAD;
+}
+
+static int get_y(int layer, int lod)
+{
+ int size = SIZE >> lod;
+ return PAD + (((1 << lod) - 1) * 2 * size);
+}
+
+static const GLfloat *get_color(int num)
+{
+ int color_index;
+
+ static const GLfloat colors[][3] = {
+ {0.0, 0.0, 0.0},
+ {0.0, 0.0, 1.0},
+ {0.0, 1.0, 0.0},
+ {0.0, 1.0, 1.0},
+ {1.0, 0.0, 0.0},
+ {1.0, 0.0, 1.0},
+ {1.0, 1.0, 0.0},
+ {1.0, 1.0, 1.0},
+ };
+
+ color_index = num % ARRAY_SIZE(colors);
+ return colors[color_index];
+}
+
+static bool
+render_tex_layers(GLuint tex)
+{
+ int lod;
+ GLint color_bias_loc;
+ GLint vertex_loc;
+ GLenum status;
+ int color_index = 0;
+ int size;
+
+ glUseProgram(fill_tex_program);
+
+ color_bias_loc = glGetUniformLocation(fill_tex_program, "color_bias");
+
+ glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);
+ vertex_loc = glGetAttribLocation(fill_tex_program, "vertex");
+ glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, 0, 0, 0);
+ glEnableVertexAttribArray(vertex_loc);
+ for (lod = 0; lod < LOD; lod++) {
+ size = SIZE >> lod;
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, lod);
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ fprintf(stderr, "fbo incomplete (status = %s)\n",
+ piglit_get_gl_enum_name(status));
+ return false;
+ }
+ glDrawBuffer(GL_COLOR_ATTACHMENT0);
+ glViewport(0, 0, size, size);
+ glUniform1i(color_bias_loc, color_index);
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, LAYERS);
+ color_index += LAYERS;
+ }
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
+ glDisableVertexAttribArray(vertex_loc);
+
+ return true;
+}
+
+static GLuint
+build_texture(void)
+{
+ GLuint tex;
+ int lod;
+ int size;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+ for (lod = 0; lod < LOD; lod++) {
+ size = SIZE >> lod;
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, lod, GL_RGBA,
+ size, size, LAYERS, 0, GL_RGBA, GL_FLOAT, NULL);
+ }
+
+ render_tex_layers(tex);
+
+ return tex;
+}
+
+static void
+draw_box(GLuint tex, int layer, int lod)
+{
+ GLint layer_loc, lod_loc, vertex_loc;
+ int x = get_x(layer);
+ int y = get_y(layer, lod);
+ int size = SIZE >> lod;
+
+ layer_loc = glGetUniformLocation(use_tex_program, "layer");
+ lod_loc = glGetUniformLocation(use_tex_program, "lod");
+
+ glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);
+
+ vertex_loc = glGetAttribLocation(use_tex_program, "vertex");
+ glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, 0, 0, 0);
+ glEnableVertexAttribArray(vertex_loc);
+
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+
+ glViewport(x, y, size, size);
+ glUniform1i(layer_loc, layer);
+ glUniform1i(lod_loc, lod);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glDisableVertexAttribArray(vertex_loc);
+}
+
+static GLboolean
+test_results(int layer, int lod)
+{
+ int x = get_x(layer);
+ int y = get_y(layer, lod);
+ const GLfloat *expected_color3f = get_color((lod * LAYERS) + layer);
+ GLboolean pass;
+ int size = SIZE >> lod;
+
+ pass = piglit_probe_rect_rgb(x, y, size, size, expected_color3f);
+
+ if (!pass) {
+ printf("2D array failed at size %d, layer %d\n",
+ size, layer);
+ }
+
+ return pass;
+}
+
+static GLboolean
+test_texture(GLuint tex)
+{
+ int layer, lod;
+ GLint tex_loc;
+ GLboolean pass = GL_TRUE;
+ glUseProgram(use_tex_program);
+ glActiveTexture(GL_TEXTURE0);
+ tex_loc = glGetUniformLocation(use_tex_program, "tex");
+ glUniform1i(tex_loc, 0);
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST);
+
+ for (lod = 0; lod < LOD; lod++) {
+ for (layer = 0; layer < LAYERS; layer++) {
+ draw_box(tex, layer, lod);
+ }
+ }
+
+ for (lod = 0; lod < LOD; lod++) {
+ for (layer = 0; layer < LAYERS; layer++) {
+ pass = test_results(layer, lod) && pass;
+ }
+ }
+
+ glUseProgram(0);
+ return pass;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ GLboolean pass;
+ GLuint vao, fbo;
+ GLuint tex;
+ static const GLfloat verts[4][2] = {
+ { 1.0, -1.0},
+ {-1.0, -1.0},
+ { 1.0, 1.0},
+ {-1.0, 1.0},
+ };
+
+ /* Clear background to gray */
+ glClearColor(0.5, 0.5, 0.5, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ glGenBuffers(1, &rectangle_vertices_bo);
+ glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
+
+ tex = build_texture();
+ pass = test_texture(tex);
+ glDeleteTextures(1, &tex);
+
+ piglit_present_results();
+
+ glDeleteBuffers(1, &rectangle_vertices_bo);
+ glDeleteFramebuffers(1, &fbo);
+ glDeleteVertexArrays(1, &vao);
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ /* For glFramebufferTexture we need either GL 3.2 or
+ * GL_ARB_geometry_shader4.
+ */
+ if (piglit_get_gl_version() < 32) {
+ piglit_require_extension("GL_ARB_geometry_shader4");
+ }
+
+ piglit_require_extension("GL_AMD_vertex_shader_layer");
+
+ fill_tex_program = piglit_build_simple_program(fill_tex_vs, fill_tex_fs);
+ piglit_check_gl_error(GL_NO_ERROR);
+
+ use_tex_program = piglit_build_simple_program(use_tex_vs, use_tex_fs);
+ piglit_check_gl_error(GL_NO_ERROR);
+}
diff --git a/tests/spec/arb_shader_viewport_layer_array/layered-depth-texture-render.c b/tests/spec/arb_shader_viewport_layer_array/layered-depth-texture-render.c
new file mode 100644
index 0000000..fbac6f1
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/layered-depth-texture-render.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2013, 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Test 2D depth array texture rendering with gl_Layer
+ * (ARB_shader_viewport_layer_array)
+ *
+ * This test uses layered rendering (gl_Layer) within the vertex shader.
+ * Support for gl_Layer in VS is added by the ARB_shader_viewport_layer_array
+ * extension.
+ *
+ * This test first renders to a depth array texture which is attached to
+ * a framebuffer. The texture has 5 layers and 7 LODs.
+ *
+ * Once depths have been rendered to each array slice & LOD, the test
+ * then verifies the depth value in each array slice & LOD.
+ */
+
+#include "piglit-util-gl.h"
+
+#define PAD 5
+#define SIZE 64
+#define LAYERS 5
+#define LOD 7
+#define DRAW_COUNT LAYERS * LOD
+#define STRINGIFY(x) #x
+#define EXP_STRINGIFY(x) STRINGIFY(x)
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_core_version = 41;
+ config.supports_gl_compat_version = 41;
+
+ config.window_width = (((SIZE+PAD)*LAYERS)+PAD);
+ config.window_height = (((SIZE+PAD)*2)+PAD);
+ config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static GLuint rectangle_vertices_bo;
+
+/* VS and FS to fill the 2D array texture */
+static const char *fill_tex_vs =
+ "#version 410\n"
+ "#extension GL_ARB_shader_viewport_layer_array: enable\n"
+ "uniform int drawing_level;\n"
+ "in vec2 vertex;\n"
+ "out vec3 color;\n"
+ "int num_layers = " EXP_STRINGIFY(LAYERS) ";\n"
+ "int draw_count = " EXP_STRINGIFY(DRAW_COUNT) ";\n"
+ "float get_z()\n"
+ "{\n"
+ " return float((drawing_level * num_layers) + gl_InstanceID) / draw_count;\n"
+ "}\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(vertex, get_z(), 1.0);\n"
+ " gl_Layer = gl_InstanceID;\n"
+ "}\n";
+
+static GLuint fill_tex_program;
+
+static bool
+render_tex_layers(GLuint tex)
+{
+ int lod;
+ GLint drawing_level_loc, vertex_loc;
+ GLenum status;
+ int color_index = 0;
+ int size;
+
+ glUseProgram(fill_tex_program);
+
+ drawing_level_loc = glGetUniformLocation(fill_tex_program, "drawing_level");
+
+ glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);
+ vertex_loc = glGetAttribLocation(fill_tex_program, "vertex");
+ glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, 0, 0, 0);
+ glEnableVertexAttribArray(vertex_loc);
+ for (lod = 0; lod < LOD; lod++) {
+ size = SIZE >> lod;
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, tex, lod);
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ fprintf(stderr, "fbo incomplete (status = %s)\n",
+ piglit_get_gl_enum_name(status));
+ return false;
+ }
+
+ /* Clear background to gray */
+ glClearDepth(1.0);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glViewport(0, 0, size, size);
+ glUniform1i(drawing_level_loc, lod);
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, LAYERS);
+ color_index += LAYERS;
+ }
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 0, 0);
+ glDisableVertexAttribArray(vertex_loc);
+
+ return true;
+}
+
+static GLuint
+build_texture(void)
+{
+ GLuint tex;
+ int lod;
+ int size;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+ for (lod = 0; lod < LOD; lod++) {
+ size = SIZE >> lod;
+ glTexImage3D(GL_TEXTURE_2D_ARRAY, lod, GL_DEPTH_COMPONENT,
+ size, size, LAYERS, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
+ }
+
+ render_tex_layers(tex);
+
+ return tex;
+}
+
+/* Attach the texture layer/lod to the read framebuffer
+ */
+static void
+set_up_read_framebuffer(GLuint tex, int level, int layer)
+{
+ GLenum status;
+
+ glFramebufferTextureLayer(GL_READ_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ tex, level, layer);
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status == GL_FRAMEBUFFER_UNSUPPORTED && level == 0) {
+ printf("This buffer combination is unsupported\n");
+ piglit_report_result(PIGLIT_SKIP);
+ } else if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("FBO incomplete at miplevel %d\n", level);
+ piglit_report_result(PIGLIT_FAIL);
+ }
+}
+
+static GLboolean
+test_texture(GLuint tex)
+{
+ int layer, lod;
+ GLboolean retval = GL_TRUE;
+ float expected;
+ float draw_count = LAYERS * LOD;
+ int dim = SIZE;
+
+ for (lod = 0; lod < LOD; lod++) {
+ for (layer = 0; layer < LAYERS; layer++) {
+ GLboolean pass;
+ set_up_read_framebuffer(tex, lod, layer);
+ expected = ((float)(lod * LAYERS) + layer) / draw_count;
+ expected = (expected / 2.0) + 0.5;
+ pass = piglit_probe_rect_depth(0, 0, dim, dim, expected);
+ retval = retval && pass;
+ }
+ dim >>= 1;
+ }
+
+ return retval;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ GLboolean pass;
+ GLuint vao, fbo;
+ GLuint tex;
+ static const GLfloat verts[4][2] = {
+ { 1.0, -1.0},
+ {-1.0, -1.0},
+ { 1.0, 1.0},
+ {-1.0, 1.0},
+ };
+
+ glEnable(GL_DEPTH_TEST);
+
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ glGenBuffers(1, &rectangle_vertices_bo);
+ glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
+
+ tex = build_texture();
+ pass = test_texture(tex);
+ glDeleteTextures(1, &tex);
+
+ glDeleteBuffers(1, &rectangle_vertices_bo);
+ glDeleteFramebuffers(1, &fbo);
+ glDeleteVertexArrays(1, &vao);
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ /* For glFramebufferTexture we need either GL 3.2 or
+ * GL_ARB_geometry_shader4.
+ */
+ if (piglit_get_gl_version() < 32) {
+ piglit_require_extension("GL_ARB_geometry_shader4");
+ }
+
+ piglit_require_extension("GL_AMD_vertex_shader_layer");
+
+ fill_tex_program = piglit_build_simple_program(fill_tex_vs, NULL);
+ piglit_check_gl_error(GL_NO_ERROR);
+}
diff --git a/tests/spec/arb_shader_viewport_layer_array/render.c b/tests/spec/arb_shader_viewport_layer_array/render.c
new file mode 100644
index 0000000..9b48498
--- /dev/null
+++ b/tests/spec/arb_shader_viewport_layer_array/render.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2013 LunarG, Inc.
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Author: Jon Ashburn <jon at lunarg.com>
+ * Adapted for vertex shader: Ilia Mirkin <imirkin at alum.mit.edu>
+ */
+
+/**
+ * Tests rendering into a single framebuffer surface with multiple viewports
+ * via a vertex shader. Confirm that each area of the surface delineated by
+ * a viewport renders the correct color.
+ * From the extension registry for ARB_viewport_array:
+ * "This extension enhances OpenGL by providing a mechanism to expose
+ * multiple viewports. Each viewport is specified as a rectangle. The
+ * destination viewport may be selected per-primitive by the geometry
+ * shader. This allows the Geometry Shader to produce different versions
+ * of primitives destined for separate viewport rectangles on the same
+ * surface.
+ * This extension allows specifying the viewport from the vertex shader.
+ */
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_core_version = 31;
+
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+const char *vsSource = {
+ "#version 410\n"
+ "#extension GL_ARB_shader_viewport_layer_array : require\n"
+ "in vec4 piglit_vertex;\n"
+ "uniform int idx;\n"
+ "void main() {\n"
+ " gl_ViewportIndex = idx;\n"
+ " gl_Position = piglit_vertex;\n"
+ "}\n"
+};
+
+const char *fsSource = {
+ "#version 140\n"
+ "uniform vec3 color;\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(color.xyz, 1.0);\n"
+ "}\n"
+};
+
+static GLint colorLoc;
+static GLint vpIndexLoc;
+
+/**
+ * Draws a single quad into multiple viewport each with a different
+ * color. Reads back the expected color to test if the drawing was correct.
+ * @param changeVPloc; if true then the vertex shader viewport location
+ * is changed with each loop, otherwise viewport location is fixed.
+ */
+static bool
+draw_multi_viewport(const bool changeVPLoc)
+{
+ bool pass = true;
+ int i, j;
+ const int divX=2, divY=4;
+ GLfloat w = (GLfloat) piglit_width / (GLfloat) divX;
+ GLfloat h = (GLfloat) piglit_height / (GLfloat) divY;
+ const GLfloat colors[][3] = {{0.0, 0.0, 1.0},
+ {0.0, 1.0, 0.0},
+ {1.0, 0.0, 0.0},
+ {1.0, 1.0, 0.0},
+ {0.0, 1.0, 1.0},
+ {1.0, 0.0, 1.0},
+ {1.0, 1.0, 1.0},
+ {0.0, 0.0, 0.5},
+ {0.0, 0.0, 0.0}};
+
+ assert(ARRAY_SIZE(colors) == divX*divY + 1);
+
+ glViewport(0, 0, piglit_width, piglit_height); /* for glClear() */
+ glClear(GL_COLOR_BUFFER_BIT);
+ glUniform1i(vpIndexLoc, divX * divY);
+ glViewportIndexedf(divX * divY, -10.0, -30.0, piglit_width, 20.0);
+ for (i = 0; i < divX; i++) {
+ for (j = 0; j < divY; j++) {
+ int p;
+ GLfloat *expected;
+ glUniform3fv(colorLoc, 1, &colors[j + i*divY][0]);
+ if (changeVPLoc) {
+ glUniform1i(vpIndexLoc, j + i*divY);
+ expected = (GLfloat *) &colors[j + i*divY][0];
+ } else {
+ expected = (GLfloat *) &colors[divX * divY][0];
+ }
+ glViewportIndexedf(j + i*divY, i * w, j * h, w, h);
+ piglit_draw_rect(-1, -1, 2, 2);
+ pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+ p = piglit_probe_pixel_rgb(i * w + w/2, j * h + h/2,
+ expected);
+ piglit_present_results();
+ if (!p) {
+ printf("Wrong color for viewport i,j %d %d changeVP=%d\n",
+ i, j, changeVPLoc);
+ pass = false;
+ }
+ }
+ }
+ return pass;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ bool pass = true;
+
+ pass = draw_multi_viewport(true);
+ pass = draw_multi_viewport(false) && pass;
+ pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ GLuint program;
+
+ piglit_require_extension("GL_ARB_shader_viewport_layer_array");
+
+ program = piglit_build_simple_program(vsSource, fsSource);
+ glUseProgram(program);
+ colorLoc = glGetUniformLocation(program, "color");
+ vpIndexLoc = glGetUniformLocation(program, "idx");
+}
--
2.9.3
More information about the Piglit
mailing list