From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/device.c | 2 +- libs/vkd3d/resource.c | 201 +++++++++++++++++++------------------ libs/vkd3d/vkd3d_private.h | 12 +-- 3 files changed, 113 insertions(+), 102 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 7522c413278a..f67713594ea5 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2758,7 +2758,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device *iface, TRACE("iface %p, desc %p, iid %s, heap %p.\n", iface, desc, debugstr_guid(iid), heap);
- if (FAILED(hr = d3d12_heap_create(device, desc, &object))) + if (FAILED(hr = d3d12_heap_create(device, desc, NULL, &object))) { *heap = NULL; return hr; diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index f1cbff11d1ea..0e13cc53e018 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -21,8 +21,6 @@ #define VKD3D_NULL_BUFFER_SIZE 16 #define VKD3D_NULL_VIEW_FORMAT DXGI_FORMAT_R8G8B8A8_UNORM
-#define VKD3D_HEAP_TYPE_INVALID ((D3D12_HEAP_TYPE)~0u) - static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *properties) { if (properties->Type == D3D12_HEAP_TYPE_DEFAULT) @@ -288,31 +286,42 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
TRACE("%p increasing refcount to %u.\n", heap, refcount);
+ assert(!heap->is_private); + return refcount; }
-static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) +static void d3d12_heap_destroy(struct d3d12_heap *heap) { - struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); - ULONG refcount = InterlockedDecrement(&heap->refcount); + struct d3d12_device *device = heap->device; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
- TRACE("%p decreasing refcount to %u.\n", heap, refcount); + TRACE("Destroying heap %p.\n", heap);
- if (!refcount) - { - struct d3d12_device *device = heap->device; - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + vkd3d_private_store_destroy(&heap->private_store);
- vkd3d_private_store_destroy(&heap->private_store); + VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
- VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL)); + pthread_mutex_destroy(&heap->mutex);
- pthread_mutex_destroy(&heap->mutex); + if (heap->is_private) + device = NULL;
- vkd3d_free(heap); + vkd3d_free(heap);
+ if (device) d3d12_device_release(device); - } +} + +static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) +{ + struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); + ULONG refcount = InterlockedDecrement(&heap->refcount); + + TRACE("%p decreasing refcount to %u.\n", heap, refcount); + + if (!refcount) + d3d12_heap_destroy(heap);
return refcount; } @@ -437,6 +446,10 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, void **d *data = (BYTE *)heap->map_ptr + offset; ++heap->map_count; } + else + { + *data = NULL; + }
pthread_mutex_unlock(&heap->mutex);
@@ -475,9 +488,9 @@ static void d3d12_heap_unmap(struct d3d12_heap *heap) pthread_mutex_unlock(&heap->mutex); }
-static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc) +static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource) { - if (!desc->SizeInBytes) + if (!resource && !desc->SizeInBytes) { WARN("Invalid size %"PRIu64".\n", desc->SizeInBytes); return E_INVALIDARG; @@ -490,7 +503,7 @@ static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc) return E_INVALIDARG; }
- if (desc->Flags & D3D12_HEAP_FLAG_ALLOW_DISPLAY) + if (!resource && desc->Flags & D3D12_HEAP_FLAG_ALLOW_DISPLAY) { WARN("D3D12_HEAP_FLAG_ALLOW_DISPLAY is only for committed resources.\n"); return E_INVALIDARG; @@ -500,15 +513,18 @@ static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc) }
static HRESULT d3d12_heap_init(struct d3d12_heap *heap, - struct d3d12_device *device, const D3D12_HEAP_DESC *desc) + struct d3d12_device *device, const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource) { VkMemoryRequirements memory_requirements; + VkDeviceSize vk_memory_size; HRESULT hr; int rc;
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl; heap->refcount = 1;
+ heap->is_private = !!resource; + heap->desc = *desc;
heap->map_ptr = NULL; @@ -525,13 +541,9 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, if (!heap->desc.Alignment) heap->desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
- if (FAILED(hr = validate_heap_desc(&heap->desc))) + if (FAILED(hr = validate_heap_desc(&heap->desc, resource))) return hr;
- memory_requirements.size = heap->desc.SizeInBytes; - memory_requirements.alignment = heap->desc.Alignment; - memory_requirements.memoryTypeBits = ~(uint32_t)0; - if ((rc = pthread_mutex_init(&heap->mutex, NULL))) { ERR("Failed to initialize mutex, error %d.\n", rc); @@ -544,21 +556,49 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, return hr; }
- if (FAILED(hr = vkd3d_allocate_device_memory(device, &heap->desc.Properties, - heap->desc.Flags, &memory_requirements, NULL, &heap->vk_memory, &heap->vk_memory_type))) + if (resource) + { + if (d3d12_resource_is_buffer(resource)) + { + hr = vkd3d_allocate_buffer_memory(device, resource->u.vk_buffer, + &heap->desc.Properties, heap->desc.Flags, + &heap->vk_memory, &heap->vk_memory_type, &vk_memory_size); + } + else + { + hr = vkd3d_allocate_image_memory(device, resource->u.vk_image, + &heap->desc.Properties, heap->desc.Flags, + &heap->vk_memory, &heap->vk_memory_type, &vk_memory_size); + } + + heap->desc.SizeInBytes = vk_memory_size; + } + else + { + memory_requirements.size = heap->desc.SizeInBytes; + memory_requirements.alignment = heap->desc.Alignment; + memory_requirements.memoryTypeBits = ~(uint32_t)0; + + hr = vkd3d_allocate_device_memory(device, &heap->desc.Properties, + heap->desc.Flags, &memory_requirements, NULL, + &heap->vk_memory, &heap->vk_memory_type); + } + if (FAILED(hr)) { vkd3d_private_store_destroy(&heap->private_store); pthread_mutex_destroy(&heap->mutex); return hr; }
- d3d12_device_add_ref(heap->device = device); + heap->device = device; + if (!heap->is_private) + d3d12_device_add_ref(heap->device);
return S_OK; }
-HRESULT d3d12_heap_create(struct d3d12_device *device, - const D3D12_HEAP_DESC *desc, struct d3d12_heap **heap) +HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc, + const struct d3d12_resource *resource, struct d3d12_heap **heap) { struct d3d12_heap *object; HRESULT hr; @@ -566,13 +606,13 @@ HRESULT d3d12_heap_create(struct d3d12_device *device, if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY;
- if (FAILED(hr = d3d12_heap_init(object, device, desc))) + if (FAILED(hr = d3d12_heap_init(object, device, desc, resource))) { vkd3d_free(object); return hr; }
- TRACE("Created heap %p.\n", object); + TRACE("Created %s %p.\n", object->is_private ? "private heap" : "heap", object);
*heap = object;
@@ -883,8 +923,8 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 else VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL));
- if (resource->vk_memory) - VK_CALL(vkFreeMemory(device->vk_device, resource->vk_memory, NULL)); + if (resource->flags & VKD3D_RESOURCE_DEDICATED_HEAP) + d3d12_heap_destroy(resource->heap); }
static ULONG d3d12_resource_incref(struct d3d12_resource *resource) @@ -914,7 +954,7 @@ static ULONG d3d12_resource_decref(struct d3d12_resource *resource)
bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource) { - return is_cpu_accessible_heap(&resource->heap_properties); + return resource->heap && is_cpu_accessible_heap(&resource->heap->desc.Properties); }
/* ID3D12Resource */ @@ -1019,10 +1059,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_SetName(ID3D12Resource *iface, c
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, resource->device->wchar_size));
- if (resource->vk_memory) + if (resource->flags & VKD3D_RESOURCE_DEDICATED_HEAP) { - if (FAILED(hr = vkd3d_set_vk_object_name(resource->device, (uint64_t)resource->vk_memory, - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, name))) + if (FAILED(hr = d3d12_heap_SetName(&resource->heap->ID3D12Heap_iface, name))) return hr; }
@@ -1048,15 +1087,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT { struct d3d12_resource *resource = impl_from_ID3D12Resource(iface); unsigned int sub_resource_count; - struct d3d12_device *device; HRESULT hr = S_OK; - VkResult vr;
TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n", iface, sub_resource, read_range, data);
- device = resource->device; - if (!d3d12_resource_is_cpu_accessible(resource)) { WARN("Resource is not CPU accessible.\n"); @@ -1077,7 +1112,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT return E_INVALIDARG; }
- if (!resource->heap && !resource->vk_memory) + if (!resource->heap) { FIXME("Not implemented for this resource type.\n"); return E_NOTIMPL; @@ -1087,22 +1122,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
if (!resource->map_count) { - if (resource->heap) - { - hr = d3d12_heap_map(resource->heap, resource->heap_offset, &resource->map_ptr); - } - else - { - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - - if ((vr = VK_CALL(vkMapMemory(device->vk_device, resource->vk_memory, - 0, VK_WHOLE_SIZE, 0, &resource->map_ptr))) < 0) - WARN("Failed to map device memory, vr %d.\n", vr); - - hr = hresult_from_vk_result(vr); - } - - if (FAILED(hr)) + if FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, &resource->map_ptr)) { WARN("Failed to map resource, hr %#x.\n", hr); resource->map_ptr = NULL; @@ -1123,7 +1143,6 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s { struct d3d12_resource *resource = impl_from_ID3D12Resource(iface); unsigned int sub_resource_count; - struct d3d12_device *device;
TRACE("iface %p, sub_resource %u, written_range %p.\n", iface, sub_resource, written_range); @@ -1141,21 +1160,15 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s return; }
- device = resource->device; - WARN("Ignoring written range %p.\n", written_range);
--resource->map_count; if (!resource->map_count) { - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - resource->map_ptr = NULL;
- if (resource->heap) - d3d12_heap_unmap(resource->heap); - else - VK_CALL(vkUnmapMemory(device->vk_device, resource->vk_memory)); + assert(resource->heap); + d3d12_heap_unmap(resource->heap); } }
@@ -1207,20 +1220,33 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS *flags) { struct d3d12_resource *resource = impl_from_ID3D12Resource(iface); + struct d3d12_heap *heap;
TRACE("iface %p, heap_properties %p, flags %p.\n", iface, heap_properties, flags);
- if (resource->heap_properties.Type == VKD3D_HEAP_TYPE_INVALID) + if (resource->flags & VKD3D_RESOURCE_EXTERNAL) + { + if (heap_properties) + { + memset(heap_properties, 0, sizeof(*heap_properties)); + heap_properties->Type = D3D12_HEAP_TYPE_DEFAULT; + } + if (flags) + *flags = D3D12_HEAP_FLAG_NONE; + return S_OK; + } + + if (!(heap = resource->heap)) { WARN("Cannot get heap properties for reserved resources.\n"); return E_INVALIDARG; }
if (heap_properties) - *heap_properties = resource->heap_properties; + *heap_properties = heap->desc.Properties; if (flags) - *flags = resource->heap_flags; + *flags = heap->desc.Flags;
return S_OK; } @@ -1382,7 +1408,6 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12 WARN("Ignoring optimized clear value.\n");
resource->gpu_address = 0; - resource->vk_memory = VK_NULL_HANDLE; resource->flags = 0;
if (FAILED(hr = d3d12_resource_validate_desc(&resource->desc))) @@ -1422,18 +1447,6 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12 resource->map_count = 0; resource->map_ptr = NULL;
- if (heap_properties) - { - resource->heap_properties = *heap_properties; - resource->heap_flags = heap_flags; - } - else - { - memset(&resource->heap_properties, 0, sizeof(resource->heap_properties)); - resource->heap_properties.Type = VKD3D_HEAP_TYPE_INVALID; - resource->heap_flags = 0; - } - resource->initial_state = initial_state;
resource->heap = NULL; @@ -1477,16 +1490,16 @@ static HRESULT vkd3d_allocate_resource_memory( struct d3d12_device *device, struct d3d12_resource *resource, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags) { - if (d3d12_resource_is_buffer(resource)) - { - return vkd3d_allocate_buffer_memory(device, resource->u.vk_buffer, - heap_properties, heap_flags, &resource->vk_memory, NULL, NULL); - } - else - { - return vkd3d_allocate_image_memory(device, resource->u.vk_image, - heap_properties, heap_flags, &resource->vk_memory, NULL, NULL); - } + D3D12_HEAP_DESC heap_desc; + HRESULT hr; + + heap_desc.SizeInBytes = 0; + heap_desc.Properties = *heap_properties; + heap_desc.Alignment = 0; + heap_desc.Flags = heap_flags; + if (SUCCEEDED(hr = d3d12_heap_create(device, &heap_desc, resource, &resource->heap))) + resource->flags |= VKD3D_RESOURCE_DEDICATED_HEAP; + return hr; }
HRESULT d3d12_committed_resource_create(struct d3d12_device *device, @@ -1642,8 +1655,6 @@ HRESULT vkd3d_create_image_resource(ID3D12Device *device, object->u.vk_image = create_info->vk_image; object->flags = VKD3D_RESOURCE_EXTERNAL; object->flags |= create_info->flags & VKD3D_RESOURCE_PUBLIC_FLAGS; - memset(&object->heap_properties, 0, sizeof(object->heap_properties)); - object->heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; object->initial_state = D3D12_RESOURCE_STATE_COMMON; if (create_info->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION) object->present_state = create_info->present_state; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index caaaa2427af7..34df976fe647 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -54,6 +54,7 @@
struct d3d12_command_list; struct d3d12_device; +struct d3d12_resource;
struct vkd3d_vk_global_procs { @@ -348,6 +349,7 @@ struct d3d12_heap ID3D12Heap ID3D12Heap_iface; LONG refcount;
+ bool is_private; D3D12_HEAP_DESC desc;
pthread_mutex_t mutex; @@ -362,13 +364,14 @@ struct d3d12_heap struct vkd3d_private_store private_store; };
-HRESULT d3d12_heap_create(struct d3d12_device *device, - const D3D12_HEAP_DESC *desc, struct d3d12_heap **heap) DECLSPEC_HIDDEN; +HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc, + const struct d3d12_resource *resource, struct d3d12_heap **heap) DECLSPEC_HIDDEN; struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface) DECLSPEC_HIDDEN;
#define VKD3D_RESOURCE_PUBLIC_FLAGS \ (VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION) -#define VKD3D_RESOURCE_EXTERNAL 0x00000004 +#define VKD3D_RESOURCE_EXTERNAL 0x00000004 +#define VKD3D_RESOURCE_DEDICATED_HEAP 0x00000008
/* ID3D12Resource */ struct d3d12_resource @@ -385,7 +388,6 @@ struct d3d12_resource VkBuffer vk_buffer; VkImage vk_image; } u; - VkDeviceMemory vk_memory; unsigned int flags;
unsigned int map_count; @@ -394,8 +396,6 @@ struct d3d12_resource struct d3d12_heap *heap; uint64_t heap_offset;
- D3D12_HEAP_PROPERTIES heap_properties; - D3D12_HEAP_FLAGS heap_flags; D3D12_RESOURCE_STATES initial_state; D3D12_RESOURCE_STATES present_state;