Module: vkd3d Branch: master Commit: 401739a387df619bd85424f73af613e6da2a902d URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=401739a387df619bd85424f7...
Author: Józef Kucia jkucia@codeweavers.com Date: Mon Mar 4 13:15:14 2019 +0100
vkd3d: Emulate NULL CBV descriptors.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
libs/vkd3d/device.c | 6 ++++ libs/vkd3d/resource.c | 83 ++++++++++++++++++++++++++++++++++++++-------- libs/vkd3d/vkd3d_private.h | 14 ++++++++ 3 files changed, 89 insertions(+), 14 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 3d9b8c9..c1de98f 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1536,6 +1536,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
vkd3d_private_store_destroy(&device->private_store);
+ vkd3d_destroy_null_resources(&device->null_resources, device); vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator); vkd3d_fence_worker_stop(&device->fence_worker, device); VK_CALL(vkDestroySampler(device->vk_device, device->vk_dummy_sampler, NULL)); @@ -2704,6 +2705,9 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, if (FAILED(hr = vkd3d_fence_worker_start(&device->fence_worker, device))) goto out_free_private_store;
+ if (FAILED(hr = vkd3d_init_null_resources(&device->null_resources, device))) + goto out_stop_fence_worker; + vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator);
if ((device->parent = create_info->parent)) @@ -2711,6 +2715,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
return S_OK;
+out_stop_fence_worker: + vkd3d_fence_worker_stop(&device->fence_worker, device); out_free_private_store: vkd3d_private_store_destroy(&device->private_store); out_free_pipeline_cache: diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 1176538..06e7c7d 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -18,10 +18,12 @@
#include "vkd3d_private.h"
+#define VKD3D_NULL_CBV_BUFFER_SIZE 4 + static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32_t memory_type_mask, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags) { - VkPhysicalDeviceMemoryProperties *memory_info = &device->memory_properties; + const VkPhysicalDeviceMemoryProperties *memory_info = &device->memory_properties; VkMemoryPropertyFlags required_flags; unsigned int i;
@@ -517,10 +519,10 @@ HRESULT vkd3d_create_buffer(struct d3d12_device *device, if ((vr = VK_CALL(vkCreateBuffer(device->vk_device, &buffer_info, NULL, vk_buffer))) < 0) { WARN("Failed to create Vulkan buffer, vr %d.\n", vr); - return hresult_from_vk_result(vr); + *vk_buffer = VK_NULL_HANDLE; }
- return S_OK; + return hresult_from_vk_result(vr); }
static unsigned int max_miplevel_count(const D3D12_RESOURCE_DESC *desc) @@ -670,10 +672,9 @@ HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_bu WARN("Failed to bind memory, vr %d.\n", vr); VK_CALL(vkFreeMemory(device->vk_device, *vk_memory, NULL)); *vk_memory = VK_NULL_HANDLE; - return hresult_from_vk_result(vr); }
- return S_OK; + return hresult_from_vk_result(vr); }
static HRESULT vkd3d_allocate_image_memory(struct d3d12_device *device, VkImage vk_image, @@ -1753,17 +1754,21 @@ void d3d12_desc_create_cbv(struct d3d12_desc *descriptor, return; }
- if (!desc->BufferLocation) + buffer_info = &descriptor->u.vk_cbv_info; + if (desc->BufferLocation) { - FIXME("NULL CBV not implemented.\n"); - return; + resource = vkd3d_gpu_va_allocator_dereference(&device->gpu_va_allocator, desc->BufferLocation); + buffer_info->buffer = resource->u.vk_buffer; + buffer_info->offset = desc->BufferLocation - resource->gpu_address; + buffer_info->range = min(desc->SizeInBytes, resource->desc.Width - buffer_info->offset); + } + else + { + /* NULL descriptor */ + buffer_info->buffer = device->null_resources.vk_uniform_buffer; + buffer_info->offset = 0; + buffer_info->range = VKD3D_NULL_CBV_BUFFER_SIZE; } - - resource = vkd3d_gpu_va_allocator_dereference(&device->gpu_va_allocator, desc->BufferLocation); - buffer_info = &descriptor->u.vk_cbv_info; - buffer_info->buffer = resource->u.vk_buffer; - buffer_info->offset = desc->BufferLocation - resource->gpu_address; - buffer_info->range = min(desc->SizeInBytes, resource->desc.Width - buffer_info->offset);
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_CBV; descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; @@ -2874,3 +2879,53 @@ HRESULT d3d12_query_heap_create(struct d3d12_device *device, const D3D12_QUERY_H
return S_OK; } + +HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources, + struct d3d12_device *device) +{ + D3D12_HEAP_PROPERTIES heap_properties; + D3D12_RESOURCE_DESC buffer_desc; + HRESULT hr; + + memset(null_resources, 0, sizeof(*null_resources)); + + memset(&heap_properties, 0, sizeof(heap_properties)); + heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; + + buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + buffer_desc.Alignment = 0; + buffer_desc.Width = VKD3D_NULL_CBV_BUFFER_SIZE; + buffer_desc.Height = 1; + buffer_desc.DepthOrArraySize = 1; + buffer_desc.MipLevels = 1; + buffer_desc.Format = DXGI_FORMAT_UNKNOWN; + buffer_desc.SampleDesc.Count = 1; + buffer_desc.SampleDesc.Quality = 0; + buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + buffer_desc.Flags = D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; + + if (FAILED(hr = vkd3d_create_buffer(device, &heap_properties, D3D12_HEAP_FLAG_NONE, + &buffer_desc, &null_resources->vk_uniform_buffer))) + goto fail; + + if (FAILED(hr = vkd3d_allocate_buffer_memory(device, null_resources->vk_uniform_buffer, + &heap_properties, D3D12_HEAP_FLAG_NONE, &null_resources->vk_uniform_buffer_memory))) + goto fail; + + return S_OK; + +fail: + ERR("Failed to initialize NULL resources, hr %#x.\n", hr); + vkd3d_destroy_null_resources(null_resources, device); + return hr; +} + +void vkd3d_destroy_null_resources(struct vkd3d_null_resources *null_resources, + struct d3d12_device *device) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + + VK_CALL(vkDestroyBuffer(device->vk_device, null_resources->vk_uniform_buffer, NULL)); + VK_CALL(vkFreeMemory(device->vk_device, null_resources->vk_uniform_buffer_memory, NULL)); + memset(null_resources, 0, sizeof(*null_resources)); +} diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 9b2fbaf..9ddc50e 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -868,6 +868,18 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_ struct d3d12_command_signature **signature) DECLSPEC_HIDDEN; struct d3d12_command_signature *unsafe_impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface) DECLSPEC_HIDDEN;
+/* NULL resources */ +struct vkd3d_null_resources +{ + VkBuffer vk_uniform_buffer; + VkDeviceMemory vk_uniform_buffer_memory; +}; + +HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources, + struct d3d12_device *device) DECLSPEC_HIDDEN; +void vkd3d_destroy_null_resources(struct vkd3d_null_resources *null_resources, + struct d3d12_device *device) DECLSPEC_HIDDEN; + /* ID3D12Device */ struct d3d12_device { @@ -910,6 +922,8 @@ struct d3d12_device struct vkd3d_private_store private_store;
HRESULT removed_reason; + + struct vkd3d_null_resources null_resources; };
HRESULT d3d12_device_create(struct vkd3d_instance *instance,