i965: Convert CC state on gen4-5 to genxml.
Use set_blend_entry_bits and set_depth_stencil_bits to fill most of the color calc struct, and then manually update the rest. v2: - Always check for depth_irb (Ken) - Always set Backface Stencil Ref (Ken) - Always set alpha reference value (Ken) Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -39,180 +39,6 @@
|
||||
#include "main/stencil.h"
|
||||
#include "intel_batchbuffer.h"
|
||||
|
||||
/**
|
||||
* Modify blend function to force destination alpha to 1.0
|
||||
*
|
||||
* If \c function specifies a blend function that uses destination alpha,
|
||||
* replace it with a function that hard-wires destination alpha to 1.0. This
|
||||
* is used when rendering to xRGB targets.
|
||||
*/
|
||||
GLenum
|
||||
brw_fix_xRGB_alpha(GLenum function)
|
||||
{
|
||||
switch (function) {
|
||||
case GL_DST_ALPHA:
|
||||
return GL_ONE;
|
||||
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
case GL_SRC_ALPHA_SATURATE:
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a CC unit packet from the current blend state.
|
||||
*/
|
||||
static void upload_cc_unit(struct brw_context *brw)
|
||||
{
|
||||
struct gl_context *ctx = &brw->ctx;
|
||||
struct brw_cc_unit_state *cc;
|
||||
|
||||
cc = brw_state_batch(brw, sizeof(*cc), 64, &brw->cc.state_offset);
|
||||
memset(cc, 0, sizeof(*cc));
|
||||
|
||||
/* _NEW_STENCIL | _NEW_BUFFERS */
|
||||
if (brw->stencil_enabled) {
|
||||
const unsigned back = ctx->Stencil._BackFace;
|
||||
|
||||
cc->cc0.stencil_enable = 1;
|
||||
cc->cc0.stencil_func =
|
||||
intel_translate_compare_func(ctx->Stencil.Function[0]);
|
||||
cc->cc0.stencil_fail_op =
|
||||
intel_translate_stencil_op(ctx->Stencil.FailFunc[0]);
|
||||
cc->cc0.stencil_pass_depth_fail_op =
|
||||
intel_translate_stencil_op(ctx->Stencil.ZFailFunc[0]);
|
||||
cc->cc0.stencil_pass_depth_pass_op =
|
||||
intel_translate_stencil_op(ctx->Stencil.ZPassFunc[0]);
|
||||
cc->cc1.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
|
||||
cc->cc1.stencil_write_mask = ctx->Stencil.WriteMask[0];
|
||||
cc->cc1.stencil_test_mask = ctx->Stencil.ValueMask[0];
|
||||
|
||||
if (brw->stencil_two_sided) {
|
||||
cc->cc0.bf_stencil_enable = 1;
|
||||
cc->cc0.bf_stencil_func =
|
||||
intel_translate_compare_func(ctx->Stencil.Function[back]);
|
||||
cc->cc0.bf_stencil_fail_op =
|
||||
intel_translate_stencil_op(ctx->Stencil.FailFunc[back]);
|
||||
cc->cc0.bf_stencil_pass_depth_fail_op =
|
||||
intel_translate_stencil_op(ctx->Stencil.ZFailFunc[back]);
|
||||
cc->cc0.bf_stencil_pass_depth_pass_op =
|
||||
intel_translate_stencil_op(ctx->Stencil.ZPassFunc[back]);
|
||||
cc->cc1.bf_stencil_ref = _mesa_get_stencil_ref(ctx, back);
|
||||
cc->cc2.bf_stencil_write_mask = ctx->Stencil.WriteMask[back];
|
||||
cc->cc2.bf_stencil_test_mask = ctx->Stencil.ValueMask[back];
|
||||
}
|
||||
|
||||
/* Not really sure about this:
|
||||
*/
|
||||
if (ctx->Stencil.WriteMask[0] ||
|
||||
(brw->stencil_two_sided && ctx->Stencil.WriteMask[back]))
|
||||
cc->cc0.stencil_write_enable = 1;
|
||||
}
|
||||
|
||||
/* _NEW_COLOR */
|
||||
if (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY) {
|
||||
cc->cc2.logicop_enable = 1;
|
||||
cc->cc5.logicop_func = intel_translate_logic_op(ctx->Color.LogicOp);
|
||||
} else if (ctx->Color.BlendEnabled && !ctx->Color._AdvancedBlendMode) {
|
||||
GLenum eqRGB = ctx->Color.Blend[0].EquationRGB;
|
||||
GLenum eqA = ctx->Color.Blend[0].EquationA;
|
||||
GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
|
||||
GLenum dstRGB = ctx->Color.Blend[0].DstRGB;
|
||||
GLenum srcA = ctx->Color.Blend[0].SrcA;
|
||||
GLenum dstA = ctx->Color.Blend[0].DstA;
|
||||
|
||||
if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
|
||||
srcRGB = dstRGB = GL_ONE;
|
||||
}
|
||||
|
||||
if (eqA == GL_MIN || eqA == GL_MAX) {
|
||||
srcA = dstA = GL_ONE;
|
||||
}
|
||||
|
||||
/* If the renderbuffer is XRGB, we have to frob the blend function to
|
||||
* force the destination alpha to 1.0. This means replacing GL_DST_ALPHA
|
||||
* with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO.
|
||||
*/
|
||||
const struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
|
||||
if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat,
|
||||
GL_TEXTURE_ALPHA_TYPE)) {
|
||||
srcRGB = brw_fix_xRGB_alpha(srcRGB);
|
||||
srcA = brw_fix_xRGB_alpha(srcA);
|
||||
dstRGB = brw_fix_xRGB_alpha(dstRGB);
|
||||
dstA = brw_fix_xRGB_alpha(dstA);
|
||||
}
|
||||
|
||||
cc->cc6.dest_blend_factor = brw_translate_blend_factor(dstRGB);
|
||||
cc->cc6.src_blend_factor = brw_translate_blend_factor(srcRGB);
|
||||
cc->cc6.blend_function = brw_translate_blend_equation(eqRGB);
|
||||
|
||||
cc->cc5.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
|
||||
cc->cc5.ia_src_blend_factor = brw_translate_blend_factor(srcA);
|
||||
cc->cc5.ia_blend_function = brw_translate_blend_equation(eqA);
|
||||
|
||||
cc->cc3.blend_enable = 1;
|
||||
cc->cc3.ia_blend_enable = (srcA != srcRGB ||
|
||||
dstA != dstRGB ||
|
||||
eqA != eqRGB);
|
||||
}
|
||||
|
||||
/* _NEW_BUFFERS */
|
||||
if (ctx->Color.AlphaEnabled && ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
|
||||
cc->cc3.alpha_test = 1;
|
||||
cc->cc3.alpha_test_func =
|
||||
intel_translate_compare_func(ctx->Color.AlphaFunc);
|
||||
cc->cc3.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
|
||||
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(cc->cc7.alpha_ref.ub[0], ctx->Color.AlphaRef);
|
||||
}
|
||||
|
||||
if (ctx->Color.DitherFlag) {
|
||||
cc->cc5.dither_enable = 1;
|
||||
cc->cc6.y_dither_offset = 0;
|
||||
cc->cc6.x_dither_offset = 0;
|
||||
}
|
||||
|
||||
/* _NEW_DEPTH */
|
||||
if (ctx->Depth.Test) {
|
||||
cc->cc2.depth_test = 1;
|
||||
cc->cc2.depth_test_function =
|
||||
intel_translate_compare_func(ctx->Depth.Func);
|
||||
cc->cc2.depth_write_enable = brw_depth_writes_enabled(brw);
|
||||
}
|
||||
|
||||
if (brw->stats_wm)
|
||||
cc->cc5.statistics_enable = 1;
|
||||
|
||||
/* BRW_NEW_CC_VP */
|
||||
cc->cc4.cc_viewport_state_offset = (brw->batch.bo->offset64 +
|
||||
brw->cc.vp_offset) >> 5; /* reloc */
|
||||
|
||||
brw->ctx.NewDriverState |= BRW_NEW_GEN4_UNIT_STATE;
|
||||
|
||||
/* Emit CC viewport relocation */
|
||||
brw_emit_reloc(&brw->batch,
|
||||
(brw->cc.state_offset +
|
||||
offsetof(struct brw_cc_unit_state, cc4)),
|
||||
brw->batch.bo, brw->cc.vp_offset,
|
||||
I915_GEM_DOMAIN_INSTRUCTION, 0);
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_cc_unit = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_BUFFERS |
|
||||
_NEW_COLOR |
|
||||
_NEW_DEPTH |
|
||||
_NEW_STENCIL,
|
||||
.brw = BRW_NEW_BATCH |
|
||||
BRW_NEW_BLORP |
|
||||
BRW_NEW_CC_VP |
|
||||
BRW_NEW_STATS_WM,
|
||||
},
|
||||
.emit = upload_cc_unit,
|
||||
};
|
||||
|
||||
static void upload_blend_constant_color(struct brw_context *brw)
|
||||
{
|
||||
struct gl_context *ctx = &brw->ctx;
|
||||
|
@@ -42,7 +42,6 @@ extern "C" {
|
||||
enum intel_msaa_layout;
|
||||
|
||||
extern const struct brw_tracked_state brw_blend_constant_color;
|
||||
extern const struct brw_tracked_state brw_cc_unit;
|
||||
extern const struct brw_tracked_state brw_clip_unit;
|
||||
extern const struct brw_tracked_state brw_vs_pull_constants;
|
||||
extern const struct brw_tracked_state brw_tcs_pull_constants;
|
||||
|
@@ -180,98 +180,6 @@ struct brw_clip_unit_state
|
||||
float viewport_ymax;
|
||||
};
|
||||
|
||||
struct brw_cc_unit_state
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned pad0:3;
|
||||
unsigned bf_stencil_pass_depth_pass_op:3;
|
||||
unsigned bf_stencil_pass_depth_fail_op:3;
|
||||
unsigned bf_stencil_fail_op:3;
|
||||
unsigned bf_stencil_func:3;
|
||||
unsigned bf_stencil_enable:1;
|
||||
unsigned pad1:2;
|
||||
unsigned stencil_write_enable:1;
|
||||
unsigned stencil_pass_depth_pass_op:3;
|
||||
unsigned stencil_pass_depth_fail_op:3;
|
||||
unsigned stencil_fail_op:3;
|
||||
unsigned stencil_func:3;
|
||||
unsigned stencil_enable:1;
|
||||
} cc0;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned bf_stencil_ref:8;
|
||||
unsigned stencil_write_mask:8;
|
||||
unsigned stencil_test_mask:8;
|
||||
unsigned stencil_ref:8;
|
||||
} cc1;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned logicop_enable:1;
|
||||
unsigned pad0:10;
|
||||
unsigned depth_write_enable:1;
|
||||
unsigned depth_test_function:3;
|
||||
unsigned depth_test:1;
|
||||
unsigned bf_stencil_write_mask:8;
|
||||
unsigned bf_stencil_test_mask:8;
|
||||
} cc2;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned pad0:8;
|
||||
unsigned alpha_test_func:3;
|
||||
unsigned alpha_test:1;
|
||||
unsigned blend_enable:1;
|
||||
unsigned ia_blend_enable:1;
|
||||
unsigned pad1:1;
|
||||
unsigned alpha_test_format:1;
|
||||
unsigned pad2:16;
|
||||
} cc3;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned pad0:5;
|
||||
unsigned cc_viewport_state_offset:27; /* Offset from GENERAL_STATE_BASE */
|
||||
} cc4;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned pad0:2;
|
||||
unsigned ia_dest_blend_factor:5;
|
||||
unsigned ia_src_blend_factor:5;
|
||||
unsigned ia_blend_function:3;
|
||||
unsigned statistics_enable:1;
|
||||
unsigned logicop_func:4;
|
||||
unsigned pad1:11;
|
||||
unsigned dither_enable:1;
|
||||
} cc5;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned clamp_post_alpha_blend:1;
|
||||
unsigned clamp_pre_alpha_blend:1;
|
||||
unsigned clamp_range:2;
|
||||
unsigned pad0:11;
|
||||
unsigned y_dither_offset:2;
|
||||
unsigned x_dither_offset:2;
|
||||
unsigned dest_blend_factor:5;
|
||||
unsigned src_blend_factor:5;
|
||||
unsigned blend_function:3;
|
||||
} cc6;
|
||||
|
||||
struct {
|
||||
union {
|
||||
float f;
|
||||
uint8_t ub[4];
|
||||
} alpha_ref;
|
||||
} cc7;
|
||||
};
|
||||
|
||||
struct brw_gs_unit_state
|
||||
{
|
||||
struct thread0 thread0;
|
||||
|
@@ -38,7 +38,6 @@
|
||||
|
||||
extern GLuint brw_translate_blend_factor( GLenum factor );
|
||||
extern GLuint brw_translate_blend_equation( GLenum mode );
|
||||
extern GLenum brw_fix_xRGB_alpha(GLenum function);
|
||||
|
||||
static inline float
|
||||
brw_get_line_width(struct brw_context *brw)
|
||||
|
@@ -1217,7 +1217,7 @@ set_depth_stencil_bits(struct brw_context *brw, DEPTH_STENCIL_GENXML *ds)
|
||||
intel_translate_stencil_op(stencil->ZFailFunc[b]);
|
||||
}
|
||||
|
||||
#if GEN_GEN >= 9
|
||||
#if GEN_GEN <= 5 || GEN_GEN >= 9
|
||||
ds->StencilReferenceValue = _mesa_get_stencil_ref(ctx, 0);
|
||||
ds->BackfaceStencilReferenceValue = _mesa_get_stencil_ref(ctx, b);
|
||||
#endif
|
||||
@@ -2530,6 +2530,28 @@ fix_dual_blend_alpha_to_one(GLenum function)
|
||||
#define blend_factor(x) brw_translate_blend_factor(x)
|
||||
#define blend_eqn(x) brw_translate_blend_equation(x)
|
||||
|
||||
/**
|
||||
* Modify blend function to force destination alpha to 1.0
|
||||
*
|
||||
* If \c function specifies a blend function that uses destination alpha,
|
||||
* replace it with a function that hard-wires destination alpha to 1.0. This
|
||||
* is used when rendering to xRGB targets.
|
||||
*/
|
||||
static GLenum
|
||||
brw_fix_xRGB_alpha(GLenum function)
|
||||
{
|
||||
switch (function) {
|
||||
case GL_DST_ALPHA:
|
||||
return GL_ONE;
|
||||
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
case GL_SRC_ALPHA_SATURATE:
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
#if GEN_GEN >= 6
|
||||
typedef struct GENX(BLEND_STATE_ENTRY) BLEND_ENTRY_GENXML;
|
||||
#else
|
||||
@@ -2555,6 +2577,9 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i,
|
||||
*/
|
||||
const bool integer = ctx->DrawBuffer->_IntegerBuffers & (0x1 << i);
|
||||
|
||||
const unsigned blend_enabled = GEN_GEN >= 6 ?
|
||||
ctx->Color.BlendEnabled & (1 << i) : ctx->Color.BlendEnabled;
|
||||
|
||||
/* _NEW_COLOR */
|
||||
if (ctx->Color.ColorLogicOpEnabled) {
|
||||
GLenum rb_type = rb ? _mesa_get_format_datatype(rb->Format)
|
||||
@@ -2570,8 +2595,8 @@ set_blend_entry_bits(struct brw_context *brw, BLEND_ENTRY_GENXML *entry, int i,
|
||||
entry->LogicOpFunction =
|
||||
intel_translate_logic_op(ctx->Color.LogicOp);
|
||||
}
|
||||
} else if (ctx->Color.BlendEnabled & (1 << i) && !integer &&
|
||||
!ctx->Color._AdvancedBlendMode) {
|
||||
} else if (blend_enabled && !ctx->Color._AdvancedBlendMode
|
||||
&& (GEN_GEN <= 5 || !integer)) {
|
||||
GLenum eqRGB = ctx->Color.Blend[i].EquationRGB;
|
||||
GLenum eqA = ctx->Color.Blend[i].EquationA;
|
||||
GLenum srcRGB = ctx->Color.Blend[i].SrcRGB;
|
||||
@@ -2997,53 +3022,80 @@ static const struct brw_tracked_state genX(multisample_state) = {
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
#if GEN_GEN >= 6
|
||||
static void
|
||||
genX(upload_color_calc_state)(struct brw_context *brw)
|
||||
{
|
||||
struct gl_context *ctx = &brw->ctx;
|
||||
|
||||
brw_state_emit(brw, GENX(COLOR_CALC_STATE), 64, &brw->cc.state_offset, cc) {
|
||||
#if GEN_GEN <= 5
|
||||
cc.IndependentAlphaBlendEnable =
|
||||
set_blend_entry_bits(brw, &cc, 0, false);
|
||||
set_depth_stencil_bits(brw, &cc);
|
||||
|
||||
if (ctx->Color.AlphaEnabled &&
|
||||
ctx->DrawBuffer->_NumColorDrawBuffers <= 1) {
|
||||
cc.AlphaTestEnable = true;
|
||||
cc.AlphaTestFunction =
|
||||
intel_translate_compare_func(ctx->Color.AlphaFunc);
|
||||
}
|
||||
|
||||
cc.ColorDitherEnable = ctx->Color.DitherFlag;
|
||||
|
||||
cc.StatisticsEnable = brw->stats_wm;
|
||||
|
||||
cc.CCViewportStatePointer =
|
||||
instruction_ro_bo(brw->batch.bo, brw->cc.vp_offset);
|
||||
#else
|
||||
/* _NEW_COLOR */
|
||||
cc.AlphaTestFormat = ALPHATEST_UNORM8;
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
|
||||
ctx->Color.AlphaRef);
|
||||
cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
|
||||
cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
|
||||
cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
|
||||
cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
|
||||
|
||||
#if GEN_GEN < 9
|
||||
/* _NEW_STENCIL */
|
||||
cc.StencilReferenceValue = _mesa_get_stencil_ref(ctx, 0);
|
||||
cc.BackfaceStencilReferenceValue =
|
||||
_mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* _NEW_COLOR */
|
||||
cc.BlendConstantColorRed = ctx->Color.BlendColorUnclamped[0];
|
||||
cc.BlendConstantColorGreen = ctx->Color.BlendColorUnclamped[1];
|
||||
cc.BlendConstantColorBlue = ctx->Color.BlendColorUnclamped[2];
|
||||
cc.BlendConstantColorAlpha = ctx->Color.BlendColorUnclamped[3];
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(cc.AlphaReferenceValueAsUNORM8,
|
||||
ctx->Color.AlphaRef);
|
||||
}
|
||||
|
||||
#if GEN_GEN >= 6
|
||||
brw_batch_emit(brw, GENX(3DSTATE_CC_STATE_POINTERS), ptr) {
|
||||
ptr.ColorCalcStatePointer = brw->cc.state_offset;
|
||||
#if GEN_GEN != 7
|
||||
ptr.ColorCalcStatePointerValid = true;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
brw->ctx.NewDriverState |= BRW_NEW_GEN4_UNIT_STATE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct brw_tracked_state genX(color_calc_state) = {
|
||||
.dirty = {
|
||||
.mesa = _NEW_COLOR |
|
||||
_NEW_STENCIL,
|
||||
_NEW_STENCIL |
|
||||
(GEN_GEN <= 5 ? _NEW_BUFFERS |
|
||||
_NEW_DEPTH
|
||||
: 0),
|
||||
.brw = BRW_NEW_BATCH |
|
||||
BRW_NEW_BLORP |
|
||||
BRW_NEW_CC_STATE |
|
||||
BRW_NEW_STATE_BASE_ADDRESS,
|
||||
(GEN_GEN <= 5 ? BRW_NEW_CC_VP |
|
||||
BRW_NEW_STATS_WM
|
||||
: BRW_NEW_CC_STATE |
|
||||
BRW_NEW_STATE_BASE_ADDRESS),
|
||||
},
|
||||
.emit = genX(upload_color_calc_state),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
@@ -4924,7 +4976,7 @@ genX(init_atoms)(struct brw_context *brw)
|
||||
&brw_recalculate_urb_fence,
|
||||
|
||||
&genX(cc_vp),
|
||||
&brw_cc_unit,
|
||||
&genX(color_calc_state),
|
||||
|
||||
/* Surface state setup. Must come before the VS/WM unit. The binding
|
||||
* table upload must be last.
|
||||
|
Reference in New Issue
Block a user