From 7f5e49d54a9b21dbc4c02e557df5964cb6a0cc0e Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Wed, 26 Sep 2018 12:08:12 +0200 Subject: [PATCH] blitter: Replace 1D by 2D on GLES host and correct texture function call When running a GL 2.1 program in that guest on a GLES host that uses 1D textures then the emitted shaders must not declare 1D sampler, since they are not supported. Instead, use 2D samplers since 1D textures are emulated by 2D textures, and also fix the texture shader call. Closes: #33 Signed-off-by: Dave Airlie --- src/vrend_blitter.c | 18 +++++++++++++----- src/vrend_blitter.h | 13 ++++++++++++- src/vrend_shader.c | 30 +++++++++++++++++++++++------- src/vrend_shader.h | 3 ++- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/vrend_blitter.c b/src/vrend_blitter.c index a4077c8..3698c8c 100644 --- a/src/vrend_blitter.c +++ b/src/vrend_blitter.c @@ -212,10 +212,13 @@ static GLuint blit_build_frag_tex_col(struct vrend_blitter_ctx *blit_ctx, if (swizzle) create_dest_swizzle_snippet(swizzle, dest_swizzle_snippet); - snprintf(shader_buf, 4096, blit_ctx->use_gles ? FS_TEXFETCH_COL_GLES : FS_TEXFETCH_COL_GL, + snprintf(shader_buf, 4096, + blit_ctx->use_gles ? (tgsi_tex_target == TGSI_TEXTURE_1D ? + FS_TEXFETCH_COL_GLES_1D : FS_TEXFETCH_COL_GLES): + FS_TEXFETCH_COL_GL, ext_str, vec4_type_for_tgsi_ret(tgsi_ret), vrend_shader_samplerreturnconv(tgsi_ret), - vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm, + vrend_shader_samplertypeconv(blit_ctx->use_gles, tgsi_tex_target, &is_shad), twm, dest_swizzle_snippet); fs_id = glCreateShader(GL_FRAGMENT_SHADER); @@ -263,7 +266,7 @@ static GLuint blit_build_frag_tex_col_msaa(struct vrend_blitter_ctx *blit_ctx, 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), + vrend_shader_samplertypeconv(blit_ctx->use_gles, tgsi_tex_target, &is_shad), nr_samples, ivec, twm, dest_swizzle_snippet); fs_id = glCreateShader(GL_FRAGMENT_SHADER); @@ -285,6 +288,11 @@ static GLuint blit_build_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, switch (tgsi_tex_target) { case TGSI_TEXTURE_1D: + if (blit_ctx->use_gles) { + twm=".xy"; + break; + } + /* fallthrough */ case TGSI_TEXTURE_BUFFER: twm = ".x"; break; @@ -314,7 +322,7 @@ static GLuint blit_build_frag_tex_writedepth(struct vrend_blitter_ctx *blit_ctx, } snprintf(shader_buf, 4096, blit_ctx->use_gles ? FS_TEXFETCH_DS_GLES : FS_TEXFETCH_DS_GL, - vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), twm); + vrend_shader_samplertypeconv(blit_ctx->use_gles, tgsi_tex_target, &is_shad), twm); fs_id = glCreateShader(GL_FRAGMENT_SHADER); @@ -348,7 +356,7 @@ static GLuint blit_build_frag_blit_msaa_depth(struct vrend_blitter_ctx *blit_ctx } snprintf(shader_buf, 4096, blit_ctx->use_gles ? FS_TEXFETCH_DS_MSAA_GLES : FS_TEXFETCH_DS_MSAA_GL, - vrend_shader_samplertypeconv(tgsi_tex_target, &is_shad), ivec, twm); + vrend_shader_samplertypeconv(blit_ctx->use_gles, tgsi_tex_target, &is_shad), ivec, twm); fs_id = glCreateShader(GL_FRAGMENT_SHADER); diff --git a/src/vrend_blitter.h b/src/vrend_blitter.h index 5d53818..7c61acf 100644 --- a/src/vrend_blitter.h +++ b/src/vrend_blitter.h @@ -59,9 +59,20 @@ " FragColor = cvec4(%s);\n" \ "}\n" +#define FS_TEXFETCH_COL_GLES_1D_BODY \ + "%s" \ + "#define cvec4 %s\n" \ + "uniform mediump %csampler%s samp;\n" \ + "in vec4 tc;\n" \ + "out cvec4 FragColor;\n" \ + "void main() {\n" \ + " cvec4 texel = texture(samp, vec2(tc%s, 0.5));\n" \ + " FragColor = cvec4(%s);\n" \ + "}\n" + #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_GLES_1D HEADER_GLES FS_TEXFETCH_COL_GLES_1D_BODY #define FS_TEXFETCH_COL_MSAA_BODY \ "%s" \ diff --git a/src/vrend_shader.c b/src/vrend_shader.c index 285719d..093759b 100644 --- a/src/vrend_shader.c +++ b/src/vrend_shader.c @@ -4185,21 +4185,37 @@ char vrend_shader_samplerreturnconv(enum tgsi_return_type type) } } -const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad) +const char *vrend_shader_samplertypeconv(bool use_gles, int sampler_type, int *is_shad) { switch (sampler_type) { case TGSI_TEXTURE_BUFFER: return "Buffer"; - case TGSI_TEXTURE_1D: return "1D"; + case TGSI_TEXTURE_1D: + if (!use_gles) + return "1D"; + /* fallthrough */ case TGSI_TEXTURE_2D: return "2D"; case TGSI_TEXTURE_3D: return "3D"; case TGSI_TEXTURE_CUBE: return "Cube"; case TGSI_TEXTURE_RECT: return "2DRect"; - case TGSI_TEXTURE_SHADOW1D: *is_shad = 1; return "1DShadow"; + case TGSI_TEXTURE_SHADOW1D: + if (!use_gles) { + *is_shad = 1; + return "1DShadow"; + } + /* fallthrough */ case TGSI_TEXTURE_SHADOW2D: *is_shad = 1; return "2DShadow"; case TGSI_TEXTURE_SHADOWRECT: *is_shad = 1; return "2DRectShadow"; - case TGSI_TEXTURE_1D_ARRAY: return "1DArray"; + case TGSI_TEXTURE_1D_ARRAY: + if (!use_gles) + return "1DArray"; + /* fallthrough */ case TGSI_TEXTURE_2D_ARRAY: return "2DArray"; - case TGSI_TEXTURE_SHADOW1D_ARRAY: *is_shad = 1; return "1DArrayShadow"; + case TGSI_TEXTURE_SHADOW1D_ARRAY: + if (!use_gles) { + *is_shad = 1; + return "1DArrayShadow"; + } + /* fallthrough */ case TGSI_TEXTURE_SHADOW2D_ARRAY: *is_shad = 1; return "2DArrayShadow"; case TGSI_TEXTURE_SHADOWCUBE: *is_shad = 1; return "CubeShadow"; case TGSI_TEXTURE_CUBE_ARRAY: return "CubeArray"; @@ -4257,7 +4273,7 @@ static void *emit_sampler_decl(struct dump_ctx *ctx, char *glsl_hdr, precision = (ctx->cfg->use_gles) ? "highp " : " "; ptc = vrend_shader_samplerreturnconv(sampler->tgsi_sampler_return); - stc = vrend_shader_samplertypeconv(sampler->tgsi_sampler_type, &is_shad); + stc = vrend_shader_samplertypeconv(ctx->cfg->use_gles, sampler->tgsi_sampler_type, &is_shad); /* GLES does not support 1D textures -- we use a 2D texture and set the parameter set to 0.5 */ if (ctx->cfg->use_gles && sampler->tgsi_sampler_type == TGSI_TEXTURE_1D) @@ -4423,7 +4439,7 @@ static void *emit_image_decl(const struct dump_ctx *ctx, char *glsl_hdr, formatstr = get_internalformat_string(image->decl.Format, &itype); ptc = vrend_shader_samplerreturnconv(itype); sname = tgsi_proc_to_prefix(ctx->prog_type); - stc = vrend_shader_samplertypeconv(image->decl.Resource, &is_shad); + stc = vrend_shader_samplertypeconv(ctx->cfg->use_gles, image->decl.Resource, &is_shad); if (!image->decl.Writable) access = "readonly "; diff --git a/src/vrend_shader.h b/src/vrend_shader.h index bcca3e3..5d76843 100644 --- a/src/vrend_shader.h +++ b/src/vrend_shader.h @@ -122,7 +122,8 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg, uint32_t req_local_mem, struct vrend_shader_key *key, struct vrend_shader_info *sinfo); -const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad); + +const char *vrend_shader_samplertypeconv(bool use_gles, 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);