diff options
Diffstat (limited to 'src/gallium/drivers/i915')
-rw-r--r-- | src/gallium/drivers/i915/i915_state.c | 15 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_state_emit.c | 85 | ||||
-rw-r--r-- | src/gallium/drivers/i915/i915_state_static.c | 28 |
3 files changed, 90 insertions, 38 deletions
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 06d4d3bd1af..8ca69fc790e 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -94,7 +94,6 @@ static unsigned translate_mip_filter( unsigned filter ) } } - /* None of this state is actually used for anything yet. */ static void * @@ -117,10 +116,10 @@ i915_create_blend_state(struct pipe_context *pipe, */ if (srcA != srcRGB || - dstA != dstRGB || - eqA != eqRGB) { + dstA != dstRGB || + eqA != eqRGB) { - cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | IAB_ENABLE | IAB_MODIFY_FUNC | @@ -131,7 +130,7 @@ i915_create_blend_state(struct pipe_context *pipe, (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT)); } else { - cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | + cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | 0); } @@ -147,7 +146,7 @@ i915_create_blend_state(struct pipe_context *pipe, if (blend->dither) cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; - /* XXX here take the target fixup into account */ + /* We potentially do some fixup at emission for non-BGRA targets */ if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_RED; @@ -276,7 +275,7 @@ i915_create_sampler_state(struct pipe_context *pipe, maxlod = CLAMP(maxlod, 0, 16 * 11); if (minlod > maxlod) - maxlod = minlod; + maxlod = minlod; cso->minlod = minlod; cso->maxlod = maxlod; @@ -499,7 +498,7 @@ i915_create_depth_stencil_state(struct pipe_context *pipe, (func << S6_DEPTH_TEST_FUNC_SHIFT)); if (depth_stencil->depth.writemask) - cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE; + cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE; } if (depth_stencil->alpha.enabled) { diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 554e967fcc0..9c16e590003 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -128,6 +128,70 @@ validate_immediate(struct i915_context *i915, unsigned *batch_space) *batch_space = 1 + util_bitcount(dirty); } +static uint target_fixup(struct pipe_surface *p, int component) +{ + const struct + { + enum pipe_format format; + uint hw_mask[4]; + } fixup_mask[] = { + { PIPE_FORMAT_R8G8B8A8_UNORM, { S5_WRITEDISABLE_BLUE, S5_WRITEDISABLE_GREEN, S5_WRITEDISABLE_RED, S5_WRITEDISABLE_ALPHA}}, + { PIPE_FORMAT_R8G8B8X8_UNORM, { S5_WRITEDISABLE_BLUE, S5_WRITEDISABLE_GREEN, S5_WRITEDISABLE_RED, S5_WRITEDISABLE_ALPHA}}, + { PIPE_FORMAT_L8_UNORM, { S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | S5_WRITEDISABLE_BLUE, 0, 0, S5_WRITEDISABLE_ALPHA}}, + { PIPE_FORMAT_I8_UNORM, { S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | S5_WRITEDISABLE_BLUE, 0, 0, S5_WRITEDISABLE_ALPHA}}, + { PIPE_FORMAT_A8_UNORM, { 0, 0, 0, S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA}}, + { 0, { S5_WRITEDISABLE_RED, S5_WRITEDISABLE_GREEN, S5_WRITEDISABLE_BLUE, S5_WRITEDISABLE_ALPHA}} + }; + int i = sizeof(fixup_mask) / sizeof(*fixup_mask); + + if (p) + for(i = 0; fixup_mask[i].format != 0; i++) + if (p->format == fixup_mask[i].format) + return fixup_mask[i].hw_mask[component]; + + /* Just return default masks */ + return fixup_mask[i].hw_mask[component]; +} + +static void emit_immediate_s5(struct i915_context *i915, uint imm) +{ + /* Fixup write mask for non-BGRA render targets */ + uint fixup_imm = imm & ~( S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | + S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA ); + struct pipe_surface *surf = i915->framebuffer.cbufs[0]; + + if (imm & S5_WRITEDISABLE_RED) + fixup_imm |= target_fixup(surf, 0); + if (imm & S5_WRITEDISABLE_GREEN) + fixup_imm |= target_fixup(surf, 1); + if (imm & S5_WRITEDISABLE_BLUE) + fixup_imm |= target_fixup(surf, 2); + if (imm & S5_WRITEDISABLE_ALPHA) + fixup_imm |= target_fixup(surf, 3); + + OUT_BATCH(fixup_imm); +} + +static void emit_immediate_s6(struct i915_context *i915, uint imm) +{ + /* Fixup blend function for A8 dst buffers. + * When we blend to an A8 buffer, the GPU thinks it's a G8 buffer, + * and therefore we need to use the color factor for alphas. */ + uint srcRGB; + + if (i915->current.target_fixup_format == PIPE_FORMAT_A8_UNORM) { + srcRGB = (imm >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK; + if (srcRGB == BLENDFACT_DST_ALPHA) + srcRGB = BLENDFACT_DST_COLR; + else if (srcRGB == BLENDFACT_INV_DST_ALPHA) + srcRGB = BLENDFACT_INV_DST_COLR; + imm &= ~SRC_BLND_FACT(BLENDFACT_MASK); + imm |= SRC_BLND_FACT(srcRGB); + } + + OUT_BATCH(imm); +} + static void emit_immediate(struct i915_context *i915) { @@ -153,23 +217,12 @@ emit_immediate(struct i915_context *i915) for (i = 1; i < I915_MAX_IMMEDIATE; i++) { if (dirty & (1 << i)) { - /* Fixup blend function for A8 dst buffers. - * When we blend to an A8 buffer, the GPU thinks it's a G8 buffer, - * and therefore we need to use the color factor for alphas. */ - if ((i == I915_IMMEDIATE_S6) && - (i915->current.target_fixup_format == PIPE_FORMAT_A8_UNORM)) { - uint32_t imm = i915->current.immediate[i]; - uint32_t srcRGB = (imm >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK; - if (srcRGB == BLENDFACT_DST_ALPHA) - srcRGB = BLENDFACT_DST_COLR; - else if (srcRGB == BLENDFACT_INV_DST_ALPHA) - srcRGB = BLENDFACT_INV_DST_COLR; - imm &= ~SRC_BLND_FACT(BLENDFACT_MASK); - imm |= SRC_BLND_FACT(srcRGB); - OUT_BATCH(imm); - } else { + if (i == I915_IMMEDIATE_S5) + emit_immediate_s5(i915, i915->current.immediate[i]); + else if (i == I915_IMMEDIATE_S6) + emit_immediate_s6(i915, i915->current.immediate[i]); + else OUT_BATCH(i915->current.immediate[i]); - } } } } diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index 41fe2225060..9a7ea227ecf 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -163,28 +163,28 @@ struct i915_tracked_state i915_hw_framebuffer = { I915_NEW_FRAMEBUFFER }; -static const struct -{ - enum pipe_format format; - uint hw_swizzle; -} fixup_formats[] = { - { PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */}, - { PIPE_FORMAT_R8G8B8X8_UNORM, 0x21030000 /* BGRX */}, - { PIPE_FORMAT_L8_UNORM, 0x00030000 /* RRRA */}, - { PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */}, - { PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */}, - { PIPE_FORMAT_NONE, 0x00000000}, -}; - static uint32_t need_target_fixup(struct pipe_surface* p, uint32_t *fixup) { + const struct + { + enum pipe_format format; + uint hw_swizzle; + } fixup_formats[] = { + { PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */}, + { PIPE_FORMAT_R8G8B8X8_UNORM, 0x21030000 /* BGRX */}, + { PIPE_FORMAT_L8_UNORM, 0x00030000 /* RRRA */}, + { PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */}, + { PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */}, + { PIPE_FORMAT_NONE, 0x00000000}, + }; + enum pipe_format f; /* if we don't have a surface bound yet, we don't need to fixup the shader */ if (!p) return 0; f = p->format; - for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) + for(int i = 0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) if (fixup_formats[i].format == f) { *fixup = fixup_formats[i].hw_swizzle; return f; |