From: Jason Ekstrand Date: Thu, 21 May 2015 23:49:55 +0000 (-0700) Subject: vk/pipeline: Track VB's that are actually used by the pipeline X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f0b5aecb87a30ddb16804f2f5cfc51eba386e8e;p=mesa.git vk/pipeline: Track VB's that are actually used by the pipeline 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. --- diff --git a/src/vulkan/device.c b/src/vulkan/device.c index d464d66982e..a1c8846f214 100644 --- a/src/vulkan/device.c +++ b/src/vulkan/device.c @@ -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; } diff --git a/src/vulkan/pipeline.c b/src/vulkan/pipeline.c index 23b94130334..52c96a248cc 100644 --- a/src/vulkan/pipeline.c +++ b/src/vulkan/pipeline.c @@ -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 diff --git a/src/vulkan/private.h b/src/vulkan/private.h index e1d306f780e..da568e87017 100644 --- a/src/vulkan/private.h +++ b/src/vulkan/private.h @@ -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];