[PATCH vkd3d 4/5] vkd3d: Create private heap objects for committed resources.
Józef Kucia
joseph.kucia at gmail.com
Thu Jun 20 14:08:08 CDT 2019
From: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Józef Kucia <jkucia at 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;
--
2.21.0
More information about the wine-devel
mailing list