=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d: Implement Map() for placed resources.
Alexandre Julliard
julliard at winehq.org
Mon Nov 12 16:26:09 CST 2018
Module: vkd3d
Branch: master
Commit: 4ff26ef3c4e8ce5794ad5ac88968a3ec9d38d9dc
URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=4ff26ef3c4e8ce5794ad5ac88968a3ec9d38d9dc
Author: Józef Kucia <jkucia at codeweavers.com>
Date: Fri Nov 9 18:06:20 2018 +0100
vkd3d: Implement Map() for placed resources.
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
libs/vkd3d/resource.c | 142 +++++++++++++++++++++++++++++++++++++++------
libs/vkd3d/vkd3d_private.h | 7 +++
2 files changed, 131 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index f857de2..21096e5 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -146,6 +146,8 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
+ pthread_mutex_destroy(&heap->mutex);
+
vkd3d_free(heap);
ID3D12Device_Release(&device->ID3D12Device_iface);
@@ -233,6 +235,76 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface)
return impl_from_ID3D12Heap(iface);
}
+static HRESULT d3d12_heap_map(struct d3d12_heap *heap, UINT64 offset, void **data)
+{
+ struct d3d12_device *device = heap->device;
+ VkResult vr;
+ int rc;
+
+ if ((rc = pthread_mutex_lock(&heap->mutex)))
+ {
+ ERR("Failed to lock mutex, error %d.\n", rc);
+ *data = NULL;
+ return E_FAIL;
+ }
+
+ if (!heap->map_ptr)
+ {
+ const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+
+ TRACE("Mapping heap %p.\n", heap);
+
+ if ((vr = VK_CALL(vkMapMemory(device->vk_device, heap->vk_memory,
+ 0, VK_WHOLE_SIZE, 0, &heap->map_ptr))) < 0)
+ {
+ WARN("Failed to map device memory, vr %d.\n", vr);
+ heap->map_ptr = NULL;
+ *data = NULL;
+ pthread_mutex_unlock(&heap->mutex);
+ return hresult_from_vk_result(vr);
+ }
+ }
+
+ *data = (BYTE *)heap->map_ptr + offset;
+ ++heap->map_count;
+
+ pthread_mutex_unlock(&heap->mutex);
+
+ return S_OK;
+}
+
+static void d3d12_heap_unmap(struct d3d12_heap *heap)
+{
+ struct d3d12_device *device = heap->device;
+ int rc;
+
+ if ((rc = pthread_mutex_lock(&heap->mutex)))
+ {
+ ERR("Failed to lock mutex, error %d.\n", rc);
+ return;
+ }
+
+ if (heap->map_count)
+ {
+ --heap->map_count;
+ if (!heap->map_count)
+ {
+ const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+
+ TRACE("Unmapping heap %p.\n", heap);
+
+ VK_CALL(vkUnmapMemory(device->vk_device, heap->vk_memory));
+ heap->map_ptr = NULL;
+ }
+ }
+ else
+ {
+ WARN("Heap %p is not mapped.\n", heap);
+ }
+
+ pthread_mutex_unlock(&heap->mutex);
+}
+
static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc)
{
if (!desc->SizeInBytes)
@@ -262,12 +334,16 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
{
VkMemoryRequirements memory_requirements;
HRESULT hr;
+ int rc;
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
heap->refcount = 1;
heap->desc = *desc;
+ heap->map_ptr = NULL;
+ heap->map_count = 0;
+
if (!heap->desc.Properties.CreationNodeMask)
heap->desc.Properties.CreationNodeMask = 1;
if (!heap->desc.Properties.VisibleNodeMask)
@@ -286,9 +362,18 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
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);
+ return E_FAIL;
+ }
+
if (FAILED(hr = vkd3d_allocate_device_memory(device, &heap->desc.Properties,
heap->desc.Flags, &memory_requirements, &heap->vk_memory, &heap->vk_memory_type)))
+ {
+ pthread_mutex_destroy(&heap->mutex);
return hr;
+ }
heap->device = device;
ID3D12Device_AddRef(&device->ID3D12Device_iface);
@@ -726,15 +811,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
const D3D12_RANGE *read_range, void **data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
- const struct vkd3d_vk_device_procs *vk_procs;
struct d3d12_device *device;
VkResult vr;
+ HRESULT hr;
TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n",
iface, sub_resource, read_range, data);
device = resource->device;
- vk_procs = &device->vk_procs;
if (!is_cpu_accessible_heap(&resource->heap_properties))
{
@@ -749,7 +833,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
return E_INVALIDARG;
}
- if (!resource->vk_memory)
+ if (!resource->heap && !resource->vk_memory)
{
FIXME("Not implemented for this resource type.\n");
return E_NOTIMPL;
@@ -759,11 +843,27 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
if (!resource->map_count)
{
- if ((vr = VK_CALL(vkMapMemory(device->vk_device, resource->vk_memory,
- 0, VK_WHOLE_SIZE, 0, &resource->map_data))) < 0)
+ if (resource->heap)
{
- WARN("Failed to map device memory, vr %d.\n", vr);
- return hresult_from_vk_result(vr);
+ hr = d3d12_heap_map(resource->heap, resource->heap_offset, &resource->map_data);
+ }
+ 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_data))) < 0)
+ WARN("Failed to map device memory, vr %d.\n", vr);
+
+ hr = hresult_from_vk_result(vr);
+ }
+
+ if (FAILED(hr))
+ {
+ WARN("Failed to map resource, hr %#x.\n", hr);
+ resource->map_data = NULL;
+ *data = NULL;
+ return hr;
}
}
@@ -777,32 +877,32 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s
const D3D12_RANGE *written_range)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
- const struct vkd3d_vk_device_procs *vk_procs;
struct d3d12_device *device;
TRACE("iface %p, sub_resource %u, written_range %p.\n",
iface, sub_resource, written_range);
- device = resource->device;
- vk_procs = &device->vk_procs;
-
- if (d3d12_resource_is_texture(resource))
- {
- FIXME("Not implemented for textures.\n");
- return;
- }
-
if (!resource->map_count)
{
WARN("Resource %p is not mapped.\n", resource);
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_data = NULL;
- VK_CALL(vkUnmapMemory(device->vk_device, resource->vk_memory));
+
+ if (resource->heap)
+ d3d12_heap_unmap(resource->heap);
+ else
+ VK_CALL(vkUnmapMemory(device->vk_device, resource->vk_memory));
}
}
@@ -1093,6 +1193,9 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
return hr;
}
+ object->heap = NULL;
+ object->heap_offset = 0;
+
TRACE("Created committed resource %p.\n", object);
*resource = object;
@@ -1155,6 +1258,9 @@ HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_h
return hr;
}
+ object->heap = heap;
+ object->heap_offset = heap_offset;
+
TRACE("Created placed resource %p.\n", object);
*resource = object;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index a2bf404..982ed68 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -194,7 +194,11 @@ struct d3d12_heap
D3D12_HEAP_DESC desc;
+ pthread_mutex_t mutex;
+
VkDeviceMemory vk_memory;
+ void *map_ptr;
+ unsigned int map_count;
uint32_t vk_memory_type;
struct d3d12_device *device;
@@ -229,6 +233,9 @@ struct d3d12_resource
unsigned int map_count;
void *map_data;
+ struct d3d12_heap *heap;
+ UINT64 heap_offset;
+
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_HEAP_FLAGS heap_flags;
D3D12_RESOURCE_STATES initial_state;
More information about the wine-cvs
mailing list