anv/gen7: Implement the VS state depth-stall workaround
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 11 Nov 2015 00:42:34 +0000 (16:42 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 11 Nov 2015 00:42:34 +0000 (16:42 -0800)
src/vulkan/anv_device.c
src/vulkan/anv_private.h
src/vulkan/gen7_cmd_buffer.c
src/vulkan/gen7_pipeline.c

index 3c6760b832d91385e0b474a0a0b1dfda9c016764..1328516c48e325495267b26151b876c7e695d217 100644 (file)
@@ -667,6 +667,8 @@ VkResult anv_CreateDevice(
    anv_state_pool_init(&device->surface_state_pool,
                        &device->surface_state_block_pool);
 
+   anv_bo_init_new(&device->workaround_bo, device, 1024);
+
    anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
 
    device->info = *physical_device->info;
@@ -705,6 +707,9 @@ void anv_DestroyDevice(
    anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
 #endif
 
+   anv_gem_munmap(device->workaround_bo.map, device->workaround_bo.size);
+   anv_gem_close(device, device->workaround_bo.gem_handle);
+
    anv_bo_pool_finish(&device->batch_bo_pool);
    anv_state_pool_finish(&device->dynamic_state_pool);
    anv_block_pool_finish(&device->dynamic_state_block_pool);
index 8a8fe8d04a4fdcb211767753c0b19227e09383ac..a60c679cede44a04c58c568617a30c0eb89ec2a0 100644 (file)
@@ -497,6 +497,8 @@ struct anv_device {
     struct anv_block_pool                       surface_state_block_pool;
     struct anv_state_pool                       surface_state_pool;
 
+    struct anv_bo                               workaround_bo;
+
     struct anv_meta_state                       meta_state;
 
     struct anv_state                            border_colors;
index b3619df2c2e8bf1583051ff0990965cd9c2d67e3..5ebf129a802e0ac4a9c7544828e75278560e3778 100644 (file)
@@ -287,6 +287,24 @@ gen7_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
       anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
    }
 
+   if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT ||
+       cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) {
+      /* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
+       *
+       *    "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth
+       *    stall needs to be sent just prior to any 3DSTATE_VS,
+       *    3DSTATE_URB_VS, 3DSTATE_CONSTANT_VS,
+       *    3DSTATE_BINDING_TABLE_POINTER_VS,
+       *    3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one
+       *    PIPE_CONTROL needs to be sent before any combination of VS
+       *    associated 3DSTATE."
+       */
+      anv_batch_emit(&cmd_buffer->batch, GEN7_PIPE_CONTROL,
+                     .DepthStallEnable = true,
+                     .PostSyncOperation = WriteImmediateData,
+                     .Address = { &cmd_buffer->device->workaround_bo, 0 });
+   }
+
    if (cmd_buffer->state.descriptors_dirty)
       anv_flush_descriptor_sets(cmd_buffer);
 
index 6eed60dbd3da6b4f6c10455453228b30cb7c17f6..1fed33a53d1e2b7576d8ae3e5d734d1483250679 100644 (file)
@@ -380,6 +380,19 @@ gen7_graphics_pipeline_create(
    anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_DS, .DSFunctionEnable = false);
    anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_STREAMOUT, .SOFunctionEnable = false);
 
+   /* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
+    *
+    *    "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth stall
+    *    needs to be sent just prior to any 3DSTATE_VS, 3DSTATE_URB_VS,
+    *    3DSTATE_CONSTANT_VS, 3DSTATE_BINDING_TABLE_POINTER_VS,
+    *    3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL
+    *    needs to be sent before any combination of VS associated 3DSTATE."
+    */
+   anv_batch_emit(&pipeline->batch, GEN7_PIPE_CONTROL,
+                  .DepthStallEnable = true,
+                  .PostSyncOperation = WriteImmediateData,
+                  .Address = { &device->workaround_bo, 0 });
+
    anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
                   .ConstantBufferOffset = 0,
                   .ConstantBufferSize = 4);