[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