summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c12
-rw-r--r--src/mesa/drivers/dri/i965/gen7_wm_surface_state.c45
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 */