Home | History | Annotate | Download | only in vulkan
      1 /*
      2  * Copyright  2015 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 <assert.h>
     25 #include <stdbool.h>
     26 #include <string.h>
     27 #include <unistd.h>
     28 #include <fcntl.h>
     29 
     30 #include "anv_private.h"
     31 
     32 #include "genxml/gen_macros.h"
     33 #include "genxml/genX_pack.h"
     34 
     35 #if GEN_GEN == 8
     36 void
     37 gen8_cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
     38 {
     39    uint32_t count = cmd_buffer->state.dynamic.viewport.count;
     40    const VkViewport *viewports = cmd_buffer->state.dynamic.viewport.viewports;
     41    struct anv_state sf_clip_state =
     42       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 64, 64);
     43 
     44    for (uint32_t i = 0; i < count; i++) {
     45       const VkViewport *vp = &viewports[i];
     46 
     47       /* The gen7 state struct has just the matrix and guardband fields, the
     48        * gen8 struct adds the min/max viewport fields. */
     49       struct GENX(SF_CLIP_VIEWPORT) sf_clip_viewport = {
     50          .ViewportMatrixElementm00 = vp->width / 2,
     51          .ViewportMatrixElementm11 = vp->height / 2,
     52          .ViewportMatrixElementm22 = 1.0,
     53          .ViewportMatrixElementm30 = vp->x + vp->width / 2,
     54          .ViewportMatrixElementm31 = vp->y + vp->height / 2,
     55          .ViewportMatrixElementm32 = 0.0,
     56          .XMinClipGuardband = -1.0f,
     57          .XMaxClipGuardband = 1.0f,
     58          .YMinClipGuardband = -1.0f,
     59          .YMaxClipGuardband = 1.0f,
     60          .XMinViewPort = vp->x,
     61          .XMaxViewPort = vp->x + vp->width - 1,
     62          .YMinViewPort = vp->y,
     63          .YMaxViewPort = vp->y + vp->height - 1,
     64       };
     65 
     66       GENX(SF_CLIP_VIEWPORT_pack)(NULL, sf_clip_state.map + i * 64,
     67                                  &sf_clip_viewport);
     68    }
     69 
     70    if (!cmd_buffer->device->info.has_llc)
     71       anv_state_clflush(sf_clip_state);
     72 
     73    anv_batch_emit(&cmd_buffer->batch,
     74                   GENX(3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP), clip) {
     75       clip.SFClipViewportPointer = sf_clip_state.offset;
     76    }
     77 }
     78 
     79 void
     80 gen8_cmd_buffer_emit_depth_viewport(struct anv_cmd_buffer *cmd_buffer,
     81                                     bool depth_clamp_enable)
     82 {
     83    uint32_t count = cmd_buffer->state.dynamic.viewport.count;
     84    const VkViewport *viewports = cmd_buffer->state.dynamic.viewport.viewports;
     85    struct anv_state cc_state =
     86       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 8, 32);
     87 
     88    for (uint32_t i = 0; i < count; i++) {
     89       const VkViewport *vp = &viewports[i];
     90 
     91       struct GENX(CC_VIEWPORT) cc_viewport = {
     92          .MinimumDepth = depth_clamp_enable ? vp->minDepth : 0.0f,
     93          .MaximumDepth = depth_clamp_enable ? vp->maxDepth : 1.0f,
     94       };
     95 
     96       GENX(CC_VIEWPORT_pack)(NULL, cc_state.map + i * 8, &cc_viewport);
     97    }
     98 
     99    if (!cmd_buffer->device->info.has_llc)
    100       anv_state_clflush(cc_state);
    101 
    102    anv_batch_emit(&cmd_buffer->batch,
    103                   GENX(3DSTATE_VIEWPORT_STATE_POINTERS_CC), cc) {
    104       cc.CCViewportPointer = cc_state.offset;
    105    }
    106 }
    107 #endif
    108 
    109 static void
    110 __emit_genx_sf_state(struct anv_cmd_buffer *cmd_buffer)
    111 {
    112       uint32_t sf_dw[GENX(3DSTATE_SF_length)];
    113       struct GENX(3DSTATE_SF) sf = {
    114          GENX(3DSTATE_SF_header),
    115          .LineWidth = cmd_buffer->state.dynamic.line_width,
    116       };
    117       GENX(3DSTATE_SF_pack)(NULL, sf_dw, &sf);
    118       /* FIXME: gen9.fs */
    119       anv_batch_emit_merge(&cmd_buffer->batch, sf_dw,
    120                            cmd_buffer->state.pipeline->gen8.sf);
    121 }
    122 
    123 void
    124 gen9_emit_sf_state(struct anv_cmd_buffer *cmd_buffer);
    125 
    126 #if GEN_GEN == 9
    127 
    128 void
    129 gen9_emit_sf_state(struct anv_cmd_buffer *cmd_buffer)
    130 {
    131    __emit_genx_sf_state(cmd_buffer);
    132 }
    133 
    134 #endif
    135 
    136 #if GEN_GEN == 8
    137 
    138 static void
    139 __emit_sf_state(struct anv_cmd_buffer *cmd_buffer)
    140 {
    141    if (cmd_buffer->device->info.is_cherryview)
    142       gen9_emit_sf_state(cmd_buffer);
    143    else
    144       __emit_genx_sf_state(cmd_buffer);
    145 }
    146 
    147 #else
    148 
    149 static void
    150 __emit_sf_state(struct anv_cmd_buffer *cmd_buffer)
    151 {
    152    __emit_genx_sf_state(cmd_buffer);
    153 }
    154 
    155 #endif
    156 
    157 void
    158 genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
    159 {
    160    struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
    161 
    162    if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
    163                                   ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH)) {
    164       __emit_sf_state(cmd_buffer);
    165    }
    166 
    167    if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
    168                                   ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS)){
    169       uint32_t raster_dw[GENX(3DSTATE_RASTER_length)];
    170       struct GENX(3DSTATE_RASTER) raster = {
    171          GENX(3DSTATE_RASTER_header),
    172          .GlobalDepthOffsetConstant = cmd_buffer->state.dynamic.depth_bias.bias,
    173          .GlobalDepthOffsetScale = cmd_buffer->state.dynamic.depth_bias.slope,
    174          .GlobalDepthOffsetClamp = cmd_buffer->state.dynamic.depth_bias.clamp
    175       };
    176       GENX(3DSTATE_RASTER_pack)(NULL, raster_dw, &raster);
    177       anv_batch_emit_merge(&cmd_buffer->batch, raster_dw,
    178                            pipeline->gen8.raster);
    179    }
    180 
    181    /* Stencil reference values moved from COLOR_CALC_STATE in gen8 to
    182     * 3DSTATE_WM_DEPTH_STENCIL in gen9. That means the dirty bits gets split
    183     * across different state packets for gen8 and gen9. We handle that by
    184     * using a big old #if switch here.
    185     */
    186 #if GEN_GEN == 8
    187    if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS |
    188                                   ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE)) {
    189       struct anv_dynamic_state *d = &cmd_buffer->state.dynamic;
    190       struct anv_state cc_state =
    191          anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
    192                                             GENX(COLOR_CALC_STATE_length) * 4,
    193                                             64);
    194       struct GENX(COLOR_CALC_STATE) cc = {
    195          .BlendConstantColorRed = cmd_buffer->state.dynamic.blend_constants[0],
    196          .BlendConstantColorGreen = cmd_buffer->state.dynamic.blend_constants[1],
    197          .BlendConstantColorBlue = cmd_buffer->state.dynamic.blend_constants[2],
    198          .BlendConstantColorAlpha = cmd_buffer->state.dynamic.blend_constants[3],
    199          .StencilReferenceValue = d->stencil_reference.front & 0xff,
    200          .BackFaceStencilReferenceValue = d->stencil_reference.back & 0xff,
    201       };
    202       GENX(COLOR_CALC_STATE_pack)(NULL, cc_state.map, &cc);
    203 
    204       if (!cmd_buffer->device->info.has_llc)
    205          anv_state_clflush(cc_state);
    206 
    207       anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_CC_STATE_POINTERS), ccp) {
    208          ccp.ColorCalcStatePointer        = cc_state.offset;
    209          ccp.ColorCalcStatePointerValid   = true;
    210       }
    211    }
    212 
    213    if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
    214                                   ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
    215                                   ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK)) {
    216       uint32_t wm_depth_stencil_dw[GENX(3DSTATE_WM_DEPTH_STENCIL_length)];
    217       struct anv_dynamic_state *d = &cmd_buffer->state.dynamic;
    218 
    219       struct GENX(3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil) = {
    220          GENX(3DSTATE_WM_DEPTH_STENCIL_header),
    221 
    222          .StencilTestMask = d->stencil_compare_mask.front & 0xff,
    223          .StencilWriteMask = d->stencil_write_mask.front & 0xff,
    224 
    225          .BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
    226          .BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
    227       };
    228       GENX(3DSTATE_WM_DEPTH_STENCIL_pack)(NULL, wm_depth_stencil_dw,
    229                                           &wm_depth_stencil);
    230 
    231       anv_batch_emit_merge(&cmd_buffer->batch, wm_depth_stencil_dw,
    232                            pipeline->gen8.wm_depth_stencil);
    233    }
    234 #else
    235    if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {
    236       struct anv_state cc_state =
    237          anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
    238                                             GEN9_COLOR_CALC_STATE_length * 4,
    239                                             64);
    240       struct GEN9_COLOR_CALC_STATE cc = {
    241          .BlendConstantColorRed = cmd_buffer->state.dynamic.blend_constants[0],
    242          .BlendConstantColorGreen = cmd_buffer->state.dynamic.blend_constants[1],
    243          .BlendConstantColorBlue = cmd_buffer->state.dynamic.blend_constants[2],
    244          .BlendConstantColorAlpha = cmd_buffer->state.dynamic.blend_constants[3],
    245       };
    246       GEN9_COLOR_CALC_STATE_pack(NULL, cc_state.map, &cc);
    247 
    248       if (!cmd_buffer->device->info.has_llc)
    249          anv_state_clflush(cc_state);
    250 
    251       anv_batch_emit(&cmd_buffer->batch, GEN9_3DSTATE_CC_STATE_POINTERS, ccp) {
    252          ccp.ColorCalcStatePointer = cc_state.offset;
    253          ccp.ColorCalcStatePointerValid = true;
    254       }
    255    }
    256 
    257    if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
    258                                   ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
    259                                   ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK |
    260                                   ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE)) {
    261       uint32_t dwords[GEN9_3DSTATE_WM_DEPTH_STENCIL_length];
    262       struct anv_dynamic_state *d = &cmd_buffer->state.dynamic;
    263       struct GEN9_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
    264          GEN9_3DSTATE_WM_DEPTH_STENCIL_header,
    265 
    266          .StencilTestMask = d->stencil_compare_mask.front & 0xff,
    267          .StencilWriteMask = d->stencil_write_mask.front & 0xff,
    268 
    269          .BackfaceStencilTestMask = d->stencil_compare_mask.back & 0xff,
    270          .BackfaceStencilWriteMask = d->stencil_write_mask.back & 0xff,
    271 
    272          .StencilReferenceValue = d->stencil_reference.front & 0xff,
    273          .BackfaceStencilReferenceValue = d->stencil_reference.back & 0xff,
    274       };
    275       GEN9_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, dwords, &wm_depth_stencil);
    276 
    277       anv_batch_emit_merge(&cmd_buffer->batch, dwords,
    278                            pipeline->gen9.wm_depth_stencil);
    279    }
    280 #endif
    281 
    282    if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
    283                                   ANV_CMD_DIRTY_INDEX_BUFFER)) {
    284       anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_VF), vf) {
    285          vf.IndexedDrawCutIndexEnable  = pipeline->primitive_restart;
    286          vf.CutIndex                   = cmd_buffer->state.restart_index;
    287       }
    288    }
    289 
    290    cmd_buffer->state.dirty = 0;
    291 }
    292 
    293 void genX(CmdBindIndexBuffer)(
    294     VkCommandBuffer                             commandBuffer,
    295     VkBuffer                                    _buffer,
    296     VkDeviceSize                                offset,
    297     VkIndexType                                 indexType)
    298 {
    299    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    300    ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
    301 
    302    static const uint32_t vk_to_gen_index_type[] = {
    303       [VK_INDEX_TYPE_UINT16]                    = INDEX_WORD,
    304       [VK_INDEX_TYPE_UINT32]                    = INDEX_DWORD,
    305    };
    306 
    307    static const uint32_t restart_index_for_type[] = {
    308       [VK_INDEX_TYPE_UINT16]                    = UINT16_MAX,
    309       [VK_INDEX_TYPE_UINT32]                    = UINT32_MAX,
    310    };
    311 
    312    cmd_buffer->state.restart_index = restart_index_for_type[indexType];
    313 
    314    anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) {
    315       ib.IndexFormat                = vk_to_gen_index_type[indexType];
    316       ib.MemoryObjectControlState   = GENX(MOCS);
    317       ib.BufferStartingAddress      =
    318          (struct anv_address) { buffer->bo, buffer->offset + offset };
    319       ib.BufferSize                 = buffer->size - offset;
    320    }
    321 
    322    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
    323 }
    324 
    325 /* Set of stage bits for which are pipelined, i.e. they get queued by the
    326  * command streamer for later execution.
    327  */
    328 #define ANV_PIPELINE_STAGE_PIPELINED_BITS \
    329    (VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | \
    330     VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | \
    331     VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT | \
    332     VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT | \
    333     VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | \
    334     VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | \
    335     VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | \
    336     VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | \
    337     VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | \
    338     VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | \
    339     VK_PIPELINE_STAGE_TRANSFER_BIT | \
    340     VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT | \
    341     VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | \
    342     VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)
    343 
    344 void genX(CmdSetEvent)(
    345     VkCommandBuffer                             commandBuffer,
    346     VkEvent                                     _event,
    347     VkPipelineStageFlags                        stageMask)
    348 {
    349    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    350    ANV_FROM_HANDLE(anv_event, event, _event);
    351 
    352    anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
    353       if (stageMask & ANV_PIPELINE_STAGE_PIPELINED_BITS) {
    354          pc.StallAtPixelScoreboard = true;
    355          pc.CommandStreamerStallEnable = true;
    356       }
    357 
    358       pc.DestinationAddressType  = DAT_PPGTT,
    359       pc.PostSyncOperation       = WriteImmediateData,
    360       pc.Address = (struct anv_address) {
    361          &cmd_buffer->device->dynamic_state_block_pool.bo,
    362          event->state.offset
    363       };
    364       pc.ImmediateData           = VK_EVENT_SET;
    365    }
    366 }
    367 
    368 void genX(CmdResetEvent)(
    369     VkCommandBuffer                             commandBuffer,
    370     VkEvent                                     _event,
    371     VkPipelineStageFlags                        stageMask)
    372 {
    373    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    374    ANV_FROM_HANDLE(anv_event, event, _event);
    375 
    376    anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
    377       if (stageMask & ANV_PIPELINE_STAGE_PIPELINED_BITS) {
    378          pc.StallAtPixelScoreboard = true;
    379          pc.CommandStreamerStallEnable = true;
    380       }
    381 
    382       pc.DestinationAddressType  = DAT_PPGTT;
    383       pc.PostSyncOperation       = WriteImmediateData;
    384       pc.Address = (struct anv_address) {
    385          &cmd_buffer->device->dynamic_state_block_pool.bo,
    386          event->state.offset
    387       };
    388       pc.ImmediateData           = VK_EVENT_RESET;
    389    }
    390 }
    391 
    392 void genX(CmdWaitEvents)(
    393     VkCommandBuffer                             commandBuffer,
    394     uint32_t                                    eventCount,
    395     const VkEvent*                              pEvents,
    396     VkPipelineStageFlags                        srcStageMask,
    397     VkPipelineStageFlags                        destStageMask,
    398     uint32_t                                    memoryBarrierCount,
    399     const VkMemoryBarrier*                      pMemoryBarriers,
    400     uint32_t                                    bufferMemoryBarrierCount,
    401     const VkBufferMemoryBarrier*                pBufferMemoryBarriers,
    402     uint32_t                                    imageMemoryBarrierCount,
    403     const VkImageMemoryBarrier*                 pImageMemoryBarriers)
    404 {
    405    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    406    for (uint32_t i = 0; i < eventCount; i++) {
    407       ANV_FROM_HANDLE(anv_event, event, pEvents[i]);
    408 
    409       anv_batch_emit(&cmd_buffer->batch, GENX(MI_SEMAPHORE_WAIT), sem) {
    410          sem.WaitMode            = PollingMode,
    411          sem.CompareOperation    = COMPARE_SAD_EQUAL_SDD,
    412          sem.SemaphoreDataDword  = VK_EVENT_SET,
    413          sem.SemaphoreAddress = (struct anv_address) {
    414             &cmd_buffer->device->dynamic_state_block_pool.bo,
    415             event->state.offset
    416          };
    417       }
    418    }
    419 
    420    genX(CmdPipelineBarrier)(commandBuffer, srcStageMask, destStageMask,
    421                             false, /* byRegion */
    422                             memoryBarrierCount, pMemoryBarriers,
    423                             bufferMemoryBarrierCount, pBufferMemoryBarriers,
    424                             imageMemoryBarrierCount, pImageMemoryBarriers);
    425 }
    426