[Piglit] [PATCH] ext_framebuffer_multisample_blit_scaled: Rewrite the fragment shader
Anuj Phogat
anuj.phogat at gmail.com
Wed Sep 10 15:24:06 PDT 2014
for ease of understanding, add comments and handle 2X msaa.
Test passes on Broadwell with recent Mesa patches (on mesa-dev list) to
implement the extension in meta path.
Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
.../blit-scaled.cpp | 194 ++++++++++++---------
1 file changed, 110 insertions(+), 84 deletions(-)
diff --git a/tests/spec/ext_framebuffer_multisample_blit_scaled/blit-scaled.cpp b/tests/spec/ext_framebuffer_multisample_blit_scaled/blit-scaled.cpp
index 4740145..0996d31 100644
--- a/tests/spec/ext_framebuffer_multisample_blit_scaled/blit-scaled.cpp
+++ b/tests/spec/ext_framebuffer_multisample_blit_scaled/blit-scaled.cpp
@@ -53,7 +53,7 @@ PIGLIT_GL_TEST_CONFIG_BEGIN
PIGLIT_GL_TEST_CONFIG_END
-static int num_samples;
+static int samples;
static TestPattern *test_pattern;
static unsigned prog, vao, vertex_buf;
const float srcX0 = 6, srcY0 = 7, dstX0 = 0, dstY0 = 0;
@@ -72,94 +72,127 @@ compile_shader(void)
{
static const char *vert =
"#version 130\n"
- "uniform mat4 proj;\n"
"in vec2 pos;\n"
"in vec2 texCoord;\n"
"out vec2 textureCoord;\n"
"void main()\n"
"{\n"
- " gl_Position = proj * vec4(pos, 0.0, 1.0);\n"
+ " gl_Position = vec4(pos, 0.0, 1.0);\n"
" textureCoord = texCoord;\n"
"}\n";
/* Bilinear filtering of samples using shader program */
- static const char *frag =
+ static const char *frag_template =
"#version 130\n"
"#extension GL_ARB_texture_multisample : require\n"
"in vec2 textureCoord;\n"
- "uniform sampler2DMS ms_tex;\n"
- "uniform int samples;\n"
- "uniform float xmin;\n"
- "uniform float ymin;\n"
- "uniform float xmax;\n"
- "uniform float ymax;\n"
+ "uniform sampler2DMS texSampler;\n"
+ "uniform float src_width;\n"
+ "uniform float src_height;\n"
"out vec4 out_color;\n"
"void main()\n"
"{\n"
+ "%s"
" float x_f, y_f;\n"
- " vec4 s_0, s_1, s_2, s_3;\n"
+ " const float x_scale = 2.0f, x_scale_inv = 0.5f;\n"
+ " const float y_scale = %ff, y_scale_inv = %ff;\n"
+ " const float x_offset = 0.25f, y_offset = %ff;\n"
" vec2 s_0_coord, s_1_coord, s_2_coord, s_3_coord;\n"
- " float x_scale = 2.0;\n"
- " float y_scale = samples / 2.0;\n"
- " int sample_map[8] = int[8](5 , 2, 4, 6, 0, 3, 7, 1);\n"
+ " vec4 s_0_color, s_1_color, s_2_color, s_3_color;\n"
+ " vec4 x_0_color, x_1_color;\n"
"\n"
- " vec2 tex_coord = vec2(textureCoord.x - 1.0 / 4,\n"
- " textureCoord.y - 1.0 / samples);\n"
- " tex_coord = vec2(x_scale * tex_coord.x,\n"
- " y_scale * tex_coord.y);\n"
+ " vec2 tex_coord = vec2(textureCoord.x - x_offset,\n"
+ " textureCoord.y - y_offset);\n"
+ " tex_coord = vec2(x_scale * tex_coord.x, y_scale * tex_coord.y);\n"
"\n"
- " if((tex_coord.x) < x_scale * xmin)\n"
- " tex_coord.x = x_scale * xmin;\n"
- " if(tex_coord.x >= x_scale * xmax - 1.0)\n"
- " tex_coord.x = x_scale * xmax - 1.0;\n"
- "\n"
- " if(tex_coord.y < y_scale * ymin)\n"
- " tex_coord.y = y_scale * ymin;\n"
- " if(tex_coord.y >= y_scale * ymax - 1.0)\n"
- " tex_coord.y = y_scale * ymax - 1.0;\n"
+ " clamp(tex_coord.x, 0.0f, x_scale * src_width - 1.0f);\n"
+ " clamp(tex_coord.y, 0.0f, y_scale * src_height - 1.0f);\n"
"\n"
" x_f = fract(tex_coord.x);\n"
" y_f = fract(tex_coord.y);\n"
"\n"
- " tex_coord.x = int(tex_coord.x) / x_scale;\n"
- " tex_coord.y = int(tex_coord.y) / y_scale;\n"
+ " tex_coord.x = int(tex_coord.x) * x_scale_inv;\n"
+ " tex_coord.y = int(tex_coord.y) * y_scale_inv;\n"
+ "\n"
"\n"
+ " /* Compute the sample coordinates used for filtering. */\n"
" s_0_coord = tex_coord;\n"
- " s_1_coord = s_0_coord + vec2(1 / x_scale, 0 / y_scale);\n"
- " s_2_coord = s_0_coord + vec2(0 / x_scale, 1 / y_scale);\n"
- " s_3_coord = s_0_coord + vec2(1 / x_scale, 1 / y_scale);\n"
+ " s_1_coord = tex_coord + vec2(x_scale_inv, 0.0f);\n"
+ " s_2_coord = tex_coord + vec2(0.0f, y_scale_inv);\n"
+ " s_3_coord = tex_coord + vec2(x_scale_inv, y_scale_inv);\n"
"\n"
- " if (samples == 4) {\n"
- " s_0 = texelFetch(ms_tex, ivec2(s_0_coord),\n"
- " int(2 * fract(s_0_coord.x) +\n"
- " samples * fract(s_0_coord.y)));\n"
- " s_1 = texelFetch(ms_tex, ivec2(s_1_coord),\n"
- " int(2 * fract(s_1_coord.x) +\n"
- " samples * fract(s_1_coord.y)));\n"
- " s_2 = texelFetch(ms_tex, ivec2(s_2_coord),\n"
- " int(2 * fract(s_2_coord.x) +\n"
- " samples * fract(s_2_coord.y)));\n"
- " s_3 = texelFetch(ms_tex, ivec2(s_3_coord),\n"
- " int(2 * fract(s_3_coord.x) +\n"
- " samples * fract(s_3_coord.y)));\n"
- " } else {\n"
- " s_0 = texelFetch(ms_tex, ivec2(s_0_coord),\n"
- " sample_map[int(2 * fract(s_0_coord.x) +\n"
- " samples * fract(s_0_coord.y))]);\n"
- " s_1 = texelFetch(ms_tex, ivec2(s_1_coord),\n"
- " sample_map[int(2 * fract(s_1_coord.x) +\n"
- " samples * fract(s_1_coord.y))]);\n"
- " s_2 = texelFetch(ms_tex, ivec2(s_2_coord),\n"
- " sample_map[int(2 * fract(s_2_coord.x) +\n"
- " samples * fract(s_2_coord.y))]);\n"
- " s_3 = texelFetch(ms_tex, ivec2(s_3_coord),\n"
- " sample_map[int(2 * fract(s_3_coord.x) +\n"
- " samples * fract(s_3_coord.y))]);\n"
- " }\n"
+ " /* Fetch sample color values. */\n"
+ "%s"
+ " s_0_color = TEXEL_FETCH(s_0_coord)\n"
+ " s_1_color = TEXEL_FETCH(s_1_coord)\n"
+ " s_2_color = TEXEL_FETCH(s_2_coord)\n"
+ " s_3_color = TEXEL_FETCH(s_3_coord)\n"
+ "#undef TEXEL_FETCH\n"
"\n"
- " vec4 color_x1 = mix(s_0, s_1, x_f);\n"
- " vec4 color_x2 = mix(s_2, s_3, x_f);\n"
- " out_color = mix(color_x1, color_x2, y_f);\n"
+ " /* Do bilinear filtering on sample colors. */\n"
+ " x_0_color = mix(s_0_color, s_1_color, x_f);\n"
+ " x_1_color = mix(s_2_color, s_3_color, x_f);\n"
+ " out_color = mix(x_0_color, x_1_color, y_f);\n"
"}\n";
+
+ char* frag, *texel_fetch_macro;
+ const char*sample_number, *sample_map = "";
+ const float y_scale = samples * 0.5;
+
+ /* Below switch is used to setup the shader expression, which computes
+ * sample index and map it to to a sample number on Intel hardware.
+ * Sample index layout shows the numbering of slots in a rectangular
+ * grid of samples with in a pixel. Sample number layout shows the
+ * rectangular grid of samples roughly corresponding to the real sample
+ * locations with in a pixel. Sample number layout matches the sample
+ * index layout in case of 2X and 4x MSAA, but they are different in
+ * case of 8X MSAA.
+ *
+ * 2X MSAA sample index / number layout
+ * ---------
+ * | 0 | 1 |
+ * ---------
+ *
+ * 4X MSAA sample index / number layout
+ * ---------
+ * | 0 | 1 |
+ * ---------
+ * | 2 | 3 |
+ * ---------
+ *
+ * 8X MSAA sample index layout 8x MSAA sample number layout
+ * --------- ---------
+ * | 0 | 1 | | 5 | 2 |
+ * --------- ---------
+ * | 2 | 3 | | 4 | 6 |
+ * --------- ---------
+ * | 4 | 5 | | 0 | 3 |
+ * --------- ---------
+ * | 6 | 7 | | 7 | 1 |
+ * --------- ---------
+ */
+ switch(samples) {
+ case 2:
+ sample_number = "int(2 * fract(coord.x))";
+ break;
+ case 4:
+ sample_number = "int(2 * fract(coord.x) + 4 * fract(coord.y))";
+ break;
+ case 8:
+ sample_map = " const int sample_map[8] = int[8](5 , 2, 4, 6, 0, 3, 7, 1);\n";
+ sample_number = "sample_map[int(2 * fract(coord.x) + 8 * fract(coord.y))]";
+ break;
+ default:
+ printf("Unsupported sample count %d\n", samples);
+ piglit_report_result(PIGLIT_SKIP);
+ }
+
+ asprintf(&texel_fetch_macro,
+ "#define TEXEL_FETCH(coord) texelFetch(texSampler, ivec2(coord), %s);\n",
+ sample_number);
+
+ asprintf(&frag, frag_template, sample_map, y_scale, 1.0f / y_scale,
+ 1.0f / samples, texel_fetch_macro);
+
/* Compile program */
prog = glCreateProgram();
GLint vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
@@ -200,14 +233,8 @@ compile_shader(void)
}
void
-ms_blit_scaled_glsl(const Fbo *src_fbo, GLint samples)
+ms_blit_scaled_glsl(const Fbo *src_fbo)
{
- const float proj[4][4] = {
- { 1, 0, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 1, 0 },
- { 0, 0, 0, 1 }};
-
float vertex_data[4][4] = {
{ -1, -1, srcX0, srcY0 },
{ -1, 1, srcX0, srcY1 },
@@ -221,16 +248,11 @@ ms_blit_scaled_glsl(const Fbo *src_fbo, GLint samples)
/* Set up uniforms */
glUseProgram(prog);
- glUniform1i(glGetUniformLocation(prog, "ms_tex"), 0);
- glUniform1i(glGetUniformLocation(prog, "samples"), samples);
- glUniform1f(glGetUniformLocation(prog, "xmin"), 0);
- glUniform1f(glGetUniformLocation(prog, "ymin"), 0);
- glUniform1f(glGetUniformLocation(prog, "xmax"),
+ glUniform1i(glGetUniformLocation(prog, "texSampler"), 0);
+ glUniform1f(glGetUniformLocation(prog, "src_width"),
multisampled_fbo.config.width);
- glUniform1f(glGetUniformLocation(prog, "ymax"),
+ glUniform1f(glGetUniformLocation(prog, "src_height"),
multisampled_fbo.config.height);
- glUniformMatrix4fv(glGetUniformLocation(prog, "proj"), 1,
- GL_TRUE, &proj[0][0]);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
@@ -246,7 +268,7 @@ piglit_init(int argc, char **argv)
/* 1st arg: num_samples */
char *endptr = NULL;
- num_samples = strtol(argv[1], &endptr, 0);
+ int num_samples = strtol(argv[1], &endptr, 0);
if (endptr != argv[1] + strlen(argv[1]))
print_usage_and_exit(argv[0]);
@@ -272,6 +294,12 @@ piglit_init(int argc, char **argv)
msConfig.num_rb_attachments = 0; /* default value is 1 */
multisampled_tex.setup(msConfig);
+ /* Implementation might not create a buffer with requested sample
+ * count. So, query the actual sample count of buffer.
+ */
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, multisampled_tex.handle);
+ glGetIntegerv(GL_SAMPLES, &samples);
+
test_pattern = new Triangles();
test_pattern->compile();
@@ -284,7 +312,6 @@ piglit_init(int argc, char **argv)
bool test_ms_blit_scaled(Fbo ms_fbo)
{
GLfloat scale;
- GLint samples;
bool pass = true, result = true;
/* Draw the test pattern into the framebuffer with texture
@@ -292,7 +319,6 @@ bool test_ms_blit_scaled(Fbo ms_fbo)
*/
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, multisampled_tex.handle);
glViewport(0, 0, srcX1, srcY1);
- glGetIntegerv(GL_SAMPLES, &samples);
glClear(GL_COLOR_BUFFER_BIT);
test_pattern->draw(TestPattern::no_projection);
@@ -340,7 +366,7 @@ bool test_ms_blit_scaled(Fbo ms_fbo)
glBindFramebuffer(GL_READ_FRAMEBUFFER, multisampled_tex.handle);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, singlesampled_fbo.handle);
glViewport(pattern_width + dstX0, dstY0, srcX1 * scale, srcY1 * scale);
- ms_blit_scaled_glsl(&multisampled_tex, samples);
+ ms_blit_scaled_glsl(&multisampled_tex);
pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
glBindFramebuffer(GL_READ_FRAMEBUFFER, singlesampled_fbo.handle);
@@ -355,10 +381,10 @@ bool test_ms_blit_scaled(Fbo ms_fbo)
0, 0, 2 * pattern_width, piglit_height,
GL_COLOR_BUFFER_BIT, GL_NEAREST);
piglit_present_results();
- printf("MS attachment = %24s, scale = %f, result = %s\n",
+ printf("MS attachment = %12s, scale = %f, result = %s\n",
ms_fbo.config.num_tex_attachments > 0 ?
- "MULTISAMPLE_TEXTURE" :
- "MULTISAMPLE_RENDERBUFFER",
+ "TEXTURE" :
+ "RENDERBUFFER",
scale, result ? "pass" : "fail");
}
return pass;
--
1.9.3
More information about the Piglit
mailing list