Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/HansKristian-Work/vkd3d-proton.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-09-28 13:58:33 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-11-10 16:32:27 +0300
commit74fc80b7257282531df5fe48327d4ac1626d3db0 (patch)
tree9ad11d4f1ba1ac50ce3d7b6dc3a1cd768abcc713
parenta049ce097d2e4e2ad13417212e2300e654e9b730 (diff)
vkd3d: Rewrite how buffers are stored in desc heap metadata.clear-uav-bda
Rather than storing VkBuffer / offset / size, we now store: - VA - Range (32-bit) - Format This accomplishes several things: - Prepares for a world where VkBufferView is not created in the heap itself (i.e. no offset buffer). - The metadata struct can now be shrunk to a neat 16 bytes instead of 32 before the refactor began. - Allow UAV clears to operate without a dependency on offset buffers. Hoisted CBV table descriptors (barely used, if ever) need to deref the VA late, but it's okay. Hopefully we get the option to push descriptors with VA later, but it's not critically important now. ClearUAV paths need to be rewritten to account for this. Rather than reusing VkBufferViews and reading the offset buffer, we can just create the buffer view on-demand instead. A VA deref is fortunately not needed since we get the ID3D12Resource inline. We already had to create fallback views for fallback clear paths anyways. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
-rw-r--r--libs/vkd3d/command.c230
-rw-r--r--libs/vkd3d/resource.c69
-rw-r--r--libs/vkd3d/vkd3d_private.h20
3 files changed, 200 insertions, 119 deletions
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 591e239e..96def8cb 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -5340,6 +5340,7 @@ static void d3d12_command_list_update_hoisted_descriptors(struct d3d12_command_l
const struct vkd3d_descriptor_metadata_types *types;
struct vkd3d_root_descriptor_info *root_parameter;
const struct vkd3d_descriptor_metadata_view *view;
+ const struct vkd3d_unique_resource *resource;
union vkd3d_descriptor_info *info;
unsigned int i;
@@ -5364,10 +5365,22 @@ static void d3d12_command_list_update_hoisted_descriptors(struct d3d12_command_l
root_parameter->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
info = &root_parameter->info;
- if (types && (types->flags & VKD3D_DESCRIPTOR_FLAG_OFFSET_RANGE))
+ if (types && (types->flags & VKD3D_DESCRIPTOR_FLAG_BUFFER_VA_RANGE))
{
/* Buffer descriptors must be valid on recording time. */
- info->buffer = view->info.buffer;
+ resource = vkd3d_va_map_deref(&list->device->memory_allocator.va_map, view->info.buffer.va);
+ if (resource)
+ {
+ info->buffer.buffer = resource->vk_buffer;
+ info->buffer.offset = view->info.buffer.va - resource->va;
+ info->buffer.range = min(view->info.buffer.range, resource->size - info->buffer.offset);
+ }
+ else
+ {
+ info->buffer.buffer = VK_NULL_HANDLE;
+ info->buffer.offset = 0;
+ info->buffer.range = VK_WHOLE_SIZE;
+ }
}
else
{
@@ -8639,15 +8652,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(d3d12_com
struct vkd3d_clear_uav_info
{
+ DXGI_FORMAT clear_dxgi_format;
bool has_view;
union
{
struct vkd3d_view *view;
- struct
- {
- VkDeviceSize offset;
- VkDeviceSize range;
- } buffer;
+ struct vkd3d_descriptor_metadata_buffer_view buffer;
} u;
};
@@ -8685,6 +8695,7 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list,
if (d3d12_resource_is_texture(resource))
{
assert(args->has_view);
+
image_info.sampler = VK_NULL_HANDLE;
image_info.imageView = args->u.view->vk_image_view;
image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
@@ -8720,7 +8731,7 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list,
write_set.pBufferInfo = &buffer_info;
/* resource heap offset is already in descriptor */
buffer_info.buffer = resource->res.vk_buffer;
- buffer_info.offset = args->u.buffer.offset;
+ buffer_info.offset = resource->mem.offset + (args->u.buffer.va - resource->res.va);
buffer_info.range = args->u.buffer.range;
}
@@ -8740,27 +8751,10 @@ static void d3d12_command_list_clear_uav(struct d3d12_command_list *list,
if (d3d12_resource_is_buffer(resource))
{
- const struct vkd3d_bound_buffer_range *ranges = d->heap->buffer_ranges.host_ptr;
-
if (args->has_view)
{
- if (list->device->bindless_state.flags & VKD3D_TYPED_OFFSET_BUFFER)
- {
- extra_offset = ranges[d->offset].element_offset;
- full_rect.right = ranges[d->offset].element_count;
- }
- else
- {
- VkDeviceSize byte_count = args->u.view->format->byte_count
- ? args->u.view->format->byte_count
- : sizeof(uint32_t); /* structured buffer */
- full_rect.right = args->u.view->info.buffer.size / byte_count;
- }
- }
- else if (list->device->bindless_state.flags & VKD3D_SSBO_OFFSET_BUFFER)
- {
- extra_offset = ranges[d->offset].byte_offset / sizeof(uint32_t);
- full_rect.right = ranges[d->offset].byte_count / sizeof(uint32_t);
+ VkDeviceSize byte_count = args->u.view->format->byte_count;
+ full_rect.right = args->u.view->info.buffer.size / byte_count;
}
else
full_rect.right = args->u.buffer.range / sizeof(uint32_t);
@@ -9053,17 +9047,18 @@ static bool vkd3d_clear_uav_check_uint_format_compatibility(struct d3d12_device
static inline bool vkd3d_clear_uav_info_from_desc(struct vkd3d_clear_uav_info *args, const struct d3d12_desc_split *d)
{
- if (d->types->flags & VKD3D_DESCRIPTOR_FLAG_VIEW)
+ if (d->types->flags & VKD3D_DESCRIPTOR_FLAG_IMAGE_VIEW)
{
args->has_view = true;
args->u.view = d->view->info.view;
+ args->clear_dxgi_format = d->view->info.view->format->dxgi_format;
return true;
}
- else if (d->types->flags & VKD3D_DESCRIPTOR_FLAG_OFFSET_RANGE)
+ else if (d->types->flags & VKD3D_DESCRIPTOR_FLAG_BUFFER_VA_RANGE)
{
+ args->u.buffer = d->view->info.buffer;
args->has_view = false;
- args->u.buffer.offset = d->view->info.buffer.offset;
- args->u.buffer.range = d->view->info.buffer.range;
+ args->clear_dxgi_format = d->view->info.buffer.dxgi_format;
return true;
}
else
@@ -9131,11 +9126,36 @@ static void vkd3d_mask_uint_clear_color(uint32_t color[4], VkFormat vk_format)
}
}
+static bool vkd3d_clear_uav_synthesize_buffer_view(struct d3d12_command_list *list,
+ struct d3d12_resource *resource, const struct vkd3d_clear_uav_info *args,
+ const struct vkd3d_format *override_format,
+ struct vkd3d_view **inline_view)
+{
+ /* We don't have a view, but we need one due to formatted clear. Synthesize a buffer view.
+ * Otherwise, we can just hit the raw SSBO path. */
+ struct vkd3d_buffer_view_desc view_desc;
+
+ view_desc.buffer = resource->res.vk_buffer;
+ view_desc.offset = resource->mem.offset + (args->u.buffer.va - resource->res.va);
+ view_desc.size = args->u.buffer.range;
+ view_desc.format = override_format ? override_format :
+ vkd3d_get_format(list->device, args->clear_dxgi_format, false);
+
+ if (!view_desc.format || !vkd3d_create_buffer_view(list->device, &view_desc, inline_view))
+ {
+ ERR("Failed to create buffer view.\n");
+ return false;
+ }
+
+ return true;
+}
+
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(d3d12_command_list_iface *iface,
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource,
const UINT values[4], UINT rect_count, const D3D12_RECT *rects)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
+ const struct vkd3d_format *clear_format;
const struct vkd3d_format *uint_format;
struct vkd3d_view *inline_view = NULL;
struct d3d12_resource *resource_impl;
@@ -9154,86 +9174,96 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(d3
if (!vkd3d_clear_uav_info_from_desc(&args, &d))
return;
- if (args.has_view)
- color = vkd3d_fixup_clear_uav_swizzle(list->device, d.view->info.view->format->dxgi_format, color);
+ if (d3d12_resource_is_texture(resource_impl) && !args.has_view)
+ {
+ /* Theoretically possibly for buggy application that tries to clear a buffer view with a texture resource.
+ * Safeguard against crash. */
+ ERR("Attempted to clear buffer with image resource.\n");
+ return;
+ }
+
+ if (args.clear_dxgi_format)
+ {
+ color = vkd3d_fixup_clear_uav_swizzle(list->device, args.clear_dxgi_format, color);
+ clear_format = vkd3d_get_format(list->device, args.clear_dxgi_format, false);
+ }
+ else
+ clear_format = NULL;
- if (args.has_view && d.view->info.view->format->type != VKD3D_FORMAT_TYPE_UINT)
+ /* Handle formatted buffer clears.
+ * Always defer creating the VkBufferView until this time. */
+ if (!args.has_view && args.clear_dxgi_format)
+ {
+ uint_format = vkd3d_clear_uav_find_uint_format(list->device, args.clear_dxgi_format);
+ if (!uint_format)
+ {
+ ERR("Unhandled format %d.\n", clear_format->dxgi_format);
+ return;
+ }
+
+ color = vkd3d_fixup_clear_uav_uint_color(list->device, clear_format->dxgi_format, color);
+ vkd3d_mask_uint_clear_color(color.uint32, uint_format->vk_format);
+
+ if (!vkd3d_clear_uav_synthesize_buffer_view(list, resource_impl, &args, uint_format, &inline_view))
+ return;
+
+ args.u.view = inline_view;
+ args.has_view = true;
+ }
+ else if (d3d12_resource_is_texture(resource_impl) && clear_format->type != VKD3D_FORMAT_TYPE_UINT)
{
const struct vkd3d_view *base_view = d.view->info.view;
- uint_format = vkd3d_clear_uav_find_uint_format(list->device, base_view->format->dxgi_format);
- color = vkd3d_fixup_clear_uav_uint_color(list->device, base_view->format->dxgi_format, color);
+ uint_format = vkd3d_clear_uav_find_uint_format(list->device, clear_format->dxgi_format);
+ color = vkd3d_fixup_clear_uav_uint_color(list->device, clear_format->dxgi_format, color);
if (!uint_format)
{
- ERR("Unhandled format %d.\n", base_view->format->dxgi_format);
+ ERR("Unhandled format %d.\n", clear_format->dxgi_format);
return;
}
vkd3d_mask_uint_clear_color(color.uint32, uint_format->vk_format);
- if (d3d12_resource_is_texture(resource_impl))
+ if (vkd3d_clear_uav_check_uint_format_compatibility(list->device, resource_impl->format, uint_format))
{
- if (vkd3d_clear_uav_check_uint_format_compatibility(list->device, resource_impl->format, uint_format))
- {
- struct vkd3d_texture_view_desc view_desc;
- memset(&view_desc, 0, sizeof(view_desc));
-
- view_desc.image = resource_impl->res.vk_image;
- view_desc.view_type = base_view->info.texture.vk_view_type;
- view_desc.format = uint_format;
- view_desc.miplevel_idx = base_view->info.texture.miplevel_idx;
- view_desc.miplevel_count = 1;
- view_desc.layer_idx = base_view->info.texture.layer_idx;
- view_desc.layer_count = base_view->info.texture.layer_count;
- view_desc.aspect_mask = view_desc.format->vk_aspect_mask;
- view_desc.image_usage = VK_IMAGE_USAGE_STORAGE_BIT;
- view_desc.allowed_swizzle = false;
-
- if (!vkd3d_create_texture_view(list->device, &view_desc, &args.u.view))
- {
- ERR("Failed to create image view.\n");
- return;
- }
+ struct vkd3d_texture_view_desc view_desc;
+ memset(&view_desc, 0, sizeof(view_desc));
- inline_view = args.u.view;
- }
- else
+ view_desc.image = resource_impl->res.vk_image;
+ view_desc.view_type = base_view->info.texture.vk_view_type;
+ view_desc.format = uint_format;
+ view_desc.miplevel_idx = base_view->info.texture.miplevel_idx;
+ view_desc.miplevel_count = 1;
+ view_desc.layer_idx = base_view->info.texture.layer_idx;
+ view_desc.layer_count = base_view->info.texture.layer_count;
+ view_desc.aspect_mask = view_desc.format->vk_aspect_mask;
+ view_desc.image_usage = VK_IMAGE_USAGE_STORAGE_BIT;
+ view_desc.allowed_swizzle = false;
+
+ if (!vkd3d_create_texture_view(list->device, &view_desc, &args.u.view))
{
- /* If the clear color is 0, we can safely use the existing view to perform the
- * clear since the bit pattern will not change. Otherwise, fill a scratch buffer
- * with the packed clear value and perform a buffer to image copy. */
- if (color.uint32[0] || color.uint32[1] || color.uint32[2] || color.uint32[3])
- {
- d3d12_command_list_clear_uav_with_copy(list, &d, resource_impl,
- &args, &color, uint_format, rect_count, rects);
- return;
- }
+ ERR("Failed to create image view.\n");
+ return;
}
+
+ inline_view = args.u.view;
}
else
{
- struct vkd3d_buffer_view_desc view_desc;
-
- if (!uint_format)
- uint_format = vkd3d_get_format(list->device, DXGI_FORMAT_R32_UINT, false);
-
- view_desc.buffer = resource_impl->res.vk_buffer;
- view_desc.format = uint_format;
- view_desc.offset = base_view->info.buffer.offset;
- view_desc.size = base_view->info.buffer.size;
-
- if (!vkd3d_create_buffer_view(list->device, &view_desc, &args.u.view))
+ /* If the clear color is 0, we can safely use the existing view to perform the
+ * clear since the bit pattern will not change. Otherwise, fill a scratch buffer
+ * with the packed clear value and perform a buffer to image copy. */
+ if (color.uint32[0] || color.uint32[1] || color.uint32[2] || color.uint32[3])
{
- ERR("Failed to create buffer view.\n");
+ d3d12_command_list_clear_uav_with_copy(list, &d, resource_impl,
+ &args, &color, uint_format, rect_count, rects);
return;
}
-
- inline_view = args.u.view;
}
}
else if (args.has_view)
{
- vkd3d_mask_uint_clear_color(color.uint32, d.view->info.view->format->vk_format);
+ vkd3d_mask_uint_clear_color(color.uint32, clear_format->vk_format);
}
d3d12_command_list_clear_uav(list, &d, resource_impl, &args, &color, rect_count, rects);
@@ -9250,6 +9280,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(d
const float values[4], UINT rect_count, const D3D12_RECT *rects)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
+ struct vkd3d_view *inline_view = NULL;
struct d3d12_resource *resource_impl;
struct vkd3d_clear_uav_info args;
struct d3d12_desc_split d;
@@ -9265,10 +9296,33 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(d
if (!vkd3d_clear_uav_info_from_desc(&args, &d))
return;
- if (args.has_view)
- color = vkd3d_fixup_clear_uav_swizzle(list->device, d.view->info.view->format->dxgi_format, color);
+ if (d3d12_resource_is_texture(resource_impl) && !args.has_view)
+ {
+ /* Theoretically possibly for buggy application that tries to clear a buffer view with a texture resource.
+ * Safeguard against crash. */
+ ERR("Attempted to clear buffer with image resource.\n");
+ return;
+ }
+
+ if (args.clear_dxgi_format)
+ color = vkd3d_fixup_clear_uav_swizzle(list->device, args.clear_dxgi_format, color);
+
+ if (!args.has_view && args.clear_dxgi_format)
+ {
+ if (!vkd3d_clear_uav_synthesize_buffer_view(list, resource_impl, &args, NULL, &inline_view))
+ return;
+
+ args.u.view = inline_view;
+ args.has_view = true;
+ }
d3d12_command_list_clear_uav(list, &d, resource_impl, &args, &color, rect_count, rects);
+
+ if (inline_view)
+ {
+ d3d12_command_allocator_add_view(list->allocator, inline_view);
+ vkd3d_view_decref(inline_view, list->device);
+ }
}
static bool d3d12_command_list_is_subresource_bound_as_rtv_dsv(struct d3d12_command_list *list,
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index af825ee1..debeca32 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -3523,6 +3523,26 @@ bool vkd3d_create_acceleration_structure_view(struct d3d12_device *device, const
#define VKD3D_VIEW_RAW_BUFFER 0x1
+static void vkd3d_get_metadata_buffer_view_for_resource(struct d3d12_device *device,
+ struct d3d12_resource *resource, DXGI_FORMAT view_format,
+ unsigned int offset, unsigned int size, unsigned int structure_stride,
+ struct vkd3d_descriptor_metadata_buffer_view *view)
+{
+ VkDeviceSize element_size;
+
+ element_size = view_format == DXGI_FORMAT_UNKNOWN
+ ? structure_stride : vkd3d_get_format(device, view_format, false)->byte_count;
+
+ view->va = resource->res.va + offset * element_size;
+ view->range = size * element_size;
+ view->dxgi_format = view_format;
+
+ /* If we would need an SSBO offset buffer for whatever reason, just fallback to a typed view instead. */
+ if (view_format == DXGI_FORMAT_UNKNOWN)
+ if (view->va & (device->device_info.properties2.properties.limits.minStorageBufferOffsetAlignment - 1))
+ view->dxgi_format = DXGI_FORMAT_R32_UINT;
+}
+
static bool vkd3d_create_buffer_view_for_resource(struct d3d12_device *device,
struct d3d12_resource *resource, DXGI_FORMAT view_format,
unsigned int offset, unsigned int size, unsigned int structure_stride,
@@ -3966,10 +3986,12 @@ void d3d12_desc_create_cbv(vkd3d_cpu_descriptor_va_t desc_va,
binding = vkd3d_bindless_state_binding_from_info_index(&device->bindless_state, info_index);
d.types->set_info_mask = 1u << info_index;
- d.types->flags = VKD3D_DESCRIPTOR_FLAG_OFFSET_RANGE | VKD3D_DESCRIPTOR_FLAG_NON_NULL |
+ d.types->flags = VKD3D_DESCRIPTOR_FLAG_BUFFER_VA_RANGE | VKD3D_DESCRIPTOR_FLAG_NON_NULL |
VKD3D_DESCRIPTOR_FLAG_SINGLE_DESCRIPTOR;
d.types->single_binding = binding;
- d.view->info.buffer = descriptor_info.buffer;
+ d.view->info.buffer.va = desc->BufferLocation;
+ d.view->info.buffer.range = desc->SizeInBytes;
+ d.view->info.buffer.dxgi_format = DXGI_FORMAT_UNKNOWN;
vkd3d_init_write_descriptor_set(&vk_write, &d, binding, vk_descriptor_type, &descriptor_info);
@@ -4198,7 +4220,12 @@ static void vkd3d_create_buffer_srv(vkd3d_cpu_descriptor_va_t desc_va,
}
d.types->set_info_mask = 0;
- d.types->flags = 0;
+ d.types->flags = VKD3D_DESCRIPTOR_FLAG_BUFFER_VA_RANGE |
+ VKD3D_DESCRIPTOR_FLAG_NON_NULL;
+
+ vkd3d_get_metadata_buffer_view_for_resource(device, resource,
+ desc->Format, desc->Buffer.FirstElement, desc->Buffer.NumElements,
+ desc->Buffer.StructureByteStride, &d.view->info.buffer);
if (d3d12_device_use_ssbo_raw_buffer(device) && emit_ssbo)
{
@@ -4214,12 +4241,8 @@ static void vkd3d_create_buffer_srv(vkd3d_cpu_descriptor_va_t desc_va,
VKD3D_BINDLESS_SET_SRV | VKD3D_BINDLESS_SET_RAW_SSBO);
binding = vkd3d_bindless_state_binding_from_info_index(&device->bindless_state, info_index);
- d.view->info.buffer = descriptor_info[vk_write_count].buffer;
- vkd3d_descriptor_metadata_view_set_qa_cookie(d.view, resource ? resource->res.cookie : 0);
d.types->set_info_mask |= 1u << info_index;
- d.types->flags |= VKD3D_DESCRIPTOR_FLAG_OFFSET_RANGE |
- VKD3D_DESCRIPTOR_FLAG_NON_NULL;
if (device->bindless_state.flags & VKD3D_SSBO_OFFSET_BUFFER)
d.types->flags |= VKD3D_DESCRIPTOR_FLAG_BUFFER_OFFSET;
d.types->single_binding = binding;
@@ -4245,14 +4268,8 @@ static void vkd3d_create_buffer_srv(vkd3d_cpu_descriptor_va_t desc_va,
VKD3D_BINDLESS_SET_SRV | VKD3D_BINDLESS_SET_BUFFER);
binding = vkd3d_bindless_state_binding_from_info_index(&device->bindless_state, info_index);
- d.view->info.view = view;
- /* Typed cookie takes precedence over raw cookie.
- * The typed cookie is more unique than raw cookie,
- * since raw cookie is just the ID3D12Resource. */
- vkd3d_descriptor_metadata_view_set_qa_cookie(d.view, view ? view->cookie : 0);
d.types->set_info_mask |= 1u << info_index;
- d.types->flags |= VKD3D_DESCRIPTOR_FLAG_VIEW | VKD3D_DESCRIPTOR_FLAG_NON_NULL;
if (device->bindless_state.flags & VKD3D_TYPED_OFFSET_BUFFER)
d.types->flags |= VKD3D_DESCRIPTOR_FLAG_BUFFER_OFFSET;
d.types->single_binding = binding;
@@ -4274,6 +4291,7 @@ static void vkd3d_create_buffer_srv(vkd3d_cpu_descriptor_va_t desc_va,
if (mutable_uses_single_descriptor)
d.types->flags |= VKD3D_DESCRIPTOR_FLAG_SINGLE_DESCRIPTOR;
+ vkd3d_descriptor_metadata_view_set_qa_cookie(d.view, resource ? resource->res.cookie : 0);
vkd3d_descriptor_debug_write_descriptor(d.heap->descriptor_heap_info.host_ptr,
d.heap->cookie, d.offset, descriptor_qa_flags, d.view->qa_cookie);
@@ -4431,7 +4449,7 @@ static void vkd3d_create_texture_srv(vkd3d_cpu_descriptor_va_t desc_va,
d.view->info.view = view;
d.types->set_info_mask = 1u << info_index;
- d.types->flags = VKD3D_DESCRIPTOR_FLAG_VIEW | VKD3D_DESCRIPTOR_FLAG_NON_NULL |
+ d.types->flags = VKD3D_DESCRIPTOR_FLAG_IMAGE_VIEW | VKD3D_DESCRIPTOR_FLAG_NON_NULL |
VKD3D_DESCRIPTOR_FLAG_SINGLE_DESCRIPTOR;
d.types->single_binding = binding;
@@ -4570,7 +4588,12 @@ static void vkd3d_create_buffer_uav(vkd3d_cpu_descriptor_va_t desc_va, struct d3
/* Handle UAV itself */
d.types->set_info_mask = 0;
d.types->flags = VKD3D_DESCRIPTOR_FLAG_RAW_VA_AUX_BUFFER |
- VKD3D_DESCRIPTOR_FLAG_NON_NULL;
+ VKD3D_DESCRIPTOR_FLAG_NON_NULL |
+ VKD3D_DESCRIPTOR_FLAG_BUFFER_VA_RANGE;
+
+ vkd3d_get_metadata_buffer_view_for_resource(device, resource,
+ desc->Format, desc->Buffer.FirstElement, desc->Buffer.NumElements,
+ desc->Buffer.StructureByteStride, &d.view->info.buffer);
if (d3d12_device_use_ssbo_raw_buffer(device) && emit_ssbo)
{
@@ -4588,10 +4611,8 @@ static void vkd3d_create_buffer_uav(vkd3d_cpu_descriptor_va_t desc_va, struct d3
VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_RAW_SSBO);
binding = vkd3d_bindless_state_binding_from_info_index(&device->bindless_state, info_index);
- d.view->info.buffer = *buffer_info;
d.types->set_info_mask |= 1u << info_index;
- d.types->flags |= VKD3D_DESCRIPTOR_FLAG_OFFSET_RANGE;
if (device->bindless_state.flags & VKD3D_SSBO_OFFSET_BUFFER)
d.types->flags |= VKD3D_DESCRIPTOR_FLAG_BUFFER_OFFSET;
d.types->single_binding = binding;
@@ -4599,7 +4620,6 @@ static void vkd3d_create_buffer_uav(vkd3d_cpu_descriptor_va_t desc_va, struct d3
vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
descriptor_qa_flags |= VKD3D_DESCRIPTOR_QA_TYPE_STORAGE_BUFFER_BIT;
- vkd3d_descriptor_metadata_view_set_qa_cookie(d.view, resource ? resource->res.cookie : 0);
vkd3d_init_write_descriptor_set(&vk_write[vk_write_count], &d, binding,
vk_descriptor_type, &descriptor_info[vk_write_count]);
vk_write_count++;
@@ -4618,14 +4638,8 @@ static void vkd3d_create_buffer_uav(vkd3d_cpu_descriptor_va_t desc_va, struct d3
VKD3D_BINDLESS_SET_UAV | VKD3D_BINDLESS_SET_BUFFER);
binding = vkd3d_bindless_state_binding_from_info_index(&device->bindless_state, info_index);
- d.view->info.view = view;
- /* Typed cookie takes precedence over raw cookie.
- * The typed cookie is more unique than raw cookie,
- * since raw cookie is just the ID3D12Resource. */
- vkd3d_descriptor_metadata_view_set_qa_cookie(d.view, view ? view->cookie : 0);
d.types->set_info_mask |= 1u << info_index;
- d.types->flags |= VKD3D_DESCRIPTOR_FLAG_VIEW;
if (device->bindless_state.flags & VKD3D_TYPED_OFFSET_BUFFER)
d.types->flags |= VKD3D_DESCRIPTOR_FLAG_BUFFER_OFFSET;
d.types->single_binding = binding;
@@ -4668,6 +4682,7 @@ static void vkd3d_create_buffer_uav(vkd3d_cpu_descriptor_va_t desc_va, struct d3
descriptor_index = d.offset;
counter_addresses[descriptor_index] = uav_counter_address;
+ vkd3d_descriptor_metadata_view_set_qa_cookie(d.view, resource ? resource->res.cookie : 0);
vkd3d_descriptor_debug_write_descriptor(d.heap->descriptor_heap_info.host_ptr,
d.heap->cookie, d.offset,
descriptor_qa_flags, d.view->qa_cookie);
@@ -4766,7 +4781,7 @@ static void vkd3d_create_texture_uav(vkd3d_cpu_descriptor_va_t desc_va,
d.view->info.view = view;
d.types->set_info_mask = 1u << info_index;
- d.types->flags = VKD3D_DESCRIPTOR_FLAG_VIEW | VKD3D_DESCRIPTOR_FLAG_NON_NULL |
+ d.types->flags = VKD3D_DESCRIPTOR_FLAG_IMAGE_VIEW | VKD3D_DESCRIPTOR_FLAG_NON_NULL |
VKD3D_DESCRIPTOR_FLAG_SINGLE_DESCRIPTOR;
d.types->single_binding = binding;
@@ -5077,7 +5092,9 @@ void d3d12_desc_create_sampler(vkd3d_cpu_descriptor_va_t desc_va,
d.view->info.view = view;
d.types->set_info_mask = 1u << info_index;
- d.types->flags = VKD3D_DESCRIPTOR_FLAG_VIEW | VKD3D_DESCRIPTOR_FLAG_NON_NULL | VKD3D_DESCRIPTOR_FLAG_SINGLE_DESCRIPTOR;
+ d.types->flags = VKD3D_DESCRIPTOR_FLAG_IMAGE_VIEW |
+ VKD3D_DESCRIPTOR_FLAG_NON_NULL |
+ VKD3D_DESCRIPTOR_FLAG_SINGLE_DESCRIPTOR;
d.types->single_binding = binding;
descriptor_info.image.sampler = view->vk_sampler;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 2ebbb66b..4774d33d 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1065,10 +1065,10 @@ bool vkd3d_create_texture_view(struct d3d12_device *device,
enum vkd3d_descriptor_flag
{
- VKD3D_DESCRIPTOR_FLAG_VIEW = (1 << 0),
+ VKD3D_DESCRIPTOR_FLAG_IMAGE_VIEW = (1 << 0),
VKD3D_DESCRIPTOR_FLAG_RAW_VA_AUX_BUFFER = (1 << 1),
VKD3D_DESCRIPTOR_FLAG_BUFFER_OFFSET = (1 << 2),
- VKD3D_DESCRIPTOR_FLAG_OFFSET_RANGE = (1 << 3),
+ VKD3D_DESCRIPTOR_FLAG_BUFFER_VA_RANGE = (1 << 3),
VKD3D_DESCRIPTOR_FLAG_NON_NULL = (1 << 4),
VKD3D_DESCRIPTOR_FLAG_SINGLE_DESCRIPTOR = (1 << 5),
};
@@ -1099,6 +1099,16 @@ STATIC_ASSERT(sizeof(struct vkd3d_descriptor_metadata_types) == 8);
/* Our use of 8-bit mask relies on MAX_BINDLESS_DESCRIPTOR_SETS fitting. */
STATIC_ASSERT(VKD3D_MAX_BINDLESS_DESCRIPTOR_SETS <= 8);
+struct vkd3d_descriptor_metadata_buffer_view
+{
+ VkDeviceAddress va;
+ /* Allows tighter packing. 64-bit view range is not supported in D3D12. */
+ uint32_t range;
+ /* Format used if used in a formatted context such as UAV clears.
+ * If UNKNOWN, denotes a raw buffer. R32_UINT can be used in place of it. */
+ DXGI_FORMAT dxgi_format;
+};
+
struct vkd3d_descriptor_metadata_view
{
#ifdef VKD3D_ENABLE_DESCRIPTOR_QA
@@ -1106,20 +1116,20 @@ struct vkd3d_descriptor_metadata_view
#endif
union
{
- VkDescriptorBufferInfo buffer;
+ struct vkd3d_descriptor_metadata_buffer_view buffer;
struct vkd3d_view *view;
} info;
};
#ifdef VKD3D_ENABLE_DESCRIPTOR_QA
-STATIC_ASSERT(sizeof(struct vkd3d_descriptor_metadata_view) == 32);
+STATIC_ASSERT(sizeof(struct vkd3d_descriptor_metadata_view) == 24);
static inline void vkd3d_descriptor_metadata_view_set_qa_cookie(
struct vkd3d_descriptor_metadata_view *view, uint64_t cookie)
{
view->qa_cookie = cookie;
}
#else
-STATIC_ASSERT(sizeof(struct vkd3d_descriptor_metadata_view) == 24);
+STATIC_ASSERT(sizeof(struct vkd3d_descriptor_metadata_view) == 16);
#define vkd3d_descriptor_metadata_view_set_qa_cookie(view, cookie) ((void)0)
#endif