Home | History | Annotate | Download | only in i965
      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 "main/framebuffer.h"
     31 #include "intel_batchbuffer.h"
     32 
     33 static void
     34 upload_sbe_state(struct brw_context *brw)
     35 {
     36    struct gl_context *ctx = &brw->ctx;
     37    /* BRW_NEW_FS_PROG_DATA */
     38    const struct brw_wm_prog_data *wm_prog_data =
     39       brw_wm_prog_data(brw->wm.base.prog_data);
     40    uint32_t num_outputs = wm_prog_data->num_varying_inputs;
     41    uint32_t dw1;
     42    uint32_t point_sprite_enables;
     43    int i;
     44    uint16_t attr_overrides[16];
     45    /* _NEW_BUFFERS */
     46    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
     47    uint32_t point_sprite_origin;
     48 
     49    /* FINISHME: Attribute Swizzle Control Mode? */
     50    dw1 = GEN7_SBE_SWIZZLE_ENABLE | num_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT;
     51 
     52    /* _NEW_POINT
     53     *
     54     * Window coordinates in an FBO are inverted, which means point
     55     * sprite origin must be inverted.
     56     */
     57    if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) {
     58       point_sprite_origin = GEN6_SF_POINT_SPRITE_LOWERLEFT;
     59    } else {
     60       point_sprite_origin = GEN6_SF_POINT_SPRITE_UPPERLEFT;
     61    }
     62    dw1 |= point_sprite_origin;
     63 
     64    /* _NEW_POINT | _NEW_LIGHT | _NEW_PROGRAM,
     65     * BRW_NEW_FS_PROG_DATA | BRW_NEW_FRAGMENT_PROGRAM |
     66     * BRW_NEW_GS_PROG_DATA | BRW_NEW_PRIMITIVE | BRW_NEW_TES_PROG_DATA |
     67     * BRW_NEW_VUE_MAP_GEOM_OUT
     68     */
     69    uint32_t urb_entry_read_length;
     70    uint32_t urb_entry_read_offset;
     71    calculate_attr_overrides(brw, attr_overrides, &point_sprite_enables,
     72                             &urb_entry_read_length, &urb_entry_read_offset);
     73    dw1 |= urb_entry_read_length << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT |
     74           urb_entry_read_offset << GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT;
     75 
     76    BEGIN_BATCH(14);
     77    OUT_BATCH(_3DSTATE_SBE << 16 | (14 - 2));
     78    OUT_BATCH(dw1);
     79 
     80    /* Output dwords 2 through 9 */
     81    for (i = 0; i < 8; i++) {
     82       OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16);
     83    }
     84 
     85    OUT_BATCH(point_sprite_enables); /* dw10 */
     86    OUT_BATCH(wm_prog_data->flat_inputs);
     87    OUT_BATCH(0); /* wrapshortest enables 0-7 */
     88    OUT_BATCH(0); /* wrapshortest enables 8-15 */
     89    ADVANCE_BATCH();
     90 }
     91 
     92 const struct brw_tracked_state gen7_sbe_state = {
     93    .dirty = {
     94       .mesa  = _NEW_BUFFERS |
     95                _NEW_LIGHT |
     96                _NEW_POINT |
     97                _NEW_POLYGON |
     98                _NEW_PROGRAM,
     99       .brw   = BRW_NEW_BLORP |
    100                BRW_NEW_CONTEXT |
    101                BRW_NEW_FRAGMENT_PROGRAM |
    102                BRW_NEW_FS_PROG_DATA |
    103                BRW_NEW_GS_PROG_DATA |
    104                BRW_NEW_TES_PROG_DATA |
    105                BRW_NEW_PRIMITIVE |
    106                BRW_NEW_VUE_MAP_GEOM_OUT,
    107    },
    108    .emit = upload_sbe_state,
    109 };
    110 
    111 static void
    112 upload_sf_state(struct brw_context *brw)
    113 {
    114    struct gl_context *ctx = &brw->ctx;
    115    uint32_t dw1, dw2, dw3;
    116    float point_size;
    117    /* _NEW_BUFFERS */
    118    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
    119    const bool multisampled_fbo = _mesa_geometric_samples(ctx->DrawBuffer) > 1;
    120 
    121    dw1 = GEN6_SF_STATISTICS_ENABLE;
    122 
    123    if (brw->sf.viewport_transform_enable)
    124        dw1 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
    125 
    126    /* _NEW_BUFFERS */
    127    dw1 |= (brw_depthbuffer_format(brw) << GEN7_SF_DEPTH_BUFFER_SURFACE_FORMAT_SHIFT);
    128 
    129    /* _NEW_POLYGON */
    130    if (ctx->Polygon._FrontBit == render_to_fbo)
    131       dw1 |= GEN6_SF_WINDING_CCW;
    132 
    133    if (ctx->Polygon.OffsetFill)
    134        dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID;
    135 
    136    if (ctx->Polygon.OffsetLine)
    137        dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME;
    138 
    139    if (ctx->Polygon.OffsetPoint)
    140        dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT;
    141 
    142    switch (ctx->Polygon.FrontMode) {
    143    case GL_FILL:
    144        dw1 |= GEN6_SF_FRONT_SOLID;
    145        break;
    146 
    147    case GL_LINE:
    148        dw1 |= GEN6_SF_FRONT_WIREFRAME;
    149        break;
    150 
    151    case GL_POINT:
    152        dw1 |= GEN6_SF_FRONT_POINT;
    153        break;
    154 
    155    default:
    156        unreachable("not reached");
    157    }
    158 
    159    switch (ctx->Polygon.BackMode) {
    160    case GL_FILL:
    161        dw1 |= GEN6_SF_BACK_SOLID;
    162        break;
    163 
    164    case GL_LINE:
    165        dw1 |= GEN6_SF_BACK_WIREFRAME;
    166        break;
    167 
    168    case GL_POINT:
    169        dw1 |= GEN6_SF_BACK_POINT;
    170        break;
    171 
    172    default:
    173        unreachable("not reached");
    174    }
    175 
    176    dw2 = GEN6_SF_SCISSOR_ENABLE;
    177 
    178    if (ctx->Polygon.CullFlag) {
    179       switch (ctx->Polygon.CullFaceMode) {
    180       case GL_FRONT:
    181 	 dw2 |= GEN6_SF_CULL_FRONT;
    182 	 break;
    183       case GL_BACK:
    184 	 dw2 |= GEN6_SF_CULL_BACK;
    185 	 break;
    186       case GL_FRONT_AND_BACK:
    187 	 dw2 |= GEN6_SF_CULL_BOTH;
    188 	 break;
    189       default:
    190 	 unreachable("not reached");
    191       }
    192    } else {
    193       dw2 |= GEN6_SF_CULL_NONE;
    194    }
    195 
    196    /* _NEW_LINE */
    197    {
    198       uint32_t line_width_u3_7 = brw_get_line_width(brw);
    199       dw2 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT;
    200    }
    201    if (ctx->Line.SmoothFlag) {
    202       dw2 |= GEN6_SF_LINE_AA_ENABLE;
    203       dw2 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0;
    204    }
    205    if (ctx->Line.StippleFlag && brw->is_haswell) {
    206       dw2 |= HSW_SF_LINE_STIPPLE_ENABLE;
    207    }
    208    /* _NEW_MULTISAMPLE */
    209    if (multisampled_fbo && ctx->Multisample.Enabled)
    210       dw2 |= GEN6_SF_MSRAST_ON_PATTERN;
    211 
    212    /* FINISHME: Last Pixel Enable?  Vertex Sub Pixel Precision Select?
    213     */
    214 
    215    dw3 = GEN6_SF_LINE_AA_MODE_TRUE;
    216 
    217    /* _NEW_PROGRAM | _NEW_POINT, BRW_NEW_VUE_MAP_GEOM_OUT */
    218    if (use_state_point_size(brw))
    219       dw3 |= GEN6_SF_USE_STATE_POINT_WIDTH;
    220 
    221    /* _NEW_POINT - Clamp to ARB_point_parameters user limits */
    222    point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
    223 
    224    /* Clamp to the hardware limits and convert to fixed point */
    225    dw3 |= U_FIXED(CLAMP(point_size, 0.125f, 255.875f), 3);
    226 
    227    /* _NEW_LIGHT */
    228    if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) {
    229       dw3 |=
    230 	 (2 << GEN6_SF_TRI_PROVOKE_SHIFT) |
    231 	 (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) |
    232 	 (1 << GEN6_SF_LINE_PROVOKE_SHIFT);
    233    } else {
    234       dw3 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT);
    235    }
    236 
    237    BEGIN_BATCH(7);
    238    OUT_BATCH(_3DSTATE_SF << 16 | (7 - 2));
    239    OUT_BATCH(dw1);
    240    OUT_BATCH(dw2);
    241    OUT_BATCH(dw3);
    242    OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant.  copied from gen4 */
    243    OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */
    244    OUT_BATCH_F(ctx->Polygon.OffsetClamp); /* global depth offset clamp */
    245    ADVANCE_BATCH();
    246 }
    247 
    248 const struct brw_tracked_state gen7_sf_state = {
    249    .dirty = {
    250       .mesa  = _NEW_BUFFERS |
    251                _NEW_LIGHT |
    252                _NEW_LINE |
    253                _NEW_MULTISAMPLE |
    254                _NEW_POINT |
    255                _NEW_POLYGON |
    256                _NEW_PROGRAM,
    257       .brw   = BRW_NEW_BLORP |
    258                BRW_NEW_CONTEXT |
    259                BRW_NEW_GS_PROG_DATA |
    260                BRW_NEW_PRIMITIVE |
    261                BRW_NEW_TES_PROG_DATA |
    262                BRW_NEW_VUE_MAP_GEOM_OUT,
    263    },
    264    .emit = upload_sf_state,
    265 };
    266