<div dir="ltr">On 6 April 2013 16:19, Christoph Bumiller <span dir="ltr"><<a href="mailto:christoph.bumiller@speed.at" target="_blank">christoph.bumiller@speed.at</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Christoph Bumiller <<a href="mailto:e0425955@student.tuwien.ac.at" target="_blank">e0425955@student.tuwien.ac.at</a>><br>

<br>
v2: Removed dependency on TextureBarrierNV and ARB_tfb_2, added<br>
comments.<br>
---<br>
 .../spec/arb_texture_multisample/CMakeLists.gl.txt |    1 +<br>
 .../spec/arb_texture_multisample/sample-position.c |  236 ++++++++++++++++++++<br>
 2 files changed, 237 insertions(+), 0 deletions(-)<br>
 create mode 100644 tests/spec/arb_texture_multisample/sample-position.c<br>
<br>
diff --git a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt<br>
index 1339d62..642418f 100644<br>
--- a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt<br>
+++ b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt<br>
@@ -18,5 +18,6 @@ piglit_add_executable (arb_texture_multisample-sample-mask sample-mask.c)<br>
 piglit_add_executable (arb_texture_multisample-sample-mask-value sample-mask-value.c)<br>
 piglit_add_executable (arb_texture_multisample-sample-mask-execution sample-mask-execution.c)<br>
 piglit_add_executable (arb_texture_multisample-negative-max-samples negative-max-samples.c)<br>
+piglit_add_executable (arb_texture_multisample-sample-position sample-position.c)<br>
<br>
 # vim: ft=cmake:<br>
