[PATCH] vkd3d: Don't allow concurrent writes to descriptors.

Chip Davis cdavis at codeweavers.com
Wed Sep 11 15:23:56 CDT 2019


Mac OS doesn't have pthread_spinlock_t.

September 11, 2019 2:18 PM, "Derek Lesho" <dlesho at codeweavers.com> wrote:

> In D3D12 it is legal to concurrently overwrite descriptors, we can't handle that.
> This patch locks descriptors from being overwritten by two threads at the same time.
> 
> Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
> ---
> libs/vkd3d/resource.c | 91 ++++++++++++++++++++++++++++++++------
> libs/vkd3d/vkd3d_private.h | 3 ++
> 2 files changed, 80 insertions(+), 14 deletions(-)
> 
> diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
> index 463f373..603434d 100644
> --- a/libs/vkd3d/resource.c
> +++ b/libs/vkd3d/resource.c
> @@ -1947,8 +1947,13 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor,
> void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src,
> struct d3d12_device *device)
> {
> + pthread_spinlock_t *resource_lock;
> +
> assert(dst != src);
> 
> + pthread_spin_lock(dst->lock);
> + resource_lock = dst->lock;
> +
> d3d12_desc_destroy(dst, device);
> 
> *dst = *src;
> @@ -1959,6 +1964,8 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src,
> {
> vkd3d_view_incref(src->u.view);
> }
> +
> + pthread_spin_unlock(resource_lock);
> }
> 
> static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12_device *device,
> @@ -2322,19 +2329,23 @@ void d3d12_desc_create_cbv(struct d3d12_desc *descriptor,
> {
> struct VkDescriptorBufferInfo *buffer_info;
> struct d3d12_resource *resource;
> + pthread_spinlock_t *resource_lock;
> +
> + pthread_spin_lock(descriptor->lock);
> + resource_lock = descriptor->lock;
> 
> d3d12_desc_destroy(descriptor, device);
> 
> if (!desc)
> {
> WARN("Constant buffer desc is NULL.\n");
> - return;
> + goto done;
> }
> 
> if (desc->SizeInBytes & (D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT - 1))
> {
> WARN("Size is not %u bytes aligned.\n", D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT);
> - return;
> + goto done;
> }
> 
> buffer_info = &descriptor->u.vk_cbv_info;
> @@ -2355,6 +2366,10 @@ void d3d12_desc_create_cbv(struct d3d12_desc *descriptor,
> 
> descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_CBV;
> descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
> +
> + done:
> + descriptor->lock = resource_lock;
> + pthread_spin_unlock(resource_lock);
> }
> 
> static unsigned int vkd3d_view_flags_from_d3d12_buffer_srv_flags(D3D12_BUFFER_SRV_FLAGS flags)
> @@ -2466,23 +2481,27 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
> {
> struct vkd3d_texture_view_desc vkd3d_desc;
> struct vkd3d_view *view;
> + pthread_spinlock_t *resource_lock;
> +
> + pthread_spin_lock(descriptor->lock);
> + resource_lock = descriptor->lock;
> 
> d3d12_desc_destroy(descriptor, device);
> 
> if (!resource)
> {
> vkd3d_create_null_srv(descriptor, device, desc);
> - return;
> + goto done;
> }
> 
> if (d3d12_resource_is_buffer(resource))
> {
> vkd3d_create_buffer_srv(descriptor, device, resource, desc);
> - return;
> + goto done;
> }
> 
> if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0))
> - return;
> + goto done;
> 
> vkd3d_desc.miplevel_count = VK_REMAINING_MIP_LEVELS;
> vkd3d_desc.allowed_swizzle = true;
> @@ -2559,11 +2578,15 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
> }
> 
> if (!vkd3d_create_texture_view(device, resource->u.vk_image, &vkd3d_desc, &view))
> - return;
> + goto done;
> 
> descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV;
> descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
> descriptor->u.view = view;
> +
> + done:
> + descriptor->lock = resource_lock;
> + pthread_spin_unlock(resource_lock);
> }
> 
> static unsigned int vkd3d_view_flags_from_d3d12_buffer_uav_flags(D3D12_BUFFER_UAV_FLAGS flags)
> @@ -2761,6 +2784,11 @@ void d3d12_desc_create_uav(struct d3d12_desc *descriptor, struct
> d3d12_device *d
> struct d3d12_resource *resource, struct d3d12_resource *counter_resource,
> const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc)
> {
> + pthread_spinlock_t *resource_lock;
> +
> + pthread_spin_lock(descriptor->lock);
> + resource_lock = descriptor->lock;
> +
> d3d12_desc_destroy(descriptor, device);
> 
> if (!resource)
> @@ -2768,7 +2796,7 @@ void d3d12_desc_create_uav(struct d3d12_desc *descriptor, struct d3d12_device
> *d
> if (counter_resource)
> FIXME("Ignoring counter resource %p.\n", counter_resource);
> vkd3d_create_null_uav(descriptor, device, desc);
> - return;
> + goto done;
> }
> 
> if (d3d12_resource_is_buffer(resource))
> @@ -2781,6 +2809,10 @@ void d3d12_desc_create_uav(struct d3d12_desc *descriptor, struct
> d3d12_device *d
> FIXME("Unexpected counter resource for texture view.\n");
> vkd3d_create_texture_uav(descriptor, device, resource, desc);
> }
> +
> + done:
> + descriptor->lock = resource_lock;
> + pthread_spin_unlock(resource_lock);
> }
> 
> bool vkd3d_create_raw_buffer_view(struct d3d12_device *device,
> @@ -2888,13 +2920,17 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
> struct d3d12_device *device, const D3D12_SAMPLER_DESC *desc)
> {
> struct vkd3d_view *view;
> + pthread_spinlock_t *resource_lock;
> +
> + pthread_spin_lock(sampler->lock);
> + resource_lock = sampler->lock;
> 
> d3d12_desc_destroy(sampler, device);
> 
> if (!desc)
> {
> WARN("NULL sampler desc.\n");
> - return;
> + goto done;
> }
> 
> if (desc->AddressU == D3D12_TEXTURE_ADDRESS_MODE_BORDER
> @@ -2904,19 +2940,23 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
> desc->BorderColor[0], desc->BorderColor[1], desc->BorderColor[2], desc->BorderColor[3]);
> 
> if (!(view = vkd3d_view_create()))
> - return;
> + goto done;
> 
> if (d3d12_create_sampler(device, desc->Filter, desc->AddressU,
> desc->AddressV, desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy,
> desc->ComparisonFunc, desc->MinLOD, desc->MaxLOD, &view->u.vk_sampler) < 0)
> {
> vkd3d_free(view);
> - return;
> + goto done;
> }
> 
> sampler->magic = VKD3D_DESCRIPTOR_MAGIC_SAMPLER;
> sampler->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLER;
> sampler->u.view = view;
> +
> + done:
> + sampler->lock = resource_lock;
> + pthread_spin_unlock(resource_lock);
> }
> 
> HRESULT vkd3d_create_static_sampler(struct d3d12_device *device,
> @@ -2950,22 +2990,26 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct
> d3d12_dev
> {
> struct vkd3d_texture_view_desc vkd3d_desc;
> struct vkd3d_view *view;
> + pthread_spinlock_t *resource_lock;
> +
> + pthread_spin_lock(rtv_desc->lock);
> + resource_lock = rtv_desc->lock;
> 
> d3d12_rtv_desc_destroy(rtv_desc, device);
> 
> if (!resource)
> {
> FIXME("NULL resource RTV not implemented.\n");
> - return;
> + goto done;
> }
> 
> if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0))
> - return;
> + goto done;
> 
> if (vkd3d_desc.format->vk_aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT)
> {
> WARN("Trying to create RTV for depth/stencil format %#x.\n", vkd3d_desc.format->dxgi_format);
> - return;
> + goto done;
> }
> 
> if (desc)
> @@ -3013,7 +3057,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct
> d3d12_dev
> assert(d3d12_resource_is_texture(resource));
> 
> if (!vkd3d_create_texture_view(device, resource->u.vk_image, &vkd3d_desc, &view))
> - return;
> + goto done;
> 
> rtv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_RTV;
> rtv_desc->sample_count = vk_samples_from_dxgi_sample_desc(&resource->desc.SampleDesc);
> @@ -3023,6 +3067,10 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct
> d3d12_dev
> rtv_desc->layer_count = vkd3d_desc.layer_count;
> rtv_desc->view = view;
> rtv_desc->resource = resource;
> +
> + done:
> + rtv_desc->lock = resource_lock;
> + pthread_spin_unlock(resource_lock);
> }
> 
> /* DSVs */
> @@ -3170,6 +3218,8 @@ static ULONG STDMETHODCALLTYPE
> d3d12_descriptor_heap_Release(ID3D12DescriptorHea
> for (i = 0; i < heap->desc.NumDescriptors; ++i)
> {
> d3d12_desc_destroy(&descriptors[i], device);
> + pthread_spin_destroy(descriptors[i].lock);
> + vkd3d_free((void*)descriptors[i].lock);
> }
> break;
> }
> @@ -3181,6 +3231,8 @@ static ULONG STDMETHODCALLTYPE
> d3d12_descriptor_heap_Release(ID3D12DescriptorHea
> for (i = 0; i < heap->desc.NumDescriptors; ++i)
> {
> d3d12_rtv_desc_destroy(&rtvs[i], device);
> + pthread_spin_destroy(rtvs[i].lock);
> + vkd3d_free((void*)rtvs[i].lock);
> }
> break;
> }
> @@ -3192,6 +3244,8 @@ static ULONG STDMETHODCALLTYPE
> d3d12_descriptor_heap_Release(ID3D12DescriptorHea
> for (i = 0; i < heap->desc.NumDescriptors; ++i)
> {
> d3d12_dsv_desc_destroy(&dsvs[i], device);
> + pthread_spin_destroy(dsvs[i].lock);
> + vkd3d_free((void*)dsvs[i].lock);
> }
> break;
> }
> @@ -3367,6 +3421,15 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
> 
> memset(object->descriptors, 0, descriptor_size * desc->NumDescriptors);
> 
> + for (unsigned int i = 0; i < desc->NumDescriptors; i++)
> + {
> + struct d3d12_desc *cur_desc = (struct d3d12_desc *) (object->descriptors + (i *
> descriptor_size));
> + pthread_spinlock_t *lock = vkd3d_malloc(sizeof(pthread_spinlock_t));
> +
> + pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE);
> + cur_desc->lock = lock;
> + }
> +
> TRACE("Created descriptor heap %p.\n", object);
> 
> *descriptor_heap = object;
> diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
> index bd9670e..6f1a957 100644
> --- a/libs/vkd3d/vkd3d_private.h
> +++ b/libs/vkd3d/vkd3d_private.h
> @@ -466,6 +466,7 @@ void vkd3d_view_incref(struct vkd3d_view *view) DECLSPEC_HIDDEN;
> struct d3d12_desc
> {
> uint32_t magic;
> + pthread_spinlock_t *lock;
> VkDescriptorType vk_descriptor_type;
> union
> {
> @@ -521,6 +522,7 @@ HRESULT vkd3d_create_static_sampler(struct d3d12_device *device,
> struct d3d12_rtv_desc
> {
> uint32_t magic;
> + pthread_spinlock_t *lock;
> VkSampleCountFlagBits sample_count;
> const struct vkd3d_format *format;
> uint64_t width;
> @@ -541,6 +543,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct
> d3d12_dev
> struct d3d12_dsv_desc
> {
> uint32_t magic;
> + pthread_spinlock_t *lock;
> VkSampleCountFlagBits sample_count;
> const struct vkd3d_format *format;
> uint64_t width;
> -- 
> 2.23.0


Chip



More information about the wine-devel mailing list