anv: Add initial support for cube maps
[mesa.git] / src / vulkan / anv_cmd_buffer.c
index 66b2f65e9f72fc9770f10b8f5b1c80e5e8297fc2..fa6943689d8d60390c6143db016199ef593a4d56 100644 (file)
@@ -50,7 +50,7 @@ const struct anv_dynamic_state default_dynamic_state = {
    .depth_bias = {
       .bias = 0.0f,
       .clamp = 0.0f,
-      .slope_scaled = 0.0f,
+      .slope = 0.0f,
    },
    .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
    .depth_bounds = {
@@ -129,28 +129,22 @@ anv_cmd_state_init(struct anv_cmd_state *state)
 
 static VkResult
 anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
-                                          VkShaderStage stage, uint32_t size)
+                                          gl_shader_stage stage, uint32_t size)
 {
    struct anv_push_constants **ptr = &cmd_buffer->state.push_constants[stage];
 
    if (*ptr == NULL) {
-      *ptr = anv_device_alloc(cmd_buffer->device, size, 8,
-                              VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+      *ptr = anv_alloc(&cmd_buffer->pool->alloc, size, 8,
+                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
       if (*ptr == NULL)
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-      (*ptr)->size = size;
    } else if ((*ptr)->size < size) {
-      void *new_data = anv_device_alloc(cmd_buffer->device, size, 8,
-                                        VK_SYSTEM_ALLOC_TYPE_INTERNAL);
-      if (new_data == NULL)
+      *ptr = anv_realloc(&cmd_buffer->pool->alloc, *ptr, size, 8,
+                         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+      if (*ptr == NULL)
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-      memcpy(new_data, *ptr, (*ptr)->size);
-      anv_device_free(cmd_buffer->device, *ptr);
-
-      *ptr = new_data;
-      (*ptr)->size = size;
    }
+   (*ptr)->size = size;
 
    return VK_SUCCESS;
 }
@@ -160,23 +154,23 @@ anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
       (offsetof(struct anv_push_constants, field) + \
        sizeof(cmd_buffer->state.push_constants[0]->field)))
 
-VkResult anv_CreateCommandBuffer(
-    VkDevice                                    _device,
-    const VkCmdBufferCreateInfo*                pCreateInfo,
-    VkCmdBuffer*                                pCmdBuffer)
+static VkResult anv_create_cmd_buffer(
+    struct anv_device *                         device,
+    struct anv_cmd_pool *                       pool,
+    VkCommandBufferLevel                        level,
+    VkCommandBuffer*                            pCommandBuffer)
 {
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_cmd_pool, pool, pCreateInfo->cmdPool);
    struct anv_cmd_buffer *cmd_buffer;
    VkResult result;
 
-   cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
-                                 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   cmd_buffer = anv_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
+                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (cmd_buffer == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
    cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
    cmd_buffer->device = device;
+   cmd_buffer->pool = pool;
 
    result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
    if (result != VK_SUCCESS)
@@ -187,8 +181,8 @@ VkResult anv_CreateCommandBuffer(
    anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
                          &device->dynamic_state_block_pool);
 
-   cmd_buffer->level = pCreateInfo->level;
-   cmd_buffer->opt_flags = 0;
+   cmd_buffer->level = level;
+   cmd_buffer->usage_flags = 0;
 
    anv_cmd_state_init(&cmd_buffer->state);
 
@@ -201,36 +195,72 @@ VkResult anv_CreateCommandBuffer(
       list_inithead(&cmd_buffer->pool_link);
    }
 
-   *pCmdBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
+   *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
 
    return VK_SUCCESS;
 
- fail: anv_device_free(device, cmd_buffer);
+ fail:
+   anv_free(&cmd_buffer->pool->alloc, cmd_buffer);
 
    return result;
 }
 
-void anv_DestroyCommandBuffer(
+VkResult anv_AllocateCommandBuffers(
     VkDevice                                    _device,
-    VkCmdBuffer                                 _cmd_buffer)
+    const VkCommandBufferAllocateInfo*          pAllocateInfo,
+    VkCommandBuffer*                            pCommandBuffers)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _cmd_buffer);
+   ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
 
+   VkResult result = VK_SUCCESS;
+   uint32_t i;
+
+   for (i = 0; i < pAllocateInfo->bufferCount; i++) {
+      result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
+                                     &pCommandBuffers[i]);
+      if (result != VK_SUCCESS)
+         break;
+   }
+
+   if (result != VK_SUCCESS)
+      anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
+                             i, pCommandBuffers);
+
+   return result;
+}
+
+static void
+anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
+{
    list_del(&cmd_buffer->pool_link);
 
    anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
 
    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
-   anv_device_free(device, cmd_buffer);
+
+   anv_free(&cmd_buffer->pool->alloc, cmd_buffer);
+}
+
+void anv_FreeCommandBuffers(
+    VkDevice                                    device,
+    VkCommandPool                               commandPool,
+    uint32_t                                    commandBufferCount,
+    const VkCommandBuffer*                      pCommandBuffers)
+{
+   for (uint32_t i = 0; i < commandBufferCount; i++) {
+      ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
+
+      anv_cmd_buffer_destroy(cmd_buffer);
+   }
 }
 
 VkResult anv_ResetCommandBuffer(
-    VkCmdBuffer                                 cmdBuffer,
-    VkCmdBufferResetFlags                       flags)
+    VkCommandBuffer                             commandBuffer,
+    VkCommandBufferResetFlags                   flags)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
 
