[virglrenderer-devel] [PATCH 1/1] Fixes an issue with blitting R8G8B8X8_UNORM buffer

Robert Tarasov tutankhamen at chromium.org
Thu Mar 29 22:27:52 UTC 2018


Ignores alpha channel while blitting R8G8B8X8_UNIFORM colorspace.
framebuffer It would be nice to perform some code refactoring in
vrend_blitter to minimize dup code. Fixes following test:
dEQP-GLES3.functional.fbo.blit.conversion.rgb8_to_rgba8']
dEQP-GLES3.functional.fbo.blit.conversion.rgb8_to_rgb10_a2
dEQP-GLES3.functional.fbo.blit.conversion.rgb8_to_rgba4']
---
 src/vrend_blitter.c  | 76 ++++++++++++++++++++++++++++++++++++++++++++
 src/vrend_blitter.h  | 11 +++++++
 src/vrend_renderer.c |  3 ++
 3 files changed, 90 insertions(+)

diff --git a/src/vrend_blitter.c b/src/vrend_blitter.c
index edbc9ea..2acad14 100644
--- a/src/vrend_blitter.c
+++ b/src/vrend_blitter.c
@@ -59,6 +59,7 @@ struct vrend_blitter_ctx {
    GLuint vs;
    GLuint vs_pos_only;
    GLuint fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
+   GLuint fs_texfetch_col_ignore_alpha[PIPE_MAX_TEXTURE_TYPES];
    GLuint fs_texfetch_col_emu_alpha[PIPE_MAX_TEXTURE_TYPES];
    GLuint fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
    GLuint fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES];
@@ -155,6 +156,61 @@ static GLuint blit_build_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int tg
       return 0;
    }
 
+
+   return fs_id;
+}
+
+static GLuint blit_build_frag_tex_col_ignore_alpha(struct vrend_blitter_ctx *blit_ctx, int tgsi_tex_target)
+{
+   GLuint fs_id;
+   char shader_buf[4096];
+   int is_shad;
+   const char *twm;
+   const char *ext_str = "";
+   switch (tgsi_tex_target) {
+   case TGSI_TEXTURE_1D:
+   case TGSI_TEXTURE_BUFFER:
+      twm = ".x";
+      break;
+   case TGSI_TEXTURE_1D_ARRAY:
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_2D_MSAA:
+   default:
+      twm = ".xy";
+      break;
+   case TGSI_TEXTURE_SHADOW1D:
+   case TGSI_TEXTURE_SHADOW2D:
+   case TGSI_TEXTURE_SHADOW1D_ARRAY:
+   case TGSI_TEXTURE_SHADOWRECT:
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+   case TGSI_TEXTURE_2D_ARRAY:
+   case TGSI_TEXTURE_2D_ARRAY_MSAA:
+      twm = ".xyz";
+      break;
+   case TGSI_TEXTURE_SHADOWCUBE:
+   case TGSI_TEXTURE_SHADOW2D_ARRAY:
+   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
+   case TGSI_TEXTURE_CUBE_ARRAY:
+      twm = "";
+      break;
+   }
+
+   if (tgsi_tex_target == TGSI_TEXTURE_CUBE_ARRAY ||
+       tgsi_tex_target == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
+      ext_str = "#extension GL_ARB_texture_cube_map_array : require\n";
+
+   snprintf(shader_buf, 4096, blit_ctx->use_gles ? FS_TEXFETCH_COL_IGNORE_ALPHA_GLES : FS_TEXFETCH_COL_IGNORE_ALPHA_GL,
+      ext_str, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm, "");
+
+   fs_id = glCreateShader(GL_FRAGMENT_SHADER);
+
+   if (!build_and_check(fs_id, shader_buf)) {
+      glDeleteShader(fs_id);
+      return 0;
+   }
+
    return fs_id;
 }
 
@@ -340,6 +396,24 @@ static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int pipe
    }
 }
 
+static GLuint blit_get_frag_tex_col_ignore_alpha(struct vrend_blitter_ctx *blit_ctx, int pipe_tex_target, unsigned nr_samples)
+{
+   assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES);
+
+   if (nr_samples > 1) {
+      return 0;
+   } else {
+      GLuint *shader = &blit_ctx->fs_texfetch_col_ignore_alpha[pipe_tex_target];
+
+      if (!*shader) {
+         unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex_target, 0);
+
+         *shader = blit_build_frag_tex_col_ignore_alpha(blit_ctx, tgsi_tex);
+      }
+      return *shader;
+   }
+}
+
 static GLuint blit_get_frag_tex_col_emu_alpha(struct vrend_blitter_ctx *blit_ctx, int pipe_tex_target, unsigned nr_samples)
 {
    assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES);
@@ -589,6 +663,8 @@ void vrend_renderer_blit_gl(struct vrend_context *ctx,
       fs_id = blit_get_frag_tex_writedepth(blit_ctx, src_res->base.target, src_res->base.nr_samples);
    else if (vrend_format_is_emulated_alpha(info->dst.format))
       fs_id = blit_get_frag_tex_col_emu_alpha(blit_ctx, src_res->base.target, src_res->base.nr_samples);
+   else if (src_res->base.format == VIRGL_FORMAT_R8G8B8X8_UNORM)
+      fs_id = blit_get_frag_tex_col_ignore_alpha(blit_ctx, src_res->base.target, src_res->base.nr_samples);
    else
       fs_id = blit_get_frag_tex_col(blit_ctx, src_res->base.target, src_res->base.nr_samples);
    glAttachShader(prog_id, fs_id);
diff --git a/src/vrend_blitter.h b/src/vrend_blitter.h
index 07573a7..8c0aac6 100644
--- a/src/vrend_blitter.h
+++ b/src/vrend_blitter.h
@@ -64,6 +64,17 @@
 #define FS_TEXFETCH_COL_GL HEADER_GL FS_TEXFETCH_COL_BODY
 #define FS_TEXFETCH_COL_GLES HEADER_GLES OUTFRAG_GLES FS_TEXFETCH_COL_BODY
 
+#define FS_TEXFETCH_COL_IGNORE_ALPHA_BODY       \
+   "%s"                                         \
+   "uniform sampler%s samp;\n"                  \
+   "in vec4 tc;\n"                              \
+   "void main() {\n"                            \
+   "   vec4 temp = texture(samp, tc%s)%s;\n"    \
+   "   gl_FragColor = vec4(temp.rgb, 1.0f);\n"  \
+   "}\n"
+
+#define FS_TEXFETCH_COL_IGNORE_ALPHA_GL HEADER_GL FS_TEXFETCH_COL_IGNORE_ALPHA_BODY
+#define FS_TEXFETCH_COL_IGNORE_ALPHA_GLES HEADER_GLES OUTFRAG_GLES FS_TEXFETCH_COL_IGNORE_ALPHA_BODY
 
 #define FS_TEXFETCH_COL_ALPHA_DEST_BODY         \
    "%s"                                         \
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 0eb8a7e..30db1b9 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -5952,6 +5952,9 @@ static void vrend_renderer_blit_int(struct vrend_context *ctx,
        vrend_format_is_emulated_alpha(info->src.format))
       use_gl = true;
 
+   if (info->src.format == VIRGL_FORMAT_R8G8B8X8_UNORM)
+      use_gl = true;
+
    if (use_gl) {
       vrend_renderer_blit_gl(ctx, src_res, dst_res, info);
       vrend_clicbs->make_current(0, ctx->sub->gl_context);
-- 
2.17.0.rc1.321.gba9d0f2565-goog



More information about the virglrenderer-devel mailing list