mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d: Persistently map host-visible heaps on creation.
This commit is contained in:
parent
616c4bf51f
commit
c8a33431e3
Notes:
Alexandre Julliard
2023-04-10 22:24:56 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/131
@ -326,6 +326,9 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
|
|||||||
|
|
||||||
vkd3d_private_store_destroy(&heap->private_store);
|
vkd3d_private_store_destroy(&heap->private_store);
|
||||||
|
|
||||||
|
if (heap->map_ptr)
|
||||||
|
VK_CALL(vkUnmapMemory(device->vk_device, heap->vk_memory));
|
||||||
|
|
||||||
VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
|
VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
|
||||||
|
|
||||||
vkd3d_mutex_destroy(&heap->mutex);
|
vkd3d_mutex_destroy(&heap->mutex);
|
||||||
@ -444,97 +447,6 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface)
|
|||||||
return impl_from_ID3D12Heap(iface);
|
return impl_from_ID3D12Heap(iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset,
|
|
||||||
struct d3d12_resource *resource, void **data)
|
|
||||||
{
|
|
||||||
struct d3d12_device *device = heap->device;
|
|
||||||
HRESULT hr = S_OK;
|
|
||||||
VkResult vr;
|
|
||||||
|
|
||||||
vkd3d_mutex_lock(&heap->mutex);
|
|
||||||
|
|
||||||
assert(!resource->map_count || heap->map_ptr);
|
|
||||||
|
|
||||||
if (!resource->map_count)
|
|
||||||
{
|
|
||||||
if (!heap->map_ptr)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
|
|
||||||
TRACE("Mapping heap %p.\n", heap);
|
|
||||||
|
|
||||||
assert(!heap->map_count);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = hresult_from_vk_result(vr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heap->map_ptr)
|
|
||||||
++heap->map_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hr == S_OK)
|
|
||||||
{
|
|
||||||
assert(heap->map_ptr);
|
|
||||||
if (data)
|
|
||||||
*data = (BYTE *)heap->map_ptr + offset;
|
|
||||||
++resource->map_count;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(!heap->map_ptr);
|
|
||||||
if (data)
|
|
||||||
*data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vkd3d_mutex_unlock(&heap->mutex);
|
|
||||||
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *resource)
|
|
||||||
{
|
|
||||||
struct d3d12_device *device = heap->device;
|
|
||||||
|
|
||||||
vkd3d_mutex_lock(&heap->mutex);
|
|
||||||
|
|
||||||
if (!resource->map_count)
|
|
||||||
{
|
|
||||||
WARN("Resource %p is not mapped.\n", resource);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
--resource->map_count;
|
|
||||||
if (resource->map_count)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (!heap->map_count)
|
|
||||||
{
|
|
||||||
ERR("Heap %p is not mapped.\n", heap);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
--heap->map_count;
|
|
||||||
if (!heap->map_count)
|
|
||||||
{
|
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
||||||
|
|
||||||
TRACE("Unmapping heap %p, ptr %p.\n", heap, heap->map_ptr);
|
|
||||||
|
|
||||||
VK_CALL(vkUnmapMemory(device->vk_device, heap->vk_memory));
|
|
||||||
heap->map_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
vkd3d_mutex_unlock(&heap->mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource)
|
static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource)
|
||||||
{
|
{
|
||||||
if (!resource && !desc->SizeInBytes)
|
if (!resource && !desc->SizeInBytes)
|
||||||
@ -559,11 +471,18 @@ static HRESULT validate_heap_desc(const D3D12_HEAP_DESC *desc, const struct d3d1
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkMemoryPropertyFlags d3d12_heap_get_memory_property_flags(const struct d3d12_heap *heap)
|
||||||
|
{
|
||||||
|
return heap->device->memory_properties.memoryTypes[heap->vk_memory_type].propertyFlags;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
|
static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
|
||||||
struct d3d12_device *device, const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource)
|
struct d3d12_device *device, const D3D12_HEAP_DESC *desc, const struct d3d12_resource *resource)
|
||||||
{
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
VkMemoryRequirements memory_requirements;
|
VkMemoryRequirements memory_requirements;
|
||||||
VkDeviceSize vk_memory_size;
|
VkDeviceSize vk_memory_size;
|
||||||
|
VkResult vr;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
|
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
|
||||||
@ -639,6 +558,18 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
|
|||||||
else
|
else
|
||||||
heap->resource_count = 1;
|
heap->resource_count = 1;
|
||||||
|
|
||||||
|
if (d3d12_heap_get_memory_property_flags(heap) & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||||
|
{
|
||||||
|
if ((vr = VK_CALL(vkMapMemory(device->vk_device,
|
||||||
|
heap->vk_memory, 0, VK_WHOLE_SIZE, 0, &heap->map_ptr))) < 0)
|
||||||
|
{
|
||||||
|
heap->map_ptr = NULL;
|
||||||
|
ERR("Failed to map memory, vr %d.\n", vr);
|
||||||
|
d3d12_heap_destroy(heap);
|
||||||
|
return hresult_from_vk_result(hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1233,12 +1164,55 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_GetDevice(ID3D12Resource *iface,
|
|||||||
return d3d12_device_query_interface(resource->device, iid, device);
|
return d3d12_device_query_interface(resource->device, iid, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *d3d12_resource_get_map_ptr(struct d3d12_resource *resource)
|
||||||
|
{
|
||||||
|
assert(resource->heap->map_ptr);
|
||||||
|
return (uint8_t *)resource->heap->map_ptr + resource->heap_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_resource_get_vk_range(struct d3d12_resource *resource,
|
||||||
|
uint64_t offset, uint64_t size, VkMappedMemoryRange *vk_range)
|
||||||
|
{
|
||||||
|
vk_range->sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||||
|
vk_range->pNext = NULL;
|
||||||
|
vk_range->memory = resource->heap->vk_memory;
|
||||||
|
vk_range->offset = resource->heap_offset + offset;
|
||||||
|
vk_range->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_resource_invalidate(struct d3d12_resource *resource, uint64_t offset, uint64_t size)
|
||||||
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &resource->device->vk_procs;
|
||||||
|
VkMappedMemoryRange vk_range;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
if (d3d12_heap_get_memory_property_flags(resource->heap) & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d3d12_resource_get_vk_range(resource, offset, size, &vk_range);
|
||||||
|
if ((vr = VK_CALL(vkInvalidateMappedMemoryRanges(resource->device->vk_device, 1, &vk_range))) < 0)
|
||||||
|
ERR("Failed to invalidate memory, vr %d.\n", vr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void d3d12_resource_flush(struct d3d12_resource *resource, uint64_t offset, uint64_t size)
|
||||||
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &resource->device->vk_procs;
|
||||||
|
VkMappedMemoryRange vk_range;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
if (d3d12_heap_get_memory_property_flags(resource->heap) & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
d3d12_resource_get_vk_range(resource, offset, size, &vk_range);
|
||||||
|
if ((vr = VK_CALL(vkFlushMappedMemoryRanges(resource->device->vk_device, 1, &vk_range))) < 0)
|
||||||
|
ERR("Failed to flush memory, vr %d.\n", vr);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT sub_resource,
|
static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT sub_resource,
|
||||||
const D3D12_RANGE *read_range, void **data)
|
const D3D12_RANGE *read_range, void **data)
|
||||||
{
|
{
|
||||||
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
|
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
|
||||||
unsigned int sub_resource_count;
|
unsigned int sub_resource_count;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n",
|
TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n",
|
||||||
iface, sub_resource, read_range, data);
|
iface, sub_resource, read_range, data);
|
||||||
@ -1269,15 +1243,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
|
|||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN("Ignoring read range %p.\n", read_range);
|
|
||||||
|
|
||||||
if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, data)))
|
|
||||||
WARN("Failed to map resource %p, hr %#x.\n", resource, hr);
|
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
|
{
|
||||||
|
*data = d3d12_resource_get_map_ptr(resource);
|
||||||
TRACE("Returning pointer %p.\n", *data);
|
TRACE("Returning pointer %p.\n", *data);
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
if (!read_range)
|
||||||
|
d3d12_resource_invalidate(resource, 0, resource->desc.Width);
|
||||||
|
else if (read_range->End > read_range->Begin)
|
||||||
|
d3d12_resource_invalidate(resource, read_range->Begin, read_range->End - read_range->Begin);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT sub_resource,
|
static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT sub_resource,
|
||||||
@ -1296,9 +1273,10 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN("Ignoring written range %p.\n", written_range);
|
if (!written_range)
|
||||||
|
d3d12_resource_flush(resource, 0, resource->desc.Width);
|
||||||
d3d12_heap_unmap(resource->heap, resource);
|
else if (written_range->End > written_range->Begin)
|
||||||
|
d3d12_resource_flush(resource, written_range->Begin, written_range->End - written_range->Begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource *iface,
|
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource *iface,
|
||||||
@ -1330,10 +1308,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc
|
|||||||
VkImageSubresource vk_sub_resource;
|
VkImageSubresource vk_sub_resource;
|
||||||
const struct vkd3d_format *format;
|
const struct vkd3d_format *format;
|
||||||
VkSubresourceLayout vk_layout;
|
VkSubresourceLayout vk_layout;
|
||||||
|
uint64_t dst_offset, dst_size;
|
||||||
struct d3d12_device *device;
|
struct d3d12_device *device;
|
||||||
uint8_t *dst_data;
|
uint8_t *dst_data;
|
||||||
D3D12_BOX box;
|
D3D12_BOX box;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("iface %p, src_data %p, src_row_pitch %u, src_slice_pitch %u, "
|
TRACE("iface %p, src_data %p, src_row_pitch %u, src_slice_pitch %u, "
|
||||||
"dst_sub_resource %u, dst_box %s.\n",
|
"dst_sub_resource %u, dst_box %s.\n",
|
||||||
@ -1391,20 +1369,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc
|
|||||||
TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", depth pitch %#"PRIx64".\n",
|
TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", depth pitch %#"PRIx64".\n",
|
||||||
vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.depthPitch);
|
vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.depthPitch);
|
||||||
|
|
||||||
if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, (void **)&dst_data)))
|
dst_data = d3d12_resource_get_map_ptr(resource);
|
||||||
{
|
dst_offset = vk_layout.offset + vkd3d_format_get_data_offset(format, vk_layout.rowPitch,
|
||||||
WARN("Failed to map resource %p, hr %#x.\n", resource, hr);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst_data += vk_layout.offset + vkd3d_format_get_data_offset(format, vk_layout.rowPitch,
|
|
||||||
vk_layout.depthPitch, dst_box->left, dst_box->top, dst_box->front);
|
vk_layout.depthPitch, dst_box->left, dst_box->top, dst_box->front);
|
||||||
|
dst_size = vk_layout.offset + vkd3d_format_get_data_offset(format, vk_layout.rowPitch,
|
||||||
|
vk_layout.depthPitch, dst_box->right, dst_box->bottom - 1, dst_box->back - 1) - dst_offset;
|
||||||
|
|
||||||
vkd3d_format_copy_data(format, src_data, src_row_pitch, src_slice_pitch,
|
vkd3d_format_copy_data(format, src_data, src_row_pitch, src_slice_pitch,
|
||||||
dst_data, vk_layout.rowPitch, vk_layout.depthPitch, dst_box->right - dst_box->left,
|
dst_data + dst_offset, vk_layout.rowPitch, vk_layout.depthPitch, dst_box->right - dst_box->left,
|
||||||
dst_box->bottom - dst_box->top, dst_box->back - dst_box->front);
|
dst_box->bottom - dst_box->top, dst_box->back - dst_box->front);
|
||||||
|
|
||||||
d3d12_heap_unmap(resource->heap, resource);
|
d3d12_resource_flush(resource, dst_offset, dst_size);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@ -1418,10 +1393,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
|
|||||||
VkImageSubresource vk_sub_resource;
|
VkImageSubresource vk_sub_resource;
|
||||||
const struct vkd3d_format *format;
|
const struct vkd3d_format *format;
|
||||||
VkSubresourceLayout vk_layout;
|
VkSubresourceLayout vk_layout;
|
||||||
|
uint64_t src_offset, src_size;
|
||||||
struct d3d12_device *device;
|
struct d3d12_device *device;
|
||||||
uint8_t *src_data;
|
uint8_t *src_data;
|
||||||
D3D12_BOX box;
|
D3D12_BOX box;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
TRACE("iface %p, dst_data %p, dst_row_pitch %u, dst_slice_pitch %u, "
|
TRACE("iface %p, dst_data %p, dst_row_pitch %u, dst_slice_pitch %u, "
|
||||||
"src_sub_resource %u, src_box %s.\n",
|
"src_sub_resource %u, src_box %s.\n",
|
||||||
@ -1479,21 +1454,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
|
|||||||
TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", depth pitch %#"PRIx64".\n",
|
TRACE("Offset %#"PRIx64", size %#"PRIx64", row pitch %#"PRIx64", depth pitch %#"PRIx64".\n",
|
||||||
vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.depthPitch);
|
vk_layout.offset, vk_layout.size, vk_layout.rowPitch, vk_layout.depthPitch);
|
||||||
|
|
||||||
if (FAILED(hr = d3d12_heap_map(resource->heap, resource->heap_offset, resource, (void **)&src_data)))
|
src_data = d3d12_resource_get_map_ptr(resource);
|
||||||
{
|
src_offset = vk_layout.offset + vkd3d_format_get_data_offset(format, vk_layout.rowPitch,
|
||||||
WARN("Failed to map resource %p, hr %#x.\n", resource, hr);
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
src_data += vk_layout.offset + vkd3d_format_get_data_offset(format, vk_layout.rowPitch,
|
|
||||||
vk_layout.depthPitch, src_box->left, src_box->top, src_box->front);
|
vk_layout.depthPitch, src_box->left, src_box->top, src_box->front);
|
||||||
|
src_size = vk_layout.offset + vkd3d_format_get_data_offset(format, vk_layout.rowPitch,
|
||||||
|
vk_layout.depthPitch, src_box->right, src_box->bottom - 1, src_box->back - 1) - src_offset;
|
||||||
|
|
||||||
vkd3d_format_copy_data(format, src_data, vk_layout.rowPitch, vk_layout.depthPitch,
|
d3d12_resource_invalidate(resource, src_offset, src_size);
|
||||||
|
|
||||||
|
vkd3d_format_copy_data(format, src_data + src_offset, vk_layout.rowPitch, vk_layout.depthPitch,
|
||||||
dst_data, dst_row_pitch, dst_slice_pitch, src_box->right - src_box->left,
|
dst_data, dst_row_pitch, dst_slice_pitch, src_box->right - src_box->left,
|
||||||
src_box->bottom - src_box->top, src_box->back - src_box->front);
|
src_box->bottom - src_box->top, src_box->back - src_box->front);
|
||||||
|
|
||||||
d3d12_heap_unmap(resource->heap, resource);
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user