vk/pipeline: Track VB's that are actually used by the pipeline
authorJason Ekstrand <jason.ekstrand@intel.com>
Thu, 21 May 2015 23:49:55 +0000 (16:49 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 21 May 2015 23:58:53 +0000 (16:58 -0700)
Previously, we just blasted out whatever VB's we had marked as "dirty"
regardless of which ones were used by the pipeline.  Given that the stride
of the VB is embedded in the pipeline this can cause problems.  One problem
is if the pipeline doesn't use the given VB binding we emit a bogus stride.
Another problem is that we weren't properly resetting the dirty bits when
the pipeline changed.

src/vulkan/device.c
src/vulkan/pipeline.c
src/vulkan/private.h

index d464d66982e9333bd77ff219dfa4f3443f10543b..a1c8846f2145af55370710151f3c238378b169e4 100644 (file)
@@ -2384,8 +2384,10 @@ void anv_CmdBindPipeline(
     VkPipeline                                  _pipeline)
 {
    struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
+   struct anv_pipeline *pipeline = (struct anv_pipeline *) _pipeline;
 
-   cmd_buffer->pipeline = (struct anv_pipeline *) _pipeline;
+   cmd_buffer->pipeline = pipeline;
+   cmd_buffer->vb_dirty |= pipeline->vb_used;
    cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
 }
 
@@ -2617,18 +2619,20 @@ anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_pipeline *pipeline = cmd_buffer->pipeline;
    struct anv_bindings *bindings = cmd_buffer->bindings;
-   const uint32_t num_buffers = __builtin_popcount(cmd_buffer->vb_dirty);
-   const uint32_t num_dwords = 1 + num_buffers * 4;
    uint32_t *p;
 
-   if (cmd_buffer->vb_dirty) {
+   uint32_t vb_emit = cmd_buffer->vb_dirty & pipeline->vb_used;
+   const uint32_t num_buffers = __builtin_popcount(vb_emit);
+   const uint32_t num_dwords = 1 + num_buffers * 4;
+
+   if (vb_emit) {
       p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
                           GEN8_3DSTATE_VERTEX_BUFFERS);
       uint32_t vb, i = 0;
-      for_each_bit(vb, cmd_buffer->vb_dirty) {
+      for_each_bit(vb, vb_emit) {
          struct anv_buffer *buffer = bindings->vb[vb].buffer;
          uint32_t offset = bindings->vb[vb].offset;
-      
+
          struct GEN8_VERTEX_BUFFER_STATE state = {
             .VertexBufferIndex = vb,
             .MemoryObjectControlState = 0,
@@ -2653,7 +2657,7 @@ anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
       anv_batch_emit_merge(&cmd_buffer->batch,
                            cmd_buffer->rs_state->state_sf, pipeline->state_sf);
 
-   cmd_buffer->vb_dirty = 0;
+   cmd_buffer->vb_dirty &= ~vb_emit;
    cmd_buffer->dirty = 0;
 }
 
index 23b9413033418455fc1e3b7b109badd232a8ad1d..52c96a248cc34045560ac5813e0213cee7453820 100644 (file)
@@ -62,11 +62,13 @@ emit_vertex_input(struct anv_pipeline *pipeline, VkPipelineVertexInputCreateInfo
    const uint32_t num_dwords = 1 + info->attributeCount * 2;
    uint32_t *p;
    bool instancing_enable[32];
-   
+
+   pipeline->vb_used = 0;
    for (uint32_t i = 0; i < info->bindingCount; i++) {
       const VkVertexInputBindingDescription *desc =
          &info->pVertexBindingDescriptions[i];
-      
+
+      pipeline->vb_used |= 1 << desc->binding;
       pipeline->binding_stride[desc->binding] = desc->strideInBytes;
 
       /* Step rate is programmed per vertex element (attribute), not
index e1d306f780e89c80ef59cc7a8a35bfbaa4de2b46..da568e87017fcea7a2ac5bb1c52fb5659e94955a 100644 (file)
@@ -610,6 +610,7 @@ struct anv_pipeline {
    uint32_t                                     gs_vec4;
    uint32_t                                     gs_vertex_count;
 
+   uint32_t                                     vb_used;
    uint32_t                                     binding_stride[MAX_VBS];
 
    uint32_t                                     state_sf[GEN8_3DSTATE_SF_length];