Home | History | Annotate | Download | only in ilo
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2013 LunarG, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Chia-I Wu <olv (at) lunarg.com>
     26  */
     27 
     28 #include "genhw/genhw.h"
     29 #include "core/ilo_builder_3d.h"
     30 #include "core/ilo_builder_render.h"
     31 
     32 #include "ilo_blitter.h"
     33 #include "ilo_resource.h"
     34 #include "ilo_shader.h"
     35 #include "ilo_state.h"
     36 #include "ilo_render_gen.h"
     37 
     38 static void
     39 gen8_wa_pre_depth(struct ilo_render *r)
     40 {
     41    ILO_DEV_ASSERT(r->dev, 8, 8);
     42 
     43    /*
     44     * From the Ivy Bridge PRM, volume 2 part 1, page 315:
     45     *
     46     *     "Restriction: Prior to changing Depth/Stencil Buffer state (i.e.,
     47     *      any combination of 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS,
     48     *      3DSTATE_STENCIL_BUFFER, 3DSTATE_HIER_DEPTH_BUFFER) SW must first
     49     *      issue a pipelined depth stall (PIPE_CONTROL with Depth Stall bit
     50     *      set), followed by a pipelined depth cache flush (PIPE_CONTROL with
     51     *      Depth Flush Bit set, followed by another pipelined depth stall
     52     *      (PIPE_CONTROL with Depth Stall Bit set), unless SW can otherwise
     53     *      guarantee that the pipeline from WM onwards is already flushed
     54     *      (e.g., via a preceding MI_FLUSH)."
     55     */
     56    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
     57    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_CACHE_FLUSH);
     58    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_DEPTH_STALL);
     59 }
     60 
     61 #define DIRTY(state) (session->pipe_dirty & ILO_DIRTY_ ## state)
     62 
     63 static void
     64 gen8_draw_sf(struct ilo_render *r,
     65              const struct ilo_state_vector *vec,
     66              struct ilo_render_draw_session *session)
     67 {
     68    /* 3DSTATE_RASTER */
     69    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_RASTER)
     70       gen8_3DSTATE_RASTER(r->builder, &vec->rasterizer->rs);
     71 
     72    /* 3DSTATE_SBE and 3DSTATE_SBE_SWIZ */
     73    if (DIRTY(FS)) {
     74       const struct ilo_state_sbe *sbe = ilo_shader_get_kernel_sbe(vec->fs);
     75 
     76       gen8_3DSTATE_SBE(r->builder, sbe);
     77       gen8_3DSTATE_SBE_SWIZ(r->builder, sbe);
     78    }
     79 
     80    /* 3DSTATE_SF */
     81    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SF)
     82       gen7_3DSTATE_SF(r->builder, &vec->rasterizer->rs);
     83 }
     84 
     85 static void
     86 gen8_draw_wm(struct ilo_render *r,
     87              const struct ilo_state_vector *vec,
     88              struct ilo_render_draw_session *session)
     89 {
     90    const union ilo_shader_cso *cso = ilo_shader_get_kernel_cso(vec->fs);
     91    const uint32_t kernel_offset = ilo_shader_get_kernel_offset(vec->fs);
     92 
     93    /* 3DSTATE_WM */
     94    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM)
     95       gen8_3DSTATE_WM(r->builder, &vec->rasterizer->rs);
     96 
     97    if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL)
     98       gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, &vec->blend->cc);
     99 
    100    /* 3DSTATE_WM_HZ_OP and 3DSTATE_WM_CHROMAKEY */
    101    if (r->hw_ctx_changed) {
    102       gen8_disable_3DSTATE_WM_HZ_OP(r->builder);
    103       gen8_3DSTATE_WM_CHROMAKEY(r->builder);
    104    }
    105 
    106    /* 3DSTATE_BINDING_TABLE_POINTERS_PS */
    107    if (session->binding_table_fs_changed) {
    108       gen7_3DSTATE_BINDING_TABLE_POINTERS_PS(r->builder,
    109             r->state.wm.BINDING_TABLE_STATE);
    110    }
    111 
    112    /* 3DSTATE_SAMPLER_STATE_POINTERS_PS */
    113    if (session->sampler_fs_changed) {
    114       gen7_3DSTATE_SAMPLER_STATE_POINTERS_PS(r->builder,
    115             r->state.wm.SAMPLER_STATE);
    116    }
    117 
    118    /* 3DSTATE_CONSTANT_PS */
    119    if (session->pcb_fs_changed) {
    120       gen7_3DSTATE_CONSTANT_PS(r->builder,
    121             &r->state.wm.PUSH_CONSTANT_BUFFER,
    122             &r->state.wm.PUSH_CONSTANT_BUFFER_size,
    123             1);
    124    }
    125 
    126    /* 3DSTATE_PS */
    127    if (DIRTY(FS) || r->instruction_bo_changed)
    128       gen8_3DSTATE_PS(r->builder, &cso->ps, kernel_offset, r->fs_scratch.bo);
    129 
    130    /* 3DSTATE_PS_EXTRA */
    131    if (DIRTY(FS))
    132       gen8_3DSTATE_PS_EXTRA(r->builder, &cso->ps);
    133 
    134    /* 3DSTATE_PS_BLEND */
    135    if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_PS_BLEND)
    136       gen8_3DSTATE_PS_BLEND(r->builder, &vec->blend->cc);
    137 
    138    /* 3DSTATE_SCISSOR_STATE_POINTERS */
    139    if (session->scissor_changed) {
    140       gen6_3DSTATE_SCISSOR_STATE_POINTERS(r->builder,
    141             r->state.SCISSOR_RECT);
    142    }
    143 
    144    /* 3DSTATE_DEPTH_BUFFER and 3DSTATE_CLEAR_PARAMS */
    145    if (DIRTY(FB) || r->batch_bo_changed) {
    146       const struct ilo_state_zs *zs;
    147       uint32_t clear_params;
    148 
    149       if (vec->fb.state.zsbuf) {
    150          const struct ilo_surface_cso *surface =
    151             (const struct ilo_surface_cso *) vec->fb.state.zsbuf;
    152          const struct ilo_texture_slice *slice =
    153             ilo_texture_get_slice(ilo_texture(surface->base.texture),
    154                   surface->base.u.tex.level, surface->base.u.tex.first_layer);
    155 
    156          assert(!surface->is_rt);
    157          zs = &surface->u.zs;
    158          clear_params = slice->clear_value;
    159       }
    160       else {
    161          zs = &vec->fb.null_zs;
    162          clear_params = 0;
    163       }
    164 
    165       gen8_wa_pre_depth(r);
    166 
    167       gen6_3DSTATE_DEPTH_BUFFER(r->builder, zs);
    168       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder, zs);
    169       gen6_3DSTATE_STENCIL_BUFFER(r->builder, zs);
    170       gen7_3DSTATE_CLEAR_PARAMS(r->builder, clear_params);
    171    }
    172 }
    173 
    174 static void
    175 gen8_draw_wm_sample_pattern(struct ilo_render *r,
    176                             const struct ilo_state_vector *vec,
    177                             struct ilo_render_draw_session *session)
    178 {
    179    /* 3DSTATE_SAMPLE_PATTERN */
    180    if (r->hw_ctx_changed)
    181       gen8_3DSTATE_SAMPLE_PATTERN(r->builder, &r->sample_pattern);
    182 }
    183 
    184 static void
    185 gen8_draw_wm_multisample(struct ilo_render *r,
    186                          const struct ilo_state_vector *vec,
    187                          struct ilo_render_draw_session *session)
    188 {
    189    /* 3DSTATE_MULTISAMPLE */
    190    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_MULTISAMPLE)
    191       gen8_3DSTATE_MULTISAMPLE(r->builder, &vec->rasterizer->rs);
    192 
    193    /* 3DSTATE_SAMPLE_MASK */
    194    if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_SAMPLE_MASK)
    195       gen6_3DSTATE_SAMPLE_MASK(r->builder, &vec->rasterizer->rs);
    196 }
    197 
    198 static void
    199 gen8_draw_vf(struct ilo_render *r,
    200              const struct ilo_state_vector *vec,
    201              struct ilo_render_draw_session *session)
    202 {
    203    /* 3DSTATE_INDEX_BUFFER */
    204    if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_INDEX_BUFFER) ||
    205        DIRTY(IB) || r->batch_bo_changed)
    206       gen8_3DSTATE_INDEX_BUFFER(r->builder, &vec->ve->vf, &vec->ib.ib);
    207 
    208    /* 3DSTATE_VF */
    209    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF)
    210       gen75_3DSTATE_VF(r->builder, &vec->ve->vf);
    211 
    212    /* 3DSTATE_VERTEX_BUFFERS */
    213    if ((session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_BUFFERS) ||
    214        DIRTY(VB) || DIRTY(VE) || r->batch_bo_changed) {
    215       gen6_3DSTATE_VERTEX_BUFFERS(r->builder, &vec->ve->vf,
    216             vec->vb.vb, vec->ve->vb_count);
    217    }
    218 
    219    /* 3DSTATE_VERTEX_ELEMENTS */
    220    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VERTEX_ELEMENTS)
    221       gen6_3DSTATE_VERTEX_ELEMENTS(r->builder, &vec->ve->vf);
    222 
    223    gen8_3DSTATE_VF_TOPOLOGY(r->builder, vec->draw_info.topology);
    224 
    225    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF_INSTANCING) {
    226       const uint8_t attr_count = ilo_state_vf_get_attr_count(&vec->ve->vf);
    227       uint8_t i;
    228 
    229       for (i = 0; i < attr_count; i++)
    230          gen8_3DSTATE_VF_INSTANCING(r->builder, &vec->ve->vf, i);
    231    }
    232 
    233    if (session->vf_delta.dirty & ILO_STATE_VF_3DSTATE_VF_SGVS)
    234       gen8_3DSTATE_VF_SGVS(r->builder, &vec->ve->vf);
    235 }
    236 
    237 void
    238 ilo_render_emit_draw_commands_gen8(struct ilo_render *render,
    239                                    const struct ilo_state_vector *vec,
    240                                    struct ilo_render_draw_session *session)
    241 {
    242    ILO_DEV_ASSERT(render->dev, 8, 8);
    243 
    244    /*
    245     * We try to keep the order of the commands match, as closely as possible,
    246     * that of the classic i965 driver.  It allows us to compare the command
    247     * streams easily.
    248     */
    249    gen6_draw_common_select(render, vec, session);
    250    gen6_draw_common_sip(render, vec, session);
    251    gen6_draw_vf_statistics(render, vec, session);
    252    gen8_draw_wm_sample_pattern(render, vec, session);
    253    gen6_draw_common_base_address(render, vec, session);
    254    gen7_draw_common_pointers_1(render, vec, session);
    255    gen7_draw_common_pcb_alloc(render, vec, session);
    256    gen7_draw_common_urb(render, vec, session);
    257    gen7_draw_common_pointers_2(render, vec, session);
    258    gen8_draw_wm_multisample(render, vec, session);
    259    gen7_draw_gs(render, vec, session);
    260    gen7_draw_hs(render, vec, session);
    261    gen7_draw_te(render, vec, session);
    262    gen7_draw_ds(render, vec, session);
    263    gen7_draw_vs(render, vec, session);
    264    gen7_draw_sol(render, vec, session);
    265    gen6_draw_clip(render, vec, session);
    266    gen8_draw_sf(render, vec, session);
    267    gen8_draw_wm(render, vec, session);
    268    gen6_draw_wm_raster(render, vec, session);
    269    gen6_draw_sf_rect(render, vec, session);
    270    gen8_draw_vf(render, vec, session);
    271 
    272    ilo_render_3dprimitive(render, &vec->draw_info);
    273 }
    274 
    275 int
    276 ilo_render_get_draw_commands_len_gen8(const struct ilo_render *render,
    277                                       const struct ilo_state_vector *vec)
    278 {
    279    static int len;
    280 
    281    ILO_DEV_ASSERT(render->dev, 8, 8);
    282 
    283    if (!len) {
    284       len += GEN7_3DSTATE_URB_ANY__SIZE * 4;
    285       len += GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_ANY__SIZE * 5;
    286       len += GEN6_3DSTATE_CONSTANT_ANY__SIZE * 5;
    287       len += GEN7_3DSTATE_POINTERS_ANY__SIZE * (5 + 5 + 4);
    288       len += GEN7_3DSTATE_SO_BUFFER__SIZE * 4;
    289       len += GEN6_PIPE_CONTROL__SIZE * 5;
    290 
    291       len +=
    292          GEN6_STATE_BASE_ADDRESS__SIZE +
    293          GEN6_STATE_SIP__SIZE +
    294          GEN6_3DSTATE_VF_STATISTICS__SIZE +
    295          GEN6_PIPELINE_SELECT__SIZE +
    296          GEN6_3DSTATE_CLEAR_PARAMS__SIZE +
    297          GEN6_3DSTATE_DEPTH_BUFFER__SIZE +
    298          GEN6_3DSTATE_STENCIL_BUFFER__SIZE +
    299          GEN6_3DSTATE_HIER_DEPTH_BUFFER__SIZE +
    300          GEN6_3DSTATE_VERTEX_BUFFERS__SIZE +
    301          GEN6_3DSTATE_VERTEX_ELEMENTS__SIZE +
    302          GEN6_3DSTATE_INDEX_BUFFER__SIZE +
    303          GEN75_3DSTATE_VF__SIZE +
    304          GEN6_3DSTATE_VS__SIZE +
    305          GEN6_3DSTATE_GS__SIZE +
    306          GEN6_3DSTATE_CLIP__SIZE +
    307          GEN6_3DSTATE_SF__SIZE +
    308          GEN6_3DSTATE_WM__SIZE +
    309          GEN6_3DSTATE_SAMPLE_MASK__SIZE +
    310          GEN7_3DSTATE_HS__SIZE +
    311          GEN7_3DSTATE_TE__SIZE +
    312          GEN7_3DSTATE_DS__SIZE +
    313          GEN7_3DSTATE_STREAMOUT__SIZE +
    314          GEN7_3DSTATE_SBE__SIZE +
    315          GEN7_3DSTATE_PS__SIZE +
    316          GEN6_3DSTATE_DRAWING_RECTANGLE__SIZE +
    317          GEN6_3DSTATE_POLY_STIPPLE_OFFSET__SIZE +
    318          GEN6_3DSTATE_POLY_STIPPLE_PATTERN__SIZE +
    319          GEN6_3DSTATE_LINE_STIPPLE__SIZE +
    320          GEN6_3DSTATE_AA_LINE_PARAMETERS__SIZE +
    321          GEN6_3DSTATE_MULTISAMPLE__SIZE +
    322          GEN7_3DSTATE_SO_DECL_LIST__SIZE +
    323          GEN6_3DPRIMITIVE__SIZE;
    324 
    325       len +=
    326          GEN8_3DSTATE_VF_INSTANCING__SIZE * 33 +
    327          GEN8_3DSTATE_VF_SGVS__SIZE +
    328          GEN8_3DSTATE_VF_TOPOLOGY__SIZE +
    329          GEN8_3DSTATE_SBE_SWIZ__SIZE +
    330          GEN8_3DSTATE_RASTER__SIZE +
    331          GEN8_3DSTATE_WM_CHROMAKEY__SIZE +
    332          GEN8_3DSTATE_WM_DEPTH_STENCIL__SIZE +
    333          GEN8_3DSTATE_WM_HZ_OP__SIZE +
    334          GEN8_3DSTATE_PS_EXTRA__SIZE +
    335          GEN8_3DSTATE_PS_BLEND__SIZE +
    336          GEN8_3DSTATE_SAMPLE_PATTERN__SIZE;
    337    }
    338 
    339    return len;
    340 }
    341 
    342 int
    343 ilo_render_get_rectlist_commands_len_gen8(const struct ilo_render *render,
    344                                           const struct ilo_blitter *blitter)
    345 {
    346    ILO_DEV_ASSERT(render->dev, 8, 8);
    347 
    348    return 96;
    349 }
    350 
    351 void
    352 ilo_render_emit_rectlist_commands_gen8(struct ilo_render *r,
    353                                        const struct ilo_blitter *blitter,
    354                                        const struct ilo_render_rectlist_session *session)
    355 {
    356    ILO_DEV_ASSERT(r->dev, 8, 8);
    357 
    358    gen8_wa_pre_depth(r);
    359 
    360    if (blitter->uses & (ILO_BLITTER_USE_FB_DEPTH |
    361                         ILO_BLITTER_USE_FB_STENCIL))
    362       gen6_3DSTATE_DEPTH_BUFFER(r->builder, &blitter->fb.dst.u.zs);
    363 
    364    if (blitter->uses & ILO_BLITTER_USE_FB_DEPTH) {
    365       gen6_3DSTATE_HIER_DEPTH_BUFFER(r->builder,
    366             &blitter->fb.dst.u.zs);
    367    }
    368 
    369    if (blitter->uses & ILO_BLITTER_USE_FB_STENCIL) {
    370       gen6_3DSTATE_STENCIL_BUFFER(r->builder,
    371             &blitter->fb.dst.u.zs);
    372    }
    373 
    374    gen7_3DSTATE_CLEAR_PARAMS(r->builder,
    375          blitter->depth_clear_value);
    376 
    377    gen6_3DSTATE_DRAWING_RECTANGLE(r->builder, 0, 0,
    378          blitter->fb.width, blitter->fb.height);
    379 
    380    gen8_3DSTATE_WM_HZ_OP(r->builder, &blitter->fb.rs,
    381          blitter->fb.width, blitter->fb.height);
    382 
    383    ilo_render_pipe_control(r, GEN6_PIPE_CONTROL_WRITE_IMM);
    384 
    385    gen8_disable_3DSTATE_WM_HZ_OP(r->builder);
    386 }
    387