libs/vkd3d: Implement reference counting for Vulkan views and samplers.

This commit is contained in:
Józef Kucia 2017-09-04 18:32:40 +02:00
parent ea8e5eaaba
commit a780b7a11c
3 changed files with 105 additions and 18 deletions

View File

@ -2447,6 +2447,8 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des
VkDescriptorImageInfo *vk_image_info, struct d3d12_desc *descriptor, VkDescriptorImageInfo *vk_image_info, struct d3d12_desc *descriptor,
VkDescriptorSet vk_descriptor_set, uint32_t vk_binding, unsigned int index) VkDescriptorSet vk_descriptor_set, uint32_t vk_binding, unsigned int index)
{ {
const struct vkd3d_view *view = descriptor->u.view;
vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
vk_descriptor_write->pNext = NULL; vk_descriptor_write->pNext = NULL;
vk_descriptor_write->dstSet = vk_descriptor_set; vk_descriptor_write->dstSet = vk_descriptor_set;
@ -2476,12 +2478,12 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des
if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|| descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) || descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
{ {
vk_descriptor_write->pTexelBufferView = &descriptor->u.vk_buffer_view; vk_descriptor_write->pTexelBufferView = &view->u.vk_buffer_view;
} }
else else
{ {
vk_image_info->sampler = VK_NULL_HANDLE; vk_image_info->sampler = VK_NULL_HANDLE;
vk_image_info->imageView = descriptor->u.vk_image_view; vk_image_info->imageView = view->u.vk_image_view;
vk_image_info->imageLayout = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV vk_image_info->imageLayout = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV
? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL; ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
@ -2490,7 +2492,7 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des
break; break;
case VKD3D_DESCRIPTOR_MAGIC_SAMPLER: case VKD3D_DESCRIPTOR_MAGIC_SAMPLER:
vk_image_info->sampler = descriptor->u.vk_sampler; vk_image_info->sampler = view->u.vk_sampler;
vk_image_info->imageView = VK_NULL_HANDLE; vk_image_info->imageView = VK_NULL_HANDLE;
vk_image_info->imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; vk_image_info->imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;

View File

@ -765,23 +765,56 @@ HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_D
} }
/* CBVs, SRVs, UAVs */ /* CBVs, SRVs, UAVs */
static void d3d12_desc_destroy(struct d3d12_desc *descriptor, static struct vkd3d_view *vkd3d_view_create(void)
struct d3d12_device *device) {
struct vkd3d_view *view;
if ((view = vkd3d_malloc(sizeof(*view))))
view->refcount = 1;
return view;
}
static void vkd3d_view_incref(struct vkd3d_view *view)
{
InterlockedIncrement(&view->refcount);
}
static void vkd3d_view_decref(struct vkd3d_view *view,
const struct d3d12_desc *descriptor, struct d3d12_device *device)
{ {
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
ULONG refcount = InterlockedDecrement(&view->refcount);
if (refcount)
return;
TRACE("Destroying view %p.\n", view);
/* Nothing to do for VKD3D_DESCRIPTOR_MAGIC_CBV. */
if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV || descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV) if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV || descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV)
{ {
if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
|| descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) || descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
VK_CALL(vkDestroyBufferView(device->vk_device, descriptor->u.vk_buffer_view, NULL)); VK_CALL(vkDestroyBufferView(device->vk_device, view->u.vk_buffer_view, NULL));
else else
VK_CALL(vkDestroyImageView(device->vk_device, descriptor->u.vk_image_view, NULL)); VK_CALL(vkDestroyImageView(device->vk_device, view->u.vk_image_view, NULL));
} }
else if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SAMPLER) else if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SAMPLER)
{ {
VK_CALL(vkDestroySampler(device->vk_device, descriptor->u.vk_sampler, NULL)); VK_CALL(vkDestroySampler(device->vk_device, view->u.vk_sampler, NULL));
}
vkd3d_free(view);
}
static void d3d12_desc_destroy(struct d3d12_desc *descriptor,
struct d3d12_device *device)
{
/* Nothing to do for VKD3D_DESCRIPTOR_MAGIC_CBV. */
if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV
|| descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV
|| descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SAMPLER)
{
vkd3d_view_decref(descriptor->u.view, descriptor, device);
} }
memset(descriptor, 0, sizeof(*descriptor)); memset(descriptor, 0, sizeof(*descriptor));
@ -933,6 +966,8 @@ static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor,
struct d3d12_device *device, struct d3d12_resource *resource, struct d3d12_device *device, struct d3d12_resource *resource,
const D3D12_SHADER_RESOURCE_VIEW_DESC *desc) const D3D12_SHADER_RESOURCE_VIEW_DESC *desc)
{ {
struct vkd3d_view *view;
if (!desc) if (!desc)
{ {
FIXME("Default SRV views not supported.\n"); FIXME("Default SRV views not supported.\n");
@ -945,15 +980,22 @@ static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor,
return; return;
} }
if (!(view = vkd3d_view_create()))
return;
if (!vkd3d_create_buffer_view(device, resource, desc->Format, if (!vkd3d_create_buffer_view(device, resource, desc->Format,
desc->u.Buffer.FirstElement, desc->u.Buffer.NumElements, desc->u.Buffer.FirstElement, desc->u.Buffer.NumElements,
desc->u.Buffer.StructureByteStride, desc->u.Buffer.StructureByteStride,
vkd3d_view_flags_from_d3d12_buffer_srv_flags(desc->u.Buffer.Flags), vkd3d_view_flags_from_d3d12_buffer_srv_flags(desc->u.Buffer.Flags),
&descriptor->u.vk_buffer_view)) &view->u.vk_buffer_view))
{
vkd3d_free(view);
return; return;
}
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV;
descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
descriptor->u.view = view;
} }
void d3d12_desc_create_srv(struct d3d12_desc *descriptor, void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
@ -962,6 +1004,7 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
{ {
const struct vkd3d_format *format; const struct vkd3d_format *format;
VkImageViewType vk_view_type; VkImageViewType vk_view_type;
struct vkd3d_view *view;
d3d12_desc_destroy(descriptor, device); d3d12_desc_destroy(descriptor, device);
@ -992,14 +1035,21 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
return; return;
} }
if (!(view = vkd3d_view_create()))
return;
vk_view_type = resource->desc.DepthOrArraySize > 1 vk_view_type = resource->desc.DepthOrArraySize > 1
? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D; ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
if (vkd3d_create_texture_view(device, resource, format, vk_view_type, if (vkd3d_create_texture_view(device, resource, format, vk_view_type,
0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS, &descriptor->u.vk_image_view) < 0) 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS, &view->u.vk_image_view) < 0)
{
vkd3d_free(view);
return; return;
}
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV;
descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
descriptor->u.view = view;
} }
static unsigned int vkd3d_view_flags_from_d3d12_buffer_uav_flags(D3D12_BUFFER_UAV_FLAGS flags) static unsigned int vkd3d_view_flags_from_d3d12_buffer_uav_flags(D3D12_BUFFER_UAV_FLAGS flags)
@ -1015,6 +1065,8 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor,
struct d3d12_device *device, struct d3d12_resource *resource, struct d3d12_device *device, struct d3d12_resource *resource,
const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc) const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc)
{ {
struct vkd3d_view *view;
if (!desc) if (!desc)
{ {
FIXME("Default UAV views not supported.\n"); FIXME("Default UAV views not supported.\n");
@ -1030,15 +1082,22 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor,
if (desc->u.Buffer.CounterOffsetInBytes) if (desc->u.Buffer.CounterOffsetInBytes)
FIXME("Ignoring counter offset %"PRIu64".\n", desc->u.Buffer.CounterOffsetInBytes); FIXME("Ignoring counter offset %"PRIu64".\n", desc->u.Buffer.CounterOffsetInBytes);
if (!(view = vkd3d_view_create()))
return;
if (!vkd3d_create_buffer_view(device, resource, desc->Format, if (!vkd3d_create_buffer_view(device, resource, desc->Format,
desc->u.Buffer.FirstElement, desc->u.Buffer.NumElements, desc->u.Buffer.FirstElement, desc->u.Buffer.NumElements,
desc->u.Buffer.StructureByteStride, desc->u.Buffer.StructureByteStride,
vkd3d_view_flags_from_d3d12_buffer_uav_flags(desc->u.Buffer.Flags), vkd3d_view_flags_from_d3d12_buffer_uav_flags(desc->u.Buffer.Flags),
&descriptor->u.vk_buffer_view)) &view->u.vk_buffer_view))
{
vkd3d_free(view);
return; return;
}
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV;
descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
descriptor->u.view = view;
} }
static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor, static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
@ -1048,6 +1107,7 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
uint32_t miplevel_idx, layer_idx, layer_count; uint32_t miplevel_idx, layer_idx, layer_count;
const struct vkd3d_format *format; const struct vkd3d_format *format;
VkImageViewType vk_view_type; VkImageViewType vk_view_type;
struct vkd3d_view *view;
if (resource->desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D) if (resource->desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D)
{ {
@ -1098,12 +1158,19 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
} }
} }
if (vkd3d_create_texture_view(device, resource, format, vk_view_type, if (!(view = vkd3d_view_create()))
miplevel_idx, 1, layer_idx, layer_count, &descriptor->u.vk_image_view) < 0)
return; return;
if (vkd3d_create_texture_view(device, resource, format, vk_view_type,
miplevel_idx, 1, layer_idx, layer_count, &view->u.vk_image_view) < 0)
{
vkd3d_free(view);
return;
}
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV;
descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
descriptor->u.view = view;
} }
void d3d12_desc_create_uav(struct d3d12_desc *descriptor, void d3d12_desc_create_uav(struct d3d12_desc *descriptor,
@ -1227,6 +1294,8 @@ static VkResult d3d12_create_sampler(struct d3d12_device *device, D3D12_FILTER f
void d3d12_desc_create_sampler(struct d3d12_desc *sampler, void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
struct d3d12_device *device, const D3D12_SAMPLER_DESC *desc) struct d3d12_device *device, const D3D12_SAMPLER_DESC *desc)
{ {
struct vkd3d_view *view;
d3d12_desc_destroy(sampler, device); d3d12_desc_destroy(sampler, device);
if (!desc) if (!desc)
@ -1241,13 +1310,20 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
FIXME("Ignoring border color {%.8e, %.8e, %.8e, %.8e}.\n", FIXME("Ignoring border color {%.8e, %.8e, %.8e, %.8e}.\n",
desc->BorderColor[0], desc->BorderColor[1], desc->BorderColor[2], desc->BorderColor[3]); desc->BorderColor[0], desc->BorderColor[1], desc->BorderColor[2], desc->BorderColor[3]);
if (!(view = vkd3d_view_create()))
return;
if (d3d12_create_sampler(device, desc->Filter, desc->AddressU, if (d3d12_create_sampler(device, desc->Filter, desc->AddressU,
desc->AddressV, desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy, desc->AddressV, desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy,
desc->ComparisonFunc, desc->MinLOD, desc->MaxLOD, &sampler->u.vk_sampler) < 0) desc->ComparisonFunc, desc->MinLOD, desc->MaxLOD, &view->u.vk_sampler) < 0)
{
vkd3d_free(view);
return; return;
}
sampler->magic = VKD3D_DESCRIPTOR_MAGIC_SAMPLER; sampler->magic = VKD3D_DESCRIPTOR_MAGIC_SAMPLER;
sampler->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLER; sampler->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLER;
sampler->u.view = view;
} }
HRESULT vkd3d_create_static_sampler(struct d3d12_device *device, HRESULT vkd3d_create_static_sampler(struct d3d12_device *device,

View File

@ -187,6 +187,17 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource) DECLSPEC_HIDDEN; const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource) DECLSPEC_HIDDEN;
struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface) DECLSPEC_HIDDEN; struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface) DECLSPEC_HIDDEN;
struct vkd3d_view
{
LONG refcount;
union
{
VkBufferView vk_buffer_view;
VkImageView vk_image_view;
VkSampler vk_sampler;
} u;
};
struct d3d12_desc struct d3d12_desc
{ {
uint32_t magic; uint32_t magic;
@ -194,9 +205,7 @@ struct d3d12_desc
union union
{ {
VkDescriptorBufferInfo vk_cbv_info; VkDescriptorBufferInfo vk_cbv_info;
VkBufferView vk_buffer_view; struct vkd3d_view *view;
VkImageView vk_image_view;
VkSampler vk_sampler;
} u; } u;
}; };