}
}
-
/* None of this state is actually used for anything yet.
*/
static void *
*/
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 |
(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);
}
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;
maxlod = CLAMP(maxlod, 0, 16 * 11);
if (minlod > maxlod)
- maxlod = minlod;
+ maxlod = minlod;
cso->minlod = minlod;
cso->maxlod = maxlod;
(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) {
*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)
{
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]);
- }
}
}
}
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;