[Piglit] [PATCH 1/3] msaa: Make changes in shared code to accomodate dual-src-blending test cases
anuj.phogat at gmail.com
anuj.phogat at gmail.com
Tue Jul 31 20:13:42 PDT 2012
From: Anuj Phogat <anuj.phogat at gmail.com>
These changes are required to enable dual-src-blending test cases to use the
shared code:
Generate fragment shader which outputs relevant color values.
Modify compute_expected_color() function to support dual-src-blending.
Use blitting in place of visualize_image() function to test blending.
Note: Following patch should be applied before this series of patches:
[PATCH 1/2] msaa: Make few changes to shared code to accomodate no-draw-buffer-zero test
Above patch is under review on piglit mailing list (Posted on Jul 23).
Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
.../alpha-to-coverage-no-draw-buffer-zero.cpp | 4 +-
.../alpha-to-one-msaa-disabled.cpp | 3 +-
.../alpha-to-one-single-sample-buffer.cpp | 4 +-
.../draw-buffers-alpha-to-coverage.cpp | 3 +-
.../draw-buffers-alpha-to-one.cpp | 3 +-
.../draw-buffers-common.cpp | 222 ++++++++++++++++----
.../draw-buffers-common.h | 2 +-
.../int-draw-buffers-alpha-to-coverage.cpp | 3 +-
.../int-draw-buffers-alpha-to-one.cpp | 4 +-
.../sample-alpha-to-coverage.cpp | 5 +-
.../sample-alpha-to-one.cpp | 3 +-
11 files changed, 207 insertions(+), 49 deletions(-)
diff --git a/tests/spec/ext_framebuffer_multisample/alpha-to-coverage-no-draw-buffer-zero.cpp b/tests/spec/ext_framebuffer_multisample/alpha-to-coverage-no-draw-buffer-zero.cpp
index ef60778..9cd197d 100644
--- a/tests/spec/ext_framebuffer_multisample/alpha-to-coverage-no-draw-buffer-zero.cpp
+++ b/tests/spec/ext_framebuffer_multisample/alpha-to-coverage-no-draw-buffer-zero.cpp
@@ -97,7 +97,9 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_NONE /* color_buffer_zero_format */);
- shader_compile();
+
+ shader_compile(true /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/alpha-to-one-msaa-disabled.cpp b/tests/spec/ext_framebuffer_multisample/alpha-to-one-msaa-disabled.cpp
index 2ad09fd..c0e1ea7 100644
--- a/tests/spec/ext_framebuffer_multisample/alpha-to-one-msaa-disabled.cpp
+++ b/tests/spec/ext_framebuffer_multisample/alpha-to-one-msaa-disabled.cpp
@@ -87,7 +87,8 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_RGBA);
- shader_compile();
+ shader_compile(false /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/alpha-to-one-single-sample-buffer.cpp b/tests/spec/ext_framebuffer_multisample/alpha-to-one-single-sample-buffer.cpp
index 6bc390a..6585259 100644
--- a/tests/spec/ext_framebuffer_multisample/alpha-to-one-single-sample-buffer.cpp
+++ b/tests/spec/ext_framebuffer_multisample/alpha-to-one-single-sample-buffer.cpp
@@ -65,7 +65,9 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_RGBA);
- shader_compile();
+
+ shader_compile(false /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-coverage.cpp b/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-coverage.cpp
index 20a69bc..31213f6 100644
--- a/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-coverage.cpp
+++ b/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-coverage.cpp
@@ -95,7 +95,8 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_RGBA);
- shader_compile();
+ shader_compile(true /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-one.cpp b/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-one.cpp
index 66bfd1c..53127aa 100644
--- a/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-one.cpp
+++ b/tests/spec/ext_framebuffer_multisample/draw-buffers-alpha-to-one.cpp
@@ -116,7 +116,8 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_RGBA);
- shader_compile();
+ shader_compile(false /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/draw-buffers-common.cpp b/tests/spec/ext_framebuffer_multisample/draw-buffers-common.cpp
index 9158a0b..2ed5b3b 100644
--- a/tests/spec/ext_framebuffer_multisample/draw-buffers-common.cpp
+++ b/tests/spec/ext_framebuffer_multisample/draw-buffers-common.cpp
@@ -88,6 +88,8 @@ static int pattern_width;
static int pattern_height;
static bool is_buffer_zero_integer_format = false;
+static bool is_dual_src_blending = false;
+
static GLenum draw_buffer_zero_format;
static const int num_components = 4; /* for RGBA formats */
@@ -116,30 +118,31 @@ static const char *vert =
" gl_Position = vec4(eye_pos.xy, 2 * depth - 1.0, 1.0);\n"
"}\n";
-/* Fragment shader outputs to three draw buffers. Output different alpha values
- * to different draw buffers. This is required to verify that alpha values from
- * draw buffer zero are used to determine the fragment coverage value for all
- * the draw buffers.
+/* Fragment shader generates three different color outputs. Different color
+ * values are generated based on if sample_alpha_to_coverage / dual_src_blend
+ * are enabled or not.
*/
static const char *frag_template =
"#version 130\n"
+ "#define DUAL_SRC_BLEND %d\n"
+ "#define ALPHA_TO_COVERAGE %d\n"
"#define OUT_TYPE %s\n"
"out OUT_TYPE frag_out_0;\n"
"out vec4 frag_out_1;\n"
"out vec4 frag_out_2;\n"
"uniform OUT_TYPE frag_0_color;\n"
"uniform vec4 color;\n"
- "uniform bool alphatocoverage;\n"
"void main()\n"
"{\n"
" frag_out_0 = frag_0_color;\n"
- " if(alphatocoverage) {\n"
+ " #if DUAL_SRC_BLEND\n"
+ " frag_out_1 = vec4(color.rgb, 1.0 - color.a / 2.0);\n"
+ " #elif ALPHA_TO_COVERAGE\n"
" frag_out_1 = vec4(color.rgb, color.a / 2);\n"
" frag_out_2 = vec4(color.rgb, color.a / 4);\n"
- " }\n"
- " else {\n"
+ " #else\n"
" frag_out_1 = frag_out_2 = color;\n"
- " }\n"
+ " #endif\n"
"}\n";
const char *
@@ -151,16 +154,20 @@ get_out_type_glsl(void)
return "vec4";
}
void
-shader_compile(void)
+shader_compile(bool sample_alpha_to_coverage, bool dual_src_blend)
{
+ is_dual_src_blending = dual_src_blend;
+
/* Compile program */
GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
+ /* Generate appropriate fragment shader program */
const char *out_type_glsl = get_out_type_glsl();;
unsigned frag_alloc_len = strlen(frag_template) +
strlen(out_type_glsl) + 1;
char *frag = (char *) malloc(frag_alloc_len);
- sprintf(frag, frag_template, out_type_glsl);
+ sprintf(frag, frag_template, is_dual_src_blending,
+ sample_alpha_to_coverage, out_type_glsl);
GLint fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
prog = piglit_link_simple_program(vs, fs);
@@ -170,12 +177,18 @@ shader_compile(void)
}
free(frag);
- glBindFragDataLocation(prog, 0, "frag_out_0");
- /* For multiple draw buffers */
- if (num_draw_buffers > 1) {
+ if (is_dual_src_blending) {
+ glBindFragDataLocationIndexed(prog, 0, 0, "frag_out_0");
+ glBindFragDataLocationIndexed(prog, 0, 1, "frag_out_1");
+
+ }
+ else if (num_draw_buffers > 1) {
+ glBindFragDataLocation(prog, 0, "frag_out_0");
glBindFragDataLocation(prog, 1, "frag_out_1");
glBindFragDataLocation(prog, 2, "frag_out_2");
}
+ else
+ glBindFragDataLocation(prog, 0, "frag_out_0");
glBindAttribLocation(prog, 0, "pos");
glEnableVertexAttribArray(0);
@@ -328,26 +341,87 @@ draw_pattern(bool sample_alpha_to_coverage,
glDisable (GL_SAMPLE_ALPHA_TO_ONE);
}
+float
+get_alpha_blend_factor(float src0_alpha, float src1_alpha,
+ bool compute_src)
+{
+ GLint blend_func;
+ if(compute_src)
+ glGetIntegerv(GL_BLEND_SRC_RGB, &blend_func);
+ else
+ glGetIntegerv(GL_BLEND_DST_RGB, &blend_func);
+
+ switch(blend_func) {
+ case GL_SRC_ALPHA:
+ return src0_alpha;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ return (1.0 - src0_alpha);
+ break;
+ case GL_SRC1_ALPHA:
+ return src1_alpha;
+ break;
+ case GL_ONE_MINUS_SRC1_ALPHA:
+ return (1.0 - src1_alpha);
+ break;
+ default:
+ printf("Blend function is not supported"
+ " by test case\n");
+ }
+}
+
+void
+compute_blend_color(float *frag_color, int rect_count,
+ bool sample_alpha_to_one)
+{
+ float src_blend_factor, dst_blend_factor;
+ /* Taking in to account alpha values output by
+ * fragment shader.
+ */
+ float src0_alpha = color[rect_count * num_components + 3];
+ float src1_alpha = 1.0 - src0_alpha / 2.0;
+
+ if(sample_alpha_to_one && num_samples) {
+ /* Set fragment src0_alpha to 1.0 and use it for
+ * blending factors.
+ */
+ src0_alpha = 1.0;
+ }
+
+ src_blend_factor = get_alpha_blend_factor(src0_alpha,
+ src1_alpha,
+ true);
+ dst_blend_factor = get_alpha_blend_factor(src0_alpha,
+ src1_alpha,
+ false);
+ /* Using default BlendEquation, blend_color is:
+ * src0_color * src_blend_factor + dst_color * dst_blend_factor
+ */
+ for (int j = 0; j < num_components; j++) {
+ float blend_color=
+ color[rect_count * num_components + j] *
+ src_blend_factor +
+ bg_color[j] *
+ dst_blend_factor;
+
+ frag_color[rect_count * num_components + j] =
+ (blend_color > 1) ? 1.0 : blend_color;
+ }
+}
+
void
compute_expected_color(bool sample_alpha_to_coverage,
bool sample_alpha_to_one,
int draw_buffer_count)
{
+ bool is_frag_color_alloc = false;
unsigned buffer_idx_offset = draw_buffer_count *
num_rects *
num_components;
- /* Coverage value decides the number of samples in multisample buffer
- * covered by an incoming fragment, which will then receive the
- * fragment data. When the multisample buffer is resolved it gets
- * blended with the background color which is written to the remaining
- * samples.
- * Page 254 (page 270 of the PDF) of the OpenGL 3.0 spec says:
- * "The method of combination is not specified, though a simple average
- * computed independently for each color component is recommended."
- * This is followed by NVIDIA and AMD in their proprietary drivers.
- */
+
for (int i = 0; i < num_rects; i++) {
+ float *frag_color = NULL;
float samples_used = coverage[i] * num_samples;
/* Expected color values are computed only for integer
* number of samples_used. Non-integer values may result
@@ -356,21 +430,48 @@ compute_expected_color(bool sample_alpha_to_coverage,
if(samples_used == (int) samples_used) {
int rect_idx_offset = buffer_idx_offset +
i * num_components;
+
+ /* Do dual source blending computations */
+ if(is_dual_src_blending) {
+ frag_color = (float *) malloc(num_rects *
+ num_components *
+ sizeof(float));
+ is_frag_color_alloc = true;
+ compute_blend_color(frag_color,
+ i /* rect_count */,
+ sample_alpha_to_one);
+ }
+ else {
+ frag_color = color;
+ }
+
+ /* Coverage value decides the number of samples in
+ * multisample buffer covered by an incoming fragment,
+ * which will then receive the fragment data. When the
+ * multisample buffer is resolved it gets blended with
+ * the background color which is written to the
+ * remaining samples. Page 254 (page 270 of the PDF) of
+ * the OpenGL 3.0 spec says: "The method of combination
+ * is not specified, though a simple average computed
+ * independently for each color component is recommended."
+ * This is followed by NVIDIA and AMD in their proprietary
+ * linux drivers.
+ */
for (int j = 0; j < num_components - 1 ; j++) {
expected_color[rect_idx_offset + j] =
- color[i * num_components + j] * coverage[i] +
+ frag_color[i * num_components + j] * coverage[i] +
bg_color[j] * (1 - coverage[i]);
}
/* Compute expected alpha values of draw buffers */
- float frag_alpha = color[i * num_components + 3];
+ float frag_alpha = frag_color[i * num_components + 3];
int alpha_idx = rect_idx_offset + 3;
if ((!num_samples &&
!sample_alpha_to_coverage) ||
is_buffer_zero_integer_format) {
- /* Taking in account alpha values modified by
+ /* Taking in to account alpha values output by
* fragment shader.
*/
expected_color[alpha_idx] =
@@ -379,7 +480,7 @@ compute_expected_color(bool sample_alpha_to_coverage,
frag_alpha;
}
else if (sample_alpha_to_coverage) {
- /* Taking in account alpha values modified by
+ /* Taking in to account alpha values output by
* fragment shader.
*/
frag_alpha /= pow(2, draw_buffer_count);
@@ -396,11 +497,15 @@ compute_expected_color(bool sample_alpha_to_coverage,
}
else {
expected_color[alpha_idx] =
- sample_alpha_to_one ? 1.0 : frag_alpha;
+ (sample_alpha_to_one) ? 1 : frag_alpha;
}
+
+ }
+ if(is_frag_color_alloc) {
+ free(frag_color);
+ is_frag_color_alloc = false;
}
}
-
}
void
@@ -427,7 +532,6 @@ compute_expected(bool sample_alpha_to_coverage,
if (num_samples &&
sample_alpha_to_coverage &&
!is_buffer_zero_integer_format) {
-
for (i = 0; i < num_rects; i++) {
/* Coverage value for all the draw buffers comes from
* the fragment alpha values of draw buffer zero
@@ -453,7 +557,6 @@ compute_expected(bool sample_alpha_to_coverage,
}
else if (buffer_to_test == GL_DEPTH_BUFFER_BIT)
compute_expected_depth();
-
}
/* This function probes all the draw buffers blitted to downsampled FBO
@@ -642,15 +745,36 @@ draw_test_image(bool sample_alpha_to_coverage, bool sample_alpha_to_one)
pattern_width, pattern_height + y_offset,
buffer_to_test, GL_NEAREST);
- if(buffer_to_test == GL_COLOR_BUFFER_BIT)
- draw_image_to_window_system_fb(i /* draw_buffer_count */,
- false /* rhs */);
+ if(buffer_to_test == GL_COLOR_BUFFER_BIT) {
+ if(is_dual_src_blending) {
+ /* Use blitting in place of visualize_image
+ * function to test blending.
+ */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER,
+ resolve_fbo.handle);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glBlitFramebuffer(0,
+ y_offset,
+ pattern_width,
+ pattern_height + y_offset,
+ 0,
+ y_offset,
+ pattern_width,
+ pattern_height + y_offset,
+ buffer_to_test,
+ GL_NEAREST);
+ }
+ else
+ /* i: draw_buffer_count */
+ draw_image_to_window_system_fb(i,
+ false /* rhs */);
+ }
/* Expected color values for all the draw buffers are computed
* to aid probe_framebuffer_color() and probe_framebuffer_depth()
* in verification.
*/
- if(sample_alpha_to_coverage) {
+ if(sample_alpha_to_coverage || is_dual_src_blending) {
/* Expected color is different for different draw
* buffers
*/
@@ -713,8 +837,30 @@ draw_reference_image(bool sample_alpha_to_coverage, bool sample_alpha_to_one)
pattern_width, pattern_height + y_offset,
buffer_to_test, GL_NEAREST);
- draw_image_to_window_system_fb(i /* buffer_count */,
- true /* rhs */ );
+ if(buffer_to_test == GL_COLOR_BUFFER_BIT) {
+ if (is_dual_src_blending) {
+ /* Use blitting in place of visualize_image
+ * function to test blending.
+ */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER,
+ resolve_fbo.handle);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glBlitFramebuffer(0,
+ y_offset,
+ pattern_width,
+ pattern_height + y_offset,
+ pattern_width,
+ y_offset,
+ 2 * pattern_width,
+ pattern_height + y_offset,
+ buffer_to_test,
+ GL_NEAREST);
+ }
+ else
+ /* i: draw_buffer_count */
+ draw_image_to_window_system_fb(i,
+ true /* rhs */);
+ }
}
}
diff --git a/tests/spec/ext_framebuffer_multisample/draw-buffers-common.h b/tests/spec/ext_framebuffer_multisample/draw-buffers-common.h
index b36bed3..43a8e42 100644
--- a/tests/spec/ext_framebuffer_multisample/draw-buffers-common.h
+++ b/tests/spec/ext_framebuffer_multisample/draw-buffers-common.h
@@ -63,4 +63,4 @@ bool probe_framebuffer_color(void);
*/
bool probe_framebuffer_depth(void);
-void shader_compile(void);
+void shader_compile(bool sample_alpha_to_coverage, bool dual_src_blend);
diff --git a/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-coverage.cpp b/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-coverage.cpp
index 40b9ddf..cfd90e5 100644
--- a/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-coverage.cpp
+++ b/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-coverage.cpp
@@ -96,7 +96,8 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_RGBA8I);
- shader_compile();
+ shader_compile(true /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-one.cpp b/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-one.cpp
index 7dae6bf..7bb85ce 100644
--- a/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-one.cpp
+++ b/tests/spec/ext_framebuffer_multisample/int-draw-buffers-alpha-to-one.cpp
@@ -93,7 +93,9 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_RGBA8I);
- shader_compile();
+
+ shader_compile(false /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/sample-alpha-to-coverage.cpp b/tests/spec/ext_framebuffer_multisample/sample-alpha-to-coverage.cpp
index 0559adc..38e4ae9 100644
--- a/tests/spec/ext_framebuffer_multisample/sample-alpha-to-coverage.cpp
+++ b/tests/spec/ext_framebuffer_multisample/sample-alpha-to-coverage.cpp
@@ -28,7 +28,7 @@
*
* Verify sample alpha to coverage with multisample FBO
*
- * When rendering to multiple draw buffers, fragment's alpha value should be
+ * When rendering to multisample FBO, fragment's alpha value should be
* used to determine the coverage value.
*
* This test operates by drawing a pattern in multisample FBO to generate
@@ -103,7 +103,8 @@ piglit_init(int argc, char **argv)
num_attachments,
buffer_to_test,
GL_RGBA);
- shader_compile();
+ shader_compile(true /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
diff --git a/tests/spec/ext_framebuffer_multisample/sample-alpha-to-one.cpp b/tests/spec/ext_framebuffer_multisample/sample-alpha-to-one.cpp
index 76d056f..85a08d5 100644
--- a/tests/spec/ext_framebuffer_multisample/sample-alpha-to-one.cpp
+++ b/tests/spec/ext_framebuffer_multisample/sample-alpha-to-one.cpp
@@ -87,7 +87,8 @@ piglit_init(int argc, char **argv)
num_attachments,
GL_COLOR_BUFFER_BIT,
GL_RGBA);
- shader_compile();
+ shader_compile(false /* sample_alpha_to_coverage */,
+ false /* dual_src_blend */);
}
enum piglit_result
--
1.7.7.6
More information about the Piglit
mailing list