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 "compiler/nir/nir.h"
     25 #include "brw_context.h"
     26 #include "brw_state.h"
     27 #include "brw_defines.h"
     28 #include "brw_util.h"
     29 #include "main/macros.h"
     30 #include "main/fbobject.h"
     31 #include "intel_batchbuffer.h"
     32 
     33 static void
     34 upload_sbe(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    uint16_t attr_overrides[VARYING_SLOT_MAX];
     42    uint32_t urb_entry_read_length;
     43    uint32_t urb_entry_read_offset;
     44    uint32_t point_sprite_enables;
     45    int sbe_cmd_length;
     46 
     47    uint32_t dw1 =
     48       GEN7_SBE_SWIZZLE_ENABLE |
     49       num_outputs << GEN7_SBE_NUM_OUTPUTS_SHIFT;
     50    uint32_t dw4 = 0;
     51    uint32_t dw5 = 0;
     52 
     53    /* _NEW_BUFFERS */
     54    bool render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
     55 
     56    /* _NEW_POINT
     57     *
     58     * Window coordinates in an FBO are inverted, which means point
     59     * sprite origin must be inverted.
     60     */
     61    if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo)
     62       dw1 |= GEN6_SF_POINT_SPRITE_LOWERLEFT;
     63    else
     64       dw1 |= GEN6_SF_POINT_SPRITE_UPPERLEFT;
     65 
     66    /* _NEW_POINT | _NEW_LIGHT | _NEW_PROGRAM,
     67     * BRW_NEW_FS_PROG_DATA | BRW_NEW_FRAGMENT_PROGRAM |
     68     * BRW_NEW_GS_PROG_DATA | BRW_NEW_PRIMITIVE | BRW_NEW_TES_PROG_DATA |
     69     * BRW_NEW_VUE_MAP_GEOM_OUT
     70     */
     71    calculate_attr_overrides(brw, attr_overrides,
     72                             &point_sprite_enables,
     73                             &urb_entry_read_length,
     74                             &urb_entry_read_offset);
     75 
     76    /* Typically, the URB entry read length and offset should be programmed in
     77     * 3DSTATE_VS and 3DSTATE_GS; SBE inherits it from the last active stage
     78     * which produces geometry.  However, we don't know the proper value until
     79     * we call calculate_attr_overrides().
     80     *
     81     * To fit with our existing code, we override the inherited values and
     82     * specify it here directly, as we did on previous generations.
     83     */
     84    dw1 |=
     85       urb_entry_read_length << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT |
     86       urb_entry_read_offset << GEN8_SBE_URB_ENTRY_READ_OFFSET_SHIFT |
     87       GEN8_SBE_FORCE_URB_ENTRY_READ_LENGTH |
     88       GEN8_SBE_FORCE_URB_ENTRY_READ_OFFSET;
     89 
     90    if (brw->gen == 8) {
     91       sbe_cmd_length = 4;
     92    } else {
     93       sbe_cmd_length = 6;
     94 
     95       /* prepare the active component dwords */
     96       int input_index = 0;
     97       for (int attr = 0; attr < VARYING_SLOT_MAX; attr++) {
     98          if (!(brw->fragment_program->info.inputs_read &
     99                BITFIELD64_BIT(attr))) {
    100             continue;
    101          }
    102 
    103          assert(input_index < 32);
    104 
    105          if (input_index < 16)
    106             dw4 |= (GEN9_SBE_ACTIVE_COMPONENT_XYZW << (input_index << 1));
    107          else
    108             dw5 |= (GEN9_SBE_ACTIVE_COMPONENT_XYZW << ((input_index - 16) << 1));
    109 
    110          ++input_index;
    111       }
    112    }
    113    BEGIN_BATCH(sbe_cmd_length);
    114    OUT_BATCH(_3DSTATE_SBE << 16 | (sbe_cmd_length - 2));
    115    OUT_BATCH(dw1);
    116    OUT_BATCH(point_sprite_enables);
    117    OUT_BATCH(wm_prog_data->flat_inputs);
    118    if (sbe_cmd_length >= 6) {
    119       OUT_BATCH(dw4);
    120       OUT_BATCH(dw5);
    121    }
    122    ADVANCE_BATCH();
    123 
    124    BEGIN_BATCH(11);
    125    OUT_BATCH(_3DSTATE_SBE_SWIZ << 16 | (11 - 2));
    126 
    127    /* Output DWords 1 through 8: */
    128    for (int i = 0; i < 8; i++) {
    129       OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16);
    130    }
    131 
    132    OUT_BATCH(0); /* wrapshortest enables 0-7 */
    133    OUT_BATCH(0); /* wrapshortest enables 8-15 */
    134    ADVANCE_BATCH();
    135 }
    136 
    137 const struct brw_tracked_state gen8_sbe_state = {
    138    .dirty = {
    139       .mesa  = _NEW_BUFFERS |
    140                _NEW_LIGHT |
    141                _NEW_POINT |
    142                _NEW_POLYGON |
    143                _NEW_PROGRAM,
    144       .brw   = BRW_NEW_BLORP |
    145                BRW_NEW_CONTEXT |
    146                BRW_NEW_FRAGMENT_PROGRAM |
    147                BRW_NEW_FS_PROG_DATA |
    148                BRW_NEW_GS_PROG_DATA |
    149                BRW_NEW_TES_PROG_DATA |
    150                BRW_NEW_VUE_MAP_GEOM_OUT,
    151    },
    152    .emit = upload_sbe,
    153 };
    154 
    155 static void
    156 upload_sf(struct brw_context *brw)
    157 {
    158    struct gl_context *ctx = &brw->ctx;
    159    uint32_t dw1 = 0, dw2 = 0, dw3 = 0;
    160    float point_size;
    161 
    162    dw1 = GEN6_SF_STATISTICS_ENABLE;
    163 
    164    if (brw->sf.viewport_transform_enable)
    165        dw1 |= GEN6_SF_VIEWPORT_TRANSFORM_ENABLE;
    166 
    167    /* _NEW_LINE */
    168    uint32_t line_width_u3_7 = brw_get_line_width(brw);
    169    if (brw->gen >= 9 || brw->is_cherryview) {
    170       dw1 |= line_width_u3_7 << GEN9_SF_LINE_WIDTH_SHIFT;
    171    } else {
    172       dw2 |= line_width_u3_7 << GEN6_SF_LINE_WIDTH_SHIFT;
    173    }
    174 
    175    if (ctx->Line.SmoothFlag) {
    176       dw2 |= GEN6_SF_LINE_END_CAP_WIDTH_1_0;
    177    }
    178 
    179    /* _NEW_POINT - Clamp to ARB_point_parameters user limits */
    180    point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
    181 
    182    /* Clamp to the hardware limits and convert to fixed point */
    183    dw3 |= U_FIXED(CLAMP(point_size, 0.125f, 255.875f), 3);
    184 
    185    /* _NEW_PROGRAM | _NEW_POINT, BRW_NEW_VUE_MAP_GEOM_OUT */
    186    if (use_state_point_size(brw))
    187       dw3 |= GEN6_SF_USE_STATE_POINT_WIDTH;
    188 
    189    /* _NEW_POINT | _NEW_MULTISAMPLE */
    190    if ((ctx->Point.SmoothFlag || _mesa_is_multisample_enabled(ctx)) &&
    191        !ctx->Point.PointSprite) {
    192       dw3 |= GEN8_SF_SMOOTH_POINT_ENABLE;
    193    }
    194 
    195    dw3 |= GEN6_SF_LINE_AA_MODE_TRUE;
    196 
    197    /* _NEW_LIGHT */
    198    if (ctx->Light.ProvokingVertex != GL_FIRST_VERTEX_CONVENTION) {
    199       dw3 |= (2 << GEN6_SF_TRI_PROVOKE_SHIFT) |
    200              (2 << GEN6_SF_TRIFAN_PROVOKE_SHIFT) |
    201              (1 << GEN6_SF_LINE_PROVOKE_SHIFT);
    202    } else {
    203       dw3 |= (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT);
    204    }
    205 
    206    BEGIN_BATCH(4);
    207    OUT_BATCH(_3DSTATE_SF << 16 | (4 - 2));
    208    OUT_BATCH(dw1);
    209    OUT_BATCH(dw2);
    210    OUT_BATCH(dw3);
    211    ADVANCE_BATCH();
    212 }
    213 
    214 const struct brw_tracked_state gen8_sf_state = {
    215    .dirty = {
    216       .mesa  = _NEW_LIGHT |
    217                _NEW_PROGRAM |
    218                _NEW_LINE |
    219                _NEW_MULTISAMPLE |
    220                _NEW_POINT,
    221       .brw   = BRW_NEW_BLORP |
    222                BRW_NEW_CONTEXT |
    223                BRW_NEW_VUE_MAP_GEOM_OUT,
    224    },
    225    .emit = upload_sf,
    226 };
    227 
    228 static void
    229 upload_raster(struct brw_context *brw)
    230 {
    231    struct gl_context *ctx = &brw->ctx;
    232    uint32_t dw1 = 0;
    233 
    234    /* _NEW_BUFFERS */
    235    bool render_to_fbo = _mesa_is_user_fbo(brw->ctx.DrawBuffer);
    236 
    237    /* _NEW_POLYGON */
    238    if (ctx->Polygon._FrontBit == render_to_fbo)
    239       dw1 |= GEN8_RASTER_FRONT_WINDING_CCW;
    240 
    241    if (ctx->Polygon.CullFlag) {
    242       switch (ctx->Polygon.CullFaceMode) {
    243       case GL_FRONT:
    244          dw1 |= GEN8_RASTER_CULL_FRONT;
    245          break;
    246       case GL_BACK:
    247          dw1 |= GEN8_RASTER_CULL_BACK;
    248          break;
    249       case GL_FRONT_AND_BACK:
    250          dw1 |= GEN8_RASTER_CULL_BOTH;
    251          break;
    252       default:
    253          unreachable("not reached");
    254       }
    255    } else {
    256       dw1 |= GEN8_RASTER_CULL_NONE;
    257    }
    258 
    259    /* _NEW_POINT */
    260    if (ctx->Point.SmoothFlag)
    261       dw1 |= GEN8_RASTER_SMOOTH_POINT_ENABLE;
    262 
    263    if (_mesa_is_multisample_enabled(ctx))
    264       dw1 |= GEN8_RASTER_API_MULTISAMPLE_ENABLE;
    265 
    266    if (ctx->Polygon.OffsetFill)
    267       dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_SOLID;
    268 
    269    if (ctx->Polygon.OffsetLine)
    270       dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_WIREFRAME;
    271 
    272    if (ctx->Polygon.OffsetPoint)
    273       dw1 |= GEN6_SF_GLOBAL_DEPTH_OFFSET_POINT;
    274 
    275    switch (ctx->Polygon.FrontMode) {
    276    case GL_FILL:
    277       dw1 |= GEN6_SF_FRONT_SOLID;
    278       break;
    279    case GL_LINE:
    280       dw1 |= GEN6_SF_FRONT_WIREFRAME;
    281       break;
    282    case GL_POINT:
    283       dw1 |= GEN6_SF_FRONT_POINT;
    284       break;
    285 
    286    default:
    287       unreachable("not reached");
    288    }
    289 
    290    switch (ctx->Polygon.BackMode) {
    291    case GL_FILL:
    292       dw1 |= GEN6_SF_BACK_SOLID;
    293       break;
    294    case GL_LINE:
    295       dw1 |= GEN6_SF_BACK_WIREFRAME;
    296       break;
    297    case GL_POINT:
    298       dw1 |= GEN6_SF_BACK_POINT;
    299       break;
    300    default:
    301       unreachable("not reached");
    302    }
    303 
    304    /* _NEW_LINE */
    305    if (ctx->Line.SmoothFlag)
    306       dw1 |= GEN8_RASTER_LINE_AA_ENABLE;
    307 
    308    /* _NEW_SCISSOR */
    309    if (ctx->Scissor.EnableFlags)
    310       dw1 |= GEN8_RASTER_SCISSOR_ENABLE;
    311 
    312    /* _NEW_TRANSFORM */
    313    if (!ctx->Transform.DepthClamp) {
    314       if (brw->gen >= 9) {
    315          dw1 |= GEN9_RASTER_VIEWPORT_Z_NEAR_CLIP_TEST_ENABLE |
    316                 GEN9_RASTER_VIEWPORT_Z_FAR_CLIP_TEST_ENABLE;
    317       } else {
    318          dw1 |= GEN8_RASTER_VIEWPORT_Z_CLIP_TEST_ENABLE;
    319       }
    320    }
    321 
    322    /* BRW_NEW_CONSERVATIVE_RASTERIZATION */
    323    if (ctx->IntelConservativeRasterization) {
    324       if (brw->gen >= 9)
    325          dw1 |= GEN9_RASTER_CONSERVATIVE_RASTERIZATION_ENABLE;
    326    }
    327 
    328    BEGIN_BATCH(5);
    329    OUT_BATCH(_3DSTATE_RASTER << 16 | (5 - 2));
    330    OUT_BATCH(dw1);
    331    OUT_BATCH_F(ctx->Polygon.OffsetUnits * 2); /* constant.  copied from gen4 */
    332    OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */
    333    OUT_BATCH_F(ctx->Polygon.OffsetClamp); /* global depth offset clamp */
    334    ADVANCE_BATCH();
    335 }
    336 
    337 const struct brw_tracked_state gen8_raster_state = {
    338    .dirty = {
    339       .mesa  = _NEW_BUFFERS |
    340                _NEW_LINE |
    341                _NEW_MULTISAMPLE |
    342                _NEW_POINT |
    343                _NEW_POLYGON |
    344                _NEW_SCISSOR |
    345                _NEW_TRANSFORM,
    346       .brw   = BRW_NEW_BLORP |
    347                BRW_NEW_CONTEXT |
    348                BRW_NEW_CONSERVATIVE_RASTERIZATION,
    349    },
    350    .emit = upload_raster,
    351 };
    352