X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fgen6_cc.c;h=6aeaaa253b919f46ee88501387b07067404202cb;hb=caa4ae5d7d864278ffbf5dbd9c25bb2932e91fc5;hp=2b16d6cdc019b2a9f509c3dd975b6f753ded13c1;hpb=10370b752cd793665feec9494e6545a3f04c69f9;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c index 2b16d6cdc01..6aeaaa253b9 100644 --- a/src/mesa/drivers/dri/i965/gen6_cc.c +++ b/src/mesa/drivers/dri/i965/gen6_cc.c @@ -33,8 +33,9 @@ #include "main/macros.h" static void -prepare_blend_state(struct brw_context *brw) +gen6_upload_blend_state(struct brw_context *brw) { + bool is_buffer_zero_integer_format = false; struct gl_context *ctx = &brw->intel.ctx; struct gen6_blend_state *blend; int b; @@ -51,30 +52,55 @@ prepare_blend_state(struct brw_context *brw) nr_draw_buffers = 1; size = sizeof(*blend) * nr_draw_buffers; - blend = brw_state_batch(brw, size, 64, &brw->cc.blend_state_offset); + blend = brw_state_batch(brw, AUB_TRACE_BLEND_STATE, + size, 64, &brw->cc.blend_state_offset); memset(blend, 0, size); for (b = 0; b < nr_draw_buffers; b++) { + /* _NEW_BUFFERS */ + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[b]; + GLenum rb_type; + bool integer; + + if (rb) + rb_type = _mesa_get_format_datatype(rb->Format); + else + rb_type = GL_UNSIGNED_NORMALIZED; + + /* Used for implementing the following bit of GL_EXT_texture_integer: + * "Per-fragment operations that require floating-point color + * components, including multisample alpha operations, alpha test, + * blending, and dithering, have no effect when the corresponding + * colors are written to an integer color buffer." + */ + integer = (rb_type == GL_INT || rb_type == GL_UNSIGNED_INT); + + if(b == 0 && integer) + is_buffer_zero_integer_format = true; + /* _NEW_COLOR */ - if (ctx->Color._LogicOpEnabled) { - struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[b]; - /* _NEW_BUFFERS */ + if (ctx->Color.ColorLogicOpEnabled) { /* Floating point RTs should have no effect from LogicOp, - * except for disabling of blending + * except for disabling of blending. + * + * From the Sandy Bridge PRM, Vol 2 Par 1, Section 8.1.11, "Logic Ops", + * + * "Logic Ops are only supported on *_UNORM surfaces (excluding + * _SRGB variants), otherwise Logic Ops must be DISABLED." */ - if (_mesa_get_format_datatype(rb->Format) != GL_FLOAT) { + if (rb_type == GL_UNSIGNED_NORMALIZED) { blend[b].blend1.logic_op_enable = 1; blend[b].blend1.logic_op_func = intel_translate_logic_op(ctx->Color.LogicOp); } - } else if (ctx->Color.BlendEnabled & (1 << b)) { - 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; + } else if (ctx->Color.BlendEnabled & (1 << b) && !integer) { + GLenum eqRGB = ctx->Color.Blend[b].EquationRGB; + GLenum eqA = ctx->Color.Blend[b].EquationA; + GLenum srcRGB = ctx->Color.Blend[b].SrcRGB; + GLenum dstRGB = ctx->Color.Blend[b].DstRGB; + GLenum srcA = ctx->Color.Blend[b].SrcA; + GLenum dstA = ctx->Color.Blend[b].DstA; if (eqRGB == GL_MIN || eqRGB == GL_MAX) { srcRGB = dstRGB = GL_ONE; @@ -98,9 +124,29 @@ prepare_blend_state(struct brw_context *brw) eqA != eqRGB); } + /* See section 8.1.6 "Pre-Blend Color Clamping" of the + * SandyBridge PRM Volume 2 Part 1 for HW requirements. + * + * We do our ARB_color_buffer_float CLAMP_FRAGMENT_COLOR + * clamping in the fragment shader. For its clamping of + * blending, the spec says: + * + * "RESOLVED: For fixed-point color buffers, the inputs and + * the result of the blending equation are clamped. For + * floating-point color buffers, no clamping occurs." + * + * So, generally, we want clamping to the render target's range. + * And, good news, the hardware tables for both pre- and + * post-blend color clamping are either ignored, or any are + * allowed, or clamping is required but RT range clamping is a + * valid option. + */ + blend[b].blend1.pre_blend_clamp_enable = 1; + blend[b].blend1.post_blend_clamp_enable = 1; + blend[b].blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT; /* _NEW_COLOR */ - if (ctx->Color.AlphaEnabled) { + if (ctx->Color.AlphaEnabled && !integer) { blend[b].blend1.alpha_test_enable = 1; blend[b].blend1.alpha_test_func = intel_translate_compare_func(ctx->Color.AlphaFunc); @@ -108,7 +154,7 @@ prepare_blend_state(struct brw_context *brw) } /* _NEW_COLOR */ - if (ctx->Color.DitherFlag) { + if (ctx->Color.DitherFlag && !integer) { blend[b].blend1.dither_enable = 1; blend[b].blend1.y_dither_offset = 0; blend[b].blend1.x_dither_offset = 0; @@ -118,6 +164,24 @@ prepare_blend_state(struct brw_context *brw) blend[b].blend1.write_disable_g = !ctx->Color.ColorMask[b][1]; blend[b].blend1.write_disable_b = !ctx->Color.ColorMask[b][2]; blend[b].blend1.write_disable_a = !ctx->Color.ColorMask[b][3]; + + /* OpenGL specification 3.3 (page 196), section 4.1.3 says: + * "If drawbuffer zero is not NONE and the buffer it references has an + * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE + * operations are skipped." + */ + if(!is_buffer_zero_integer_format) { + /* _NEW_MULTISAMPLE */ + blend[b].blend1.alpha_to_coverage = + ctx->Multisample._Enabled && ctx->Multisample.SampleAlphaToCoverage; + blend[b].blend1.alpha_to_one = + ctx->Multisample._Enabled && ctx->Multisample.SampleAlphaToOne; + blend[b].blend1.alpha_to_coverage_dither = (brw->intel.gen >= 7); + } + else { + blend[b].blend1.alpha_to_coverage = false; + blend[b].blend1.alpha_to_one = false; + } } brw->state.dirty.cache |= CACHE_NEW_BLEND_STATE; @@ -126,20 +190,22 @@ prepare_blend_state(struct brw_context *brw) const struct brw_tracked_state gen6_blend_state = { .dirty = { .mesa = (_NEW_COLOR | - _NEW_BUFFERS), + _NEW_BUFFERS | + _NEW_MULTISAMPLE), .brw = BRW_NEW_BATCH, .cache = 0, }, - .prepare = prepare_blend_state, + .emit = gen6_upload_blend_state, }; static void -gen6_prepare_color_calc_state(struct brw_context *brw) +gen6_upload_color_calc_state(struct brw_context *brw) { struct gl_context *ctx = &brw->intel.ctx; struct gen6_color_calc_state *cc; - cc = brw_state_batch(brw, sizeof(*cc), 64, &brw->cc.state_offset); + cc = brw_state_batch(brw, AUB_TRACE_CC_STATE, + sizeof(*cc), 64, &brw->cc.state_offset); memset(cc, 0, sizeof(*cc)); /* _NEW_COLOR */ @@ -165,7 +231,7 @@ const struct brw_tracked_state gen6_color_calc_state = { .brw = BRW_NEW_BATCH, .cache = 0, }, - .prepare = gen6_prepare_color_calc_state, + .emit = gen6_upload_color_calc_state, }; static void upload_cc_state_pointers(struct brw_context *brw) @@ -183,7 +249,8 @@ static void upload_cc_state_pointers(struct brw_context *brw) const struct brw_tracked_state gen6_cc_state_pointers = { .dirty = { .mesa = 0, - .brw = BRW_NEW_BATCH, + .brw = (BRW_NEW_BATCH | + BRW_NEW_STATE_BASE_ADDRESS), .cache = (CACHE_NEW_BLEND_STATE | CACHE_NEW_COLOR_CALC_STATE | CACHE_NEW_DEPTH_STENCIL_STATE)