vkd3d: Use a unique cookie per resource/view.
We cannot compare resource pointers or view pointers, since the pointers might have been recycled. This leads to a scenario where we're not updating descriptors we're supposed to, and the GPU reads a stale descriptor. Fixes a GPU hang in Death Stranding (and possibly lots of other weird crashes as well). Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
3f1132ee8c
commit
af5a4cf311
|
@ -3027,6 +3027,8 @@ static HRESULT d3d12_resource_init_sparse_info(struct d3d12_resource *resource,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static LONG64 global_cookie_counter;
|
||||
|
||||
static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12_device *device,
|
||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
|
||||
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
|
||||
|
@ -3039,6 +3041,7 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
|
|||
resource->internal_refcount = 1;
|
||||
|
||||
resource->desc = *desc;
|
||||
resource->cookie = InterlockedIncrement64(&global_cookie_counter);
|
||||
|
||||
if (FAILED(hr = vkd3d_view_map_init(&resource->view_map)))
|
||||
return hr;
|
||||
|
@ -3395,6 +3398,7 @@ static struct vkd3d_view *vkd3d_view_create(enum vkd3d_view_type type)
|
|||
view->type = type;
|
||||
view->vk_counter_view = VK_NULL_HANDLE;
|
||||
view->vk_counter_address = 0;
|
||||
view->cookie = InterlockedIncrement64(&global_cookie_counter);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
@ -3447,17 +3451,23 @@ void d3d12_desc_copy(struct d3d12_desc *dst, struct d3d12_desc *src,
|
|||
bool needs_update;
|
||||
|
||||
/* Only update the descriptor if something has changed */
|
||||
if (!(needs_update = (metadata.flags != dst->metadata.flags)))
|
||||
if (!(needs_update = (metadata.cookie != dst->metadata.cookie)))
|
||||
{
|
||||
if (metadata.flags & VKD3D_DESCRIPTOR_FLAG_VIEW)
|
||||
/* We don't have a cookie for the UAV counter, so just force update if we have that.
|
||||
* If flags differ, we also need to update. E.g. happens if UAV counter flag is turned off.
|
||||
* We have no cookie for the UAV counter itself.
|
||||
* Lastly, if we have plain VkBuffers, offset/range might differ. */
|
||||
if ((metadata.flags & VKD3D_DESCRIPTOR_FLAG_UAV_COUNTER) != 0 ||
|
||||
(metadata.flags != dst->metadata.flags))
|
||||
{
|
||||
needs_update = dst->info.view != src->info.view;
|
||||
needs_update = true;
|
||||
}
|
||||
else if (metadata.flags & VKD3D_DESCRIPTOR_FLAG_DEFINED)
|
||||
else if ((metadata.flags & VKD3D_DESCRIPTOR_FLAG_DEFINED) != 0 &&
|
||||
(metadata.flags & VKD3D_DESCRIPTOR_FLAG_VIEW) == 0)
|
||||
{
|
||||
needs_update = dst->info.vk_cbv_info.buffer != src->info.vk_cbv_info.buffer ||
|
||||
dst->info.vk_cbv_info.offset != src->info.vk_cbv_info.offset ||
|
||||
dst->info.vk_cbv_info.range != src->info.vk_cbv_info.range;
|
||||
needs_update =
|
||||
dst->info.vk_cbv_info.offset != src->info.vk_cbv_info.offset ||
|
||||
dst->info.vk_cbv_info.range != src->info.vk_cbv_info.range;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3886,8 +3896,8 @@ void d3d12_desc_create_cbv(struct d3d12_desc *descriptor,
|
|||
{
|
||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||
union vkd3d_descriptor_info descriptor_info;
|
||||
struct d3d12_resource *resource = NULL;
|
||||
VkDescriptorType vk_descriptor_type;
|
||||
struct d3d12_resource *resource;
|
||||
VkWriteDescriptorSet vk_write;
|
||||
|
||||
if (!desc)
|
||||
|
@ -3924,6 +3934,7 @@ void d3d12_desc_create_cbv(struct d3d12_desc *descriptor,
|
|||
|
||||
vk_descriptor_type = vkd3d_bindless_state_get_cbv_descriptor_type(&device->bindless_state);
|
||||
|
||||
descriptor->metadata.cookie = resource ? resource->cookie : 0;
|
||||
descriptor->metadata.set_index = d3d12_descriptor_heap_cbv_set_index();
|
||||
descriptor->metadata.flags = VKD3D_DESCRIPTOR_FLAG_DEFINED;
|
||||
descriptor->info.vk_cbv_info = descriptor_info.buffer;
|
||||
|
@ -3988,6 +3999,7 @@ static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor,
|
|||
descriptor_info.buffer_view = view ? view->vk_buffer_view : VK_NULL_HANDLE;
|
||||
|
||||
descriptor->info.view = view;
|
||||
descriptor->metadata.cookie = view ? view->cookie : 0;
|
||||
descriptor->metadata.set_index = d3d12_descriptor_heap_srv_set_index(true);
|
||||
descriptor->metadata.flags = VKD3D_DESCRIPTOR_FLAG_DEFINED | VKD3D_DESCRIPTOR_FLAG_VIEW;
|
||||
|
||||
|
@ -4144,6 +4156,7 @@ static void vkd3d_create_texture_srv(struct d3d12_desc *descriptor,
|
|||
descriptor_info.image.imageLayout = view ? view->info.texture.vk_layout : VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
descriptor->info.view = view;
|
||||
descriptor->metadata.cookie = view ? view->cookie : 0;
|
||||
descriptor->metadata.set_index = d3d12_descriptor_heap_srv_set_index(false);
|
||||
descriptor->metadata.flags = VKD3D_DESCRIPTOR_FLAG_DEFINED | VKD3D_DESCRIPTOR_FLAG_VIEW;
|
||||
|
||||
|
@ -4245,6 +4258,7 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_
|
|||
}
|
||||
|
||||
descriptor->info.view = view;
|
||||
descriptor->metadata.cookie = view ? view->cookie : 0;
|
||||
descriptor->metadata.set_index = d3d12_descriptor_heap_uav_set_index(true);
|
||||
descriptor->metadata.flags = VKD3D_DESCRIPTOR_FLAG_DEFINED | VKD3D_DESCRIPTOR_FLAG_VIEW | VKD3D_DESCRIPTOR_FLAG_UAV_COUNTER;
|
||||
|
||||
|
@ -4412,6 +4426,7 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
|
|||
descriptor_info.image.imageLayout = view ? view->info.texture.vk_layout : VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
|
||||
descriptor->info.view = view;
|
||||
descriptor->metadata.cookie = view ? view->cookie : 0;
|
||||
descriptor->metadata.set_index = d3d12_descriptor_heap_uav_set_index(false);
|
||||
descriptor->metadata.flags = VKD3D_DESCRIPTOR_FLAG_DEFINED | VKD3D_DESCRIPTOR_FLAG_VIEW;
|
||||
|
||||
|
@ -4705,6 +4720,7 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
|
|||
return;
|
||||
|
||||
sampler->info.view = view;
|
||||
sampler->metadata.cookie = view->cookie;
|
||||
sampler->metadata.set_index = d3d12_descriptor_heap_sampler_set_index();
|
||||
sampler->metadata.flags = VKD3D_DESCRIPTOR_FLAG_DEFINED | VKD3D_DESCRIPTOR_FLAG_VIEW;
|
||||
|
||||
|
|
|
@ -488,6 +488,8 @@ struct d3d12_resource
|
|||
LONG refcount;
|
||||
LONG internal_refcount;
|
||||
|
||||
uint64_t cookie;
|
||||
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
|
||||
D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
|
||||
|
@ -570,6 +572,8 @@ struct vkd3d_view
|
|||
{
|
||||
LONG refcount;
|
||||
enum vkd3d_view_type type;
|
||||
uint64_t cookie;
|
||||
|
||||
union
|
||||
{
|
||||
VkBufferView vk_buffer_view;
|
||||
|
@ -636,15 +640,16 @@ enum vkd3d_descriptor_flag
|
|||
|
||||
struct vkd3d_descriptor_data
|
||||
{
|
||||
uint64_t cookie;
|
||||
uint32_t set_index;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct d3d12_desc
|
||||
{
|
||||
struct vkd3d_descriptor_data metadata;
|
||||
struct d3d12_descriptor_heap *heap;
|
||||
uint32_t heap_offset;
|
||||
struct vkd3d_descriptor_data metadata;
|
||||
union
|
||||
{
|
||||
VkDescriptorBufferInfo vk_cbv_info;
|
||||
|
|
Loading…
Reference in New Issue