summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/spec/arb_post_depth_coverage/multisampling.c349
1 files changed, 133 insertions, 216 deletions
diff --git a/tests/spec/arb_post_depth_coverage/multisampling.c b/tests/spec/arb_post_depth_coverage/multisampling.c
index f90208d74..af23b3e93 100644
--- a/tests/spec/arb_post_depth_coverage/multisampling.c
+++ b/tests/spec/arb_post_depth_coverage/multisampling.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 Intel Corporation.
+ * Copyright (c) 2017 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,9 +24,15 @@
#include "piglit-util-gl.h"
/*
- * A test to check whether the right values are written to gl_SampleMaskIn
- * when ARB_post_depth_coverage and multisampling are enabled. Tests at
- * 2, 4, 8, 16 sample rates.
+ * A test to check that when ARB_post_depth_coverage is enabled, the values in
+ * gl_SampleMaskIn accurately reflect the results of the depth test being run
+ * before the respective fragment shader invocation. As well, we also check to
+ * make sure that when the extension is disabled, the values in
+ * gl_SampleMaskIn do not reflect the results of the depth test in each
+ * respective fragment shader invocation.
+ * For good measure, we test this behavior at sample rates of 2, 4, 8, and 16
+ * (if the GPU does not support a high enough sample rate to test all of these
+ * rates, we skip the ones we can't test).
*/
PIGLIT_GL_TEST_CONFIG_BEGIN
@@ -38,24 +44,21 @@ PIGLIT_GL_TEST_CONFIG_BEGIN
PIGLIT_GL_VISUAL_DOUBLE;
PIGLIT_GL_TEST_CONFIG_END
-static GLuint prog1, prog2, vao, ssbo, tex_color, tex_depth, fbo;
-static GLint *sample_mask;
+GLint prog1, prog2, prog3;
static const char *vs_text =
"#version 430\n"
- "in vec4 pos_in;\n"
- "void main()\n"
- "{\n"
- " gl_Position = pos_in;\n"
+ "in vec4 piglit_vertex;\n"
+ "void main() {\n"
+ " gl_Position = piglit_vertex;\n"
"}\n";
static const char *fs_text1 =
"#version 430\n"
"out vec4 color;\n"
- "void main()\n"
- "{\n"
- " gl_FragDepth = 0.5f;\n"
- " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ "void main() {\n"
+ " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ " gl_SampleMask[0] = 1;\n"
"}\n";
static const char *fs_text2 =
@@ -67,149 +70,111 @@ static const char *fs_text2 =
"layout(std430, binding = 0) buffer MaskOutput {\n"
" int data[];\n"
"} mask_output;\n"
- "layout(location = 1) uniform int width;\n"
- "layout(location = 2) uniform int samples;\n"
- "void main()\n"
- "{\n"
- " int index = int(gl_FragCoord.y) * width + int(gl_FragCoord.x);\n"
- " atomicAdd(mask_output.data[index], bitCount(gl_SampleMaskIn[0]));\n"
- " color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+ "void main() {\n"
+ " int index = int(gl_FragCoord.y) * 160 + int(gl_FragCoord.x);\n"
+ " atomicOr(mask_output.data[index], gl_SampleMaskIn[0]);\n"
+ " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
"}\n";
-static GLuint
-make_shader_program1(void)
-{
- GLuint prog;
-
- prog = piglit_build_simple_program(vs_text, fs_text1);
- glUseProgram(prog);
-
- glBindAttribLocation(prog, 0, "pos_in");
-
- glLinkProgram(prog);
-
- if (!piglit_check_gl_error(GL_NO_ERROR)) {
- piglit_report_result(PIGLIT_FAIL);
- }
-
- return prog;
-}
+static const char *fs_text3 =
+ "#version 430\n"
+ "out vec4 color;\n"
+ "layout(early_fragment_tests) in;\n"
+ "layout(std430, binding = 0) buffer MaskOutput {\n"
+ " int data[];\n"
+ "} mask_output;\n"
+ "void main() {\n"
+ " int index = int(gl_FragCoord.y) * 160 + int(gl_FragCoord.x);\n"
+ " atomicOr(mask_output.data[index], gl_SampleMaskIn[0]);\n"
+ " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ "}\n";
-static GLuint
-make_shader_program2(void)
+static inline bool
+draw_and_check_sample_mask(GLint prog, int sample_count, int ssbo_value)
{
- GLuint prog;
-
- prog = piglit_build_simple_program(vs_text, fs_text2);
- glUseProgram(prog);
+ const size_t sample_mask_size = piglit_width * piglit_height;
+ GLint *sample_mask = calloc(sizeof(GLint), sample_mask_size);
+ GLuint fbo, tex_color, tex_depth, ssbo;
+ int i;
+ bool ret = true;
- glBindAttribLocation(prog, 0, "pos_in");
-
- glLinkProgram(prog);
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- if (!piglit_check_gl_error(GL_NO_ERROR)) {
- piglit_report_result(PIGLIT_FAIL);
- }
+ /* Create new textures */
+ glGenTextures(1, &tex_color);
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_color);
+ glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sample_count,
+ GL_RGBA32F, piglit_width, piglit_height,
+ false);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D_MULTISAMPLE, tex_color, 0);
- return prog;
-}
+ glGenTextures(1, &tex_depth);
+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_depth);
+ glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sample_count,
+ GL_DEPTH_COMPONENT24,
+ piglit_width, piglit_height, false);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_TEXTURE_2D_MULTISAMPLE, tex_depth, 0);
-static GLuint
-make_ssbo(void)
-{
- GLuint ssbo;
+ /* Setup the ssbo */
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
+ glBufferData(GL_SHADER_STORAGE_BUFFER,
+ sample_mask_size * sizeof(GLint),
+ sample_mask, GL_DYNAMIC_DRAW);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!piglit_check_gl_error(GL_NO_ERROR)) {
- piglit_report_result(PIGLIT_FAIL);
+ ret = false;
+ goto finish;
}
- return ssbo;
-}
+ /* Draw a rectangle that covers the entire depth texture, but only in
+ * the first sample.
+ */
+ glUseProgram(prog1);
+ piglit_draw_rect_z(0.25, -1.0, -1.0, 4.0, 4.0);
-static GLuint
-make_fbo(void)
-{
- GLuint fbo;
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo );
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_color);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D_MULTISAMPLE, tex_color, 0);
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_depth);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_TEXTURE_2D_MULTISAMPLE, tex_depth, 0);
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
-
- return fbo;
-}
-
-static GLuint
-make_texture_color(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, 0);
-
- return tex;
-}
-
-static GLuint
-make_texture_depth(void)
-{
- GLuint tex;
-
- glGenTextures(1, &tex);
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
- glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,
- GL_DEPTH24_STENCIL8, piglit_width, piglit_height, false);
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
-
- return tex;
-}
-
-static GLuint
-make_vao(void)
-{
- static const float pos_tc[12][2] = {
- { -1.0, -1.0 },
- { 0.0, -1.0 },
- { 0.0, 1.0 },
- { 0.0, 1.0 },
- { -1.0, 1.0 },
- { -1.0, -1.0 },
- { -1.0, -1.0 },
- { 1.0, -1.0 },
- { 1.0, 1.0 },
- { 1.0, 1.0 },
- { -1.0, 1.0 },
- { -1.0, -1.0 }
- };
- const int stride = sizeof(pos_tc[0]);
- GLuint vbo, vao;
-
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
-
- glGenBuffers(1, &vbo);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(pos_tc), pos_tc, GL_STATIC_DRAW);
- piglit_check_gl_error(GL_NO_ERROR);
+ /* Now draw another rectangle that inhabits all of the samples, and
+ * see which ones are covered in gl_SampleMaskIn when the fragment
+ * shader is executed.
+ */
+ glUseProgram(prog);
+ piglit_draw_rect_z(0.5, -1.0, -1.0, 4.0, 4.0);
+
+ glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0,
+ sample_mask_size * sizeof(GLint), sample_mask);
+ for (i = 0; i < sample_mask_size; i++) {
+ if (sample_mask[i] != ssbo_value) {
+ fprintf(stderr,
+ "(%d, %d) expected 0x%x in ssbo, got 0x%x\n",
+ i % 160, i / 160, ssbo_value, sample_mask[i]);
+ ret = false;
+ break;
+ }
+ }
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride, (void *) 0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
+ glBlitFramebuffer(0, 0, piglit_width, piglit_height,
+ 0, 0, piglit_width, piglit_height,
+ GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
+ GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
- glEnableVertexAttribArray(0);
+ piglit_present_results();
- if (!piglit_check_gl_error(GL_NO_ERROR)) {
- piglit_report_result(PIGLIT_FAIL);
- }
+finish:
+ glDeleteTextures(2, (GLuint[2]) { tex_color, tex_depth });
+ glDeleteBuffers(1, &ssbo);
+ glDeleteFramebuffers(1, &fbo);
+ free(sample_mask);
- return vbo;
+ return ret;
}
void
@@ -218,96 +183,48 @@ piglit_init(int argc, char **argv)
piglit_require_extension("GL_ARB_post_depth_coverage");
glEnable(GL_DEPTH_TEST);
- glEnable(GL_STENCIL_TEST);
glEnable(GL_MULTISAMPLE);
- glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClearColor(0.2, 0.2, 0.2, 0.2);
- prog1 = make_shader_program1();
- prog2 = make_shader_program2();
- vao = make_vao();
- ssbo = make_ssbo();
- tex_color = make_texture_color();
- tex_depth = make_texture_depth();
- fbo = make_fbo();
+ prog1 = piglit_build_simple_program(vs_text, fs_text1);
+ prog2 = piglit_build_simple_program(vs_text, fs_text2);
+ prog3 = piglit_build_simple_program(vs_text, fs_text3);
}
-
enum piglit_result
piglit_display(void)
{
- int samples[4] = { 2, 4, 8, 16 };
- int max_samples;
+ const int samples[] = {2, 4, 8, 16};
+ int max_sample_count, mask, i, j;
bool pass = true;
- int i, j, k;
+ glGetIntegerv(GL_MAX_SAMPLES, &max_sample_count);
glViewport(0, 0, piglit_width, piglit_height);
- glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
-
- for (j = 0; j < 4 && samples[j] <= max_samples; j++) {
- sample_mask = (GLint*) calloc (piglit_width * piglit_height,
- sizeof(GLint));
- glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLint) * piglit_width *
- piglit_height, &sample_mask[0], GL_DYNAMIC_DRAW);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_color);
- glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples[j],
- GL_RGBA8, piglit_width, piglit_height, false);
- glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_depth);
- glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples[j],
- GL_DEPTH24_STENCIL8, piglit_width, piglit_height, false);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
- GL_STENCIL_BUFFER_BIT);
- glUseProgram(prog1);
- glStencilFunc(GL_ALWAYS, 1, 0xFF);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- glDrawArrays(GL_TRIANGLES, 0, 6);
-
- glUseProgram(prog2);
- glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glUniform1i(1, piglit_width);
- glUniform1i(2, samples[j]);
- glDrawArrays(GL_TRIANGLES, 6, 6);
-
- glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLint) *
- piglit_width * piglit_height, sample_mask);
-
- for (i = 0; i < piglit_width; i++) {
- for (k = 0; k < piglit_height; k++) {
- if (i >= piglit_width / 2) {
- if (sample_mask[piglit_width * k + i] != samples[j]) {
- pass = false;
- break;
- }
- } else {
- if (sample_mask[piglit_width * k + i] != 0) {
- pass = false;
- break;
- }
- }
- }
-
- if (!pass)
- break;
- }
-
- 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);
-
- piglit_present_results();
- free(sample_mask);
- if (!pass)
- break;
+ for (i = 0;
+ i < ARRAY_SIZE(samples) && samples[i] <= max_sample_count;
+ i++)
+ {
+ for (j = 0, mask = 0; j < samples[i]; j++)
+ mask |= (1 << j);
+
+ /* With post depth coverage, the depth test will be run on
+ * each sample before the fragment shader's invocation. As a
+ * result, sample 0 should fail the depth test and
+ * gl_SampleMaskIn[0] should indicate that all samples but 0
+ * are covered by the fragment shader.
+ */
+ if (!draw_and_check_sample_mask(prog2, samples[i], mask & ~1))
+ pass = false;
+
+ /* Without post depth coverage, the depth test will not have
+ * been run by the time that the fragment shader is invoked,
+ * and thus gl_SampleMaskIn[0] will indicate that all samples
+ * are covered by the fragment shader.
+ */
+ if (!draw_and_check_sample_mask(prog3, samples[i], mask))
+ pass = false;
}
- pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
-
return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}