<div dir="ltr">On 26 August 2013 11:44, Jacob Penner <span dir="ltr"><<a href="mailto:jkpenner91@gmail.com" target="_blank">jkpenner91@gmail.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">---<br>
 tests/spec/gl-3.2/layered-rendering/blit.c | 352 +++++++++++++++++++++++++++++<br>
 1 file changed, 352 insertions(+)<br>
 create mode 100644 tests/spec/gl-3.2/layered-rendering/blit.c<br>
<br>
diff --git a/tests/spec/gl-3.2/layered-rendering/blit.c b/tests/spec/gl-3.2/layered-rendering/blit.c<br>
new file mode 100644<br>
index 0000000..d897840<br>
--- /dev/null<br>
+++ b/tests/spec/gl-3.2/layered-rendering/blit.c<br>
@@ -0,0 +1,352 @@<br>
+/*<br>
+ * Copyright © 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>
+/** @file blit.c<br>
+ *<br>
+ * Section 4.3.2(Reading and Copying Pixels) From GL spec 3.2 core:<br>
+ *   If the read framebuffer is layered (see section 4.4.7), pixel values are<br>
+ * read from layer zero. If the draw framebuffer is layered, pixel values are<br>
+ * written to layer zero. If both read and draw framebuffers are layered, the<br>
+ * blit operation is still performed only on layer zero.<br>
+ *<br>
+ * Test Layout<br>
+ * *-------*-------*    test1:<br>
+ * |       |       |      Source tex is layered, Dest tex is layered<br>
+ * | test3 | test4 |    test2:<br>
+ * |       |       |      Source tex is layered, Dest tex is not layered<br>
+ * *-------*-------*    test3:<br>
+ * |       |       |      Source tex is not layered, Dest tex is layered<br>
+ * | test1 | test2 |    test4:<br>
+ * |       |       |      Source tex is not layered, Dest tex is not layered<br>
+ * *-------*-------*<br>
+ *<br>
+ *    src dest           Each Test<br>
+ *   *---*---*             Display source tex layers on left<br>
+ *   |   |   | layer 1     Blit source tex to dest tex<br>
+ *   *---*---*             Display resulting layers<br>
+ *   |   |   | layer 2<br>
+ *   *---*---*<br>
+ */<br>
+<br>
+#include "piglit-util-gl-common.h"<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_BEGIN<br>
+<br>
+       config.supports_gl_compat_version = 32;<br>
+       config.supports_gl_core_version = 32;<br>
+<br>
+       config.window_width  = 128;<br>
+       config.window_height = 128;<br>
+       config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_END<br>
+<br>
+/* Values Set in piglit init */<br>
+const int texWidth  = 32;<br>
+const int texHeight = 32;<br>
+const int texDepth  = 2;<br>
+const int texelsPerLayer = 32 * 32;<br>
+const int floatPerLayer  = 32 * 32 * 3;<br>
+<br>
+static const float srcColors[2][3] = {<br>
+       {1, 0, 0}, {0, 1, 0}<br>
+};<br>
+<br>
+static const float desColors[2][3] = {<br>
+       {0, 0, 1}, {0, 1, 1}<br>
+};<br></blockquote><div><br></div><div>"des" is a nonstandard abbreviation for "destination".  Pleaste use "dst".<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>
+/*<br>
+ * Blit the passed texture to the screen. If texture is layered,<br>
+ * loops through each layer and blit it to the screen.<br>
+ */<br>
+bool<br>
+display_texture(int x, int y, int w, int h,<br>
+                    GLuint tex, int layers)<br>
+{<br>
+       GLuint tempFBO;<br>
+       int i, dx1, dy1, dx2, dy2;<br>
+       GLenum fbStatus;<br>
+<br>
+       dx1 = x;<br>
+       dx2 = x+w;<br>
+<br>
+       /* Gen temp fbo to work with */<br>
+       glGenFramebuffers(1, &tempFBO);<br>
+<br>
+       if(layers == 1) {<br>
+               dy1 = y;<br>
+               dy2 = y+h;<br>
+<br>
+               glBindFramebuffer(GL_FRAMEBUFFER, tempFBO);<br>
+               glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,<br>
+                                      GL_TEXTURE_2D, tex, 0);<br>
+<br>
+               /* Blit layer to screen */<br>
+               glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);<br>
+               glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFBO);<br>
+               glBlitFramebuffer(0, 0, texWidth, texHeight,<br>
+                                 dx1, dy1, dx2, dy2,<br>
+                                 GL_COLOR_BUFFER_BIT, GL_NEAREST);<br>
+       }<br>
+       else {<br></blockquote><div><br></div><div>Style nit: we usually put this on a single line like this: "} else {"<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">

+               /* loop through each layer */<br>
+               for( i = 0; i < layers; i++) {<br>
+                       dy1 = y + i*(h/layers);<br>
+                       dy2 = y + (i+1)*(h/layers);<br>
+<br>
+                       /* Bind new layer to display */<br>
+                       glBindFramebuffer(GL_FRAMEBUFFER, tempFBO);<br>
+                       glFramebufferTextureLayer(GL_FRAMEBUFFER,<br>
+                                                 GL_COLOR_ATTACHMENT0,<br>
+                                                 tex, 0, i);<br>
+<br>
+                       fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);<br>
+                       if(fbStatus != GL_FRAMEBUFFER_COMPLETE) {<br>
+                               printf("Framebuffer Status: %s\n",<br>
+                                      piglit_get_gl_enum_name(fbStatus));<br>
+                               return false;<br>
+                       }<br>
+<br>
+                       /* Blit layer to screen */<br>
+                       glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);<br>
+                       glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFBO);<br>
+                       glBlitFramebuffer(0, 0, texWidth, texHeight,<br>
+                                         dx1, dy1, dx2, dy2,<br>
+                                         GL_COLOR_BUFFER_BIT, GL_NEAREST);<br>
+               }<br>
+       }<br>
+<br>
+       /* Cleanup temp fbo */<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);<br>
+       glDeleteFramebuffers(1, &tempFBO);<br>
+<br>
+       return piglit_check_gl_error(GL_NO_ERROR);<br>
+}<br>
+<br>
+void<br>
+gen_color_data(float *colorData, int texelsPerLayer, int layers, bool useSrcTex)<br>
+{<br>
+       int i, j;<br>
+       for(j = 0; j < layers; j++)<br>
+       for(i = 0; i < texelsPerLayer; i++) {<br></blockquote><div><br></div><div>The second for loop should be indented to clarify that it is nested inside the first.<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">

+               int offset = j * texelsPerLayer * 3 + i * 3;<br>
+               if(useSrcTex) {<br>
+                       colorData[offset + 0] = srcColors[j][0];<br>
+                       colorData[offset + 1] = srcColors[j][1];<br>
+                       colorData[offset + 2] = srcColors[j][2];<br>
+               }<br>
+               else {<br>
+                       colorData[offset + 0] = desColors[j][0];<br>
+                       colorData[offset + 1] = desColors[j][1];<br>
+                       colorData[offset + 2] = desColors[j][2];<br>
+               }<br>
+       }<br>
+} <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>
+void<br>
+create_bind_texture(GLenum textureType, GLuint *texture, bool useSrcTex)<br></blockquote><div><br></div><div>Unless there's a special reason to do so, it's better to output data from the function via a return value than via a pointer.  I'd change this to:<br>
<br></div><div>GLuint<br></div><div>create_bind_texture(GLenum textureType, bool useSrcTex) <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_check_gl_error(GL_NO_ERROR);<br>
+<br>
+       glGenTextures(1, texture);<br>
+       glBindTexture(textureType, *texture);<br>
+<br>
+       glTexParameteri(textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR);<br>
+       glTexParameteri(textureType, GL_TEXTURE_MAG_FILTER, GL_LINEAR);<br>
+       glTexParameteri(textureType, GL_TEXTURE_WRAP_S, GL_REPEAT);<br>
+       glTexParameteri(textureType, GL_TEXTURE_WRAP_T, GL_REPEAT);<br>
+       glTexParameteri(textureType, GL_TEXTURE_WRAP_R, GL_REPEAT);<br>
+<br>
+       if(textureType == GL_TEXTURE_2D) {<br>
+               float colorData[floatPerLayer];<br>
+               gen_color_data(colorData, texelsPerLayer, 1, useSrcTex);<br>
+               glTexImage2D(textureType, 0, GL_RGB, texWidth, texHeight, 0,<br>
+                            GL_RGB, GL_FLOAT, colorData);<br>
+       }<br>
+       else if(textureType == GL_TEXTURE_3D) {<br>
+               float colorData[texDepth * floatPerLayer];<br>
+               gen_color_data(colorData, texelsPerLayer, texDepth, useSrcTex);<br>
+               glTexImage3D(textureType, 0, GL_RGB, texWidth, texHeight,<br>
+                            texDepth, 0, GL_RGB, GL_FLOAT, colorData);<br>
+       }<br></blockquote><div><br></div><div>This should be a switch statement.<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>
+       if(!piglit_check_gl_error(GL_NO_ERROR)) {<br>
+               glDeleteTextures(1, texture);<br>
+               *texture = 0;<br>
+       }<br>
+}<br>
+<br>
+bool<br>
+testFramebufferBlitLayered(int x, int y, int w, int h,<br>
+                          bool sLayered, bool dLayered)<br></blockquote><div><br></div><div>It's not obvious from initial reading that sLayered and dLayered refer to src and dst.  I'd recommend renaming them to srcLayered and dstLayered.<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>
+       bool pass = true;<br>
+       GLuint srcFBO, desFBO;<br>
+       GLuint srcTex, desTex;<br>
+       GLenum fbStatus;<br>
+       int srclayers = (sLayered) ? (texDepth) : (1);<br>
+       int deslayers = (dLayered) ? (texDepth) : (1);<br>
+<br>
+       /* Set up source fbo */<br>
+       glGenFramebuffers(1, &srcFBO);<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);<br>
+<br>
+       piglit_check_gl_error(GL_NO_ERROR);<br>
+       if(sLayered) {<br>
+               create_bind_texture(GL_TEXTURE_3D, &srcTex, true);<br>
+               glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,<br>
+                                    srcTex, 0);<br>
+       }<br>
+       else {<br>
+               create_bind_texture(GL_TEXTURE_2D, &srcTex, true);<br>
+               glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,<br>
+                                    GL_TEXTURE_2D, srcTex, 0);<br>
+       }<br>
+<br>
+       /* Check source framebuffer status */<br>
+       fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);<br>
+       if(fbStatus != GL_FRAMEBUFFER_COMPLETE) {<br>
+               printf("FtestFramebufferBlitLayered srcFBO Status: %s\n",<br>
+                      piglit_get_gl_enum_name(fbStatus));<br></blockquote><div><br></div><div>I assume "Ftest..." is a typo?<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">

+               return false;<br>
+       }<br>
+<br>
+       /* Set up dest fbo */<br>
+       glGenFramebuffers(1, &desFBO);<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, desFBO);<br>
+<br>
+       if(dLayered) {<br>
+               create_bind_texture(GL_TEXTURE_3D, &desTex, false);<br>
+               glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,<br>
+                                    desTex, 0);<br>
+       }<br>
+       else {<br>
+               create_bind_texture(GL_TEXTURE_2D, &desTex, false);<br>
+               glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,<br>
+                                      GL_TEXTURE_2D, desTex, 0);<br>
+       }<br>
+<br>
+       /* Check dest framebuffer status */<br>
+       fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);<br>
+       if(fbStatus != GL_FRAMEBUFFER_COMPLETE) {<br>
+               printf("testFramebufferBlitLayered desFBO Status: %s\n",<br>
+                      piglit_get_gl_enum_name(fbStatus));<br>
+               return false;<br>
+       }<br>
+<br>
+       /* Check for if any errors have occured */<br>
+       if(!piglit_check_gl_error(GL_NO_ERROR)) {<br>
+               printf("Error setting up framebuffers for test.\n");<br>
+               return false;<br>
+       }<br>
+<br>
+       /* Blit from source to dest framebuffers */<br>
+       glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);<br>
+       glBindFramebuffer(GL_DRAW_FRAMEBUFFER, desFBO);<br>
+       glBlitFramebuffer(0, 0, texWidth, texHeight,<br>
+                         0, 0, texWidth, texHeight,<br>
+                         GL_COLOR_BUFFER_BIT, GL_LINEAR);<br>
+<br>
+       /* Display the results */<br>
+       display_texture(x, y, w/2, h, srcTex, srclayers);<br>
+       display_texture(x+w/2, y, w/2, h, desTex, deslayers);<br>
+<br>
+       /* Check for pass condition */<br>
+       if(sLayered) {<br>
+               pass = piglit_probe_rect_rgb(x, y, w/2, h/2, srcColors[0])<br>
+                      && pass;<br>
+               pass = piglit_probe_rect_rgb(x, y+h/2, w/2, h/2, srcColors[1])<br>
+                      && pass;<br>
+       }<br>
+       else {<br>
+               pass = piglit_probe_rect_rgb(x, y, w/2, h, srcColors[0])<br>
+                      && pass;<br>
+       }<br></blockquote><div><br></div><div>The above tests seem weird--why do we need to check the source texture?<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>
+       if(dLayered) {<br>
+               pass = piglit_probe_rect_rgb(x+w/2, y, w/2, h/2, srcColors[0])<br>
+                      && pass;<br>
+               pass = piglit_probe_rect_rgb(x+w/2, y+h/2, w/2, h/2,<br>
+                                            desColors[1])<br>
+                      && pass;<br>
+       }<br>
+       else {<br>
+               pass = piglit_probe_rect_rgb(x+w/2, y, w/2, h, srcColors[0])<br>
+                      && pass;<br>
+       }<br>
+<br>
+<br>
+       /* Clean up */<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);<br>
+       glDeleteFramebuffers(1, &srcFBO);<br>
+       glDeleteFramebuffers(1, &desFBO);<br>
+       glDeleteTextures(1, &srcTex);<br>
+       glDeleteTextures(1, &desTex);<br>
+<br>
+       /* Check for if any errors have occured */<br>
+       if(!piglit_check_gl_error(GL_NO_ERROR)) {<br>
+               printf("Error setting up framebuffers for test.\n");<br>
+               return false;<br>
+       }<br>
+<br>
+       return pass;<br>
+}<br>
+<br>
+void<br>
+piglit_init(int argc, char **argv)<br>
+{<br>
+<br>
+}<br>
+<br>
+enum piglit_result<br>
+piglit_display(void)<br>
+{<br>
+       bool pass = true;<br>
+       int hw = piglit_width/2;<br>
+       int hh = piglit_height/2;<br>
+<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);<br>
+       glClearColor(1,1,1,1);<br>
+       glClear(GL_COLOR_BUFFER_BIT);<br>
+<br>
+       /* Source is layered, Dest is layered */<br>
+       pass = testFramebufferBlitLayered( 0,  0, hw, hh, true,  true)  && pass;<br>
+<br>
+       /* Source is layered, Dest is not layered */<br>
+       pass = testFramebufferBlitLayered(hw,  0, hw, hh, true,  false) && pass;<br>
+<br>
+       /* Source not is layered, Dest is layered */<br>
+       pass = testFramebufferBlitLayered( 0, hh, hw, hh, false, true)  && pass;<br>
+<br>
+       /* Source not is layered, Dest is not layered */<br>
+       pass = testFramebufferBlitLayered(hw, hh, hw, hh, false, false) && pass;<br>
+<br>
+       /* Check for if any errors have occured */<br>
+       pass = piglit_check_gl_error(GL_NO_ERROR) && pass;<br>
+<br>
+       piglit_present_results();<br>
+<br>
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;<br>
+}<br></blockquote><div><br></div><div>With those minor fixes, this patch is:<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div></div></div></div>