glsl path of _mesa_meta_GenerateMipmap() function would require different fragment shaders depending on the texture target. This patch adds the code to generate appropriate fragment shader programs at run time. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=54296
NOTE: This is a candidate for stable branches. Signed-off-by: Anuj Phogat <anuj.pho...@gmail.com> --- src/mesa/drivers/common/meta.c | 100 +++++++++++++++++++++++++++++++++++---- 1 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 36672a7..7d701f4 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -286,6 +286,15 @@ struct gen_mipmap_state GLuint IntegerShaderProg; }; +/** + * State for GLSL texture sampler which is used to generate fragment + * shader in _mesa_meta_generate_mipmap(). + */ +struct glsl_sampler { + const char *type; + const char *func; + const char *texcoords; +}; /** * State for texture decompression @@ -2974,7 +2983,7 @@ setup_texture_coords(GLenum faceTarget, static void setup_ff_generate_mipmap(struct gl_context *ctx, - struct gen_mipmap_state *mipmap) + struct gen_mipmap_state *mipmap) { struct vertex { GLfloat x, y, tex[3]; @@ -3004,12 +3013,53 @@ setup_ff_generate_mipmap(struct gl_context *ctx, static void +setup_texture_sampler(GLenum target, struct glsl_sampler *sampler) +{ + switch(target) { + case GL_TEXTURE_1D: + sampler->type = "sampler1D"; + sampler->func = "texture1D"; + sampler->texcoords = "texCoords.x"; + break; + case GL_TEXTURE_2D: + sampler->type = "sampler2D"; + sampler->func = "texture2D"; + sampler->texcoords = "texCoords.xy"; + break; + case GL_TEXTURE_3D: + sampler->type = "sampler3D"; + sampler->func = "texture3D"; + sampler->texcoords = "texCoords"; + break; + case GL_TEXTURE_CUBE_MAP: + sampler->type = "samplerCube"; + sampler->func = "textureCube"; + sampler->texcoords = "texCoords"; + break; + case GL_TEXTURE_1D_ARRAY: + sampler->type = "sampler1DARRAY"; + sampler->texcoords = "texCoords.xy"; + break; + case GL_TEXTURE_2D_ARRAY: + sampler->type = "sampler2DARRAY"; + sampler->texcoords = "texCoords"; + break; + default: + /* unexpected texture target */ + return; + } +} + + +static void setup_glsl_generate_mipmap(struct gl_context *ctx, - struct gen_mipmap_state *mipmap) + struct gen_mipmap_state *mipmap, + GLenum target) { struct vertex { GLfloat x, y, tex[3]; }; + struct glsl_sampler sampler; static const char *vs_source = "attribute vec2 position;\n" @@ -3020,14 +3070,17 @@ setup_glsl_generate_mipmap(struct gl_context *ctx, " texCoords = textureCoords;\n" " gl_Position = vec4(position, 0.0, 1.0);\n" "}\n"; - static const char *fs_source = - "uniform sampler2D tex2d;\n" + static const char *fs_template = + "#define SAMPLER_TYPE %s\n" + "#define SAMPLER_FUNCTION %s\n" + "#define TEX_COORDS %s\n" + "uniform SAMPLER_TYPE texSampler;\n" "varying vec3 texCoords;\n" "void main()\n" "{\n" - " gl_FragColor = texture2D(tex2d, texCoords.xy);\n" + " gl_FragColor = SAMPLER_FUNCTION(texSampler, TEX_COORDS);\n" "}\n"; - + static const char *vs_int_source = "#version 130\n" "in vec2 position;\n" @@ -3036,18 +3089,22 @@ setup_glsl_generate_mipmap(struct gl_context *ctx, "void main()\n" "{\n" " texCoords = textureCoords;\n" - " gl_Position = gl_Vertex;\n" + " gl_Position = vec4(position, 0.0, 1.0);\n" "}\n"; - static const char *fs_int_source = + static const char *fs_int_template = "#version 130\n" - "uniform isampler2D tex2d;\n" + "#define SAMPLER_TYPE i%s\n" + "#define TEX_COORDS %s\n" + "uniform SAMPLER_TYPE texSampler;\n" "in vec3 texCoords;\n" "out ivec4 out_color;\n" "\n" "void main()\n" "{\n" - " out_color = texture(tex2d, texCoords.xy);\n" + " out_color = texture(texSampler, TEX_COORDS);\n" "}\n"; + char *fs_source, *fs_int_source; + unsigned fs_alloc_len; GLuint vs, fs; /* Check if already initialized */ @@ -3067,6 +3124,15 @@ setup_glsl_generate_mipmap(struct gl_context *ctx, _mesa_VertexAttribPointerARB(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct vertex), OFFSET(tex)); + /* Generate a fragment shader program appropriate for the texture target */ + setup_texture_sampler(target, &sampler); + fs_alloc_len = strlen(fs_template) + strlen(sampler.type) + + strlen(sampler.func) + strlen(sampler.texcoords) + 1; + fs_source = (char *) malloc(fs_alloc_len); + + sprintf(fs_source, fs_template, + sampler.type, sampler.func, sampler.texcoords); + vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_source); fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_source); @@ -3080,9 +3146,20 @@ setup_glsl_generate_mipmap(struct gl_context *ctx, _mesa_EnableVertexAttribArrayARB(0); _mesa_EnableVertexAttribArrayARB(1); link_program_with_debug(ctx, mipmap->ShaderProg); + free(fs_source); if ((_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130) || _mesa_is_gles3(ctx)){ + /* Generate a fragment shader program appropriate for the texture + * target + */ + fs_alloc_len = strlen(fs_int_template) + strlen(sampler.type) + + strlen(sampler.texcoords) + 1; + fs_int_source = (char *) malloc(fs_alloc_len); + + sprintf(fs_int_source, fs_int_template, + sampler.type, sampler.texcoords); + vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source); fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source); @@ -3099,6 +3176,7 @@ setup_glsl_generate_mipmap(struct gl_context *ctx, * BindFragDataLocation to 0. */ link_program_with_debug(ctx, mipmap->IntegerShaderProg); + free(fs_int_source); } } @@ -3172,7 +3250,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, * GenerateMipmap function. */ if (use_glsl_version) { - setup_glsl_generate_mipmap(ctx, mipmap); + setup_glsl_generate_mipmap(ctx, mipmap, target); if (texObj->_IsIntegerFormat) _mesa_UseProgramObjectARB(mipmap->IntegerShaderProg); -- 1.7.7.6 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev