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.ba...@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 <j...@lunarg.com> + * Adapted for vertex shader: Ilia Mirkin <imir...@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
_______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit