<div dir="ltr">On 19 April 2013 17:09, Jordan Justen <span dir="ltr"><<a href="mailto:jordan.l.justen@intel.com" target="_blank">jordan.l.justen@intel.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This tests the AMD_vertex_shader_layer extension using a<br>
2D array texture.<br>
<br>
Signed-off-by: Jordan Justen <<a href="mailto:jordan.l.justen@intel.com">jordan.l.justen@intel.com</a>><br>
---<br>
 tests/all.tests                                    |    4 +<br>
 tests/spec/CMakeLists.txt                          |    1 +<br>
 .../spec/amd_vertex_shader_layer/CMakeLists.gl.txt |   13 +<br>
 tests/spec/amd_vertex_shader_layer/CMakeLists.txt  |    1 +<br>
 .../layered-2d-texture-render.c                    |  331 ++++++++++++++++++++<br>
 5 files changed, 350 insertions(+)<br>
 create mode 100644 tests/spec/amd_vertex_shader_layer/CMakeLists.gl.txt<br>
 create mode 100644 tests/spec/amd_vertex_shader_layer/CMakeLists.txt<br>
 create mode 100644 tests/spec/amd_vertex_shader_layer/layered-2d-texture-render.c<br>
<br>
diff --git a/tests/all.tests b/tests/all.tests<br>
index 495de59..6c1298d 100644<br>
--- a/tests/all.tests<br>
+++ b/tests/all.tests<br>
@@ -2146,6 +2146,10 @@ amd_seamless_cubemap_per_texture = Group()<br>
 spec['AMD_seamless_cubemap_per_texture'] = amd_seamless_cubemap_per_texture<br>
 add_plain_test(amd_seamless_cubemap_per_texture, 'amd_seamless_cubemap_per_texture')<br>
<br>
+amd_vertex_shader_layer = Group()<br>
+spec['AMD_vertex_shader_layer'] = amd_vertex_shader_layer<br>
+add_plain_test(amd_vertex_shader_layer, 'amd_vertex_shader_layer-layered-2d-texture-render')<br>
+<br>
 ext_fog_coord = Group()<br>
 spec['EXT_fog_coord'] = ext_fog_coord<br>
 add_plain_test(ext_fog_coord, 'ext_fog_coord-modes')<br>
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt<br>
index a1492cc..f901a20 100644<br>
--- a/tests/spec/CMakeLists.txt<br>
+++ b/tests/spec/CMakeLists.txt<br>
@@ -16,6 +16,7 @@ add_subdirectory (arb_robustness)<br>
 add_subdirectory (arb_sampler_objects)<br>
 add_subdirectory (arb_seamless_cube_map)<br>
 add_subdirectory (amd_seamless_cubemap_per_texture)<br>
+add_subdirectory (amd_vertex_shader_layer)<br>
 add_subdirectory (arb_shader_texture_lod/execution)<br>
 add_subdirectory (arb_shader_objects)<br>
 add_subdirectory (arb_sync)<br>
diff --git a/tests/spec/amd_vertex_shader_layer/CMakeLists.gl.txt b/tests/spec/amd_vertex_shader_layer/CMakeLists.gl.txt<br>
new file mode 100644<br>
index 0000000..cdfb4cd<br>
--- /dev/null<br>
+++ b/tests/spec/amd_vertex_shader_layer/CMakeLists.gl.txt<br>
@@ -0,0 +1,13 @@<br>
+include_directories(<br>
+       ${GLEXT_INCLUDE_DIR}<br>
+       ${OPENGL_INCLUDE_PATH}<br>
+)<br>
+<br>
+link_libraries (<br>
+       piglitutil_${piglit_target_api}<br>
+       ${OPENGL_gl_LIBRARY}<br>
+       ${OPENGL_glu_LIBRARY}<br>
+)<br>
+<br>
+piglit_add_executable (amd_vertex_shader_layer-layered-2d-texture-render layered-2d-texture-render.c)<br>
+<br>
diff --git a/tests/spec/amd_vertex_shader_layer/CMakeLists.txt b/tests/spec/amd_vertex_shader_layer/CMakeLists.txt<br>
new file mode 100644<br>
index 0000000..144a306<br>
--- /dev/null<br>
+++ b/tests/spec/amd_vertex_shader_layer/CMakeLists.txt<br>
@@ -0,0 +1 @@<br>
+piglit_include_target_api()<br>
diff --git a/tests/spec/amd_vertex_shader_layer/layered-2d-texture-render.c b/tests/spec/amd_vertex_shader_layer/layered-2d-texture-render.c<br>
new file mode 100644<br>
index 0000000..1e6a6ff<br>
--- /dev/null<br>
+++ b/tests/spec/amd_vertex_shader_layer/layered-2d-texture-render.c<br>
@@ -0,0 +1,331 @@<br>
+/*<br>
+ * Copyright (c) 2013 Intel Corporation<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
+ * IN THE SOFTWARE.<br>
+ *<br>
+ */<br>
+<br>
+/*<br>
+ * Test 2D array texture rendering with gl_Layer (amd_vertex_shader_layer)<br>
+ */<br></blockquote><div><br></div><div>Would you mind adding a comment here that gives a basic outline of what the test does, and how to interpret its output?  I'm having trouble following it from reading the code, and since I don't have a device that supports this extension I can't just run the test in the debugger to find out.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+#include "piglit-util-gl-common.h"<br>
+<br>
+#define PAD            5<br>
+#define SIZE           64<br>
+#define LAYERS         5<br>
+#define LOD            7<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_BEGIN<br>
+<br>
+       config.supports_gl_core_version = 31;<br>
+       config.supports_gl_compat_version = 30;<br></blockquote><div><br></div><div>Shouldn't this been config.supports_gl_compat_version = 31?  I think GL 3.1 is required because of your use of gl_InstanceID.<br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+       config.window_width = (((SIZE+PAD)*LAYERS)+PAD);<br>
+       config.window_height = (((SIZE+PAD)*2)+PAD);<br>
+       config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB;<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_END<br>
+<br>
+static GLuint rectangle_vertices_bo;<br>
+<br>
+/* VS and FS to fill the 2D array texture */<br>
+static const char *fill_tex_vs =<br>
+ "#version 140\n" <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ "#extension GL_AMD_vertex_shader_layer: enable\n"<br>
+ "uniform int color_bias;\n"<br>
+ "in vec2 vertex;\n"<br>
+ "out vec3 color;\n"<br>
+ "vec3 get_color(int num)\n"<br>
+ "{\n"<br>
+ " vec3 result = vec3(0.0);\n"<br>
+ " if ((num & 4) != 0) result.r = 1.0;"<br>
+ " if ((num & 2) != 0) result.g = 1.0;"<br>
+ " if ((num & 1) != 0) result.b = 1.0;"<br>
+ " return result;\n"<br>
+ "}\n"<br>
+ "void main()\n"<br>
+ "{\n"<br>
+ " gl_Position = vec4(vertex, vec2(0.0, 1.0));\n"<br>
+ " gl_Layer = gl_InstanceID;\n"<br>
+ " color = get_color(color_bias + gl_InstanceID);\n"<br>
+ "}\n";<br>
+<br>
+static const char *fill_tex_fs =<br>
+ "#version 140\n"<br>
+ "in vec3 color;\n"<br>
+ "void main()\n"<br>
+ "{\n"<br>
+ " gl_FragColor = vec4(color, 1.0);\n"<br>
+ "}\n";<br>
+<br>
+/* VS and FS to use and test the 2D array texture */<br>
+static const char *use_tex_vs =<br>
+ "#version 130\n"<br>
+ "in vec2 vertex;\n"<br>
+ "out vec2 coord;\n"<br>
+ "void main()\n"<br>
+ "{\n"<br>
+ " gl_Position = vec4(vertex, vec2(0.0, 1.0));\n"<br>
+ " coord = (vertex * 0.5) + 0.5;\n"<br>
+ "}\n";<br>
+<br>
+static const char *use_tex_fs =<br>
+ "#version 130\n"<br>
+ "uniform sampler2DArray tex; \n"<br>
+ "uniform int layer;\n"<br>
+ "uniform int lod;\n"<br>
+ "in vec2 coord;\n"<br>
+ "void main()\n"<br>
+ "{\n"<br>
+ " gl_FragColor = textureLod(tex, vec3(coord, float(layer)), lod);\n"<br>
+ "}\n";<br>
+<br>
+static GLuint fill_tex_program;<br>
+static GLuint use_tex_program;<br>
+<br>
+static int get_x(int layer)<br>
+{<br>
+       return ((SIZE + PAD) * layer) + PAD;<br>
+}<br>
+<br>
+static int get_y(int layer, int lod)<br>
+{<br>
+       int size = SIZE >> lod;<br>
+       return PAD + (((1 << lod) - 1) * 2 * size);<br>
+}<br>
+<br>
+static GLfloat* get_color(int num) <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+{<br>
+       int color_index;<br>
+<br>
+       static GLfloat colors[][3] = {<br>
+               {0.0, 0.0, 0.0},<br>
+               {0.0, 0.0, 1.0},<br>
+               {0.0, 1.0, 0.0},<br>
+               {0.0, 1.0, 1.0},<br>
+               {1.0, 0.0, 0.0},<br>
+               {1.0, 0.0, 1.0},<br>
+               {1.0, 1.0, 0.0},<br>
+               {1.0, 1.0, 1.0},<br>
+       };<br>
+<br>
+       color_index = num % ARRAY_SIZE(colors);<br>
+       return colors[color_index];<br>
+}<br>
+<br>
+static bool<br>
+render_tex_layers(GLuint tex)<br>
+{<br>
+       int lod;<br>
+       GLint color_bias_loc;<br>
+       GLenum status;<br>
+       int color_index = 0;<br>
+       int size;<br>
+<br>
+       glUseProgram(fill_tex_program);<br>
+<br>
+       color_bias_loc = glGetUniformLocation(fill_tex_program, "color_bias");<br>
+<br>
+       glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);<br>
+       glBindAttribLocation(fill_tex_program, 0, "vertex"); <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       glVertexAttribPointer(0, 2, GL_FLOAT, 0, 0, 0);<br>
+       glEnableVertexAttribArray(0);<br></blockquote><div><br><div>glBindAttribLocation has no effect if you've already linked the 
program.  Probably you're just getting lucky and it's working because 
the linker assigned "vertex" to attrib 0 anyhow.<br><br></div>I'd recommend changing this to something like:<br><br></div><div>vertex_attr = glGetAttribLocation(fill_tex_program, "vertex");<br></div>
<div>glVertexAttribPointer(vertex_attr, 2, GL_FLOAT, 0, 0, 0);<br></div><div>glEnableVertexAttribArray(vertex_attr);<br><br></div><div>(don't forget to update the call to glDisableVertexAttribArray() below)<br></div><div>
 </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       for (lod = 0; lod < LOD; lod++) {<br>
+               size = SIZE >> lod;<br>
+               glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, lod);<br>
+               status = glCheckFramebufferStatus(GL_FRAMEBUFFER);<br>
+               if (status != GL_FRAMEBUFFER_COMPLETE) {<br>
+                       fprintf(stderr, "fbo incomplete (status = %s)\n",<br>
+                               piglit_get_gl_enum_name(status));<br>
+                       return false;<br>
+               }<br>
+               glDrawBuffer(GL_COLOR_ATTACHMENT0);<br>
+               glViewport(0, 0, size, size);<br>
+               glUniform1i(color_bias_loc, color_index);<br>
+               glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, LAYERS);<br>
+               color_index += LAYERS;<br>
+               glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, lod);<br></blockquote><div><br></div><div>Is it necessary for this last line to be in the loop?  It seems like it's only going to have an effect the last time the loop runs.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       }<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);<br>
+       glDisableVertexAttribArray(0);<br>
+<br>
+       return true;<br>
+}<br>
+<br>
+static GLuint<br>
+build_texture(void)<br>
+{<br>
+       GLuint tex;<br>
+       int lod;<br>
+       int size;<br>
+<br>
+       glGenTextures(1, &tex);<br>
+       glBindTexture(GL_TEXTURE_2D_ARRAY, tex);<br>
+       for (lod = 0; lod < LOD; lod++) {<br>
+               size = SIZE >> lod;<br>
+               glTexImage3D(GL_TEXTURE_2D_ARRAY, lod, GL_RGBA,<br>
+                            size, size, LAYERS, 0, GL_RGBA, GL_FLOAT, NULL);<br>
+       }<br>
+<br>
+       render_tex_layers(tex);<br>
+<br>
+       return tex;<br>
+}<br>
+<br>
+static void<br>
+draw_box(GLuint tex, int layer, int lod)<br>
+{<br>
+       GLint layer_loc, lod_loc;<br>
+       int x = get_x(layer);<br>
+       int y = get_y(layer, lod);<br>
+       int size = SIZE >> lod;<br>
+<br>
+       layer_loc = glGetUniformLocation(use_tex_program, "layer");<br>
+       lod_loc = glGetUniformLocation(use_tex_program, "lod");<br>
+<br>
+       glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);<br>
+<br>
+       glBindAttribLocation(use_tex_program, 0, "vertex"); <br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       glVertexAttribPointer(0, 2, GL_FLOAT, 0, 0, 0);<br>
+       glEnableVertexAttribArray(0);<br></blockquote><div><br></div><div>Similar problem with glBindAttribLocation() here.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

