Home | History | Annotate | Download | only in i965
      1 /*
      2  * Copyright  2009 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21  * IN THE SOFTWARE.
     22  *
     23  * Authors:
     24  *    Eric Anholt <eric (at) anholt.net>
     25  *
     26  */
     27 
     28 #include "brw_context.h"
     29 #include "brw_state.h"
     30 #include "brw_defines.h"
     31 #include "brw_util.h"
     32 #include "intel_batchbuffer.h"
     33 #include "main/macros.h"
     34 #include "main/enums.h"
     35 #include "main/glformats.h"
     36 #include "main/stencil.h"
     37 
     38 static void
     39 gen6_upload_blend_state(struct brw_context *brw)
     40 {
     41    bool is_buffer_zero_integer_format = false;
     42    struct gl_context *ctx = &brw->ctx;
     43    struct gen6_blend_state *blend;
     44    int b;
     45    int nr_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers;
     46    int size;
     47 
     48    /* We need at least one BLEND_STATE written, because we might do
     49     * thread dispatch even if _NumColorDrawBuffers is 0 (for example
     50     * for computed depth or alpha test), which will do an FB write
     51     * with render target 0, which will reference BLEND_STATE[0] for
     52     * alpha test enable.
     53     */
     54    if (nr_draw_buffers == 0)
     55       nr_draw_buffers = 1;
     56 
     57    size = sizeof(*blend) * nr_draw_buffers;
     58    blend = brw_state_batch(brw, AUB_TRACE_BLEND_STATE,
     59 			   size, 64, &brw->cc.blend_state_offset);
     60 
     61    memset(blend, 0, size);
     62 
     63    for (b = 0; b < nr_draw_buffers; b++) {
     64       /* _NEW_BUFFERS */
     65       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[b];
     66       GLenum rb_type;
     67       bool integer;
     68 
     69       if (rb)
     70 	 rb_type = _mesa_get_format_datatype(rb->Format);
     71       else
     72 	 rb_type = GL_UNSIGNED_NORMALIZED;
     73 
     74       /* Used for implementing the following bit of GL_EXT_texture_integer:
     75        *     "Per-fragment operations that require floating-point color
     76        *      components, including multisample alpha operations, alpha test,
     77        *      blending, and dithering, have no effect when the corresponding
     78        *      colors are written to an integer color buffer."
     79       */
     80       integer = (rb_type == GL_INT || rb_type == GL_UNSIGNED_INT);
     81 
     82       if(b == 0 && integer)
     83          is_buffer_zero_integer_format = true;
     84 
     85       /* _NEW_COLOR */
     86       if (ctx->Color.ColorLogicOpEnabled) {
     87 	 /* Floating point RTs should have no effect from LogicOp,
     88 	  * except for disabling of blending, but other types should.
     89 	  *
     90 	  * However, from the Sandy Bridge PRM, Vol 2 Par 1, Section 8.1.11,
     91 	  * "Logic Ops",
     92 	  *
     93 	  *     "Logic Ops are only supported on *_UNORM surfaces (excluding
     94 	  *      _SRGB variants), otherwise Logic Ops must be DISABLED."
     95 	  */
     96          WARN_ONCE(ctx->Color.LogicOp != GL_COPY &&
     97                    rb_type != GL_UNSIGNED_NORMALIZED &&
     98                    rb_type != GL_FLOAT, "Ignoring %s logic op on %s "
     99                    "renderbuffer\n",
    100                    _mesa_enum_to_string(ctx->Color.LogicOp),
    101                    _mesa_enum_to_string(rb_type));
    102 	 if (rb_type == GL_UNSIGNED_NORMALIZED) {
    103 	    blend[b].blend1.logic_op_enable = 1;
    104 	    blend[b].blend1.logic_op_func =
    105 	       intel_translate_logic_op(ctx->Color.LogicOp);
    106 	 }
    107       } else if (ctx->Color.BlendEnabled & (1 << b) && !integer &&
    108                  !ctx->Color._AdvancedBlendMode) {
    109 	 GLenum eqRGB = ctx->Color.Blend[b].EquationRGB;
    110 	 GLenum eqA = ctx->Color.Blend[b].EquationA;
    111 	 GLenum srcRGB = ctx->Color.Blend[b].SrcRGB;
    112 	 GLenum dstRGB = ctx->Color.Blend[b].DstRGB;
    113 	 GLenum srcA = ctx->Color.Blend[b].SrcA;
    114 	 GLenum dstA = ctx->Color.Blend[b].DstA;
    115 
    116 	 if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
    117 	    srcRGB = dstRGB = GL_ONE;
    118 	 }
    119 
    120 	 if (eqA == GL_MIN || eqA == GL_MAX) {
    121 	    srcA = dstA = GL_ONE;
    122 	 }
    123 
    124          /* Due to hardware limitations, the destination may have information
    125           * in an alpha channel even when the format specifies no alpha
    126           * channel. In order to avoid getting any incorrect blending due to
    127           * that alpha channel, coerce the blend factors to values that will
    128           * not read the alpha channel, but will instead use the correct
    129           * implicit value for alpha.
    130           */
    131          if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE))
    132          {
    133             srcRGB = brw_fix_xRGB_alpha(srcRGB);
    134             srcA = brw_fix_xRGB_alpha(srcA);
    135             dstRGB = brw_fix_xRGB_alpha(dstRGB);
    136             dstA = brw_fix_xRGB_alpha(dstA);
    137          }
    138 
    139 	 blend[b].blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
    140 	 blend[b].blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
    141 	 blend[b].blend0.blend_func = brw_translate_blend_equation(eqRGB);
    142 
    143 	 blend[b].blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
    144 	 blend[b].blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
    145 	 blend[b].blend0.ia_blend_func = brw_translate_blend_equation(eqA);
    146 
    147 	 blend[b].blend0.blend_enable = 1;
    148 	 blend[b].blend0.ia_blend_enable = (srcA != srcRGB ||
    149 					 dstA != dstRGB ||
    150 					 eqA != eqRGB);
    151       }
    152 
    153       /* See section 8.1.6 "Pre-Blend Color Clamping" of the
    154        * SandyBridge PRM Volume 2 Part 1 for HW requirements.
    155        *
    156        * We do our ARB_color_buffer_float CLAMP_FRAGMENT_COLOR
    157        * clamping in the fragment shader.  For its clamping of
    158        * blending, the spec says:
    159        *
    160        *     "RESOLVED: For fixed-point color buffers, the inputs and
    161        *      the result of the blending equation are clamped.  For
    162        *      floating-point color buffers, no clamping occurs."
    163        *
    164        * So, generally, we want clamping to the render target's range.
    165        * And, good news, the hardware tables for both pre- and
    166        * post-blend color clamping are either ignored, or any are
    167        * allowed, or clamping is required but RT range clamping is a
    168        * valid option.
    169        */
    170       blend[b].blend1.pre_blend_clamp_enable = 1;
    171       blend[b].blend1.post_blend_clamp_enable = 1;
    172       blend[b].blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT;
    173 
    174       /* _NEW_COLOR */
    175       if (ctx->Color.AlphaEnabled && !integer) {
    176 	 blend[b].blend1.alpha_test_enable = 1;
    177 	 blend[b].blend1.alpha_test_func =
    178 	    intel_translate_compare_func(ctx->Color.AlphaFunc);
    179 
    180       }
    181 
    182       /* _NEW_COLOR */
    183       if (ctx->Color.DitherFlag && !integer) {
    184 	 blend[b].blend1.dither_enable = 1;
    185 	 blend[b].blend1.y_dither_offset = 0;
    186 	 blend[b].blend1.x_dither_offset = 0;
    187       }
    188 
    189       blend[b].blend1.write_disable_r = !ctx->Color.ColorMask[b][0];
    190       blend[b].blend1.write_disable_g = !ctx->Color.ColorMask[b][1];
    191       blend[b].blend1.write_disable_b = !ctx->Color.ColorMask[b][2];
    192       blend[b].blend1.write_disable_a = !ctx->Color.ColorMask[b][3];
    193 
    194       /* OpenGL specification 3.3 (page 196), section 4.1.3 says:
    195        * "If drawbuffer zero is not NONE and the buffer it references has an
    196        * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE
    197        * operations are skipped."
    198        */
    199       if(!is_buffer_zero_integer_format) {
    200          /* _NEW_MULTISAMPLE */
    201          blend[b].blend1.alpha_to_coverage =
    202             _mesa_is_multisample_enabled(ctx) && ctx->Multisample.SampleAlphaToCoverage;
    203 
    204 	/* From SandyBridge PRM, volume 2 Part 1, section 8.2.3, BLEND_STATE:
    205 	 * DWord 1, Bit 30 (AlphaToOne Enable):
    206 	 * "If Dual Source Blending is enabled, this bit must be disabled"
    207 	 */
    208          WARN_ONCE(ctx->Color.Blend[b]._UsesDualSrc &&
    209                    _mesa_is_multisample_enabled(ctx) &&
    210                    ctx->Multisample.SampleAlphaToOne,
    211                    "HW workaround: disabling alpha to one with dual src "
    212                    "blending\n");
    213 	 if (ctx->Color.Blend[b]._UsesDualSrc)
    214             blend[b].blend1.alpha_to_one = false;
    215 	 else
    216 	    blend[b].blend1.alpha_to_one =
    217 	       _mesa_is_multisample_enabled(ctx) && ctx->Multisample.SampleAlphaToOne;
    218 
    219          blend[b].blend1.alpha_to_coverage_dither = (brw->gen >= 7);
    220       }
    221       else {
    222          blend[b].blend1.alpha_to_coverage = false;
    223          blend[b].blend1.alpha_to_one = false;
    224       }
    225    }
    226 
    227    /* Point the GPU at the new indirect state. */
    228    if (brw->gen == 6) {
    229       BEGIN_BATCH(4);
    230       OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2));
    231       OUT_BATCH(brw->cc.blend_state_offset | 1);
    232       OUT_BATCH(0);
    233       OUT_BATCH(0);
    234       ADVANCE_BATCH();
    235    } else {
    236       BEGIN_BATCH(2);
    237       OUT_BATCH(_3DSTATE_BLEND_STATE_POINTERS << 16 | (2 - 2));
    238       OUT_BATCH(brw->cc.blend_state_offset | 1);
    239       ADVANCE_BATCH();
    240    }
    241 }
    242 
    243 const struct brw_tracked_state gen6_blend_state = {
    244    .dirty = {
    245       .mesa = _NEW_BUFFERS |
    246               _NEW_COLOR |
    247               _NEW_MULTISAMPLE,
    248       .brw = BRW_NEW_BATCH |
    249              BRW_NEW_BLORP |
    250              BRW_NEW_STATE_BASE_ADDRESS,
    251    },
    252    .emit = gen6_upload_blend_state,
    253 };
    254 
    255 static void
    256 gen6_upload_color_calc_state(struct brw_context *brw)
    257 {
    258    struct gl_context *ctx = &brw->ctx;
    259    struct gen6_color_calc_state *cc;
    260 
    261    cc = brw_state_batch(brw, AUB_TRACE_CC_STATE,
    262 			sizeof(*cc), 64, &brw->cc.state_offset);
    263    memset(cc, 0, sizeof(*cc));
    264 
    265    /* _NEW_COLOR */
    266    cc->cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
    267    UNCLAMPED_FLOAT_TO_UBYTE(cc->cc1.alpha_ref_fi.ui, ctx->Color.AlphaRef);
    268 
    269    if (brw->gen < 9) {
    270       /* _NEW_STENCIL */
    271       cc->cc0.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
    272       cc->cc0.bf_stencil_ref =
    273          _mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace);
    274    }
    275 
    276    /* _NEW_COLOR */
    277    cc->constant_r = ctx->Color.BlendColorUnclamped[0];
    278    cc->constant_g = ctx->Color.BlendColorUnclamped[1];
    279    cc->constant_b = ctx->Color.BlendColorUnclamped[2];
    280    cc->constant_a = ctx->Color.BlendColorUnclamped[3];
    281 
    282    /* Point the GPU at the new indirect state. */
    283    if (brw->gen == 6) {
    284       BEGIN_BATCH(4);
    285       OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2));
    286       OUT_BATCH(0);
    287       OUT_BATCH(0);
    288       OUT_BATCH(brw->cc.state_offset | 1);
    289       ADVANCE_BATCH();
    290    } else {
    291       BEGIN_BATCH(2);
    292       OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (2 - 2));
    293       OUT_BATCH(brw->cc.state_offset | 1);
    294       ADVANCE_BATCH();
    295    }
    296 }
    297 
    298 const struct brw_tracked_state gen6_color_calc_state = {
    299    .dirty = {
    300       .mesa = _NEW_COLOR |
    301               _NEW_STENCIL,
    302       .brw = BRW_NEW_BATCH |
    303              BRW_NEW_BLORP |
    304              BRW_NEW_CC_STATE |
    305              BRW_NEW_STATE_BASE_ADDRESS,
    306    },
    307    .emit = gen6_upload_color_calc_state,
    308 };
    309