From 2f941194a5e7aad0a9b1d7641eca5dd994032e4b Mon Sep 17 00:00:00 2001 From: Alexandros Frantzis Date: Fri, 25 May 2018 16:51:53 +0300 Subject: [PATCH] vrend: Support GL blits with integer color formats Update the GL blit code to emit correct shaders when integer color formats are involved. Signed-off-by: Alexandros Frantzis Signed-off-by: Dave Airlie --- 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 19e5a4b..b5df872 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -2736,7 +2736,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