+<br>
+       glBindTexture(GL_TEXTURE_2D_ARRAY, tex);<br>
+<br>
+       glViewport(x, y, size, size);<br>
+       glUniform1i(layer_loc, layer);<br>
+       glUniform1i(lod_loc, lod);<br>
+       glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);<br>
+<br>
+       glDisableVertexAttribArray(0);<br>
+}<br>
+<br>
+static GLboolean<br>
+test_results(int layer, int lod)<br>
+{<br>
+       int x = get_x(layer);<br>
+       int y = get_y(layer, lod);<br>
+       GLfloat *color3f = get_color((lod * LAYERS) + layer);<br></blockquote><div><br></div><div>I stumbled on this line because I couldn't remember if get_color() computed the expected color or the actual rendered color.  How about if we rename "color3f" to "expected_color3f"?<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       GLboolean pass;<br>
+       int size = SIZE >> lod;<br>
+<br>
+       pass = piglit_probe_rect_rgb(x, y, size, size, color3f);<br>
+<br>
+       if (!pass) {<br>
+               printf("2D array failed at size %d, layer %d\n",<br>
+                      size, layer);<br>
+       }<br>
+<br>
+       return pass;<br>
+}<br>
+<br>
+static GLboolean<br>
+test_texture(GLuint tex)<br>
+{<br>
+       int layer, lod;<br>
+       GLint tex_loc;<br>
+       GLboolean pass = GL_TRUE;<br>
+       glUseProgram(use_tex_program);<br>
+       glActiveTexture(GL_TEXTURE0);<br>
+       tex_loc = glGetUniformLocation(use_tex_program, "tex");<br>
+       glUniform1i(tex_loc, 0);<br>
+<br>
+       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,<br>
+                       GL_NEAREST_MIPMAP_NEAREST);<br>
+       glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,<br>
+                       GL_NEAREST);<br>
+<br>
+       for (lod = 0; lod < LOD; lod++) {<br>
+               for (layer = 0; layer < LAYERS; layer++) {<br>
+                       draw_box(tex, layer, lod);<br>
+                       pass = test_results(layer, lod) && pass;<br>
+               }<br>
+       }<br></blockquote><div><br></div><div>You might want to consider separating this into two loops, one to do all the draw_box() calls and one to do all the test_results() calls.  That will make it easier to run this test in the simulator, because all of the drawing will go into a single batch buffer.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+       glUseProgram(0);<br>
+       return pass;<br>
+}<br>
+<br>
+enum piglit_result<br>
+piglit_display(void)<br>
+{<br>
+       GLboolean pass;<br>
+       GLuint vao, fbo;<br>
+       GLuint tex;<br>
+       static GLfloat verts[4][2] = {<br>
+               { 1.0, -1.0},<br>
+               {-1.0, -1.0},<br>
+               { 1.0,  1.0},<br>
+               {-1.0,  1.0},<br>
+       };<br>
+<br>
+       /* Clear background to gray */<br>
+       glClearColor(0.5, 0.5, 0.5, 1.0);<br>
+       glClear(GL_COLOR_BUFFER_BIT);<br>
+<br>
+       glGenFramebuffers(1, &fbo);<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);<br>
+       glGenVertexArrays(1, &vao);<br>
+       glBindVertexArray(vao);<br>
+       glGenBuffers(1, &rectangle_vertices_bo);<br>
+       glBindBuffer(GL_ARRAY_BUFFER, rectangle_vertices_bo);<br>
+       glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);<br>
+<br>
+       tex = build_texture();<br>
+       pass = test_texture(tex);<br>
+       glDeleteTextures(1, &tex);<br>
+<br>
+       piglit_present_results();<br>
+<br>
+       glDeleteBuffers(1, &rectangle_vertices_bo);<br>
+       glDeleteFramebuffers(1, &fbo);<br>
+       glDeleteVertexArrays(1, &vao);<br>
+<br>
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;<br>
+}<br>
+<br>
+void<br>
+piglit_init(int argc, char **argv)<br>
+{<br>
+       GLuint vs, fs;<br>
+<br>
+       /* For glFramebufferTexture we need either GL 3.2 or<br>
+        * GL_ARB_geometry_shader4.<br>
+        */<br>
+       if (piglit_get_gl_version() < 32) {<br>
+               piglit_require_extension("GL_ARB_geometry_shader4");<br>
+       }<br></blockquote><div><br></div><div>Wow, I didn't realize that AMD_vertex_shader_layer didn't provide glFramebufferTexture().  This extension is of startlingly limited use without geometry shaders!<br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+       piglit_require_extension("GL_AMD_vertex_shader_layer");<br>
+<br>
+       vs = piglit_compile_shader_text(GL_VERTEX_SHADER, fill_tex_vs);<br>
+       piglit_check_gl_error(GL_NO_ERROR);<br>
+       fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fill_tex_fs);<br>
+       piglit_check_gl_error(GL_NO_ERROR);<br>
+       fill_tex_program = piglit_link_simple_program(vs, fs);<br>
+       piglit_check_gl_error(GL_NO_ERROR);<br>
+<br>
+       vs = piglit_compile_shader_text(GL_VERTEX_SHADER, use_tex_vs);<br>
+       piglit_check_gl_error(GL_NO_ERROR);<br>
+       fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, use_tex_fs);<br>
+       piglit_check_gl_error(GL_NO_ERROR);<br>
+       use_tex_program = piglit_link_simple_program(vs, fs);<br>
+       piglit_check_gl_error(GL_NO_ERROR);<br>
+}<br>
<span class=""><font color="#888888">--<br>
1.7.10.4<br>
<br></font></span></blockquote><div><br></div><div>Of all my comments, the only one I think is critical is the glBindAttribLocation() issue.  With that fixed, this test is:<br><br></div><div>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br>
</div></div></div></div>