Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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@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 && ctx->Color.AlphaEnabled)
  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_lookup_enum_by_nr(ctx->Color.LogicOp),
  101.                    _mesa_lookup_enum_by_nr(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.          GLenum eqRGB = ctx->Color.Blend[b].EquationRGB;
  109.          GLenum eqA = ctx->Color.Blend[b].EquationA;
  110.          GLenum srcRGB = ctx->Color.Blend[b].SrcRGB;
  111.          GLenum dstRGB = ctx->Color.Blend[b].DstRGB;
  112.          GLenum srcA = ctx->Color.Blend[b].SrcA;
  113.          GLenum dstA = ctx->Color.Blend[b].DstA;
  114.  
  115.          if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
  116.             srcRGB = dstRGB = GL_ONE;
  117.          }
  118.  
  119.          if (eqA == GL_MIN || eqA == GL_MAX) {
  120.             srcA = dstA = GL_ONE;
  121.          }
  122.  
  123.          /* Due to hardware limitations, the destination may have information
  124.           * in an alpha channel even when the format specifies no alpha
  125.           * channel. In order to avoid getting any incorrect blending due to
  126.           * that alpha channel, coerce the blend factors to values that will
  127.           * not read the alpha channel, but will instead use the correct
  128.           * implicit value for alpha.
  129.           */
  130.          if (rb && !_mesa_base_format_has_channel(rb->_BaseFormat, GL_TEXTURE_ALPHA_TYPE))
  131.          {
  132.             srcRGB = brw_fix_xRGB_alpha(srcRGB);
  133.             srcA = brw_fix_xRGB_alpha(srcA);
  134.             dstRGB = brw_fix_xRGB_alpha(dstRGB);
  135.             dstA = brw_fix_xRGB_alpha(dstA);
  136.          }
  137.  
  138.          blend[b].blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
  139.          blend[b].blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
  140.          blend[b].blend0.blend_func = brw_translate_blend_equation(eqRGB);
  141.  
  142.          blend[b].blend0.ia_dest_blend_factor = brw_translate_blend_factor(dstA);
  143.          blend[b].blend0.ia_source_blend_factor = brw_translate_blend_factor(srcA);
  144.          blend[b].blend0.ia_blend_func = brw_translate_blend_equation(eqA);
  145.  
  146.          blend[b].blend0.blend_enable = 1;
  147.          blend[b].blend0.ia_blend_enable = (srcA != srcRGB ||
  148.                                          dstA != dstRGB ||
  149.                                          eqA != eqRGB);
  150.       }
  151.  
  152.       /* See section 8.1.6 "Pre-Blend Color Clamping" of the
  153.        * SandyBridge PRM Volume 2 Part 1 for HW requirements.
  154.        *
  155.        * We do our ARB_color_buffer_float CLAMP_FRAGMENT_COLOR
  156.        * clamping in the fragment shader.  For its clamping of
  157.        * blending, the spec says:
  158.        *
  159.        *     "RESOLVED: For fixed-point color buffers, the inputs and
  160.        *      the result of the blending equation are clamped.  For
  161.        *      floating-point color buffers, no clamping occurs."
  162.        *
  163.        * So, generally, we want clamping to the render target's range.
  164.        * And, good news, the hardware tables for both pre- and
  165.        * post-blend color clamping are either ignored, or any are
  166.        * allowed, or clamping is required but RT range clamping is a
  167.        * valid option.
  168.        */
  169.       blend[b].blend1.pre_blend_clamp_enable = 1;
  170.       blend[b].blend1.post_blend_clamp_enable = 1;
  171.       blend[b].blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT;
  172.  
  173.       /* _NEW_COLOR */
  174.       if (ctx->Color.AlphaEnabled && !integer) {
  175.          blend[b].blend1.alpha_test_enable = 1;
  176.          blend[b].blend1.alpha_test_func =
  177.             intel_translate_compare_func(ctx->Color.AlphaFunc);
  178.  
  179.       }
  180.  
  181.       /* _NEW_COLOR */
  182.       if (ctx->Color.DitherFlag && !integer) {
  183.          blend[b].blend1.dither_enable = 1;
  184.          blend[b].blend1.y_dither_offset = 0;
  185.          blend[b].blend1.x_dither_offset = 0;
  186.       }
  187.  
  188.       blend[b].blend1.write_disable_r = !ctx->Color.ColorMask[b][0];
  189.       blend[b].blend1.write_disable_g = !ctx->Color.ColorMask[b][1];
  190.       blend[b].blend1.write_disable_b = !ctx->Color.ColorMask[b][2];
  191.       blend[b].blend1.write_disable_a = !ctx->Color.ColorMask[b][3];
  192.  
  193.       /* OpenGL specification 3.3 (page 196), section 4.1.3 says:
  194.        * "If drawbuffer zero is not NONE and the buffer it references has an
  195.        * integer format, the SAMPLE_ALPHA_TO_COVERAGE and SAMPLE_ALPHA_TO_ONE
  196.        * operations are skipped."
  197.        */
  198.       if(!is_buffer_zero_integer_format) {
  199.          /* _NEW_MULTISAMPLE */
  200.          blend[b].blend1.alpha_to_coverage =
  201.             ctx->Multisample._Enabled && ctx->Multisample.SampleAlphaToCoverage;
  202.  
  203.         /* From SandyBridge PRM, volume 2 Part 1, section 8.2.3, BLEND_STATE:
  204.          * DWord 1, Bit 30 (AlphaToOne Enable):
  205.          * "If Dual Source Blending is enabled, this bit must be disabled"
  206.          */
  207.          WARN_ONCE(ctx->Color.Blend[b]._UsesDualSrc &&
  208.                    ctx->Multisample._Enabled &&
  209.                    ctx->Multisample.SampleAlphaToOne,
  210.                    "HW workaround: disabling alpha to one with dual src "
  211.                    "blending\n");
  212.          if (ctx->Color.Blend[b]._UsesDualSrc)
  213.             blend[b].blend1.alpha_to_one = false;
  214.          else
  215.             blend[b].blend1.alpha_to_one =
  216.                ctx->Multisample._Enabled && ctx->Multisample.SampleAlphaToOne;
  217.  
  218.          blend[b].blend1.alpha_to_coverage_dither = (brw->gen >= 7);
  219.       }
  220.       else {
  221.          blend[b].blend1.alpha_to_coverage = false;
  222.          blend[b].blend1.alpha_to_one = false;
  223.       }
  224.    }
  225.  
  226.    /* Point the GPU at the new indirect state. */
  227.    if (brw->gen == 6) {
  228.       BEGIN_BATCH(4);
  229.       OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2));
  230.       OUT_BATCH(brw->cc.blend_state_offset | 1);
  231.       OUT_BATCH(0);
  232.       OUT_BATCH(0);
  233.       ADVANCE_BATCH();
  234.    } else {
  235.       BEGIN_BATCH(2);
  236.       OUT_BATCH(_3DSTATE_BLEND_STATE_POINTERS << 16 | (2 - 2));
  237.       OUT_BATCH(brw->cc.blend_state_offset | 1);
  238.       ADVANCE_BATCH();
  239.    }
  240. }
  241.  
  242. const struct brw_tracked_state gen6_blend_state = {
  243.    .dirty = {
  244.       .mesa = (_NEW_COLOR |
  245.                _NEW_BUFFERS |
  246.                _NEW_MULTISAMPLE),
  247.       .brw = BRW_NEW_BATCH | BRW_NEW_STATE_BASE_ADDRESS,
  248.       .cache = 0,
  249.    },
  250.    .emit = gen6_upload_blend_state,
  251. };
  252.  
  253. static void
  254. gen6_upload_color_calc_state(struct brw_context *brw)
  255. {
  256.    struct gl_context *ctx = &brw->ctx;
  257.    struct gen6_color_calc_state *cc;
  258.  
  259.    cc = brw_state_batch(brw, AUB_TRACE_CC_STATE,
  260.                         sizeof(*cc), 64, &brw->cc.state_offset);
  261.    memset(cc, 0, sizeof(*cc));
  262.  
  263.    /* _NEW_COLOR */
  264.    cc->cc0.alpha_test_format = BRW_ALPHATEST_FORMAT_UNORM8;
  265.    UNCLAMPED_FLOAT_TO_UBYTE(cc->cc1.alpha_ref_fi.ui, ctx->Color.AlphaRef);
  266.  
  267.    /* _NEW_STENCIL */
  268.    cc->cc0.stencil_ref = _mesa_get_stencil_ref(ctx, 0);
  269.    cc->cc0.bf_stencil_ref = _mesa_get_stencil_ref(ctx, ctx->Stencil._BackFace);
  270.  
  271.    /* _NEW_COLOR */
  272.    cc->constant_r = ctx->Color.BlendColorUnclamped[0];
  273.    cc->constant_g = ctx->Color.BlendColorUnclamped[1];
  274.    cc->constant_b = ctx->Color.BlendColorUnclamped[2];
  275.    cc->constant_a = ctx->Color.BlendColorUnclamped[3];
  276.  
  277.    /* Point the GPU at the new indirect state. */
  278.    if (brw->gen == 6) {
  279.       BEGIN_BATCH(4);
  280.       OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (4 - 2));
  281.       OUT_BATCH(0);
  282.       OUT_BATCH(0);
  283.       OUT_BATCH(brw->cc.state_offset | 1);
  284.       ADVANCE_BATCH();
  285.    } else {
  286.       BEGIN_BATCH(2);
  287.       OUT_BATCH(_3DSTATE_CC_STATE_POINTERS << 16 | (2 - 2));
  288.       OUT_BATCH(brw->cc.state_offset | 1);
  289.       ADVANCE_BATCH();
  290.    }
  291. }
  292.  
  293. const struct brw_tracked_state gen6_color_calc_state = {
  294.    .dirty = {
  295.       .mesa = _NEW_COLOR | _NEW_STENCIL,
  296.       .brw = BRW_NEW_BATCH | BRW_NEW_STATE_BASE_ADDRESS,
  297.       .cache = 0,
  298.    },
  299.    .emit = gen6_upload_color_calc_state,
  300. };
  301.