mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d: Write a resource null descriptor to all applicable sets when one set is written.
Binding a shader with the wrong null descriptor type works in Windows. The introduction of Vulkan-backed heaps may cause a regression in clients which do this, because the written index will remain unpopulated in all other sets, but a shader may access it in one of them. Signed-off-by: Conor McCarthy <cmccarthy@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0627462192
commit
e3045090a8
@ -2131,6 +2131,7 @@ void vkd3d_view_decref(struct vkd3d_view *view, struct d3d12_device *device)
|
|||||||
vkd3d_view_destroy(view, device);
|
vkd3d_view_destroy(view, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: write null descriptors to all applicable sets (invalid behaviour workaround). */
|
||||||
static void d3d12_descriptor_heap_write_vk_descriptor_range(struct d3d12_descriptor_heap_vk_set *descriptor_set,
|
static void d3d12_descriptor_heap_write_vk_descriptor_range(struct d3d12_descriptor_heap_vk_set *descriptor_set,
|
||||||
struct d3d12_desc_copy_location *locations, unsigned int write_count)
|
struct d3d12_desc_copy_location *locations, unsigned int write_count)
|
||||||
{
|
{
|
||||||
@ -2178,6 +2179,47 @@ static void d3d12_descriptor_heap_write_vk_descriptor_range(struct d3d12_descrip
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_heap *descriptor_heap,
|
||||||
|
uint32_t dst_array_element, const struct d3d12_device *device)
|
||||||
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
|
struct d3d12_descriptor_heap_vk_set *descriptor_set;
|
||||||
|
VkBufferView vk_buffer_view = VK_NULL_HANDLE;
|
||||||
|
enum vkd3d_vk_descriptor_set_index i;
|
||||||
|
VkDescriptorBufferInfo vk_cbv_info;
|
||||||
|
|
||||||
|
vk_cbv_info.buffer = VK_NULL_HANDLE;
|
||||||
|
vk_cbv_info.offset = 0;
|
||||||
|
vk_cbv_info.range = VK_WHOLE_SIZE;
|
||||||
|
|
||||||
|
/* Binding a shader with the wrong null descriptor type works in Windows.
|
||||||
|
* To support that here we must write one to all applicable Vulkan sets. */
|
||||||
|
for (i = VKD3D_SET_INDEX_UNIFORM_BUFFER; i <= VKD3D_SET_INDEX_STORAGE_IMAGE; ++i)
|
||||||
|
{
|
||||||
|
descriptor_set = &descriptor_heap->vk_descriptor_sets[i];
|
||||||
|
descriptor_set->vk_descriptor_writes[0].dstArrayElement = dst_array_element;
|
||||||
|
descriptor_set->vk_descriptor_writes[0].descriptorCount = 1;
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case VKD3D_SET_INDEX_UNIFORM_BUFFER:
|
||||||
|
descriptor_set->vk_descriptor_writes[0].pBufferInfo = &vk_cbv_info;
|
||||||
|
break;
|
||||||
|
case VKD3D_SET_INDEX_SAMPLED_IMAGE:
|
||||||
|
case VKD3D_SET_INDEX_STORAGE_IMAGE:
|
||||||
|
descriptor_set->vk_image_infos[0].imageView = VK_NULL_HANDLE;
|
||||||
|
break;
|
||||||
|
case VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER:
|
||||||
|
case VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER:
|
||||||
|
descriptor_set->vk_descriptor_writes[0].pTexelBufferView = &vk_buffer_view;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
VK_CALL(vkUpdateDescriptorSets(device->vk_device, 1, descriptor_set->vk_descriptor_writes, 0, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* dst and src contain the same data unless another thread overwrites dst. The array index is
|
/* dst and src contain the same data unless another thread overwrites dst. The array index is
|
||||||
* calculated from dst, and src is thread safe. */
|
* calculated from dst, and src is thread safe. */
|
||||||
static void d3d12_desc_write_vk_heap(const struct d3d12_desc *dst, const struct d3d12_desc *src,
|
static void d3d12_desc_write_vk_heap(const struct d3d12_desc *dst, const struct d3d12_desc *src,
|
||||||
@ -2186,6 +2228,7 @@ static void d3d12_desc_write_vk_heap(const struct d3d12_desc *dst, const struct
|
|||||||
struct d3d12_descriptor_heap_vk_set *descriptor_set;
|
struct d3d12_descriptor_heap_vk_set *descriptor_set;
|
||||||
struct d3d12_descriptor_heap *descriptor_heap;
|
struct d3d12_descriptor_heap *descriptor_heap;
|
||||||
const struct vkd3d_vk_device_procs *vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs;
|
||||||
|
bool is_null = false;
|
||||||
|
|
||||||
descriptor_heap = vkd3d_gpu_descriptor_allocator_heap_from_descriptor(&device->gpu_descriptor_allocator, dst);
|
descriptor_heap = vkd3d_gpu_descriptor_allocator_heap_from_descriptor(&device->gpu_descriptor_allocator, dst);
|
||||||
descriptor_set = &descriptor_heap->vk_descriptor_sets[vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(
|
descriptor_set = &descriptor_heap->vk_descriptor_sets[vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(
|
||||||
@ -2201,14 +2244,16 @@ static void d3d12_desc_write_vk_heap(const struct d3d12_desc *dst, const struct
|
|||||||
{
|
{
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||||
descriptor_set->vk_descriptor_writes[0].pBufferInfo = &src->u.vk_cbv_info;
|
descriptor_set->vk_descriptor_writes[0].pBufferInfo = &src->u.vk_cbv_info;
|
||||||
|
is_null = !src->u.vk_cbv_info.buffer;
|
||||||
break;
|
break;
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||||
descriptor_set->vk_image_infos[0].imageView = src->u.view_info.view->u.vk_image_view;
|
is_null = !(descriptor_set->vk_image_infos[0].imageView = src->u.view_info.view->u.vk_image_view);
|
||||||
break;
|
break;
|
||||||
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
||||||
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
||||||
descriptor_set->vk_descriptor_writes[0].pTexelBufferView = &src->u.view_info.view->u.vk_buffer_view;
|
descriptor_set->vk_descriptor_writes[0].pTexelBufferView = &src->u.view_info.view->u.vk_buffer_view;
|
||||||
|
is_null = !src->u.view_info.view->u.vk_buffer_view;
|
||||||
break;
|
break;
|
||||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||||
descriptor_set->vk_image_infos[0].sampler = src->u.view_info.view->u.vk_sampler;
|
descriptor_set->vk_image_infos[0].sampler = src->u.view_info.view->u.vk_sampler;
|
||||||
@ -2217,6 +2262,14 @@ static void d3d12_desc_write_vk_heap(const struct d3d12_desc *dst, const struct
|
|||||||
ERR("Unhandled descriptor type %#x.\n", src->vk_descriptor_type);
|
ERR("Unhandled descriptor type %#x.\n", src->vk_descriptor_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (is_null && device->vk_info.EXT_robustness2)
|
||||||
|
{
|
||||||
|
d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap,
|
||||||
|
descriptor_set->vk_descriptor_writes[0].dstArrayElement, device);
|
||||||
|
vkd3d_mutex_unlock(&descriptor_heap->vk_sets_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
VK_CALL(vkUpdateDescriptorSets(device->vk_device, 1, descriptor_set->vk_descriptor_writes, 0, NULL));
|
VK_CALL(vkUpdateDescriptorSets(device->vk_device, 1, descriptor_set->vk_descriptor_writes, 0, NULL));
|
||||||
|
|
||||||
if (src->magic == VKD3D_DESCRIPTOR_MAGIC_UAV && src->u.view_info.view->vk_counter_view)
|
if (src->magic == VKD3D_DESCRIPTOR_MAGIC_UAV && src->u.view_info.view->vk_counter_view)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user