Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2011 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.  
  24. #include "brw_context.h"
  25. #include "brw_state.h"
  26. #include "brw_defines.h"
  27. #include "brw_util.h"
  28. #include "main/macros.h"
  29. #include "main/fbobject.h"
  30. #include "intel_batchbuffer.h"
  31.  
  32. static void
  33. upload_sbe_state(struct brw_context *brw)
  34. {
  35.    struct gl_context *ctx = &brw->ctx;
  36.    /* BRW_NEW_FS_PROG_DATA */
  37.    uint32_t num_outputs = brw->wm.prog_data->num_varying_inputs;
  38.    uint32_t dw1;
  39.    uint32_t point_sprite_enables;
  40.    uint32_t flat_enables;
  41.    int i;
  42.    const int urb_entry_read_offset = BRW_SF_URB_ENTRY_READ_OFFSET;
  43.    uint16_t attr_overrides[16];
  44.    /* _NEW_BUFFERS */
  45.    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
  46.    uint32_t point_sprite_origin;
  47.  
  48.    /* FINISHME: Attribute Swizzle Control Mode? */
  49.    dw1 = GEN7_SBE_SWIZZLE_ENABLE | num_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT;
  50.  
  51.    /* _NEW_POINT
  52.     *
  53.     * Window coordinates in an FBO are inverted, which means point
  54.     * sprite origin must be inverted.
  55.     */
  56.    if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) {
  57.       point_sprite_origin = GEN6_SF_POINT_SPRITE_LOWERLEFT;
  58.    } else {
  59.       point_sprite_origin = GEN6_SF_POINT_SPRITE_UPPERLEFT;
  60.    }
  61.    dw1 |= point_sprite_origin;
  62.  
  63.    /* BRW_NEW_VUE_MAP_GEOM_OUT | BRW_NEW_FRAGMENT_PROGRAM
  64.     * _NEW_POINT | _NEW_LIGHT | _NEW_PROGRAM | BRW_NEW_FS_PROG_DATA
  65.     */
  66.    uint32_t urb_entry_read_length;
  67.    calculate_attr_overrides(brw, attr_overrides, &point_sprite_enables,
  68.                             &flat_enables, &urb_entry_read_length);
  69.    dw1 |= urb_entry_read_length << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT |
  70.           urb_entry_read_offset << GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT;
  71.  
  72.    BEGIN_BATCH(14);
  73.    OUT_BATCH(_3DSTATE_SBE << 16 | (14 - 2));
  74.    OUT_BATCH(dw1);
  75.  
  76.    /* Output dwords 2 through 9 */
  77.    for (i = 0; i < 8; i++) {
  78.       OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16);
  79.    }
  80.  
  81.    OUT_BATCH(point_sprite_enables); /* dw10 */
  82.    OUT_BATCH(flat_enables);
  83.    OUT_BATCH(0); /* wrapshortest enables 0-7 */
  84.    OUT_BATCH(0); /* wrapshortest enables 8-15 */
  85.    ADVANCE_BATCH();
  86. }
  87.  
  88. const struct brw_tracked_state gen7_sbe_state = {
  89.    .dirty = {
  90.       .mesa  = _NEW_BUFFERS |
  91.                _NEW_LIGHT |
  92.                _NEW_POINT |
  93.                _NEW_PROGRAM,
  94.       .brw   = BRW_NEW_CONTEXT |
  95.                BRW_NEW_FRAGMENT_PROGRAM |
  96.                BRW_NEW_FS_PROG_DATA |
  97.                BRW_NEW_GEOMETRY_PROGRAM |
  98.                BRW_NEW_PRIMITIVE |
  99.                BRW_NEW_VUE_MAP_GEOM_OUT,
  100.    },
  101.    .emit = upload_sbe_state,
  102. };
  103.  
  104. static void
  105. upload_sf_state(struct brw_context *brw)
  106. {
  107.    struct gl_context *ctx = &brw->ctx;
  108.    uint32_t dw1, dw2, dw3;
  109.    float point_size;
  110.    /* _NEW_BUFFERS */
  111.    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
  112.    bool multisampled_fbo = ctx->DrawBuffer->Visual.samples > 1;
  113.  
  114.    dw1 = GEN6_SF_STATISTICS_ENABLE;
  115.  
  116.    if (brw->sf.viewport_transform_enable)
  117.        dw1 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
  118.  
  119.    /* _NEW_BUFFERS */
  120.    dw1 |= (brw_depthbuffer_format(brw) << GEN7_SF_DEPTH_BUFFER_SURFACE_FORMAT_SHIFT);
  121.  
  122.    /* _NEW_POLYGON */
  123.    if (ctx->Polygon._FrontBit == render_to_fbo)
  124.       dw1 |= GEN6_SF_WINDING_CCW;
  125.  
  126.    if (ctx->Polygon.OffsetFill)
  127.        dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID;
  128.  
  129.    if (ctx->Polygon.OffsetLine)
  130.        dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME;
  131.  
  132.    if (ctx->Polygon.OffsetPoint)
  133.        dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT;
  134.  
  135.    switch (ctx->Polygon.FrontMode) {
  136.    case GL_FILL:
  137.        dw1 |= GEN6_SF_FRONT_SOLID;
  138.        break;
  139.  
  140.    case GL_LINE:
  141.        dw1 |= GEN6_SF_FRONT_WIREFRAME;
  142.        break;
  143.  
  144.    case GL_POINT:
  145.        dw1 |= GEN6_SF_FRONT_POINT;
  146.        break;
  147.  
  148.    default:
  149.        unreachable("not reached");
  150.    }
  151.  
  152.    switch (ctx->Polygon.BackMode) {
  153.    case GL_FILL:
  154.        dw1 |= GEN6_SF_BACK_SOLID;
  155.        break;
  156.  
  157.    case GL_LINE:
  158.        dw1 |= GEN6_SF_BACK_WIREFRAME;
  159.        break;
  160.  
  161.    case GL_POINT:
  162.        dw1 |= GEN6_SF_BACK_POINT;
  163.        break;
  164.  
  165.    default:
  166.        unreachable("not reached");
  167.    }
  168.  
  169.    dw2 = 0;
  170.  
  171.    if (ctx->Polygon.CullFlag) {
  172.       switch (ctx->Polygon.CullFaceMode) {
  173.       case GL_FRONT:
  174.          dw2 |= GEN6_SF_CULL_FRONT;
  175.          break;
  176.       case GL_BACK:
  177.          dw2 |= GEN6_SF_CULL_BACK;
  178.          break;
  179.       case GL_FRONT_AND_BACK:
  180.          dw2 |= GEN6_SF_CULL_BOTH;
  181.          break;
  182.       default:
  183.          unreachable("not reached");
  184.       }
  185.    } else {
  186.       dw2 |= GEN6_SF_CULL_NONE;
  187.    }
  188.  
  189.    /* _NEW_SCISSOR */
  190.    if (ctx->Scissor.EnableFlags)
  191.       dw2 |= GEN6_SF_SCISSOR_ENABLE;
  192.  
  193.    /* _NEW_LINE */
  194.    {
  195.       /* OpenGL dictates that line width should be rounded to the nearest
  196.        * integer
  197.        */
  198.       float line_width =
  199.          roundf(CLAMP(ctx->Line.Width, 0.0, ctx->Const.MaxLineWidth));
  200.       uint32_t line_width_u3_7 = U_FIXED(line_width, 7);
  201.       /* Line width of 0 is not allowed when MSAA enabled */
  202.       if (ctx->Multisample._Enabled) {
  203.          if (line_width_u3_7 == 0)
  204.              line_width_u3_7 = 1;
  205.       } else if (ctx->Line.SmoothFlag && ctx->Line.Width < 1.5) {
  206.          /* For 1 pixel line thickness or less, the general
  207.           * anti-aliasing algorithm gives up, and a garbage line is
  208.           * generated.  Setting a Line Width of 0.0 specifies the
  209.           * rasterization of the "thinnest" (one-pixel-wide),
  210.           * non-antialiased lines.
  211.           *
  212.           * Lines rendered with zero Line Width are rasterized using
  213.           * Grid Intersection Quantization rules as specified by
  214.           * bspec section 6.3.12.1 Zero-Width (Cosmetic) Line
  215.           * Rasterization.
  216.           */
  217.          line_width_u3_7 = 0;
  218.       }
  219.       dw2 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT;
  220.    }
  221.    if (ctx->Line.SmoothFlag) {
  222.       dw2 |= GEN6_SF_LINE_AA_ENABLE;
  223.       dw2 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0;
  224.    }
  225.    if (ctx->Line.StippleFlag && brw->is_haswell) {
  226.       dw2 |= HSW_SF_LINE_STIPPLE_ENABLE;
  227.    }
  228.    /* _NEW_MULTISAMPLE */
  229.    if (multisampled_fbo && ctx->Multisample.Enabled)
  230.       dw2 |= GEN6_SF_MSRAST_ON_PATTERN;
  231.  
  232.    /* FINISHME: Last Pixel Enable?  Vertex Sub Pixel Precision Select?
  233.     */
  234.  
  235.    dw3 = GEN6_SF_LINE_AA_MODE_TRUE;
  236.  
  237.    /* _NEW_PROGRAM | _NEW_POINT */
  238.    if (!(ctx->VertexProgram.PointSizeEnabled || ctx->Point._Attenuated))
  239.       dw3 |= GEN6_SF_USE_STATE_POINT_WIDTH;
  240.  
  241.    /* Clamp to ARB_point_parameters user limits */
  242.    point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
  243.  
  244.    /* Clamp to the hardware limits and convert to fixed point */
  245.    dw3 |= U_FIXED(CLAMP(point_size, 0.125, 255.875), 3);
  246.  
  247.    /* _NEW_LIGHT */
  248.    if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) {
  249.       dw3 |=
  250.          (2 << GEN6_SF_TRI_PROVOKE_SHIFT) |
  251.          (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) |
  252.          (1 << GEN6_SF_LINE_PROVOKE_SHIFT);
  253.    } else {
  254.       dw3 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT);
  255.    }
  256.  
  257.    BEGIN_BATCH(7);
  258.    OUT_BATCH(_3DSTATE_SF << 16 | (7 - 2));
  259.    OUT_BATCH(dw1);
  260.    OUT_BATCH(dw2);
  261.    OUT_BATCH(dw3);
  262.    OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant.  copied from gen4 */
  263.    OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */
  264.    OUT_BATCH_F(ctx->Polygon.OffsetClamp); /* global depth offset clamp */
  265.    ADVANCE_BATCH();
  266. }
  267.  
  268. const struct brw_tracked_state gen7_sf_state = {
  269.    .dirty = {
  270.       .mesa  = _NEW_BUFFERS |
  271.                _NEW_LIGHT |
  272.                _NEW_LINE |
  273.                _NEW_MULTISAMPLE |
  274.                _NEW_POINT |
  275.                _NEW_POLYGON |
  276.                _NEW_PROGRAM |
  277.                _NEW_SCISSOR,
  278.       .brw   = BRW_NEW_CONTEXT,
  279.    },
  280.    .emit = upload_sf_state,
  281. };
  282.