vkd3d: Implement D3D12_HEAP_TYPE_WRITE_WATCH
Needed for D3D12 APITrace. Closes: #373 Signed-off-by: Joshua Ashton <joshua@froggi.es>
This commit is contained in:
parent
bb4c75cdcc
commit
b6d1487ad5
|
@ -462,6 +462,70 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(d3d12_heap_iface *iface)
|
|||
|
||||
static ULONG d3d12_resource_decref(struct d3d12_resource *resource);
|
||||
|
||||
static void *d3d12_allocate_write_watch_pointer(const D3D12_HEAP_PROPERTIES* properties, VkDeviceSize size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD protect;
|
||||
void *ptr;
|
||||
|
||||
switch (properties->Type)
|
||||
{
|
||||
case D3D12_HEAP_TYPE_DEFAULT:
|
||||
return NULL;
|
||||
case D3D12_HEAP_TYPE_UPLOAD:
|
||||
protect = PAGE_READWRITE | PAGE_WRITECOMBINE;
|
||||
break;
|
||||
case D3D12_HEAP_TYPE_READBACK:
|
||||
/* WRITE_WATCH fails for this type in native D3D12;
|
||||
* otherwise it would be PAGE_READWRITE.
|
||||
*/
|
||||
return NULL;
|
||||
case D3D12_HEAP_TYPE_CUSTOM:
|
||||
switch (properties->CPUPageProperty)
|
||||
{
|
||||
case D3D12_CPU_PAGE_PROPERTY_UNKNOWN:
|
||||
return NULL;
|
||||
case D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE:
|
||||
return NULL;
|
||||
case D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE:
|
||||
protect = PAGE_READWRITE | PAGE_WRITECOMBINE;
|
||||
break;
|
||||
case D3D12_CPU_PAGE_PROPERTY_WRITE_BACK:
|
||||
protect = PAGE_READWRITE;
|
||||
break;
|
||||
default:
|
||||
ERR("Invalid CPU page property %#x.\n", properties->CPUPageProperty);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ERR("Invalid heap type %#x.\n", properties->Type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_WRITE_WATCH, protect)))
|
||||
{
|
||||
ERR("Failed to allocate write watch pointer %#x.\n", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
#else
|
||||
ERR("WRITE_WATCH not supported on this platform.\n");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void d3d12_free_write_watch_pointer(const D3D12_HEAP_DESC* desc, void *pointer)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (VirtualFree(pointer, 0, MEM_RELEASE) == 0)
|
||||
ERR("Failed to free write watch pointer %#x.\n", GetLastError());
|
||||
#else
|
||||
/* Not supported on other platforms. */
|
||||
#endif
|
||||
}
|
||||
|
||||
static void d3d12_heap_cleanup(struct d3d12_heap *heap)
|
||||
{
|
||||
struct d3d12_device *device = heap->device;
|
||||
|
@ -472,6 +536,9 @@ static void d3d12_heap_cleanup(struct d3d12_heap *heap)
|
|||
|
||||
VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
|
||||
|
||||
if (heap->write_watch_ptr)
|
||||
d3d12_free_write_watch_pointer(&heap->desc, heap->write_watch_ptr);
|
||||
|
||||
if (heap->is_private)
|
||||
device = NULL;
|
||||
|
||||
|
@ -723,13 +790,13 @@ static HRESULT d3d12_heap_allocate_storage(struct d3d12_heap *heap,
|
|||
{
|
||||
if (d3d12_resource_is_buffer(resource))
|
||||
{
|
||||
hr = vkd3d_allocate_buffer_memory(device, resource->vk_buffer, NULL,
|
||||
hr = vkd3d_allocate_buffer_memory(device, resource->vk_buffer, host_memory,
|
||||
&heap->desc.Properties, heap->desc.Flags | D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS,
|
||||
&heap->vk_memory, &heap->vk_memory_type, &vk_memory_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = vkd3d_allocate_image_memory(device, resource->vk_image,
|
||||
hr = vkd3d_allocate_image_memory(device, resource->vk_image, host_memory,
|
||||
&heap->desc.Properties, heap->desc.Flags,
|
||||
&heap->vk_memory, &heap->vk_memory_type, &vk_memory_size);
|
||||
}
|
||||
|
@ -788,6 +855,7 @@ static HRESULT d3d12_heap_allocate_storage(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)
|
||||
{
|
||||
const struct vkd3d_vk_device_procs* vk_procs = &device->vk_procs;
|
||||
bool buffers_allowed;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -839,7 +907,52 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
|
|||
return hr;
|
||||
}
|
||||
|
||||
if (FAILED(hr = d3d12_heap_allocate_storage(heap, device, resource, NULL)))
|
||||
if (heap->desc.Flags & D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH)
|
||||
{
|
||||
VkDeviceSize size = heap->desc.SizeInBytes;
|
||||
|
||||
if (resource)
|
||||
{
|
||||
VkMemoryRequirements2 memory_requirements2;
|
||||
if (d3d12_resource_is_buffer(resource))
|
||||
{
|
||||
VkBufferMemoryRequirementsInfo2 info;
|
||||
|
||||
memory_requirements2.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
memory_requirements2.pNext = NULL;
|
||||
|
||||
info.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
||||
info.pNext = NULL;
|
||||
info.buffer = resource->vk_buffer;
|
||||
|
||||
VK_CALL(vkGetBufferMemoryRequirements2(device->vk_device, &info, &memory_requirements2));
|
||||
}
|
||||
else
|
||||
{
|
||||
VkImageMemoryRequirementsInfo2 info;
|
||||
|
||||
assert(d3d12_resource_is_texture(resource));
|
||||
|
||||
memory_requirements2.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
memory_requirements2.pNext = NULL;
|
||||
|
||||
info.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
|
||||
info.pNext = NULL;
|
||||
info.image = resource->vk_image;
|
||||
|
||||
VK_CALL(vkGetImageMemoryRequirements2(device->vk_device, &info, &memory_requirements2));
|
||||
}
|
||||
|
||||
size = memory_requirements2.memoryRequirements.size;
|
||||
}
|
||||
|
||||
if (device->vk_info.EXT_external_memory_host)
|
||||
heap->write_watch_ptr = d3d12_allocate_write_watch_pointer(&heap->desc.Properties, size);
|
||||
else
|
||||
WARN("VK_EXT_external_memory_host is not supported. This may break replay in tracing tools.\n");
|
||||
}
|
||||
|
||||
if (FAILED(hr = d3d12_heap_allocate_storage(heap, device, resource, heap->write_watch_ptr)))
|
||||
{
|
||||
d3d12_heap_cleanup(heap);
|
||||
return hr;
|
||||
|
|
|
@ -415,6 +415,7 @@ struct d3d12_heap
|
|||
|
||||
VkDeviceMemory vk_memory;
|
||||
void *map_ptr;
|
||||
void *write_watch_ptr;
|
||||
uint32_t vk_memory_type;
|
||||
|
||||
struct d3d12_resource *buffer_resource;
|
||||
|
|
Loading…
Reference in New Issue