In vk_write_descriptor_set_from_d3d12_desc() this avoids memory reads from the view object on the heap which often cause cache misses. It is a relatively simple (but hacky) change for a 0.5% frame rate increase in SotTR.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/command.c | 10 ++++------ libs/vkd3d/resource.c | 38 ++++++++++++++++++++++++-------------- libs/vkd3d/vkd3d_private.h | 7 ++++++- 3 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 0532ec0..69d1baa 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2548,8 +2548,6 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des uint32_t descriptor_range_magic, VkDescriptorSet vk_descriptor_set, uint32_t vk_binding, unsigned int index) { - const struct vkd3d_view *view = descriptor->u.view; - if (descriptor->magic != descriptor_range_magic) return false;
@@ -2582,12 +2580,12 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) { - vk_descriptor_write->pTexelBufferView = &view->u.vk_buffer_view; + vk_descriptor_write->pTexelBufferView = (const VkBufferView *)&descriptor->u.v.vk_view; } else { vk_image_info->sampler = VK_NULL_HANDLE; - vk_image_info->imageView = view->u.vk_image_view; + vk_image_info->imageView = descriptor->u.v.vk_view; vk_image_info->imageLayout = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
@@ -2596,7 +2594,7 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des break;
case VKD3D_DESCRIPTOR_MAGIC_SAMPLER: - vk_image_info->sampler = view->u.vk_sampler; + vk_image_info->sampler = descriptor->u.v.vk_view; vk_image_info->imageView = VK_NULL_HANDLE; vk_image_info->imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -2649,7 +2647,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list && register_idx < ARRAY_SIZE(bindings->vk_uav_counter_views)) { VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV - ? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE; + ? descriptor->u.v.vk_counter_view : VK_NULL_HANDLE; if (bindings->vk_uav_counter_views[register_idx] != vk_counter_view) bindings->uav_counter_dirty_mask |= 1u << register_idx; bindings->vk_uav_counter_views[register_idx] = vk_counter_view; diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index d6e999e..5627aef 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -2044,7 +2044,7 @@ void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *sr struct d3d12_desc destroy_desc; pthread_mutex_t *mutex;
- destroy_desc.u.view = NULL; + destroy_desc.u.v.view = NULL;
mutex = d3d12_device_get_descriptor_mutex(device, dst); pthread_mutex_lock(mutex); @@ -2053,7 +2053,7 @@ void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *sr if ((dst->magic == VKD3D_DESCRIPTOR_MAGIC_SRV || dst->magic == VKD3D_DESCRIPTOR_MAGIC_UAV || dst->magic == VKD3D_DESCRIPTOR_MAGIC_SAMPLER) - && !InterlockedDecrement(&dst->u.view->refcount)) + && !InterlockedDecrement(&dst->u.v.view->refcount)) destroy_desc = *dst;
*dst = *src; @@ -2061,8 +2061,8 @@ void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *sr pthread_mutex_unlock(mutex);
/* Destroy the view after unlocking to reduce wait time. */ - if (destroy_desc.u.view) - vkd3d_view_destroy_descriptor(destroy_desc.u.view, &destroy_desc, device); + if (destroy_desc.u.v.view) + vkd3d_view_destroy_descriptor(destroy_desc.u.v.view, &destroy_desc, device); }
static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_device *device) @@ -2089,7 +2089,7 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, || src->magic == VKD3D_DESCRIPTOR_MAGIC_UAV || src->magic == VKD3D_DESCRIPTOR_MAGIC_SAMPLER) { - vkd3d_view_incref(src->u.view); + vkd3d_view_incref(src->u.v.view); }
tmp = *src; @@ -2527,7 +2527,8 @@ static void vkd3d_create_null_srv(struct d3d12_desc *descriptor, { descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_buffer_view; } return;
@@ -2563,7 +2564,8 @@ static void vkd3d_create_null_srv(struct d3d12_desc *descriptor,
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_image_view; }
static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor, @@ -2593,7 +2595,8 @@ static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor,
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_buffer_view; }
void d3d12_desc_create_srv(struct d3d12_desc *descriptor, @@ -2697,7 +2700,8 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_image_view; }
static unsigned int vkd3d_view_flags_from_d3d12_buffer_uav_flags(D3D12_BUFFER_UAV_FLAGS flags) @@ -2734,7 +2738,8 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor, { descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_buffer_view; } return;
@@ -2770,7 +2775,8 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor,
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_image_view; }
static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_device *device, @@ -2803,7 +2809,8 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_buffer_view;
if (counter_resource) { @@ -2820,6 +2827,7 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_ view->vk_counter_view = VK_NULL_HANDLE; d3d12_desc_destroy(descriptor, device); } + descriptor->u.v.vk_counter_view = view->vk_counter_view; }
/* FIXME: Clears are implemented only for R32_UINT buffer UAVs. */ @@ -2883,7 +2891,8 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - descriptor->u.view = view; + descriptor->u.v.view = view; + descriptor->u.v.vk_view = view->u.vk_image_view;
descriptor->uav.texture.vk_aspect_mask = vkd3d_desc.format->vk_aspect_mask; descriptor->uav.texture.miplevel_idx = vkd3d_desc.miplevel_idx; @@ -3046,7 +3055,8 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
sampler->magic = VKD3D_DESCRIPTOR_MAGIC_SAMPLER; sampler->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLER; - sampler->u.view = view; + sampler->u.v.view = view; + sampler->u.v.vk_view = view->u.vk_sampler; }
HRESULT vkd3d_create_static_sampler(struct d3d12_device *device, diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 2d62fda..0f2d916 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -480,7 +480,12 @@ struct d3d12_desc union { VkDescriptorBufferInfo vk_cbv_info; - struct vkd3d_view *view; + struct + { + struct vkd3d_view *view; + void *vk_view; + VkBufferView vk_counter_view; + } v; } u;
union
On Fri, 1 Nov 2019 at 09:16, Conor McCarthy cmccarthy@codeweavers.com wrote:
from the view object on the heap which often cause cache misses. It is a relatively simple (but hacky) change for a 0.5% frame rate increase in SotTR.
Simple is good, hacky not so much. Could you at least use a proper structure instead of the void pointer and VkBufferView field?