@@ -258,16 +288,16 @@ anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
 }
 
 VkResult anv_BeginCommandBuffer(
-    VkCmdBuffer                                 cmdBuffer,
-    const VkCmdBufferBeginInfo*                 pBeginInfo)
+    VkCommandBuffer                             commandBuffer,
+    const VkCommandBufferBeginInfo*             pBeginInfo)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
 
-   cmd_buffer->opt_flags = pBeginInfo->flags;
+   cmd_buffer->usage_flags = pBeginInfo->flags;
 
-   if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_SECONDARY) {
+   if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY) {
       cmd_buffer->state.framebuffer =
          anv_framebuffer_from_handle(pBeginInfo->framebuffer);
       cmd_buffer->state.pass =
@@ -286,14 +316,14 @@ VkResult anv_BeginCommandBuffer(
 }
 
 VkResult anv_EndCommandBuffer(
-    VkCmdBuffer                                 cmdBuffer)
+    VkCommandBuffer                             commandBuffer)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    struct anv_device *device = cmd_buffer->device;
 
    anv_cmd_buffer_end_batch_buffer(cmd_buffer);
 
-   if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY) {
+   if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
       /* The algorithm used to compute the validate list is not threadsafe as
        * it uses the bo->index field.  We have to lock the device around it.
        * Fortunately, the chances for contention here are probably very low.
@@ -307,11 +337,11 @@ VkResult anv_EndCommandBuffer(
 }
 
 void anv_CmdBindPipeline(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkPipelineBindPoint                         pipelineBindPoint,
     VkPipeline                                  _pipeline)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
 
    switch (pipelineBindPoint) {
@@ -341,11 +371,11 @@ void anv_CmdBindPipeline(
 }
 
 void anv_CmdSetViewport(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     uint32_t                                    viewportCount,
     const VkViewport*                           pViewports)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    cmd_buffer->state.dynamic.viewport.count = viewportCount;
    memcpy(cmd_buffer->state.dynamic.viewport.viewports,
@@ -355,11 +385,11 @@ void anv_CmdSetViewport(
 }
 
 void anv_CmdSetScissor(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     uint32_t                                    scissorCount,
     const VkRect2D*                             pScissors)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    cmd_buffer->state.dynamic.scissor.count = scissorCount;
    memcpy(cmd_buffer->state.dynamic.scissor.scissors,
@@ -369,48 +399,48 @@ void anv_CmdSetScissor(
 }
 
 void anv_CmdSetLineWidth(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     float                                       lineWidth)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    cmd_buffer->state.dynamic.line_width = lineWidth;
    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
 }
 
 void anv_CmdSetDepthBias(
-    VkCmdBuffer                                 cmdBuffer,
-    float                                       depthBias,
+    VkCommandBuffer                             commandBuffer,
+    float                                       depthBiasConstantFactor,
     float                                       depthBiasClamp,
-    float                                       slopeScaledDepthBias)
+    float                                       depthBiasSlopeFactor)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
-   cmd_buffer->state.dynamic.depth_bias.bias = depthBias;
+   cmd_buffer->state.dynamic.depth_bias.bias = depthBiasConstantFactor;
    cmd_buffer->state.dynamic.depth_bias.clamp = depthBiasClamp;
-   cmd_buffer->state.dynamic.depth_bias.slope_scaled = slopeScaledDepthBias;
+   cmd_buffer->state.dynamic.depth_bias.slope = depthBiasSlopeFactor;
 
    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
 }
 
 void anv_CmdSetBlendConstants(
-    VkCmdBuffer                                 cmdBuffer,
-    const float                                 blendConst[4])
+    VkCommandBuffer                             commandBuffer,
+    const float                                 blendConstants[4])
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    memcpy(cmd_buffer->state.dynamic.blend_constants,
-          blendConst, sizeof(float) * 4);
+          blendConstants, sizeof(float) * 4);
 
    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
 }
 
 void anv_CmdSetDepthBounds(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     float                                       minDepthBounds,
     float                                       maxDepthBounds)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    cmd_buffer->state.dynamic.depth_bounds.min = minDepthBounds;
    cmd_buffer->state.dynamic.depth_bounds.max = maxDepthBounds;
@@ -419,68 +449,68 @@ void anv_CmdSetDepthBounds(
 }
 
 void anv_CmdSetStencilCompareMask(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkStencilFaceFlags                          faceMask,
-    uint32_t                                    stencilCompareMask)
+    uint32_t                                    compareMask)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
-      cmd_buffer->state.dynamic.stencil_compare_mask.front = stencilCompareMask;
+      cmd_buffer->state.dynamic.stencil_compare_mask.front = compareMask;
    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
-      cmd_buffer->state.dynamic.stencil_compare_mask.back = stencilCompareMask;
+      cmd_buffer->state.dynamic.stencil_compare_mask.back = compareMask;
 
    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
 }
 
 void anv_CmdSetStencilWriteMask(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkStencilFaceFlags                          faceMask,
-    uint32_t                                    stencilWriteMask)
+    uint32_t                                    writeMask)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
-      cmd_buffer->state.dynamic.stencil_write_mask.front = stencilWriteMask;
+      cmd_buffer->state.dynamic.stencil_write_mask.front = writeMask;
    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
-      cmd_buffer->state.dynamic.stencil_write_mask.back = stencilWriteMask;
+      cmd_buffer->state.dynamic.stencil_write_mask.back = writeMask;
 
    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
 }
 
 void anv_CmdSetStencilReference(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkStencilFaceFlags                          faceMask,
-    uint32_t                                    stencilReference)
+    uint32_t                                    reference)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
-      cmd_buffer->state.dynamic.stencil_reference.front = stencilReference;
+      cmd_buffer->state.dynamic.stencil_reference.front = reference;
    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
-      cmd_buffer->state.dynamic.stencil_reference.back = stencilReference;
+      cmd_buffer->state.dynamic.stencil_reference.back = reference;
 
    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
 }
 
 void anv_CmdBindDescriptorSets(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkPipelineBindPoint                         pipelineBindPoint,
     VkPipelineLayout                            _layout,
     uint32_t                                    firstSet,
-    uint32_t                                    setCount,
+    uint32_t                                    descriptorSetCount,
     const VkDescriptorSet*                      pDescriptorSets,
     uint32_t                                    dynamicOffsetCount,
     const uint32_t*                             pDynamicOffsets)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
    struct anv_descriptor_set_layout *set_layout;
 
-   assert(firstSet + setCount < MAX_SETS);
+   assert(firstSet + descriptorSetCount < MAX_SETS);
 
    uint32_t dynamic_slot = 0;
-   for (uint32_t i = 0; i < setCount; i++) {
+   for (uint32_t i = 0; i < descriptorSetCount; i++) {
       ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
       set_layout = layout->set[firstSet + i].layout;
 
@@ -490,8 +520,7 @@ void anv_CmdBindDescriptorSets(
       }
 
       if (set_layout->dynamic_offset_count > 0) {
-         VkShaderStage s;
-         for_each_bit(s, set_layout->shader_stages) {
+         anv_foreach_stage(s, set_layout->shader_stages) {
             anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, s, dynamic);
 
             struct anv_push_constants *push =
@@ -519,13 +548,13 @@ void anv_CmdBindDescriptorSets(
 }
 
 void anv_CmdBindVertexBuffers(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     uint32_t                                    startBinding,
     uint32_t                                    bindingCount,
     const VkBuffer*                             pBuffers,
     const VkDeviceSize*                         pOffsets)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
    struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
 
    /* We have to defer setting up vertex buffer since we need the buffer
@@ -549,33 +578,25 @@ add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,
 
    const uint32_t dword = cmd_buffer->device->info.gen < 8 ? 1 : 8;
 
-   anv_reloc_list_add(&cmd_buffer->surface_relocs, cmd_buffer->device,
+   anv_reloc_list_add(&cmd_buffer->surface_relocs, &cmd_buffer->pool->alloc,
                       state.offset + dword * 4, bo, offset);
 }
 
 static void
 fill_descriptor_buffer_surface_state(struct anv_device *device, void *state,
-                                     VkShaderStage stage, VkDescriptorType type,
+                                     gl_shader_stage stage,
+                                     VkDescriptorType type,
                                      uint32_t offset, uint32_t range)
 {
    VkFormat format;
-   uint32_t stride;
-
    switch (type) {
    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
-      if (anv_is_scalar_shader_stage(device->instance->physicalDevice.compiler,
-                                     stage)) {
-         stride = 4;
-      } else {
-         stride = 16;
-      }
       format = VK_FORMAT_R32G32B32A32_SFLOAT;
       break;
 
    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
-      stride = 1;
       format = VK_FORMAT_UNDEFINED;
       break;
 
@@ -585,24 +606,25 @@ fill_descriptor_buffer_surface_state(struct anv_device *device, void *state,
 
    anv_fill_buffer_surface_state(device, state,
                                  anv_format_for_vk_format(format),
-                                 offset, range, stride);
+                                 offset, range, 1);
 }
 
 VkResult
 anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
-                                  VkShaderStage stage, struct anv_state *bt_state)
+                                  gl_shader_stage stage,
+                                  struct anv_state *bt_state)
 {
    struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
    struct anv_subpass *subpass = cmd_buffer->state.subpass;
    struct anv_pipeline_layout *layout;
    uint32_t color_count, bias, state_offset;
 
-   if (stage == VK_SHADER_STAGE_COMPUTE)
+   if (stage == MESA_SHADER_COMPUTE)
       layout = cmd_buffer->state.compute_pipeline->layout;
    else
       layout = cmd_buffer->state.pipeline->layout;
 
-   if (stage == VK_SHADER_STAGE_FRAGMENT) {
+   if (stage == MESA_SHADER_FRAGMENT) {
       bias = MAX_RTS;
       color_count = subpass->color_count;
    } else {
@@ -636,8 +658,18 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
    }
 
    if (layout == NULL)
-      return VK_SUCCESS;
+      goto out;
+
+   if (layout->stage[stage].image_count > 0) {
+      VkResult result =
+         anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, images);
+      if (result != VK_SUCCESS)
+         return result;
+
+      cmd_buffer->state.push_constants_dirty |= 1 << stage;
+   }
 
+   uint32_t image = 0;
    for (uint32_t s = 0; s < layout->stage[stage].surface_count; s++) {
       struct anv_pipeline_binding *binding =
          &layout->stage[stage].surface_to_descriptor[s];
@@ -668,6 +700,10 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
                                               surface_state.map,
                                               stage, desc->type,
                                               bo_offset, desc->range);
+
+         if (!cmd_buffer->device->info.has_llc)
+            anv_state_clflush(surface_state);
+
          break;
       }
 
@@ -679,8 +715,26 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
          bo_offset = desc->image_view->offset;
          break;
 
-      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
+         surface_state = desc->image_view->storage_surface_state;
+         bo = desc->image_view->bo;
+         bo_offset = desc->image_view->offset;
+
+         struct brw_image_param *image_param =
+            &cmd_buffer->state.push_constants[stage]->images[image++];
+
+         anv_image_view_fill_image_param(cmd_buffer->device, desc->image_view,
+                                         image_param);
+         image_param->surface_idx = bias + s;
+         break;
+      }
+
       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+         surface_state = desc->buffer_view->surface_state;
+         bo = desc->buffer_view->bo;
+         bo_offset = desc->buffer_view->offset;
+         break;
+
       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
          assert(!"Unsupported descriptor type");
          break;
@@ -693,18 +747,23 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
       bt_map[bias + s] = surface_state.offset + state_offset;
       add_surface_state_reloc(cmd_buffer, surface_state, bo, bo_offset);
    }
+   assert(image == layout->stage[stage].image_count);
+
+ out:
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(*bt_state);
 
    return VK_SUCCESS;
 }
 
 VkResult
 anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
-                             VkShaderStage stage, struct anv_state *state)
+                             gl_shader_stage stage, struct anv_state *state)
 {
    struct anv_pipeline_layout *layout;
    uint32_t sampler_count;
 
-   if (stage == VK_SHADER_STAGE_COMPUTE)
+   if (stage == MESA_SHADER_COMPUTE)
       layout = cmd_buffer->state.compute_pipeline->layout;
    else
       layout = cmd_buffer->state.pipeline->layout;
@@ -742,20 +801,25 @@ anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
              sampler->state, sizeof(sampler->state));
    }
 
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(*state);
+
    return VK_SUCCESS;
 }
 
 struct anv_state
 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
-                             uint32_t *a, uint32_t dwords, uint32_t alignment)
+                            const void *data, uint32_t size, uint32_t alignment)
 {
    struct anv_state state;
 
-   state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
-                                              dwords * 4, alignment);
-   memcpy(state.map, a, dwords * 4);
+   state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
+   memcpy(state.map, data, size);
+
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(state);
 
-   VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
+   VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
 
    return state;
 }
@@ -774,6 +838,9 @@ anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
    for (uint32_t i = 0; i < dwords; i++)
       p[i] = a[i] | b[i];
 
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(state);
+
    VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
 
    return state;
@@ -799,7 +866,7 @@ anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
 }
 
 void anv_CmdSetEvent(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkEvent                                     event,
     VkPipelineStageFlags                        stageMask)
 {
@@ -807,7 +874,7 @@ void anv_CmdSetEvent(
 }
 
 void anv_CmdResetEvent(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkEvent                                     event,
     VkPipelineStageFlags                        stageMask)
 {
@@ -815,7 +882,7 @@ void anv_CmdResetEvent(
 }
 
 void anv_CmdWaitEvents(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     uint32_t                                    eventCount,
     const VkEvent*                              pEvents,
     VkPipelineStageFlags                        srcStageMask,
@@ -828,7 +895,7 @@ void anv_CmdWaitEvents(
 
 struct anv_state
 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
-                              VkShaderStage stage)
+                              gl_shader_stage stage)
 {
    struct anv_push_constants *data =
       cmd_buffer->state.push_constants[stage];
@@ -851,45 +918,101 @@ anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
       u32_map[i] = *(uint32_t *)((uint8_t *)data + offset);
    }
 
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(state);
+
+   return state;
+}
+
+struct anv_state
+anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_push_constants *data =
+      cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE];
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   const struct brw_cs_prog_data *cs_prog_data = &pipeline->cs_prog_data;
+   const struct brw_stage_prog_data *prog_data = &cs_prog_data->base;
+
+   const unsigned local_id_dwords = cs_prog_data->local_invocation_id_regs * 8;
+   const unsigned push_constant_data_size =
+      (local_id_dwords + prog_data->nr_params) * 4;
+   const unsigned reg_aligned_constant_size = ALIGN(push_constant_data_size, 32);
+   const unsigned param_aligned_count =
+      reg_aligned_constant_size / sizeof(uint32_t);
+
+   /* If we don't actually have any push constants, bail. */
+   if (reg_aligned_constant_size == 0)
+      return (struct anv_state) { .offset = 0 };
+
+   const unsigned threads = pipeline->cs_thread_width_max;
+   const unsigned total_push_constants_size =
+      reg_aligned_constant_size * threads;
+   struct anv_state state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+                                         total_push_constants_size,
+                                         32 /* bottom 5 bits MBZ */);
+
+   /* Walk through the param array and fill the buffer with data */
+   uint32_t *u32_map = state.map;
+
+   brw_cs_fill_local_id_payload(cs_prog_data, u32_map, threads,
+                                reg_aligned_constant_size);
+
+   /* Setup uniform data for the first thread */
+   for (unsigned i = 0; i < prog_data->nr_params; i++) {
+      uint32_t offset = (uintptr_t)prog_data->param[i];
+      u32_map[local_id_dwords + i] = *(uint32_t *)((uint8_t *)data + offset);
+   }
+
+   /* Copy uniform data from the first thread to every other thread */
+   const size_t uniform_data_size = prog_data->nr_params * sizeof(uint32_t);
+   for (unsigned t = 1; t < threads; t++) {
+      memcpy(&u32_map[t * param_aligned_count + local_id_dwords],
+             &u32_map[local_id_dwords],
+             uniform_data_size);
+   }
+
+   if (!cmd_buffer->device->info.has_llc)
+      anv_state_clflush(state);
+
    return state;
 }
 
 void anv_CmdPushConstants(
-    VkCmdBuffer                                 cmdBuffer,
+    VkCommandBuffer                             commandBuffer,
     VkPipelineLayout                            layout,
     VkShaderStageFlags                          stageFlags,
-    uint32_t                                    start,
-    uint32_t                                    length,
-    const void*                                 values)
+    uint32_t                                    offset,
+    uint32_t                                    size,
+    const void*                                 pValues)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   VkShaderStage stage;
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
 
