[virglrenderer-devel] [PATCH 1/3] vrend: Support GL blits with integer color formats

Alexandros Frantzis alexandros.frantzis at collabora.com
Fri May 25 13:51:53 UTC 2018


Update the GL blit code to emit correct shaders when integer color
formats are involved.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>
---
 src/vrend_blitter.c | 50 +++++++++++++++++++++++++++++++++++++--------
 src/vrend_blitter.h | 15 ++++++--------
 src/vrend_shader.c  |  2 +-
 src/vrend_shader.h  |  2 ++
 4 files changed, 50 insertions(+), 19 deletions(-)

diff --git a/src/vrend_blitter.c b/src/vrend_blitter.c
index 042a115..1c1ae80 100644
--- a/src/vrend_blitter.c
+++ b/src/vrend_blitter.c
@@ -144,8 +144,28 @@ static void create_dest_swizzle_snippet(const uint8_t swizzle[4],
    }
 }
 
+static const char *vec4_type_for_tgsi_ret(enum tgsi_return_type tgsi_ret)
+{
+   switch (tgsi_ret) {
+   case TGSI_RETURN_TYPE_SINT: return "ivec4";
+   case TGSI_RETURN_TYPE_UINT: return "uvec4";
+   default: return "vec4";
+   }
+}
+
+static enum tgsi_return_type tgsi_ret_for_format(enum virgl_formats format)
+{
+   if (util_format_is_pure_uint(format))
+      return TGSI_RETURN_TYPE_UINT;
+   else if (util_format_is_pure_sint(format))
+      return TGSI_RETURN_TYPE_SINT;
+
+   return TGSI_RETURN_TYPE_UNORM;
+}
+
 static GLuint blit_build_frag_tex_col(struct vrend_blitter_ctx *blit_ctx,
                                       int tgsi_tex_target,
+                                      enum tgsi_return_type tgsi_ret,
                                       const uint8_t swizzle[4])
 {
    GLuint fs_id;
@@ -192,7 +212,9 @@ static GLuint blit_build_frag_tex_col(struct vrend_blitter_ctx *blit_ctx,
       create_dest_swizzle_snippet(swizzle, dest_swizzle_snippet);
 
    snprintf(shader_buf, 4096, blit_ctx->use_gles ? FS_TEXFETCH_COL_GLES : FS_TEXFETCH_COL_GL,
-            ext_str, vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm,
+            ext_str, vec4_type_for_tgsi_ret(tgsi_ret),
+            vrend_shader_samplerreturnconv(tgsi_ret),
+            vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm,
             dest_swizzle_snippet);
 
    fs_id = glCreateShader(GL_FRAGMENT_SHADER);
@@ -315,21 +337,26 @@ static GLuint blit_get_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, i
    }
 }
 
-static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int pipe_tex_target, unsigned nr_samples, const struct vrend_format_table *entry)
+static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx,
+                                    int pipe_tex_target,
+                                    unsigned nr_samples,
+                                    const struct vrend_format_table *src_entry,
+                                    const struct vrend_format_table *dst_entry)
 {
    assert(pipe_tex_target < PIPE_MAX_TEXTURE_TYPES);
 
    if (nr_samples > 1) {
       return 0;
-   } else if (entry->flags & VREND_BIND_NEED_SWIZZLE) {
+   } else if (dst_entry->flags & VREND_BIND_NEED_SWIZZLE) {
       GLuint *shader = &blit_ctx->fs_texfetch_col_swizzle;
       if (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);
 
-     *shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex, entry->swizzle);
+     *shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex, tgsi_ret, dst_entry->swizzle);
 
       return *shader;
    } else {
@@ -337,8 +364,9 @@ static GLuint blit_get_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, int pipe
 
       if (!*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);
 
-         *shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex, NULL);
+         *shader = blit_build_frag_tex_col(blit_ctx, tgsi_tex, tgsi_ret, NULL);
       }
       return *shader;
    }
@@ -660,10 +688,14 @@ void vrend_renderer_blit_gl(struct vrend_context *ctx,
    prog_id = glCreateProgram();
    glAttachShader(prog_id, blit_ctx->vs);
 
-   if (blit_depth || blit_stencil)
-      fs_id = blit_get_frag_tex_writedepth(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, dst_entry);
+   if (blit_depth || blit_stencil) {
+      fs_id = blit_get_frag_tex_writedepth(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,
+                                    src_entry, dst_entry);
+   }
    glAttachShader(prog_id, fs_id);
 
    glLinkProgram(prog_id);
diff --git a/src/vrend_blitter.h b/src/vrend_blitter.h
index ce05bbc..d20110c 100644
--- a/src/vrend_blitter.h
+++ b/src/vrend_blitter.h
@@ -35,11 +35,6 @@
    "#version 300 es\n"                          \
    "precision mediump float;\n"                 \
 
-#define OUTFRAG_GLES                            \
-   "out vec4 FragColor;\n"                      \
-   "#define gl_FragColor FragColor\n"
-
-
 #define VS_PASSTHROUGH_BODY                     \
    "in vec4 arg0;\n"                            \
    "in vec4 arg1;\n"                            \
@@ -55,15 +50,17 @@
 
 #define FS_TEXFETCH_COL_BODY                    \
    "%s"                                         \
-   "uniform sampler%s samp;\n"                  \
+   "#define cvec4 %s\n"                         \
+   "uniform mediump %csampler%s samp;\n"        \
    "in vec4 tc;\n"                              \
+   "out cvec4 FragColor;\n"                     \
    "void main() {\n"                            \
-   "   vec4 texel = texture(samp, tc%s);\n"     \
-   "   gl_FragColor = vec4(%s);\n" \
+   "   cvec4 texel = texture(samp, tc%s);\n"    \
+   "   FragColor = cvec4(%s);\n"                \
    "}\n"
 
 #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_GLES HEADER_GLES FS_TEXFETCH_COL_BODY
 
 #define FS_TEXFETCH_DS_BODY                             \
    "uniform sampler%s samp;\n"                          \
diff --git a/src/vrend_shader.c b/src/vrend_shader.c
index a64dcf0..8b33549 100644
--- a/src/vrend_shader.c
+++ b/src/vrend_shader.c
@@ -2643,7 +2643,7 @@ static char *emit_header(struct dump_ctx *ctx, char *glsl_hdr)
    return glsl_hdr;
 }
 
-static char vrend_shader_samplerreturnconv(enum tgsi_return_type type)
+char vrend_shader_samplerreturnconv(enum tgsi_return_type type)
 {
    switch (type) {
    case TGSI_RETURN_TYPE_SINT:
diff --git a/src/vrend_shader.h b/src/vrend_shader.h
index 897d750..149f389 100644
--- a/src/vrend_shader.h
+++ b/src/vrend_shader.h
@@ -26,6 +26,7 @@
 #define VREND_SHADER_H
 
 #include "pipe/p_state.h"
+#include "pipe/p_shader_tokens.h"
 
 /* need to store patching info for interpolation */
 struct vrend_interp_info {
@@ -105,6 +106,7 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
                            struct vrend_shader_key *key,
                            struct vrend_shader_info *sinfo);
 const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad);
+char vrend_shader_samplerreturnconv(enum tgsi_return_type type);
 
 int shader_lookup_sampler_array(struct vrend_shader_info *sinfo, int index);
 #endif
-- 
2.17.0



More information about the virglrenderer-devel mailing list