Hi Plamena,

On 24.04.2017 23:04, Manolova, Plamena wrote:
[snip]
        +       static const char *fs_text =
        +               "#version 430\n"
        +               "#extension GL_ARB_fragment_shader_interlock:
        require\n"
        +               "layout(sample_interlock_ordered) in;\n"


    Since the shader writes to per-pixel data, it needs to be
    pixel_interlock_ordered. Otherwise, there might be a race between
    shader invocations that affect the same pixel but disjoint sets of
    samples (i.e. along the seams between triangles).


Actually this test cares only about the data written to image3D
img_output  which stores data on a per-sample basis (with the z
coordinate being the sample number), so we actually want
sample_interlock_ordered.

The last plane/slice of img_output contains the per-pixel average over all samples.

So I'm concerned about the following scenario of two invocations operating on different samples of the same pixel and interleaving as follows:

Invocation 1                       Invocation 2
------------                       ------------
Write current-sample data
Read and average all samples
                                   Write current-sample data
                                   Read and average all samples
                                   Write per-pixel data
Write per-pixel data

Invocation 1 will produce the final per-pixel data, but won't take into account the per-sample data written by Invocation 2. This particular issue is fixed by using any of the pixel_interlock_* modes.

Thanks,
Nicolai





        +               "layout(rgba32f, binding = 0) uniform image3D
        img_output;\n"
        +               "layout(location = 1) uniform int sample_rate;\n"
        +               "smooth in vec4 col_vary;\n"
        +               "out vec4 col_out;\n"
        +               "void main()\n"
        +               "{\n"
        +               "       vec4 result = vec4(0.0, 0.0, 0.0, 1.0);\n"
        +               "       ivec3 current_sample_coord =
        ivec3(gl_FragCoord.x, gl_FragCoord.y, gl_SampleID);\n"
        +               "       ivec3 result_coord =
        ivec3(gl_FragCoord.x, gl_FragCoord.y, sample_rate);\n"
        +               "       int i;\n"
        +               "       beginInvocationInterlockARB();\n"
        +               "       vec4 current_sample_color =
        imageLoad(img_output, current_sample_coord);\n"
        +               "       result.rgb += col_vary.a * col_vary.rgb
        + (1 - col_vary.a) * current_sample_color.rgb;\n"
        +               "       imageStore(img_output,
        current_sample_coord, result);\n"
        +               "\n"
        +               "       for (i = 0; i < sample_rate; i++) {\n"
        +               "               if (i != gl_SampleID) {\n"
        +               "                       ivec3 sample_coord =
        ivec3(gl_FragCoord.x, gl_FragCoord.y, i);\n"
        +               "                       vec4 sample_color =
        imageLoad(img_output, sample_coord);\n"
        +               "                       result.rgb +=
        sample_color.rgb;\n"
        +               "               }\n"
        +               "       }\n"
        +               "       result.rgb /= sample_rate;\n"
        +               "       imageStore(img_output, result_coord,
        result);\n"
        +               "       endInvocationInterlockARB();\n"
        +               "       col_out = result;\n"
        +               "}\n";
        +
        +       GLuint prog;
        +
        +       prog = piglit_build_simple_program(vs_text, fs_text);
        +       glUseProgram(prog);
        +
        +       glBindAttribLocation(prog, 0, "pos_in");
        +       glBindAttribLocation(prog, 1, "col_in");
        +
        +       glLinkProgram(prog);
        +
        +       if (!piglit_check_gl_error(GL_NO_ERROR)) {
        +               piglit_report_result(PIGLIT_FAIL);
        +       }
        +
        +       return prog;
        +}
        +
        +static GLuint
        +make_texture_buffer(void)
        +{
        +       GLuint tex;
        +
        +       glGenTextures(1, &tex);
        +       glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
        +       glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,
        +               GL_RGBA32F, piglit_width, piglit_height, false);
        +       glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
        +
        +       return tex;
        +}
        +
        +static GLuint
        +make_texture_blend(void)
        +{
        +       GLuint tex;
        +
        +       glGenTextures(1, &tex);
        +       glActiveTexture(GL_TEXTURE0);
        +       glBindTexture(GL_TEXTURE_3D, tex);
        +       glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,
        GL_CLAMP_TO_EDGE);
        +       glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,
        GL_CLAMP_TO_EDGE);
        +       glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,
        GL_LINEAR);
        +       glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,
        GL_LINEAR);
        +       glBindImageTexture(0, tex, 0, GL_TRUE, 0, GL_READ_WRITE,
        GL_RGBA32F);
        +
        +       return tex;
        +}
        +
        +static GLuint
        +make_vao(void)
        +{
        +       static const float pos_col[18][6] = {
        +               { -1.0, -1.0, 0.0, 1.0, 0.0, 0.25 },
        +               {  0.0, -1.0, 0.0, 1.0, 0.0, 0.25 },
        +               {  0.0,  1.0, 0.0, 1.0, 0.0, 0.25 },
        +               {  0.0,  1.0, 0.0, 1.0, 0.0, 0.25 },
        +               { -1.0,  1.0, 0.0, 1.0, 0.0, 0.25 },
        +               { -1.0, -1.0, 0.0, 1.0, 0.0, 0.25 },
        +               { -1.0, -1.0, 1.0, 0.0, 0.0, 0.25 },
        +               {  1.0, -1.0, 1.0, 0.0, 0.0, 0.25 },
        +               {  1.0,  1.0, 1.0, 0.0, 0.0, 0.25 },
        +               {  1.0,  1.0, 1.0, 0.0, 0.0, 0.25 },
        +               { -1.0,  1.0, 1.0, 0.0, 0.0, 0.25 },
        +               { -1.0, -1.0, 1.0, 0.0, 0.0, 0.25 },
        +               { -1.0, -1.0, 0.0, 0.0, 1.0, 0.25 },
        +               {  1.0, -1.0, 0.0, 0.0, 1.0, 0.25 },
        +               {  1.0,  1.0, 0.0, 0.0, 1.0, 0.25 },
        +               {  1.0,  1.0, 0.0, 0.0, 1.0, 0.25 },
        +               { -1.0,  1.0, 0.0, 0.0, 1.0, 0.25 },
        +               { -1.0, -1.0, 0.0, 0.0, 1.0, 0.25 }
        +       };
        +
        +       const int stride = sizeof(pos_col[0]);
        +       GLuint vbo, vao;
        +
        +       glGenVertexArrays(1, &vao);
        +       glBindVertexArray(vao);
        +
        +       glGenBuffers(1, &vbo);
        +       glBindBuffer(GL_ARRAY_BUFFER, vbo);
        +       glBufferData(GL_ARRAY_BUFFER, sizeof(pos_col), pos_col,
        GL_STATIC_DRAW);
        +
        +       glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride,
        (void *) 0);
        +       glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, stride,
        +               (void *)(sizeof(float) * 2));
        +
        +       glEnableVertexAttribArray(0);
        +       glEnableVertexAttribArray(1);
        +
        +       if (!piglit_check_gl_error(GL_NO_ERROR)) {
        +               piglit_report_result(PIGLIT_FAIL);
        +       }
        +
        +       return vao;
        +}
        +
        +void
        +piglit_init(int argc, char **argv)
        +{
        +
         piglit_require_extension("GL_ARB_fragment_shader_interlock");
        +
        +       glEnable(GL_MULTISAMPLE);
        +       glDisable(GL_CULL_FACE);
        +       glClearColor(0.0, 0.0, 0.0, 1.0);
        +
        +       prog = make_shader_program();
        +       vao = make_vao();
        +       tex_frame = make_texture_buffer();
        +       fbo = make_fbo();
        +       tex_blend = make_texture_blend();
        +}
        +
        +enum piglit_result
        +piglit_display(void)
        +{
        +       int samples[4] = { 2, 4, 8, 16 };
        +       bool pass = true;
        +       uint i, j, k, l;
        +       uint result1[4] = { 47, 35, 63, 255 };
        +       uint result2[4] = { 47, 0, 63, 255 };
        +
        +       glViewport(0, 0, piglit_width, piglit_height);
        +
        +       for (i = 0; i < 4; i++) {
        +               GLfloat *tex_data = calloc(piglit_width *
        piglit_height *
        +                       (samples[i] + 1) * 4, sizeof(GLfloat));
        +
        +               glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F,
        piglit_width, piglit_height,
        +                       samples[i] + 1, 0, GL_RGBA, GL_FLOAT,
        tex_data);


    Iterations should be skipped when the given number of samples is not
    supported.


        +
        +               glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
        +               glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_frame);
        +
         glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples[i],
        +                       GL_RGBA8, piglit_width, piglit_height,
        false);
        +               glUniform1i(1, samples[i]);
        +
        +               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
        +                       GL_STENCIL_BUFFER_BIT);
        +
        +               glUseProgram(prog);
        +               glDrawArrays(GL_TRIANGLES, 0, 18);
        +
        +               glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        +               glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
        +               glDrawBuffer(GL_BACK);
        +               glBlitFramebuffer(0, 0, piglit_width,
        piglit_height, 0, 0, piglit_width,
        +                       piglit_height, GL_COLOR_BUFFER_BIT,
        GL_NEAREST);


    Maybe add piglit_check_gl_error?

    Cheers,
    Nicolai



        +               piglit_present_results();
        +
        +               glGetTexImage(GL_TEXTURE_3D, 0, GL_RGBA,
        GL_FLOAT, tex_data);
        +               for (j = 0; j < samples[i] + 1; j++) {
        +                       for (k = 0; k < piglit_height; k++) {
        +                               for (l = 0; l < piglit_width; l++) {
        +                                       uint m = ((piglit_width
        * piglit_height * j) +
        +                                               (k *
        piglit_width) + l) * 4;
        +                                       uint r =
        fabs(tex_data[m]) * 255;
        +                                       uint g = fabs(tex_data[m
        + 1]) * 255;
        +                                       uint b = fabs(tex_data[m
        + 2]) * 255;
        +                                       uint a = fabs(tex_data[m
        + 3]) * 255;
        +
        +                                       if ((l < piglit_width /
        2) && (r != result1[0] ||
        +                                                 g !=
        result1[1] || b != result1[2] || a != result1[3])) {
        +                                               printf("observed
        %u %u %u     %u %u %u %u\n", j, k, l, r,
        +                                                       g, b, a);
        +                                               printf("expected
        %u %u %u     %u %u %u %u\n", j, k, l,
        +                                               result1[0],
        result1[1], result1[2], result1[3]);
        +                                               pass = false;
        +                                               break;
        +                                       }
        +
        +                                       if ((l > piglit_width /
        2) && (r != result2[0] ||
        +                                                 g !=
        result2[1] || b != result2[2] || a != result2[3])) {
        +                                               printf("observed
        %u %u %u     %u %u %u %u\n", j, k, l, r,
        +                                                       g, b, a);
        +                                               printf("expected
        %u %u %u     %u %u %u %u\n", j, k, l,
        +
         result1[0], result1[1], result1[2], result1[3]);
        +                                               pass = false;
        +                                               break;
        +                                       }
        +                               }
        +                               if (!pass)
        +                                       break;
        +                       }
        +                       if (!pass)
        +                               break;
        +               }
        +
        +               free(tex_data);
        +               pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
        +               if (!pass)
        +                       break;
        +       }
        +
        +       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
        +}



    --
    Lerne, wie die Welt wirklich ist,
    Aber vergiss niemals, wie sie sein sollte.




--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
_______________________________________________
Piglit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to