-   for_each_bit(stage, stageFlags) {
+   anv_foreach_stage(stage, stageFlags) {
       anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, client_data);
 
-      memcpy(cmd_buffer->state.push_constants[stage]->client_data + start,
-             values, length);
+      memcpy(cmd_buffer->state.push_constants[stage]->client_data + offset,
+             pValues, size);
    }
 
    cmd_buffer->state.push_constants_dirty |= stageFlags;
 }
 
 void anv_CmdExecuteCommands(
-    VkCmdBuffer                                 cmdBuffer,
-    uint32_t                                    cmdBuffersCount,
-    const VkCmdBuffer*                          pCmdBuffers)
+    VkCommandBuffer                             commandBuffer,
+    uint32_t                                    commandBuffersCount,
+    const VkCommandBuffer*                      pCmdBuffers)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, primary, cmdBuffer);
+   ANV_FROM_HANDLE(anv_cmd_buffer, primary, commandBuffer);
 
-   assert(primary->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
+   assert(primary->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
 
    anv_assert(primary->state.subpass == &primary->state.pass->subpasses[0]);
 
-   for (uint32_t i = 0; i < cmdBuffersCount; i++) {
+   for (uint32_t i = 0; i < commandBuffersCount; i++) {
       ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]);
 
-      assert(secondary->level == VK_CMD_BUFFER_LEVEL_SECONDARY);
+      assert(secondary->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY);
 
       anv_cmd_buffer_add_secondary(primary, secondary);
    }
@@ -897,17 +1020,23 @@ void anv_CmdExecuteCommands(
 
 VkResult anv_CreateCommandPool(
     VkDevice                                    _device,
-    const VkCmdPoolCreateInfo*                  pCreateInfo,
-    VkCmdPool*                                  pCmdPool)
+    const VkCommandPoolCreateInfo*              pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkCommandPool*                              pCmdPool)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
    struct anv_cmd_pool *pool;
 
-   pool = anv_device_alloc(device, sizeof(*pool), 8,
-                           VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   pool = anv_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
+                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (pool == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   if (pAllocator)
+      pool->alloc = *pAllocator;
+   else
+      pool->alloc = device->alloc;
+
    list_inithead(&pool->cmd_buffers);
 
    *pCmdPool = anv_cmd_pool_to_handle(pool);
@@ -917,26 +1046,27 @@ VkResult anv_CreateCommandPool(
 
 void anv_DestroyCommandPool(
     VkDevice                                    _device,
-    VkCmdPool                                   cmdPool)
+    VkCommandPool                               commandPool,
+    const VkAllocationCallbacks*                pAllocator)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
+   ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
 
-   anv_ResetCommandPool(_device, cmdPool, 0);
+   anv_ResetCommandPool(_device, commandPool, 0);
 
-   anv_device_free(device, pool);
+   anv_free2(&device->alloc, pAllocator, pool);
 }
 
 VkResult anv_ResetCommandPool(
     VkDevice                                    device,
-    VkCmdPool                                   cmdPool,
-    VkCmdPoolResetFlags                         flags)
+    VkCommandPool                               commandPool,
+    VkCommandPoolResetFlags                     flags)
 {
-   ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
+   ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
 
    list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
                             &pool->cmd_buffers, pool_link) {
-      anv_DestroyCommandBuffer(device, anv_cmd_buffer_to_handle(cmd_buffer));
+      anv_cmd_buffer_destroy(cmd_buffer);
    }
 
    return VK_SUCCESS;