[PATCH vkd3d 1/8] vkd3d: Emulate NULL CBV descriptors.

Józef Kucia joseph.kucia at gmail.com
Mon Mar 4 06:15:14 CST 2019


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 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 3d9b8c9aae8d..c1de98f4a2ba 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 1176538f5c54..06e7c7dcb52c 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 9b2fbaf4abe0..9ddc50e9a25f 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,
-- 
2.19.2




More information about the wine-devel mailing list