diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index f20781f5..4a994f63 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2571,6 +2571,7 @@ static HRESULT d3d12_device_create_scratch_buffer(struct d3d12_device *device, e alloc_info.heap_desc.SizeInBytes = size; alloc_info.heap_desc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; alloc_info.heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS | D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + alloc_info.extra_allocation_flags = VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH; if (FAILED(hr = vkd3d_allocate_heap_memory(device, &device->memory_allocator, &alloc_info, &scratch->allocation))) @@ -2587,7 +2588,7 @@ static HRESULT d3d12_device_create_scratch_buffer(struct d3d12_device *device, e alloc_info.memory_requirements.alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; alloc_info.heap_flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS | D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; alloc_info.optional_memory_properties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - alloc_info.flags = VKD3D_ALLOCATION_FLAG_GLOBAL_BUFFER; + alloc_info.flags = VKD3D_ALLOCATION_FLAG_GLOBAL_BUFFER | VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH; if (FAILED(hr = vkd3d_allocate_memory(device, &device->memory_allocator, &alloc_info, &scratch->allocation))) diff --git a/libs/vkd3d/heap.c b/libs/vkd3d/heap.c index 6640ebe7..910d8344 100644 --- a/libs/vkd3d/heap.c +++ b/libs/vkd3d/heap.c @@ -240,6 +240,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, struct d3d12_device *dev alloc_info.heap_desc = heap->desc; alloc_info.host_ptr = host_address; + alloc_info.extra_allocation_flags = 0; if (FAILED(hr = vkd3d_private_store_init(&heap->private_store))) return hr; diff --git a/libs/vkd3d/memory.c b/libs/vkd3d/memory.c index 13307cdb..f7ff0829 100644 --- a/libs/vkd3d/memory.c +++ b/libs/vkd3d/memory.c @@ -349,12 +349,15 @@ static HRESULT vkd3d_import_host_memory(struct d3d12_device *device, void *host_ return hr; } -static HRESULT vkd3d_allocation_assign_gpu_address(struct vkd3d_memory_allocation *allocation, struct d3d12_device *device, struct vkd3d_memory_allocator *allocator) +static HRESULT vkd3d_allocation_assign_gpu_address(struct vkd3d_memory_allocation *allocation, + struct d3d12_device *device, struct vkd3d_memory_allocator *allocator) { if (device->device_info.buffer_device_address_features.bufferDeviceAddress) allocation->resource.va = vkd3d_get_buffer_device_address(device, allocation->resource.vk_buffer); - else + else if (!(allocation->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH)) allocation->resource.va = vkd3d_va_map_alloc_fake_va(&allocator->va_map, allocation->resource.size); + else + allocation->resource.va = 0xdeadbeef; if (!allocation->resource.va) { @@ -362,7 +365,9 @@ static HRESULT vkd3d_allocation_assign_gpu_address(struct vkd3d_memory_allocatio return E_OUTOFMEMORY; } - vkd3d_va_map_insert(&allocator->va_map, &allocation->resource); + /* Internal scratch buffers are not visible to application so we never have to map it back to VkBuffer. */ + if (!(allocation->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH)) + vkd3d_va_map_insert(&allocator->va_map, &allocation->resource); return S_OK; } @@ -446,10 +451,12 @@ static void vkd3d_memory_allocation_free(const struct vkd3d_memory_allocation *a if ((allocation->flags & VKD3D_ALLOCATION_FLAG_GPU_ADDRESS) && allocation->resource.va) { - vkd3d_va_map_remove(&allocator->va_map, &allocation->resource); - - if (!device->device_info.buffer_device_address_features.bufferDeviceAddress) - vkd3d_va_map_free_fake_va(&allocator->va_map, allocation->resource.va, allocation->resource.size); + if (!(allocation->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH)) + { + vkd3d_va_map_remove(&allocator->va_map, &allocation->resource); + if (!device->device_info.buffer_device_address_features.bufferDeviceAddress) + vkd3d_va_map_free_fake_va(&allocator->va_map, allocation->resource.va, allocation->resource.size); + } } if (allocation->resource.view_map) @@ -1398,7 +1405,8 @@ HRESULT vkd3d_allocate_memory(struct d3d12_device *device, struct vkd3d_memory_a HRESULT hr; if (!info->pNext && !info->host_ptr && info->memory_requirements.size < VKD3D_VA_BLOCK_SIZE && - !(info->heap_flags & (D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH))) + !(info->heap_flags & (D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_ALLOW_WRITE_WATCH)) && + !(info->flags & VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH)) hr = vkd3d_suballocate_memory(device, allocator, info, allocation); else hr = vkd3d_memory_allocation_init(allocation, device, allocator, info); @@ -1447,6 +1455,7 @@ HRESULT vkd3d_allocate_heap_memory(struct d3d12_device *device, struct vkd3d_mem alloc_info.heap_flags = info->heap_desc.Flags; alloc_info.host_ptr = info->host_ptr; + alloc_info.flags |= info->extra_allocation_flags; if (!(info->heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS)) alloc_info.flags |= VKD3D_ALLOCATION_FLAG_GLOBAL_BUFFER; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 2baab669..a9198889 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -586,6 +586,10 @@ enum vkd3d_allocation_flag VKD3D_ALLOCATION_FLAG_ALLOW_WRITE_WATCH = (1u << 3), VKD3D_ALLOCATION_FLAG_NO_FALLBACK = (1u << 4), VKD3D_ALLOCATION_FLAG_DEDICATED = (1u << 5), + /* Intended for internal allocation of scratch buffers. + * They are never suballocated since we do that ourselves, + * and we do not consume space in the VA map. */ + VKD3D_ALLOCATION_FLAG_INTERNAL_SCRATCH = (1u << 6), }; #define VKD3D_MEMORY_CHUNK_SIZE (VKD3D_VA_BLOCK_SIZE * 8) @@ -607,6 +611,7 @@ struct vkd3d_allocate_heap_memory_info { D3D12_HEAP_DESC heap_desc; void *host_ptr; + uint32_t extra_allocation_flags; }; struct vkd3d_allocate_resource_memory_info