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 
     35 static void
     36 gen6_upload_blend_state(struct brw_context *brw)
     37 {
     38    bool is_buffer_zero_integer_format = false;
     39    struct gl_context *ctx = &brw->intel.ctx;
     40    struct gen6_blend_state *blend;
     41    int b;
     42    int nr_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers;
     43    int size;
     44 
     45    /* We need at least one BLEND_STATE written, because we might do
     46     * thread dispatch even if _NumColorDrawBuffers is 0 (for example
     47     * for computed depth or alpha test), which will do an FB write
     48     * with render target 0, which will reference BLEND_STATE[0] for
     49     * alpha test enable.
     50     */
     51    if (nr_draw_buffers == 0 && ctx->Color.AlphaEnabled)
     52       nr_draw_buffers = 1;
     53 
     54    size = sizeof(*blend) * nr_draw_buffers;
     55    blend = brw_state_batch(brw, AUB_TRACE_BLEND_STATE,
     56 			   size, 64, &brw->cc.blend_state_offset);
     57 
     58    memset(blend, 0, size);
     59 
     60    for (b = 0; b < nr_draw_buffers; b++) {
     61       /* _NEW_BUFFERS */
     62       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[b];
     63       GLenum rb_type;
     64       bool integer;
     65 
     66       if (rb)
     67 	 rb_type = _mesa_get_format_datatype(rb->Format);
     68       else
     69 	 rb_type = GL_UNSIGNED_NORMALIZED;
     70 
     71       /* Used for implementing the following bit of GL_EXT_texture_integer:
     72        *     "Per-fragment operations that require floating-point color
     73        *      components, including multisample alpha operations, alpha test,
     74        *      blending, and dithering, have no effect when the corresponding
     75        *      colors are written to an integer color buffer."
     76       */
     77       integer = (rb_type == GL_INT || rb_type == GL_UNSIGNED_INT);
     78 
     79       if(b == 0 && integer)
     80          is_buffer_zero_integer_format = true;
     81 
     82       /* _NEW_COLOR */
     83       if (ctx->Color.ColorLogicOpEnabled) {
     84 	 /* Floating point RTs should have no effect from LogicOp,
     85 	  * except for disabling of blending.
     86 	  *
     87 	  * From the Sandy Bridge PRM, Vol 2 Par 1, Section 8.1.11, "Logic Ops",
     88 	  *
     89 	  *     "Logic Ops are only supported on *_UNORM surfaces (excluding
     90 	  *      _SRGB variants), otherwise Logic Ops must be DISABLED."
     91 	  */
     92 	 if (rb_type == GL_UNSIGNED_NORMALIZED) {
     93 	    blend[b].blend1.logic_op_enable = 1;
     94 	    blend[b].blend1.logic_op_func =
     95 	       intel_translate_logic_op(ctx->Color.LogicOp);
     96 	 }
     97       } else if (ctx->Color.BlendEnabled & (1 << b) && !integer) {
     98 	 GLenum eqRGB = ctx->Color.Blend[b].EquationRGB;
     99 	 GLenum eqA = ctx->Color.Blend[b].EquationA;
    100 	 GLenum srcRGB = ctx->Color.Blend[b].SrcRGB;
    101 	 GLenum dstRGB = ctx->Color.Blend[b].DstRGB;
    102 	 GLenum srcA = ctx->Color.Blend[b].SrcA;
    103 	 GLenum dstA = ctx->Color.Blend[b].DstA;
    104 
    105 	 if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
    106 	    srcRGB = dstRGB = GL_ONE;
    107 	 }
    108 
    109 	 if (eqA == GL_MIN || eqA == GL_MAX) {
    110 	    srcA = dstA = GL_ONE;
    111 	 }
    112 
    113 	 blend[b].blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
    114 	 blend[b].blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
    115 	 blend[b].blend0.blend_func = brw_translate_blend_equation(eqRGB);
    116 
    117 	 blend[b].blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
    118 	 blend[b].blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
    119 	 blend[b].blend0.ia_blend_func = brw_translate_blend_equation(eqA);
    120 
    121 	 blend[b].blend0.blend_enable = 1;
    122 	 blend[b].blend0.ia_blend_enable = (srcA != srcRGB ||
    123 					 dstA != dstRGB ||
    124 					 eqA != eqRGB);
    125       }
    126 
    127       /* See section 8.1.6 "Pre-Blend Color Clamping" of the
    128        * SandyBridge PRM Volume 2 Part 1 for HW requirements.
    129        *
    130        * We do our ARB_color_buffer_float CLAMP_FRAGMENT_COLOR
    131        * clamping in the fragment shader.  For its clamping of
    132        * blending, the spec says:
    133        *
    134        *     "RESOLVED: For fixed-point color buffers, the inputs and
    135        *      the result of the blending equation are clamped.  For
    136        *      floating-point color buffers, no clamping occurs."
    137        *
    138        * So, generally, we want clamping to the render target's range.
    139        * And, good news, the hardware tables for both pre- and
    140        * post-blend color clamping are either ignored, or any are
    141        * allowed, or clamping is required but RT range clamping is a
    142        * valid option.
    143        */
    144       blend[b].blend1.pre_blend_clamp_enable = 1;
    145       blend[b].blend1.post_blend_clamp_enable = 1;
    146       blend[b].blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT;
    147 
    148       /* _NEW_COLOR */
    149       if (ctx->Color.AlphaEnabled && !integer) {
    150 	 blend[b].blend1.alpha_test_enable = 1;
    151 	 blend[b].blend1.alpha_test_func =
    152 	    intel_translate_compare_func(ctx->Color.AlphaFunc);
    153 
    154       }
    155 
    156       /* _NEW_COLOR */
    157       if (ctx->Color.DitherFlag && !integer) {
    158 	 blend[b].blend1.dither_enable = 1;
    159 	 blend[b].blend1.y_dither_offset = 0;
    160 	 blend[b].blend1.x_dither_offset = 0;
    161       }
    162 
    163       blend[b].blend1.write_disable_r = !ctx->Color.ColorMask[b][0];
    164       blend[b].blend1.write_disable_g = !ctx->Color.ColorMask[b][1];
    165       blend[b].blend1.write_disable_b = !ctx->Color.ColorMask[b][2];
    166       blend[b].blend1.write_disable_a = !ctx->Color.ColorMask[b][3];
    167 
    168       /* OpenGL specification 3.3 (page 196), section 4.1.3 says:
    169        * "If drawbuffer zero is not NONE and the buffer it references has an
    170        * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE
    171        * operations are skipped."
    172        */
    173       if(!is_buffer_zero_integer_format) {
    174          /* _NEW_MULTISAMPLE */
    175          blend[b].blend1.alpha_to_coverage =
    176             ctx->Multisample._Enabled && ctx->Multisample.SampleAlphaToCoverage;
    177 
    178 	/* From SandyBridge PRM, volume 2 Part 1, section 8.2.3, BLEND_STATE:
    179 	 * DWord 1, Bit 30 (AlphaToOne Enable):
    180 	 * "If Dual Source Blending is enabled, this bit must be disabled"
    181 	 */
    182 	 if (ctx->Color.Blend[b]._UsesDualSrc)
    183             blend[b].blend1.alpha_to_one = false;
    184 	 else
    185 	    blend[b].blend1.alpha_to_one =
    186 	       ctx->Multisample._Enabled && ctx->Multisample.SampleAlphaToOne;
    187 
    188          blend[b].blend1.alpha_to_coverage_dither = (brw->intel.gen >= 7);
    189       }
    190       else {
    191          blend[b].blend1.alpha_to_coverage = false;
    192          blend[b].blend1.alpha_to_one = false;
    193       }
    194    }
    195 
    196    brw->state.dirty.cache |= CACHE_NEW_BLEND_STATE;
    197 }
    198 
    199 const struct brw_tracked_state gen6_blend_state = {
    200    .dirty = {
    201       .mesa = (_NEW_COLOR |
    202                _NEW_BUFFERS |
    203                _NEW_MULTISAMPLE),
    204       .brw = BRW_NEW_BATCH,
    205       .cache = 0,
    206    },
    207    .emit = gen6_upload_blend_state,
    208 };
    209 
    210 static void
    211 gen6_upload_color_calc_state(struct brw_context *brw)
    212 {
    213    struct gl_context *ctx = &brw->intel.ctx;
    214    struct gen6_color_calc_state *cc;
    215 
    216    cc = brw_state_batch(brw, AUB_TRACE_CC_STATE,
    217 			sizeof(*cc), 64, &brw->cc.state_offset);
    218    memset(cc, 0, sizeof(*cc));
    219 
    220    /* _NEW_COLOR */
    221    cc->cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
    222    UNCLAMPED_FLOAT_TO_UBYTE(cc->cc1.alpha_ref_fi.ui, ctx->Color.AlphaRef);
    223 
    224    /* _NEW_STENCIL */
    225    cc->cc0.stencil_ref = ctx->Stencil.Ref[0];
    226    cc->cc0.bf_stencil_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace];
    227 
    228    /* _NEW_COLOR */
    229    cc->constant_r = ctx->Color.BlendColorUnclamped[0];
    230    cc->constant_g = ctx->Color.BlendColorUnclamped[1];
    231    cc->constant_b = ctx->Color.BlendColorUnclamped[2];
    232    cc->constant_a = ctx->Color.BlendColorUnclamped[3];
    233 
    234    brw->state.dirty.cache |= CACHE_NEW_COLOR_CALC_STATE;
    235 }
    236 
    237 const struct brw_tracked_state gen6_color_calc_state = {
    238    .dirty = {
    239       .mesa = _NEW_COLOR | _NEW_STENCIL,
    240       .brw = BRW_NEW_BATCH,
    241       .cache = 0,
    242    },
    243    .emit = gen6_upload_color_calc_state,
    244 };
    245 
    246 static void upload_cc_state_pointers(struct brw_context *brw)
    247 {
    248    struct intel_context *intel = &brw->intel;
    249 
    250    BEGIN_BATCH(4);
    251    OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2));
    252    OUT_BATCH(brw->cc.blend_state_offset | 1);
    253    OUT_BATCH(brw->cc.depth_stencil_state_offset | 1);
    254    OUT_BATCH(brw->cc.state_offset | 1);
    255    ADVANCE_BATCH();
    256 }
    257 
    258 const struct brw_tracked_state gen6_cc_state_pointers = {
    259    .dirty = {
    260       .mesa = 0,
    261       .brw = (BRW_NEW_BATCH |
    262 	      BRW_NEW_STATE_BASE_ADDRESS),
    263       .cache = (CACHE_NEW_BLEND_STATE |
    264 		CACHE_NEW_COLOR_CALC_STATE |
    265 		CACHE_NEW_DEPTH_STENCIL_STATE)
    266    },
    267    .emit = upload_cc_state_pointers,
    268 };
    269