diff --git a/tests/spec/arb_texture_multisample/sample-position.c b/tests/spec/arb_texture_multisample/sample-position.c<br>
new file mode 100644<br>
index 0000000..fed9f27<br>
--- /dev/null<br>
+++ b/tests/spec/arb_texture_multisample/sample-position.c<br>
@@ -0,0 +1,236 @@<br>
+/*<br>
+ * Copyright © The Piglit Project 2013<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<br>
+ * DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ * Authors: Christoph Bumiller<br>
+ */<br>
+#include "piglit-util-gl-common.h"<br>
+<br>
+/* File: sample-position.c<br>
+ *<br>
+ * Tests whether the sample positions reported by the driver via<br>
+ * glGetMultisamplefv correspond to the actually positions used when rendering.<br>
+ *<br>
+ * This test draws creates a 1x1 multisample texture and renders a triangle<br>
+ * covering all of the render target starting at a specific x/y offset from<br>
+ * the left/bottom to test the x/y coordinate.<br>
+ * After each such draw, the value of all the samples is recorded into a buffer<br>
+ * via transform feedback, and the offset is increased slightly.<br>
+ * In the end, the buffer is mapped to check if the correct samples were<br>
+ * covered.<br>
+ */<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_BEGIN<br>
+<br>
+    config.supports_gl_compat_version = 30;<br>
+    config.window_visual = PIGLIT_GL_VISUAL_RGB;<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_END<br>
+<br>
+#define NUM_STEPS   32<br>
+#define MAX_SAMPLES 32<br>
+<br>
+static GLuint tfb;<br>
+static GLuint buf;<br>
+static GLuint tex;<br>
+static GLuint fbo;<br>
+static GLuint prog;<br>
+<br>
+static int samples = 0;<br>
+<br>
+enum piglit_result<br>
+piglit_display(void)<br>
+{<br>
+       float mspos[MAX_SAMPLES][2];<br>
+       float *res;<br>
+       const float inc = 2.0f / (float)NUM_STEPS;<br>
+       GLint u;<br>
+       unsigned int i, s;<br>
+       enum piglit_result result = PIGLIT_PASS;<br>
+<br>
+       glUseProgram(prog);<br>
+<br>
+       u = glGetUniformLocation(prog, "pos");<br>
+<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);<br>
+       for (i = 0; i < samples; ++i)<br>
+               glGetMultisamplefv(GL_SAMPLE_POSITION, i, &mspos[i][0]);<br>
+<br>
+       glActiveTexture(GL_TEXTURE0);<br>
+       glUniform1i(glGetUniformLocation(prog, "tex"), 0);<br>
+<br>
+       glClearColor(0.0f, 0.0f, 0.0f, 0.0f);<br>
+<br>
+       /* render triangles from x = -1 + i*increment to test coverage at x */<br>
+       for (i = 0; i < NUM_STEPS; ++i) {<br>
+               /* clear and draw to MS texture */<br>
+               glBindFramebuffer(GL_FRAMEBUFFER, fbo);<br>
+               glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);<br>
+               glClear(GL_COLOR_BUFFER_BIT);<br>
+               /* set bottom left vertex (others generated via gl_VertexID) */<br>
+               glUniform2f(u, -1.0f + inc * (float)i, -1.0f);<br>
+               glDrawArrays(GL_TRIANGLES, 0, 3);<br></blockquote><div><br></div><div>The use of gl_VertexID to generate the other vertices seems unnecessarily obscure.  How about just making pos a vertex attribute and doing something like this?<br>
<br></div><div>GLfloat x = -1.0 + inc * i;<br></div><div>GLfloat y = -1.0;<br></div><div>GLfloat pos[3][2] = { { x, y }, { x + 2, y }, { x, y + 2 } };<br></div><div>glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);<br>
glEnableVertexAttribArray(0);<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+               /* bind MS texture as texture to record samples */<br>
+               glBindFramebuffer(GL_FRAMEBUFFER, 0);<br>
+               glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);<br>
+               glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf,<br>
+                                 MAX_SAMPLES * sizeof(float) * i,<br>
+                                 MAX_SAMPLES * sizeof(float));<br>
+               glBeginTransformFeedback(GL_POINTS);<br>
+               glDrawArrays(GL_POINTS, 0, 1);<br>
+               glEndTransformFeedback();<br>
+       }<br>
+       /* render triangles from y = -1 + i*increment to test coverage at y */<br>
+       for (i = 0; i < NUM_STEPS; ++i) {<br>
+               /* clear and draw to MS texture */<br>
+               glBindFramebuffer(GL_FRAMEBUFFER, fbo);<br>
+               glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);<br>
+               glClear(GL_COLOR_BUFFER_BIT);<br>
+               /* set bottom left vertex (others generated via gl_VertexID) */<br>
+               glUniform2f(u, -1.0f, -1.0f + inc * (float)i);<br>
+               glDrawArrays(GL_TRIANGLES, 0, 3);<br>
+<br>
+               /* bind MS texture as texture to record samples */<br>
+               glBindFramebuffer(GL_FRAMEBUFFER, 0);<br>
+               glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);<br>
+               glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf,<br>
+                                 MAX_SAMPLES * sizeof(float) * (i + NUM_STEPS),<br>
+                                 MAX_SAMPLES * sizeof(float));<br>
+               glBeginTransformFeedback(GL_POINTS);<br>
+               glDrawArrays(GL_POINTS, 0, 1);<br>
+               glEndTransformFeedback();<br>
+       }<br></blockquote><div><br></div><div>The contents of this loop are almost identical to the contents of the loop above.  Can we put the loop contents in a function so that we don't have to duplicate code?<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+       res = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);<br>
+<br>
+       for (i = 0; i < NUM_STEPS; ++i) {<br>
+               float p = (float)i / (float)NUM_STEPS; /* x/y offset */<br>
+<br>
+               int base_x = i * MAX_SAMPLES;<br>
+               int base_y = i * MAX_SAMPLES + NUM_STEPS * MAX_SAMPLES;<br>
+#if 0<br>
+               fprintf(stderr, "x >= %f:", p);<br>
+               for (s = 0; s < samples; ++s)<br>
+                       if (res[base_x + s] == 1.0f)<br>
+                               fprintf(stderr, " %u", s);<br>
+               fprintf(stderr, "\n");<br>
+               fprintf(stderr, "y >= %f:", p);<br>
+               for (s = 0; s < samples; ++s)<br>
+                       if (res[base_y + s] == 1.0f)<br>
+                               fprintf(stderr, " %u", s);<br>
+               fprintf(stderr, "\n");<br>
+#endif<br>
+               /* See which samples are covered at this x/y offset and if it<br>
+                * matches what we expect from GL_SAMPLE_POSITION.<br>
+                */<br>
+               for (s = 0; s < samples; ++s) {<br>
+                       if ((p >  mspos[s][0] && res[base_x + s] == 1.0f) ||<br>
+                           (p <= mspos[s][0] && res[base_x + s] != 1.0f)) {<br>
+                               result = PIGLIT_FAIL;<br>
+                               fprintf(stderr, "sample %i x position (%f, %f) "<br>
+                                       "incorrect !\n",s,<br>
+                                       mspos[s][0], mspos[s][1]);<br>
+                       }<br>
+                       if ((p >  mspos[s][1] && res[base_y + s] == 1.0f) ||<br>
+                           (p <= mspos[s][1] && res[base_y + s] != 1.0f)) {<br>
+                               result = PIGLIT_FAIL;<br>
+                               fprintf(stderr, "sample %i y position (%f, %f) "<br>
+                                       "incorrect !\n",s,<br>
+                                       mspos[s][0], mspos[s][1]);<br>
+                       }<br>
+               }<br></blockquote><div><br></div><div>Can we modify the test so that it also prints out what sample position was observed?  Without this information it's really difficult to investigate failures.<br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+       }<br>
+       glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);<br>
+<br>
+       return result;<br>
+}<br>
+<br>
+static const char *vsSource = "#version 130 \n"<br>
+       "#extension GL_ARB_texture_multisample : require\n"<br>
+       "uniform sampler2DMS tex; \n"<br>
+       "uniform vec2 pos; \n"<br>
+       "out float sample[32]; \n" /* 32 == MAX_SAMPLES */<br>
+       "void main() { \n"<br>
+       "   int v = int(gl_VertexID); \n" /* if I can't have immediate mode ... */<br>
+       "   int i; \n"<br>
+       "   gl_Position.xy = pos + 8.0 * vec2(float(v & 1), float(v & 2)); \n"<br>
+       "   gl_Position.zw = vec2(0.0, 1.0); \n"<br>
+       "   for (i = 0; i < 32; ++i) \n"<br>
+       "      sample[i] = texelFetch(tex, ivec2(0, 0), i).g; \n"<br>
+       "} \n";<br></blockquote><div><br></div><div>I found this program difficult to follow because it is used twice to do two completely independent things:<br><br></div><div>- once to generate triangles (which are written to the multisample texture).<br>
</div><div>- once to read data back from the multisample texture.<br><br></div><div>Can we split it into two separate programs? <br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
+static const char *fsSource = "#version 130 \n"<br>
+       "void main() { \n"<br>
+       "   gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); \n"<br>
+       "} \n";<br>
+<br>
+void<br>
+piglit_init(int argc, char **argv)<br>
+{<br>
+       static const char *varyings[] = { "sample" };<br>
+       GLuint vs, fs;<br>
+       GLuint max_samples;<br>
+<br>
+       piglit_require_extension("GL_ARB_texture_multisample");<br>
+       piglit_require_extension("GL_EXT_transform_feedback");<br>
+<br>
+       if (argc < 2) {<br>
+               fprintf(stderr, "texelFetch <sample_count>\n");<br></blockquote><div><br></div><div>I don't think you mean "texelFetch" here.  I usually do something like:<br><br></div><div>

fprintf(stderr, "%s <sample_count>\n", argv[0]);<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+               exit(0);<br></blockquote><div><br></div><div>I would be a little more comfortable with exit(1), so that just in case someone tries to automate this test they'll be more likely to notice if there's an error.<br>

<br>Alternatively, you could just use "piglit_report_result(PIGLIT_FAIL);"<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+       }<br>
+       samples = strtoul(argv[1], NULL, 0);<br>
+<br>
+       glGetIntegerv(GL_MAX_SAMPLES, (GLint *)&max_samples);<br>
+       if (samples > max_samples)<br>
+               piglit_report_result(PIGLIT_SKIP);<br>
+<br>
+       vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vsSource);<br>
+       fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fsSource);<br>
+       prog = piglit_link_simple_program(vs, fs);<br>
+<br>
+       glGenTransformFeedbacks(1, &tfb);<br>
+       glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb);<br></blockquote><div><br></div><div>The two lines above require ARB_transform_feedback2, but it looks like you aren't using any transform_feedback2 functionality.  Can we drop these two lines (and the "tfb" global)?<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+       glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS);<br>
+       glLinkProgram(prog);<br>
+       glGenBuffers(1, &buf);<br>
+       glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);<br>
+       glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,<br>
+                    MAX_SAMPLES * sizeof(float) * NUM_STEPS * 2, NULL,<br>
+                    GL_STREAM_DRAW);<br>
+<br>
+       glGenTextures(1, &tex);<br>
+       glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);<br>
+       glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples,<br>
+                               GL_RGBA8,<br>
+                               1, 1, GL_TRUE);<br>
+       glGenFramebuffers(1, &fbo);<br>
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);<br>
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,<br>
+                              GL_TEXTURE_2D_MULTISAMPLE, tex, 0);<br>
+<br>
+       assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);<br>
+<br>
+       glViewport(0, 0, 1, 1);<br>
+<br>
+       if (!piglit_check_gl_error(GL_NO_ERROR))<br>
+               piglit_report_result(PIGLIT_FAIL);<br>
+}<br>
<span><font color="#888888">--<br>
1.7.3.4<br>
<br>
_______________________________________________<br>
Piglit mailing list<br>
<a href="mailto:Piglit@lists.freedesktop.org" target="_blank">Piglit@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/piglit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/piglit</a><br>
</font></span></blockquote></div><br></div></div>