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 "vk_format_info.h"
     33 
     34 /** \file anv_cmd_buffer.c
     35  *
     36  * This file contains all of the stuff for emitting commands into a command
     37  * buffer.  This includes implementations of most of the vkCmd*
     38  * entrypoints.  This file is concerned entirely with state emission and
     39  * not with the command buffer data structure itself.  As far as this file
     40  * is concerned, most of anv_cmd_buffer is magic.
     41  */
     42 
     43 /* TODO: These are taken from GLES.  We should check the Vulkan spec */
     44 const struct anv_dynamic_state default_dynamic_state = {
     45    .viewport = {
     46       .count = 0,
     47    },
     48    .scissor = {
     49       .count = 0,
     50    },
     51    .line_width = 1.0f,
     52    .depth_bias = {
     53       .bias = 0.0f,
     54       .clamp = 0.0f,
     55       .slope = 0.0f,
     56    },
     57    .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
     58    .depth_bounds = {
     59       .min = 0.0f,
     60       .max = 1.0f,
     61    },
     62    .stencil_compare_mask = {
     63       .front = ~0u,
     64       .back = ~0u,
     65    },
     66    .stencil_write_mask = {
     67       .front = ~0u,
     68       .back = ~0u,
     69    },
     70    .stencil_reference = {
     71       .front = 0u,
     72       .back = 0u,
     73    },
     74 };
     75 
     76 void
     77 anv_dynamic_state_copy(struct anv_dynamic_state *dest,
     78                        const struct anv_dynamic_state *src,
     79                        uint32_t copy_mask)
     80 {
     81    if (copy_mask & (1 << VK_DYNAMIC_STATE_VIEWPORT)) {
     82       dest->viewport.count = src->viewport.count;
     83       typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
     84                    src->viewport.count);
     85    }
     86 
     87    if (copy_mask & (1 << VK_DYNAMIC_STATE_SCISSOR)) {
     88       dest->scissor.count = src->scissor.count;
     89       typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
     90                    src->scissor.count);
     91    }
     92 
     93    if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH))
     94       dest->line_width = src->line_width;
     95 
     96    if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS))
     97       dest->depth_bias = src->depth_bias;
     98 
     99    if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS))
    100       typed_memcpy(dest->blend_constants, src->blend_constants, 4);
    101 
    102    if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS))
    103       dest->depth_bounds = src->depth_bounds;
    104 
    105    if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))
    106       dest->stencil_compare_mask = src->stencil_compare_mask;
    107 
    108    if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))
    109       dest->stencil_write_mask = src->stencil_write_mask;
    110 
    111    if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE))
    112       dest->stencil_reference = src->stencil_reference;
    113 }
    114 
    115 static void
    116 anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
    117 {
    118    struct anv_cmd_state *state = &cmd_buffer->state;
    119 
    120    memset(state, 0, sizeof(*state));
    121 
    122    state->current_pipeline = UINT32_MAX;
    123    state->restart_index = UINT32_MAX;
    124    state->gfx.dynamic = default_dynamic_state;
    125 }
    126 
    127 static void
    128 anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer,
    129                               struct anv_cmd_pipeline_state *pipe_state)
    130 {
    131    for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++)
    132       vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]);
    133 }
    134 
    135 static void
    136 anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer)
    137 {
    138    struct anv_cmd_state *state = &cmd_buffer->state;
    139 
    140    anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base);
    141    anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base);
    142 
    143    for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++)
    144       vk_free(&cmd_buffer->pool->alloc, state->push_constants[i]);
    145 
    146    vk_free(&cmd_buffer->pool->alloc, state->attachments);
    147 }
    148 
    149 static void
    150 anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
    151 {
    152    anv_cmd_state_finish(cmd_buffer);
    153    anv_cmd_state_init(cmd_buffer);
    154 }
    155 
    156 VkResult
    157 anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
    158                                           gl_shader_stage stage, uint32_t size)
    159 {
    160    struct anv_push_constants **ptr = &cmd_buffer->state.push_constants[stage];
    161 
    162    if (*ptr == NULL) {
    163       *ptr = vk_alloc(&cmd_buffer->pool->alloc, size, 8,
    164                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    165       if (*ptr == NULL) {
    166          anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
    167          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
    168       }
    169    } else if ((*ptr)->size < size) {
    170       *ptr = vk_realloc(&cmd_buffer->pool->alloc, *ptr, size, 8,
    171                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    172       if (*ptr == NULL) {
    173          anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
    174          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
    175       }
    176    }
    177    (*ptr)->size = size;
    178 
    179    return VK_SUCCESS;
    180 }
    181 
    182 static VkResult anv_create_cmd_buffer(
    183     struct anv_device *                         device,
    184     struct anv_cmd_pool *                       pool,
    185     VkCommandBufferLevel                        level,
    186     VkCommandBuffer*                            pCommandBuffer)
    187 {
    188    struct anv_cmd_buffer *cmd_buffer;
    189    VkResult result;
    190 
    191    cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
    192                           VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    193    if (cmd_buffer == NULL)
    194       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
    195 
    196    cmd_buffer->batch.status = VK_SUCCESS;
    197 
    198    cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
    199    cmd_buffer->device = device;
    200    cmd_buffer->pool = pool;
    201    cmd_buffer->level = level;
    202 
    203    result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
    204    if (result != VK_SUCCESS)
    205       goto fail;
    206 
    207    anv_state_stream_init(&cmd_buffer->surface_state_stream,
    208                          &device->surface_state_pool, 4096);
    209    anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
    210                          &device->dynamic_state_pool, 16384);
    211 
    212    anv_cmd_state_init(cmd_buffer);
    213 
    214    if (pool) {
    215       list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
    216    } else {
    217       /* Init the pool_link so we can safefly call list_del when we destroy
    218        * the command buffer
    219        */
    220       list_inithead(&cmd_buffer->pool_link);
    221    }
    222 
    223    *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
    224 
    225    return VK_SUCCESS;
    226 
    227  fail:
    228    vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
    229 
    230    return result;
    231 }
    232 
    233 VkResult anv_AllocateCommandBuffers(
    234     VkDevice                                    _device,
    235     const VkCommandBufferAllocateInfo*          pAllocateInfo,
    236     VkCommandBuffer*                            pCommandBuffers)
    237 {
    238    ANV_FROM_HANDLE(anv_device, device, _device);
    239    ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
    240 
    241    VkResult result = VK_SUCCESS;
    242    uint32_t i;
    243 
    244    for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
    245       result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
    246                                      &pCommandBuffers[i]);
    247       if (result != VK_SUCCESS)
    248          break;
    249    }
    250 
    251    if (result != VK_SUCCESS) {
    252       anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
    253                              i, pCommandBuffers);
    254       for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
    255          pCommandBuffers[i] = VK_NULL_HANDLE;
    256    }
    257 
    258    return result;
    259 }
    260 
    261 static void
    262 anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
    263 {
    264    list_del(&cmd_buffer->pool_link);
    265 
    266    anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
    267 
    268    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
    269    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
    270 
    271    anv_cmd_state_finish(cmd_buffer);
    272 
    273    vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
    274 }
    275 
    276 void anv_FreeCommandBuffers(
    277     VkDevice                                    device,
    278     VkCommandPool                               commandPool,
    279     uint32_t                                    commandBufferCount,
    280     const VkCommandBuffer*                      pCommandBuffers)
    281 {
    282    for (uint32_t i = 0; i < commandBufferCount; i++) {
    283       ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
    284 
    285       if (!cmd_buffer)
    286          continue;
    287 
    288       anv_cmd_buffer_destroy(cmd_buffer);
    289    }
    290 }
    291 
    292 VkResult
    293 anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
    294 {
    295    cmd_buffer->usage_flags = 0;
    296    anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
    297    anv_cmd_state_reset(cmd_buffer);
    298 
    299    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
    300    anv_state_stream_init(&cmd_buffer->surface_state_stream,
    301                          &cmd_buffer->device->surface_state_pool, 4096);
    302 
    303    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
    304    anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
    305                          &cmd_buffer->device->dynamic_state_pool, 16384);
    306    return VK_SUCCESS;
    307 }
    308 
    309 VkResult anv_ResetCommandBuffer(
    310     VkCommandBuffer                             commandBuffer,
    311     VkCommandBufferResetFlags                   flags)
    312 {
    313    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    314    return anv_cmd_buffer_reset(cmd_buffer);
    315 }
    316 
    317 void
    318 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
    319 {
    320    switch (cmd_buffer->device->info.gen) {
    321    case 7:
    322       if (cmd_buffer->device->info.is_haswell)
    323          return gen75_cmd_buffer_emit_state_base_address(cmd_buffer);
    324       else
    325          return gen7_cmd_buffer_emit_state_base_address(cmd_buffer);
    326    case 8:
    327       return gen8_cmd_buffer_emit_state_base_address(cmd_buffer);
    328    case 9:
    329       return gen9_cmd_buffer_emit_state_base_address(cmd_buffer);
    330    case 10:
    331       return gen10_cmd_buffer_emit_state_base_address(cmd_buffer);
    332    default:
    333       unreachable("unsupported gen\n");
    334    }
    335 }
    336 
    337 void anv_CmdBindPipeline(
    338     VkCommandBuffer                             commandBuffer,
    339     VkPipelineBindPoint                         pipelineBindPoint,
    340     VkPipeline                                  _pipeline)
    341 {
    342    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    343    ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
    344 
    345    switch (pipelineBindPoint) {
    346    case VK_PIPELINE_BIND_POINT_COMPUTE:
    347       cmd_buffer->state.compute.base.pipeline = pipeline;
    348       cmd_buffer->state.compute.pipeline_dirty = true;
    349       cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
    350       cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
    351       break;
    352 
    353    case VK_PIPELINE_BIND_POINT_GRAPHICS:
    354       cmd_buffer->state.gfx.base.pipeline = pipeline;
    355       cmd_buffer->state.gfx.vb_dirty |= pipeline->vb_used;
    356       cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
    357       cmd_buffer->state.push_constants_dirty |= pipeline->active_stages;
    358       cmd_buffer->state.descriptors_dirty |= pipeline->active_stages;
    359 
    360       /* Apply the dynamic state from the pipeline */
    361       cmd_buffer->state.gfx.dirty |= pipeline->dynamic_state_mask;
    362       anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,
    363                              &pipeline->dynamic_state,
    364                              pipeline->dynamic_state_mask);
    365       break;
    366 
    367    default:
    368       assert(!"invalid bind point");
    369       break;
    370    }
    371 }
    372 
    373 void anv_CmdSetViewport(
    374     VkCommandBuffer                             commandBuffer,
    375     uint32_t                                    firstViewport,
    376     uint32_t                                    viewportCount,
    377     const VkViewport*                           pViewports)
    378 {
    379    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    380 
    381    const uint32_t total_count = firstViewport + viewportCount;
    382    if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)
    383       cmd_buffer->state.gfx.dynamic.viewport.count = total_count;
    384 
    385    memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,
    386           pViewports, viewportCount * sizeof(*pViewports));
    387 
    388    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
    389 }
    390 
    391 void anv_CmdSetScissor(
    392     VkCommandBuffer                             commandBuffer,
    393     uint32_t                                    firstScissor,
    394     uint32_t                                    scissorCount,
    395     const VkRect2D*                             pScissors)
    396 {
    397    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    398 
    399    const uint32_t total_count = firstScissor + scissorCount;
    400    if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)
    401       cmd_buffer->state.gfx.dynamic.scissor.count = total_count;
    402 
    403    memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,
    404           pScissors, scissorCount * sizeof(*pScissors));
    405 
    406    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
    407 }
    408 
    409 void anv_CmdSetLineWidth(
    410     VkCommandBuffer                             commandBuffer,
    411     float                                       lineWidth)
    412 {
    413    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    414 
    415    cmd_buffer->state.gfx.dynamic.line_width = lineWidth;
    416    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
    417 }
    418 
    419 void anv_CmdSetDepthBias(
    420     VkCommandBuffer                             commandBuffer,
    421     float                                       depthBiasConstantFactor,
    422     float                                       depthBiasClamp,
    423     float                                       depthBiasSlopeFactor)
    424 {
    425    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    426 
    427    cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;
    428    cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;
    429    cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;
    430 
    431    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
    432 }
    433 
    434 void anv_CmdSetBlendConstants(
    435     VkCommandBuffer                             commandBuffer,
    436     const float                                 blendConstants[4])
    437 {
    438    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    439 
    440    memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,
    441           blendConstants, sizeof(float) * 4);
    442 
    443    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
    444 }
    445 
    446 void anv_CmdSetDepthBounds(
    447     VkCommandBuffer                             commandBuffer,
    448     float                                       minDepthBounds,
    449     float                                       maxDepthBounds)
    450 {
    451    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    452 
    453    cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;
    454    cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;
    455 
    456    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
    457 }
    458 
    459 void anv_CmdSetStencilCompareMask(
    460     VkCommandBuffer                             commandBuffer,
    461     VkStencilFaceFlags                          faceMask,
    462     uint32_t                                    compareMask)
    463 {
    464    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    465 
    466    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
    467       cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;
    468    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
    469       cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;
    470 
    471    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
    472 }
    473 
    474 void anv_CmdSetStencilWriteMask(
    475     VkCommandBuffer                             commandBuffer,
    476     VkStencilFaceFlags                          faceMask,
    477     uint32_t                                    writeMask)
    478 {
    479    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    480 
    481    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
    482       cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;
    483    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
    484       cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;
    485 
    486    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
    487 }
    488 
    489 void anv_CmdSetStencilReference(
    490     VkCommandBuffer                             commandBuffer,
    491     VkStencilFaceFlags                          faceMask,
    492     uint32_t                                    reference)
    493 {
    494    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    495 
    496    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
    497       cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;
    498    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
    499       cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;
    500 
    501    cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
    502 }
    503 
    504 static void
    505 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
    506                                    VkPipelineBindPoint bind_point,
    507                                    struct anv_pipeline_layout *layout,
    508                                    uint32_t set_index,
    509                                    struct anv_descriptor_set *set,
    510                                    uint32_t *dynamic_offset_count,
    511                                    const uint32_t **dynamic_offsets)
    512 {
    513    struct anv_descriptor_set_layout *set_layout =
    514       layout->set[set_index].layout;
    515 
    516    struct anv_cmd_pipeline_state *pipe_state;
    517    if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
    518       pipe_state = &cmd_buffer->state.compute.base;
    519    } else {
    520       assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
    521       pipe_state = &cmd_buffer->state.gfx.base;
    522    }
    523    pipe_state->descriptors[set_index] = set;
    524 
    525    if (dynamic_offsets) {
    526       if (set_layout->dynamic_offset_count > 0) {
    527          uint32_t dynamic_offset_start =
    528             layout->set[set_index].dynamic_offset_start;
    529 
    530          /* Assert that everything is in range */
    531          assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
    532          assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
    533                 ARRAY_SIZE(pipe_state->dynamic_offsets));
    534 
    535          typed_memcpy(&pipe_state->dynamic_offsets[dynamic_offset_start],
    536                       *dynamic_offsets, set_layout->dynamic_offset_count);
    537 
    538          *dynamic_offsets += set_layout->dynamic_offset_count;
    539          *dynamic_offset_count -= set_layout->dynamic_offset_count;
    540       }
    541    }
    542 
    543    if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
    544       cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
    545    } else {
    546       assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
    547       cmd_buffer->state.descriptors_dirty |=
    548          set_layout->shader_stages & VK_SHADER_STAGE_ALL_GRAPHICS;
    549    }
    550 }
    551 
    552 void anv_CmdBindDescriptorSets(
    553     VkCommandBuffer                             commandBuffer,
    554     VkPipelineBindPoint                         pipelineBindPoint,
    555     VkPipelineLayout                            _layout,
    556     uint32_t                                    firstSet,
    557     uint32_t                                    descriptorSetCount,
    558     const VkDescriptorSet*                      pDescriptorSets,
    559     uint32_t                                    dynamicOffsetCount,
    560     const uint32_t*                             pDynamicOffsets)
    561 {
    562    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    563    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
    564 
    565    assert(firstSet + descriptorSetCount < MAX_SETS);
    566 
    567    for (uint32_t i = 0; i < descriptorSetCount; i++) {
    568       ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
    569       anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
    570                                          layout, firstSet + i, set,
    571                                          &dynamicOffsetCount,
    572                                          &pDynamicOffsets);
    573    }
    574 }
    575 
    576 void anv_CmdBindVertexBuffers(
    577     VkCommandBuffer                             commandBuffer,
    578     uint32_t                                    firstBinding,
    579     uint32_t                                    bindingCount,
    580     const VkBuffer*                             pBuffers,
    581     const VkDeviceSize*                         pOffsets)
    582 {
    583    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    584    struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
    585 
    586    /* We have to defer setting up vertex buffer since we need the buffer
    587     * stride from the pipeline. */
    588 
    589    assert(firstBinding + bindingCount <= MAX_VBS);
    590    for (uint32_t i = 0; i < bindingCount; i++) {
    591       vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
    592       vb[firstBinding + i].offset = pOffsets[i];
    593       cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
    594    }
    595 }
    596 
    597 enum isl_format
    598 anv_isl_format_for_descriptor_type(VkDescriptorType type)
    599 {
    600    switch (type) {
    601    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
    602    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
    603       return ISL_FORMAT_R32G32B32A32_FLOAT;
    604 
    605    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
    606    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
    607       return ISL_FORMAT_RAW;
    608 
    609    default:
    610       unreachable("Invalid descriptor type");
    611    }
    612 }
    613 
    614 struct anv_state
    615 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
    616                             const void *data, uint32_t size, uint32_t alignment)
    617 {
    618    struct anv_state state;
    619 
    620    state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
    621    memcpy(state.map, data, size);
    622 
    623    anv_state_flush(cmd_buffer->device, state);
    624 
    625    VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
    626 
    627    return state;
    628 }
    629 
    630 struct anv_state
    631 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
    632                              uint32_t *a, uint32_t *b,
    633                              uint32_t dwords, uint32_t alignment)
    634 {
    635    struct anv_state state;
    636    uint32_t *p;
    637 
    638    state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
    639                                               dwords * 4, alignment);
    640    p = state.map;
    641    for (uint32_t i = 0; i < dwords; i++)
    642       p[i] = a[i] | b[i];
    643 
    644    anv_state_flush(cmd_buffer->device, state);
    645 
    646    VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
    647 
    648    return state;
    649 }
    650 
    651 static uint32_t
    652 anv_push_constant_value(struct anv_push_constants *data, uint32_t param)
    653 {
    654    if (BRW_PARAM_IS_BUILTIN(param)) {
    655       switch (param) {
    656       case BRW_PARAM_BUILTIN_ZERO:
    657          return 0;
    658       default:
    659          unreachable("Invalid param builtin");
    660       }
    661    } else {
    662       uint32_t offset = ANV_PARAM_PUSH_OFFSET(param);
    663       assert(offset % sizeof(uint32_t) == 0);
    664       if (offset < data->size)
    665          return *(uint32_t *)((uint8_t *)data + offset);
    666       else
    667          return 0;
    668    }
    669 }
    670 
    671 struct anv_state
    672 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
    673                               gl_shader_stage stage)
    674 {
    675    struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline;
    676 
    677    /* If we don't have this stage, bail. */
    678    if (!anv_pipeline_has_stage(pipeline, stage))
    679       return (struct anv_state) { .offset = 0 };
    680 
    681    struct anv_push_constants *data =
    682       cmd_buffer->state.push_constants[stage];
    683    const struct brw_stage_prog_data *prog_data =
    684       pipeline->shaders[stage]->prog_data;
    685 
    686    /* If we don't actually have any push constants, bail. */
    687    if (data == NULL || prog_data == NULL || prog_data->nr_params == 0)
    688       return (struct anv_state) { .offset = 0 };
    689 
    690    struct anv_state state =
    691       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
    692                                          prog_data->nr_params * sizeof(float),
    693                                          32 /* bottom 5 bits MBZ */);
    694 
    695    /* Walk through the param array and fill the buffer with data */
    696    uint32_t *u32_map = state.map;
    697    for (unsigned i = 0; i < prog_data->nr_params; i++)
    698       u32_map[i] = anv_push_constant_value(data, prog_data->param[i]);
    699 
    700    anv_state_flush(cmd_buffer->device, state);
    701 
    702    return state;
    703 }
    704 
    705 struct anv_state
    706 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
    707 {
    708    struct anv_push_constants *data =
    709       cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE];
    710    struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline;
    711    const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
    712    const struct brw_stage_prog_data *prog_data = &cs_prog_data->base;
    713 
    714    /* If we don't actually have any push constants, bail. */
    715    if (cs_prog_data->push.total.size == 0)
    716       return (struct anv_state) { .offset = 0 };
    717 
    718    const unsigned push_constant_alignment =
    719       cmd_buffer->device->info.gen < 8 ? 32 : 64;
    720    const unsigned aligned_total_push_constants_size =
    721       ALIGN(cs_prog_data->push.total.size, push_constant_alignment);
    722    struct anv_state state =
    723       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
    724                                          aligned_total_push_constants_size,
    725                                          push_constant_alignment);
    726 
    727    /* Walk through the param array and fill the buffer with data */
    728    uint32_t *u32_map = state.map;
    729 
    730    if (cs_prog_data->push.cross_thread.size > 0) {
    731       for (unsigned i = 0;
    732            i < cs_prog_data->push.cross_thread.dwords;
    733            i++) {
    734          assert(prog_data->param[i] != BRW_PARAM_BUILTIN_SUBGROUP_ID);
    735          u32_map[i] = anv_push_constant_value(data, prog_data->param[i]);
    736       }
    737    }
    738 
    739    if (cs_prog_data->push.per_thread.size > 0) {
    740       for (unsigned t = 0; t < cs_prog_data->threads; t++) {
    741          unsigned dst =
    742             8 * (cs_prog_data->push.per_thread.regs * t +
    743                  cs_prog_data->push.cross_thread.regs);
    744          unsigned src = cs_prog_data->push.cross_thread.dwords;
    745          for ( ; src < prog_data->nr_params; src++, dst++) {
    746             if (prog_data->param[src] == BRW_PARAM_BUILTIN_SUBGROUP_ID) {
    747                u32_map[dst] = t;
    748             } else {
    749                u32_map[dst] =
    750                   anv_push_constant_value(data, prog_data->param[src]);
    751             }
    752          }
    753       }
    754    }
    755 
    756    anv_state_flush(cmd_buffer->device, state);
    757 
    758    return state;
    759 }
    760 
    761 void anv_CmdPushConstants(
    762     VkCommandBuffer                             commandBuffer,
    763     VkPipelineLayout                            layout,
    764     VkShaderStageFlags                          stageFlags,
    765     uint32_t                                    offset,
    766     uint32_t                                    size,
    767     const void*                                 pValues)
    768 {
    769    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    770 
    771    anv_foreach_stage(stage, stageFlags) {
    772       VkResult result =
    773          anv_cmd_buffer_ensure_push_constant_field(cmd_buffer,
    774                                                    stage, client_data);
    775       if (result != VK_SUCCESS)
    776          return;
    777 
    778       memcpy(cmd_buffer->state.push_constants[stage]->client_data + offset,
    779              pValues, size);
    780    }
    781 
    782    cmd_buffer->state.push_constants_dirty |= stageFlags;
    783 }
    784 
    785 VkResult anv_CreateCommandPool(
    786     VkDevice                                    _device,
    787     const VkCommandPoolCreateInfo*              pCreateInfo,
    788     const VkAllocationCallbacks*                pAllocator,
    789     VkCommandPool*                              pCmdPool)
    790 {
    791    ANV_FROM_HANDLE(anv_device, device, _device);
    792    struct anv_cmd_pool *pool;
    793 
    794    pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
    795                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    796    if (pool == NULL)
    797       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
    798 
    799    if (pAllocator)
    800       pool->alloc = *pAllocator;
    801    else
    802       pool->alloc = device->alloc;
    803 
    804    list_inithead(&pool->cmd_buffers);
    805 
    806    *pCmdPool = anv_cmd_pool_to_handle(pool);
    807 
    808    return VK_SUCCESS;
    809 }
    810 
    811 void anv_DestroyCommandPool(
    812     VkDevice                                    _device,
    813     VkCommandPool                               commandPool,
    814     const VkAllocationCallbacks*                pAllocator)
    815 {
    816    ANV_FROM_HANDLE(anv_device, device, _device);
    817    ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
    818 
    819    if (!pool)
    820       return;
    821 
    822    list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
    823                             &pool->cmd_buffers, pool_link) {
    824       anv_cmd_buffer_destroy(cmd_buffer);
    825    }
    826 
    827    vk_free2(&device->alloc, pAllocator, pool);
    828 }
    829 
    830 VkResult anv_ResetCommandPool(
    831     VkDevice                                    device,
    832     VkCommandPool                               commandPool,
    833     VkCommandPoolResetFlags                     flags)
    834 {
    835    ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
    836 
    837    list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,
    838                        &pool->cmd_buffers, pool_link) {
    839       anv_cmd_buffer_reset(cmd_buffer);
    840    }
    841 
    842    return VK_SUCCESS;
    843 }
    844 
    845 void anv_TrimCommandPoolKHR(
    846     VkDevice                                    device,
    847     VkCommandPool                               commandPool,
    848     VkCommandPoolTrimFlagsKHR                   flags)
    849 {
    850    /* Nothing for us to do here.  Our pools stay pretty tidy. */
    851 }
    852 
    853 /**
    854  * Return NULL if the current subpass has no depthstencil attachment.
    855  */
    856 const struct anv_image_view *
    857 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
    858 {
    859    const struct anv_subpass *subpass = cmd_buffer->state.subpass;
    860    const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
    861 
    862    if (subpass->depth_stencil_attachment.attachment == VK_ATTACHMENT_UNUSED)
    863       return NULL;
    864 
    865    const struct anv_image_view *iview =
    866       fb->attachments[subpass->depth_stencil_attachment.attachment];
    867 
    868    assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
    869                                 VK_IMAGE_ASPECT_STENCIL_BIT));
    870 
    871    return iview;
    872 }
    873 
    874 static struct anv_push_descriptor_set *
    875 anv_cmd_buffer_get_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
    876                                        VkPipelineBindPoint bind_point,
    877                                        uint32_t set)
    878 {
    879    struct anv_cmd_pipeline_state *pipe_state;
    880    if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
    881       pipe_state = &cmd_buffer->state.compute.base;
    882    } else {
    883       assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
    884       pipe_state = &cmd_buffer->state.gfx.base;
    885    }
    886 
    887    struct anv_push_descriptor_set **push_set =
    888       &pipe_state->push_descriptors[set];
    889 
    890    if (*push_set == NULL) {
    891       *push_set = vk_alloc(&cmd_buffer->pool->alloc,
    892                            sizeof(struct anv_push_descriptor_set), 8,
    893                            VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    894       if (*push_set == NULL) {
    895          anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
    896          return NULL;
    897       }
    898    }
    899 
    900    return *push_set;
    901 }
    902 
    903 void anv_CmdPushDescriptorSetKHR(
    904     VkCommandBuffer commandBuffer,
    905     VkPipelineBindPoint pipelineBindPoint,
    906     VkPipelineLayout _layout,
    907     uint32_t _set,
    908     uint32_t descriptorWriteCount,
    909     const VkWriteDescriptorSet* pDescriptorWrites)
    910 {
    911    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    912    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
    913 
    914    assert(_set < MAX_SETS);
    915 
    916    const struct anv_descriptor_set_layout *set_layout =
    917       layout->set[_set].layout;
    918 
    919    struct anv_push_descriptor_set *push_set =
    920       anv_cmd_buffer_get_push_descriptor_set(cmd_buffer,
    921                                              pipelineBindPoint, _set);
    922    if (!push_set)
    923       return;
    924 
    925    struct anv_descriptor_set *set = &push_set->set;
    926 
    927    set->layout = set_layout;
    928    set->size = anv_descriptor_set_layout_size(set_layout);
    929    set->buffer_count = set_layout->buffer_count;
    930    set->buffer_views = push_set->buffer_views;
    931 
    932    /* Go through the user supplied descriptors. */
    933    for (uint32_t i = 0; i < descriptorWriteCount; i++) {
    934       const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
    935 
    936       switch (write->descriptorType) {
    937       case VK_DESCRIPTOR_TYPE_SAMPLER:
    938       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
    939       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
    940       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
    941       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
    942          for (uint32_t j = 0; j < write->descriptorCount; j++) {
    943             anv_descriptor_set_write_image_view(set, &cmd_buffer->device->info,
    944                                                 write->pImageInfo + j,
    945                                                 write->descriptorType,
    946                                                 write->dstBinding,
    947                                                 write->dstArrayElement + j);
    948          }
    949          break;
    950 
    951       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
    952       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
    953          for (uint32_t j = 0; j < write->descriptorCount; j++) {
    954             ANV_FROM_HANDLE(anv_buffer_view, bview,
    955                             write->pTexelBufferView[j]);
    956 
    957             anv_descriptor_set_write_buffer_view(set,
    958                                                  write->descriptorType,
    959                                                  bview,
    960                                                  write->dstBinding,
    961                                                  write->dstArrayElement + j);
    962          }
    963          break;
    964 
    965       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
    966       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
    967       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
    968       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
    969          for (uint32_t j = 0; j < write->descriptorCount; j++) {
    970             assert(write->pBufferInfo[j].buffer);
    971             ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
    972             assert(buffer);
    973 
    974             anv_descriptor_set_write_buffer(set,
    975                                             cmd_buffer->device,
    976                                             &cmd_buffer->surface_state_stream,
    977                                             write->descriptorType,
    978                                             buffer,
    979                                             write->dstBinding,
    980                                             write->dstArrayElement + j,
    981                                             write->pBufferInfo[j].offset,
    982                                             write->pBufferInfo[j].range);
    983          }
    984          break;
    985 
    986       default:
    987          break;
    988       }
    989    }
    990 
    991    anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
    992                                       layout, _set, set, NULL, NULL);
    993 }
    994 
    995 void anv_CmdPushDescriptorSetWithTemplateKHR(
    996     VkCommandBuffer                             commandBuffer,
    997     VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
    998     VkPipelineLayout                            _layout,
    999     uint32_t                                    _set,
   1000     const void*                                 pData)
   1001 {
   1002    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
   1003    ANV_FROM_HANDLE(anv_descriptor_update_template, template,
   1004                    descriptorUpdateTemplate);
   1005    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
   1006 
   1007    assert(_set < MAX_PUSH_DESCRIPTORS);
   1008 
   1009    const struct anv_descriptor_set_layout *set_layout =
   1010       layout->set[_set].layout;
   1011 
   1012    struct anv_push_descriptor_set *push_set =
   1013       anv_cmd_buffer_get_push_descriptor_set(cmd_buffer,
   1014                                              template->bind_point, _set);
   1015    if (!push_set)
   1016       return;
   1017 
   1018    struct anv_descriptor_set *set = &push_set->set;
   1019 
   1020    set->layout = set_layout;
   1021    set->size = anv_descriptor_set_layout_size(set_layout);
   1022    set->buffer_count = set_layout->buffer_count;
   1023    set->buffer_views = push_set->buffer_views;
   1024 
   1025    anv_descriptor_set_write_template(set,
   1026                                      cmd_buffer->device,
   1027                                      &cmd_buffer->surface_state_stream,
   1028                                      template,
   1029                                      pData);
   1030 
   1031    anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,
   1032                                       layout, _set, set, NULL, NULL);
   1033 }
   1034