diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm.c | 12 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/gen7_wm_surface_state.c | 45 |
2 files changed, 52 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 0f115259867..f8eb54fce1d 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -491,6 +491,8 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx, const struct gl_program *prog, struct brw_sampler_prog_key_data *key) { + struct intel_context *intel = intel_context(ctx); + for (int s = 0; s < MAX_SAMPLERS; s++) { key->swizzles[s] = SWIZZLE_NOOP; @@ -505,7 +507,15 @@ brw_populate_sampler_prog_key_data(struct gl_context *ctx, const struct gl_texture_image *img = t->Image[0][t->BaseLevel]; struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit_id); - key->swizzles[s] = brw_get_texture_swizzle(t); + const bool alpha_depth = t->DepthMode == GL_ALPHA && + (img->_BaseFormat == GL_DEPTH_COMPONENT || + img->_BaseFormat == GL_DEPTH_STENCIL); + + /* Haswell handles texture swizzling as surface format overrides + * (except for GL_ALPHA); all other platforms need MOVs in the shader. + */ + if (!intel->is_haswell || alpha_depth) + key->swizzles[s] = brw_get_texture_swizzle(t); if (img->InternalFormat == GL_YCBCR_MESA) { key->yuvtex_mask |= 1 << s; diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c index 97ae0e2f9a4..dd7b0d4cfe1 100644 --- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c @@ -35,6 +35,32 @@ #include "brw_defines.h" #include "brw_wm.h" +/** + * Convert an swizzle enumeration (i.e. SWIZZLE_X) to one of the Gen7.5+ + * "Shader Channel Select" enumerations (i.e. HSW_SCS_RED) + */ +static unsigned +swizzle_to_scs(GLenum swizzle) +{ + switch (swizzle) { + case SWIZZLE_X: + return HSW_SCS_RED; + case SWIZZLE_Y: + return HSW_SCS_GREEN; + case SWIZZLE_Z: + return HSW_SCS_BLUE; + case SWIZZLE_W: + return HSW_SCS_ALPHA; + case SWIZZLE_ZERO: + return HSW_SCS_ZERO; + case SWIZZLE_ONE: + return HSW_SCS_ONE; + } + + assert(!"Should not get here: invalid swizzle mode"); + return HSW_SCS_ZERO; +} + void gen7_set_surface_tiling(struct gen7_surface_state *surf, uint32_t tiling) { @@ -343,10 +369,21 @@ gen7_update_texture_surface(struct gl_context *ctx, */ if (brw->intel.is_haswell) { - surf->ss7.shader_channel_select_r = HSW_SCS_RED; - surf->ss7.shader_channel_select_g = HSW_SCS_GREEN; - surf->ss7.shader_channel_select_b = HSW_SCS_BLUE; - surf->ss7.shader_channel_select_a = HSW_SCS_ALPHA; + /* Handling GL_ALPHA as a surface format override breaks 1.30+ style + * texturing functions that return a float, as our code generation always + * selects the .x channel (which would always be 0). + */ + const bool alpha_depth = tObj->DepthMode == GL_ALPHA && + (firstImage->_BaseFormat == GL_DEPTH_COMPONENT || + firstImage->_BaseFormat == GL_DEPTH_STENCIL); + + const int swizzle = + unlikely(alpha_depth) ? SWIZZLE_XYZW : brw_get_texture_swizzle(tObj); + + surf->ss7.shader_channel_select_r = swizzle_to_scs(GET_SWZ(swizzle, 0)); + surf->ss7.shader_channel_select_g = swizzle_to_scs(GET_SWZ(swizzle, 1)); + surf->ss7.shader_channel_select_b = swizzle_to_scs(GET_SWZ(swizzle, 2)); + surf->ss7.shader_channel_select_a = swizzle_to_scs(GET_SWZ(swizzle, 3)); } /* Emit relocation to surface contents */ |