From: Marek Olšák <marek.ol...@amd.com> Fixes piglit: spec@glsl-1.30@execution@fs-texture-sampler2dshadow-10 spec@glsl-1.30@execution@fs-texture-sampler2dshadow-11
v2: use st_shader_stage_to_ptarget --- src/mesa/state_tracker/st_atom_texture.c | 74 +++++++++++++++++++++--------- src/mesa/state_tracker/st_context.h | 23 ++++++++++ src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 27 +---------- 3 files changed, 77 insertions(+), 47 deletions(-) diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index ba3cf9b..4012d88 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -103,7 +103,8 @@ swizzle_swizzle(unsigned swizzle1, unsigned swizzle2) */ static unsigned compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode, - enum pipe_format actualFormat) + enum pipe_format actualFormat, + unsigned glsl_version) { switch (baseFormat) { case GL_RGBA: @@ -157,8 +158,26 @@ compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode, case GL_INTENSITY: return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X); case GL_ALPHA: - return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, - SWIZZLE_ZERO, SWIZZLE_X); + /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore + * the depth mode and return float, while older shadow* functions + * and ARB_fp instructions return vec4 according to the depth mode. + * + * The problem with the GLSL 1.30 functions is that GL_ALPHA forces + * them to return 0, breaking them completely. + * + * A proper fix would increase code complexity and that's not worth + * it for a rarely used feature such as the GL_ALPHA depth mode + * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all + * shaders that use GLSL 1.30 or later. + * + * BTW, it's required that sampler views are updated when + * shaders change (check_sampler_swizzle takes care of that). + */ + if (glsl_version && glsl_version >= 130) + return SWIZZLE_XXXX; + else + return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, + SWIZZLE_ZERO, SWIZZLE_X); case GL_RED: return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE); @@ -174,7 +193,8 @@ compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode, static unsigned -get_texture_format_swizzle(const struct st_texture_object *stObj) +get_texture_format_swizzle(const struct st_texture_object *stObj, + unsigned glsl_version) { GLenum baseFormat = _mesa_texture_base_format(&stObj->base); unsigned tex_swizzle; @@ -182,7 +202,8 @@ get_texture_format_swizzle(const struct st_texture_object *stObj) if (baseFormat != GL_NONE) { tex_swizzle = compute_texture_format_swizzle(baseFormat, stObj->base.DepthMode, - stObj->pt->format); + stObj->pt->format, + glsl_version); } else { tex_swizzle = SWIZZLE_XYZW; @@ -201,9 +222,9 @@ get_texture_format_swizzle(const struct st_texture_object *stObj) */ static boolean check_sampler_swizzle(const struct st_texture_object *stObj, - struct pipe_sampler_view *sv) + struct pipe_sampler_view *sv, unsigned glsl_version) { - unsigned swizzle = get_texture_format_swizzle(stObj); + unsigned swizzle = get_texture_format_swizzle(stObj, glsl_version); return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) || (sv->swizzle_g != GET_SWZ(swizzle, 1)) || @@ -233,10 +254,11 @@ static struct pipe_sampler_view * st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe, struct st_texture_object *stObj, const struct gl_sampler_object *samp, - enum pipe_format format) + enum pipe_format format, + unsigned glsl_version) { struct pipe_sampler_view templ; - unsigned swizzle = get_texture_format_swizzle(stObj); + unsigned swizzle = get_texture_format_swizzle(stObj, glsl_version); u_sampler_view_default_template(&templ, stObj->pt, @@ -284,7 +306,8 @@ static struct pipe_sampler_view * st_get_texture_sampler_view_from_stobj(struct st_context *st, struct st_texture_object *stObj, const struct gl_sampler_object *samp, - enum pipe_format format) + enum pipe_format format, + unsigned glsl_version) { struct pipe_sampler_view **sv; const struct st_texture_image *firstImage; @@ -306,7 +329,7 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, /* if sampler view has changed dereference it */ if (*sv) { - if (check_sampler_swizzle(stObj, *sv) || + if (check_sampler_swizzle(stObj, *sv, glsl_version) || (format != (*sv)->format) || gl_target_to_pipe(stObj->base.Target) != (*sv)->target || stObj->base.MinLevel + stObj->base.BaseLevel != (*sv)->u.tex.first_level || @@ -318,7 +341,8 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, } if (!*sv) { - *sv = st_create_texture_sampler_view_from_stobj(st->pipe, stObj, samp, format); + *sv = st_create_texture_sampler_view_from_stobj(st->pipe, stObj, samp, + format, glsl_version); } else if ((*sv)->context != st->pipe) { /* Recreate view in correct context, use existing view as template */ @@ -334,7 +358,7 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st, static GLboolean update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_view, - GLuint texUnit) + GLuint texUnit, unsigned glsl_version) { struct gl_context *ctx = st->ctx; const struct gl_sampler_object *samp; @@ -374,8 +398,9 @@ update_single_texture(struct st_context *st, } } - *sampler_view = st_get_texture_sampler_view_from_stobj(st, stObj, samp, - view_format); + *sampler_view = + st_get_texture_sampler_view_from_stobj(st, stObj, samp, view_format, + glsl_version); return GL_TRUE; } @@ -383,7 +408,7 @@ update_single_texture(struct st_context *st, static void update_textures(struct st_context *st, - unsigned shader_stage, + gl_shader_stage mesa_shader, const struct gl_program *prog, unsigned max_units, struct pipe_sampler_view **sampler_views, @@ -392,6 +417,10 @@ update_textures(struct st_context *st, const GLuint old_max = *num_textures; GLbitfield samplers_used = prog->SamplersUsed; GLuint unit; + struct gl_shader_program *shader = + st->ctx->_Shader->CurrentProgram[mesa_shader]; + unsigned glsl_version = shader ? shader->Version : 0; + unsigned shader_stage = st_shader_stage_to_ptarget(mesa_shader); if (samplers_used == 0x0 && old_max == 0) return; @@ -406,7 +435,8 @@ update_textures(struct st_context *st, const GLuint texUnit = prog->SamplerUnits[unit]; GLboolean retval; - retval = update_single_texture(st, &sampler_view, texUnit); + retval = update_single_texture(st, &sampler_view, texUnit, + glsl_version); if (retval == GL_FALSE) continue; @@ -435,7 +465,7 @@ update_vertex_textures(struct st_context *st) if (ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits > 0) { update_textures(st, - PIPE_SHADER_VERTEX, + MESA_SHADER_VERTEX, &ctx->VertexProgram._Current->Base, ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_VERTEX], @@ -450,7 +480,7 @@ update_fragment_textures(struct st_context *st) const struct gl_context *ctx = st->ctx; update_textures(st, - PIPE_SHADER_FRAGMENT, + MESA_SHADER_FRAGMENT, &ctx->FragmentProgram._Current->Base, ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_FRAGMENT], @@ -465,7 +495,7 @@ update_geometry_textures(struct st_context *st) if (ctx->GeometryProgram._Current) { update_textures(st, - PIPE_SHADER_GEOMETRY, + MESA_SHADER_GEOMETRY, &ctx->GeometryProgram._Current->Base, ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_GEOMETRY], @@ -481,7 +511,7 @@ update_tessctrl_textures(struct st_context *st) if (ctx->TessCtrlProgram._Current) { update_textures(st, - PIPE_SHADER_TESS_CTRL, + MESA_SHADER_TESS_CTRL, &ctx->TessCtrlProgram._Current->Base, ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_TESS_CTRL], @@ -497,7 +527,7 @@ update_tesseval_textures(struct st_context *st) if (ctx->TessEvalProgram._Current) { update_textures(st, - PIPE_SHADER_TESS_EVAL, + MESA_SHADER_TESS_EVAL, &ctx->TessEvalProgram._Current->Base, ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits, st->state.sampler_views[PIPE_SHADER_TESS_EVAL], diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 8183412..0d89260 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -278,6 +278,29 @@ st_fb_orientation(const struct gl_framebuffer *fb) } +static inline unsigned +st_shader_stage_to_ptarget(gl_shader_stage stage) +{ + switch (stage) { + case MESA_SHADER_VERTEX: + return PIPE_SHADER_VERTEX; + case MESA_SHADER_FRAGMENT: + return PIPE_SHADER_FRAGMENT; + case MESA_SHADER_GEOMETRY: + return PIPE_SHADER_GEOMETRY; + case MESA_SHADER_TESS_CTRL: + return PIPE_SHADER_TESS_CTRL; + case MESA_SHADER_TESS_EVAL: + return PIPE_SHADER_TESS_EVAL; + case MESA_SHADER_COMPUTE: + return PIPE_SHADER_COMPUTE; + } + + assert(!"should not be reached"); + return PIPE_SHADER_VERTEX; +} + + /** clear-alloc a struct-sized object, with casting */ #define ST_CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T)) diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 905d661..4c6e48a 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -5693,29 +5693,6 @@ out: /* ----------------------------- End TGSI code ------------------------------ */ -static unsigned -shader_stage_to_ptarget(gl_shader_stage stage) -{ - switch (stage) { - case MESA_SHADER_VERTEX: - return PIPE_SHADER_VERTEX; - case MESA_SHADER_FRAGMENT: - return PIPE_SHADER_FRAGMENT; - case MESA_SHADER_GEOMETRY: - return PIPE_SHADER_GEOMETRY; - case MESA_SHADER_TESS_CTRL: - return PIPE_SHADER_TESS_CTRL; - case MESA_SHADER_TESS_EVAL: - return PIPE_SHADER_TESS_EVAL; - case MESA_SHADER_COMPUTE: - return PIPE_SHADER_COMPUTE; - } - - assert(!"should not be reached"); - return PIPE_SHADER_VERTEX; -} - - /** * Convert a shader's GLSL IR into a Mesa gl_program, although without * generating Mesa IR. @@ -5732,7 +5709,7 @@ get_mesa_program(struct gl_context *ctx, struct gl_shader_compiler_options *options = &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader->Type)]; struct pipe_screen *pscreen = ctx->st->pipe->screen; - unsigned ptarget = shader_stage_to_ptarget(shader->Stage); + unsigned ptarget = st_shader_stage_to_ptarget(shader->Stage); validate_ir_tree(shader->ir); @@ -5921,7 +5898,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(prog->_LinkedShaders[i]->Type); const struct gl_shader_compiler_options *options = &ctx->Const.ShaderCompilerOptions[stage]; - unsigned ptarget = shader_stage_to_ptarget(stage); + unsigned ptarget = st_shader_stage_to_ptarget(stage); bool have_dround = pscreen->get_shader_param(pscreen, ptarget, PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED); bool have_dfrexp = pscreen->get_shader_param(pscreen, ptarget, -- 2.1.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev