From fd3eaabf28cf96b0ca8a5c69c80e8265e31a8cdf Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 2 Sep 2021 16:16:40 -0400 Subject: [PATCH] lavapipe: unbreak push descriptor templates the stride/offset calculation on this was all wrong, so just unroll the template before enqueuing to present a uniform stream of descriptors without trying to copy potentially megabytes of data Reviewed-by: Tomeu Vizoso Part-of: --- .../frontends/lavapipe/lvp_cmd_buffer.c | 74 +++++++++++++------ src/gallium/frontends/lavapipe/lvp_execute.c | 6 +- 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c index b9ebaa0b2d1..7edf78e73f6 100644 --- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c +++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c @@ -443,34 +443,60 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdPushDescriptorSetWithTemplateKHR( for (unsigned i = 0; i < templ->entry_count; i++) { VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i]; - if (entry->descriptorCount > 1) { - info_size += entry->stride * entry->descriptorCount; - } else { - switch (entry->descriptorType) { - case VK_DESCRIPTOR_TYPE_SAMPLER: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - info_size += sizeof(VkDescriptorImageInfo); - break; - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - info_size += sizeof(VkBufferView); - break; - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - default: - info_size += sizeof(VkDescriptorBufferInfo); - break; - } + switch (entry->descriptorType) { + case VK_DESCRIPTOR_TYPE_SAMPLER: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + info_size += sizeof(VkDescriptorImageInfo) * entry->descriptorCount; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + info_size += sizeof(VkBufferView) * entry->descriptorCount; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + default: + info_size += sizeof(VkDescriptorBufferInfo) * entry->descriptorCount; + break; } } cmd->u.push_descriptor_set_with_template_khr.data = vk_zalloc(cmd_buffer->queue.alloc, info_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); - memcpy(cmd->u.push_descriptor_set_with_template_khr.data, pData, info_size); + + uint64_t offset = 0; + for (unsigned i = 0; i < templ->entry_count; i++) { + VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i]; + + unsigned size = 0; + switch (entry->descriptorType) { + case VK_DESCRIPTOR_TYPE_SAMPLER: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + size = sizeof(VkDescriptorImageInfo); + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + size = sizeof(VkBufferView); + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + default: + size = sizeof(VkDescriptorBufferInfo); + break; + } + for (unsigned i = 0; i < entry->descriptorCount; i++) { + memcpy((uint8_t*)cmd->u.push_descriptor_set_with_template_khr.data + offset, (const uint8_t*)pData + entry->offset + i * entry->stride, size); + offset += size; + } + } } VKAPI_ATTR void VKAPI_CALL lvp_CmdBindDescriptorSets( diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 26757199673..5b47821a40c 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -3277,10 +3277,10 @@ static void handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry * pds->descriptor_writes = (struct VkWriteDescriptorSet *)(pds + 1); const uint8_t *next_info = (const uint8_t *) (pds->descriptor_writes + templ->entry_count); + const uint8_t *pSrc = cmd->u.push_descriptor_set_with_template_khr.data; for (unsigned i = 0; i < templ->entry_count; i++) { struct VkWriteDescriptorSet *desc = &pds->descriptor_writes[i]; struct VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i]; - const uint8_t *pSrc = ((const uint8_t *) cmd->u.push_descriptor_set_with_template_khr.data) + entry->offset; /* dstSet is ignored */ desc->dstBinding = entry->dstBinding; @@ -3300,11 +3300,13 @@ static void handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry * case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: memcpy((VkDescriptorImageInfo*)&desc->pImageInfo[j], pSrc, sizeof(VkDescriptorImageInfo)); next_info += sizeof(VkDescriptorImageInfo); + pSrc += sizeof(VkDescriptorImageInfo); break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: memcpy((VkBufferView*)&desc->pTexelBufferView[j], pSrc, sizeof(VkBufferView)); next_info += sizeof(VkBufferView); + pSrc += sizeof(VkBufferView); break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: @@ -3313,9 +3315,9 @@ static void handle_push_descriptor_set_with_template(struct vk_cmd_queue_entry * default: memcpy((VkDescriptorBufferInfo*)&desc->pBufferInfo[j], pSrc, sizeof(VkDescriptorBufferInfo)); next_info += sizeof(VkDescriptorBufferInfo); + pSrc += sizeof(VkDescriptorBufferInfo); break; } - pSrc += entry->stride; } } handle_push_descriptor_set_generic(pds, state);