From a79e837b0d44199776612d2436c3c98a05287412 Mon Sep 17 00:00:00 2001 From: Alexandros Frantzis Date: Fri, 25 May 2018 16:51:54 +0300 Subject: [PATCH] vrend: Support GL blits for multisample textures Update the GL blit code to support blitting for multisample textures, for both normalized and integer color formats. The minimum GLSL ES version in the shaders is also raised to 3.1, since GLSL ES 3.0 doesn't support multisample textures. Fixes: dEQP-GLES3.functional.fbo.msaa.2_samples.rgb8 dEQP-GLES3.functional.fbo.msaa.4_samples.rgb8 dEQP-GLES3.functional.fbo.msaa.8_samples.rgb8 Various piglit MSAA luminance related regressions Signed-off-by: Alexandros Frantzis Signed-off-by: Dave Airlie --- src/vrend_blitter.c | 70 ++++++++++++++++++++++++++++++++++++++++----- src/vrend_blitter.h | 21 +++++++++++++- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/vrend_blitter.c b/src/vrend_blitter.c index 1c1ae80..5bcaf72 100644 --- a/src/vrend_blitter.c +++ b/src/vrend_blitter.c @@ -227,6 +227,54 @@ static GLuint blit_build_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, return fs_id; } +static GLuint blit_build_frag_tex_col_msaa(struct vrend_blitter_ctx *blit_ctx, + int tgsi_tex_target, + enum tgsi_return_type tgsi_ret, + const uint8_t swizzle[4], + int nr_samples) +{ + GLuint fs_id; + char shader_buf[4096]; + int is_shad; + const char *twm; + const char *ivec; + char dest_swizzle_snippet[DEST_SWIZZLE_SNIPPET_SIZE] = "texel"; + const char *ext_str = blit_ctx->use_gles ? "" : + "#extension GL_ARB_texture_multisample : enable\n"; + + switch (tgsi_tex_target) { + case TGSI_TEXTURE_2D_MSAA: + twm = ".xy"; + ivec = "ivec2"; + break; + case TGSI_TEXTURE_2D_ARRAY_MSAA: + twm = ".xyz"; + ivec = "ivec3"; + break; + default: + return 0; + } + + if (swizzle) + create_dest_swizzle_snippet(swizzle, dest_swizzle_snippet); + + snprintf(shader_buf, 4096, + blit_ctx->use_gles ? FS_TEXFETCH_COL_MSAA_GLES : FS_TEXFETCH_COL_MSAA_GL, + ext_str, vec4_type_for_tgsi_ret(tgsi_ret), + vrend_shader_samplerreturnconv(tgsi_ret), + vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), + nr_samples, ivec, twm, dest_swizzle_snippet); + + fs_id = glCreateShader(GL_FRAGMENT_SHADER); + + if (!build_and_check(fs_id, shader_buf)) { + glDeleteShader(fs_id); + return 0; + } + + return fs_id; +} + static GLuint blit_build_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target) { GLuint fs_id; @@ -345,18 +393,26 @@ static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, { assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES); - if (nr_samples > 1) { - return 0; - } else if (dst_entry->flags & VREND_BIND_NEED_SWIZZLE) { + bool needs_swizzle = dst_entry->flags & VREND_BIND_NEED_SWIZZLE; + + if (needs_swizzle || nr_samples > 1) { + const uint8_t *swizzle = needs_swizzle ? dst_entry->swizzle : NULL; GLuint *shader = &blit_ctx->fs_texfetch_col_swizzle; if (shader) { - glDeleteShader(*shader); + glDeleteShader(*shader); } - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, 0); - enum tgsi_return_type tgsi_ret = tgsi_ret_for_format(src_entry->format); + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, nr_samples); + enum tgsi_return_type tgsi_ret = tgsi_ret_for_format(src_entry->format); - *shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex, tgsi_ret, dst_entry->swizzle); + if (nr_samples > 1) { + // Integer textures are resolved using just one sample + int msaa_samples = tgsi_ret == TGSI_RETURN_TYPE_UNORM ? nr_samples : 1; + *shader = blit_build_frag_tex_col_msaa(blit_ctx, tgsi_tex, tgsi_ret, + swizzle, msaa_samples); + } else { + *shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex, tgsi_ret, swizzle); + } return *shader; } else { diff --git a/src/vrend_blitter.h b/src/vrend_blitter.h index d20110c..5d53818 100644 --- a/src/vrend_blitter.h +++ b/src/vrend_blitter.h @@ -32,7 +32,7 @@ #define HEADER_GLES \ "// Blitter\n" \ - "#version 300 es\n" \ + "#version 310 es\n" \ "precision mediump float;\n" \ #define VS_PASSTHROUGH_BODY \ @@ -62,6 +62,25 @@ #define FS_TEXFETCH_COL_GL HEADER_GL FS_TEXFETCH_COL_BODY #define FS_TEXFETCH_COL_GLES HEADER_GLES FS_TEXFETCH_COL_BODY + +#define FS_TEXFETCH_COL_MSAA_BODY \ + "%s" \ + "#define cvec4 %s\n" \ + "uniform mediump %csampler%s samp;\n" \ + "in vec4 tc;\n" \ + "out cvec4 FragColor;\n" \ + "void main() {\n" \ + " const int num_samples = %d;\n" \ + " cvec4 texel = cvec4(0);\n" \ + " for (int i = 0; i < num_samples; ++i) \n" \ + " texel += texelFetch(samp, %s(tc%s), i);\n" \ + " texel = texel / cvec4(num_samples);\n" \ + " FragColor = cvec4(%s);\n" \ + "}\n" + +#define FS_TEXFETCH_COL_MSAA_GL HEADER_GL FS_TEXFETCH_COL_MSAA_BODY +#define FS_TEXFETCH_COL_MSAA_GLES HEADER_GLES FS_TEXFETCH_COL_MSAA_BODY + #define FS_TEXFETCH_DS_BODY \ "uniform sampler%s samp;\n" \ "in vec4 tc;\n" \