st/mesa: fix GLSL 1.30 texture shadow functions with the GL_ALPHA depth mode (v2)

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

Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Marek Olšák 2015-07-23 21:57:19 +02:00
parent 82546729e3
commit 768b4a25b9
3 changed files with 77 additions and 47 deletions

View file

@ -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)) ||
@ -232,10 +253,11 @@ static unsigned last_layer(struct st_texture_object *stObj)
static struct pipe_sampler_view *
st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
struct st_texture_object *stObj,
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,
@ -282,7 +304,8 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
static struct pipe_sampler_view *
st_get_texture_sampler_view_from_stobj(struct st_context *st,
struct st_texture_object *stObj,
enum pipe_format format)
enum pipe_format format,
unsigned glsl_version)
{
struct pipe_sampler_view **sv;
const struct st_texture_image *firstImage;
@ -304,7 +327,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 ||
@ -316,7 +339,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, format);
*sv = st_create_texture_sampler_view_from_stobj(st->pipe, stObj,
format, glsl_version);
} else if ((*sv)->context != st->pipe) {
/* Recreate view in correct context, use existing view as template */
@ -332,7 +356,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;
@ -372,8 +396,9 @@ update_single_texture(struct st_context *st,
}
}
*sampler_view = st_get_texture_sampler_view_from_stobj(st, stObj,
view_format);
*sampler_view =
st_get_texture_sampler_view_from_stobj(st, stObj, view_format,
glsl_version);
return GL_TRUE;
}
@ -381,7 +406,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,
@ -390,6 +415,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;
@ -404,7 +433,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;
@ -433,7 +463,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],
@ -448,7 +478,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],
@ -463,7 +493,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],
@ -479,7 +509,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],
@ -495,7 +525,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],

View file

@ -279,6 +279,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))

View file

@ -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,