From 6c2c5be150279877adb61e54394ba98db7fd4f76 Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Wed, 24 Nov 2021 18:39:03 +0100 Subject: [PATCH 1/3] dzn: Get an ID3D12Device1 object We need SetEventOnMultipleFenceCompletion() to implement vk_sync.wait_many(), and this method is part of the ID3D12Device1 interface. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> --- src/microsoft/vulkan/dzn_device.cpp | 2 +- src/microsoft/vulkan/dzn_private.h | 8 ++++---- src/microsoft/vulkan/dzn_util.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/microsoft/vulkan/dzn_device.cpp b/src/microsoft/vulkan/dzn_device.cpp index baa327f8515d6..8323309958a4d 100644 --- a/src/microsoft/vulkan/dzn_device.cpp +++ b/src/microsoft/vulkan/dzn_device.cpp @@ -364,7 +364,7 @@ dzn_physical_device::get_max_array_layers() return get_max_extent(false); } -ID3D12Device * +ID3D12Device1 * dzn_physical_device::get_d3d12_dev() { std::lock_guard<std::mutex> lock(dev_lock); diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 30939812620b3..8fb444102faf8 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -356,7 +356,7 @@ struct dzn_physical_device { const VkAllocationCallbacks *alloc); ~dzn_physical_device(); const VkAllocationCallbacks *get_vk_allocator(); - ID3D12Device *get_d3d12_dev(); + ID3D12Device1 *get_d3d12_dev(); const D3D12_FEATURE_DATA_ARCHITECTURE1 &get_arch_caps() const; const VkPhysicalDeviceMemoryProperties &get_memory() const; @@ -383,7 +383,7 @@ private: uint32_t get_max_extent(bool is_3d); std::mutex dev_lock; - ComPtr<ID3D12Device> dev; + ComPtr<ID3D12Device1> dev; D3D_FEATURE_LEVEL feature_level = (D3D_FEATURE_LEVEL)0; D3D12_FEATURE_DATA_ARCHITECTURE1 architecture = {}; D3D12_FEATURE_DATA_D3D12_OPTIONS options = {}; @@ -415,7 +415,7 @@ d3d12_enable_debug_layer(); void d3d12_enable_gpu_validation(); -ComPtr<ID3D12Device> +ComPtr<ID3D12Device1> d3d12_create_device(IUnknown *adapter, bool experimental_features); struct dzn_queue { @@ -444,7 +444,7 @@ struct dzn_device { struct vk_device_extension_table enabled_extensions; struct vk_device_dispatch_table dispatch; - ID3D12Device *dev; + ID3D12Device1 *dev; dzn_object_unique_ptr<dzn_meta_indirect_draw> indirect_draws[DZN_NUM_INDIRECT_DRAW_TYPES]; dzn_object_unique_ptr<dzn_meta_triangle_fan_rewrite_index> triangle_fan[dzn_meta_triangle_fan_rewrite_index::NUM_INDEX_TYPE]; diff --git a/src/microsoft/vulkan/dzn_util.cpp b/src/microsoft/vulkan/dzn_util.cpp index bf8d72e1b7160..921747340d5f4 100644 --- a/src/microsoft/vulkan/dzn_util.cpp +++ b/src/microsoft/vulkan/dzn_util.cpp @@ -112,7 +112,7 @@ d3d12_enable_gpu_validation() debug3->SetEnableGPUBasedValidation(true); } -ComPtr<ID3D12Device> +ComPtr<ID3D12Device1> d3d12_create_device(IUnknown *adapter, bool experimental_features) { typedef HRESULT(WINAPI *PFN_D3D12CREATEDEVICE)(IUnknown*, D3D_FEATURE_LEVEL, REFIID, void**); @@ -143,7 +143,7 @@ d3d12_create_device(IUnknown *adapter, bool experimental_features) return NULL; } - ComPtr<ID3D12Device> dev; + ComPtr<ID3D12Device1> dev; if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&dev)))) return dev; -- GitLab From 5a086d788b86a5013e53229bc6c57d9087d29e55 Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Wed, 24 Nov 2021 18:42:14 +0100 Subject: [PATCH 2/3] dzn: Implement a dzn_sync class to transition to the common sync/queue infra Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> --- src/microsoft/vulkan/dzn_private.h | 25 +++ src/microsoft/vulkan/dzn_sync.cpp | 280 +++++++++++++++++++++++++++++ src/microsoft/vulkan/meson.build | 1 + 3 files changed, 306 insertions(+) create mode 100644 src/microsoft/vulkan/dzn_sync.cpp diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 8fb444102faf8..60574bf0b3875 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -30,6 +30,7 @@ #include "vk_image.h" #include "vk_log.h" #include "vk_physical_device.h" +#include "vk_sync.h" #include "vk_queue.h" #include "vk_shader_module.h" #include "wsi_common.h" @@ -1576,6 +1577,30 @@ struct dzn_event { ~dzn_event(); }; +struct dzn_sync { + dzn_sync(dzn_device *device, uint64_t initial_value); + ~dzn_sync() = default; + + VkResult signal(uint64_t value); + uint64_t get_value(); + VkResult move(dzn_device *device, dzn_sync *dst); + ID3D12Fence *get_fence(); + + static VkResult wait(dzn_device *device, + uint32_t wait_count, + const struct vk_sync_wait *waits, + enum vk_sync_wait_flags wait_flags, + uint64_t abs_timeout_ns); + + static dzn_sync *to_dzn_sync(const struct vk_sync *sync); + static const struct vk_sync_type *get_type(); + + struct vk_sync vk; + +private: + ComPtr<ID3D12Fence> fence; +}; + struct dzn_query_pool { struct query { enum status { diff --git a/src/microsoft/vulkan/dzn_sync.cpp b/src/microsoft/vulkan/dzn_sync.cpp new file mode 100644 index 0000000000000..0d63e39c910e6 --- /dev/null +++ b/src/microsoft/vulkan/dzn_sync.cpp @@ -0,0 +1,280 @@ +/* + * Copyright © Microsoft Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "dzn_private.h" + +#include "vk_alloc.h" +#include "vk_debug_report.h" +#include "vk_util.h" + +#include "util/macros.h" +#include "util/os_time.h" + +static VkResult +dzn_sync_init(struct vk_device *device, + struct vk_sync *sync, + uint64_t initial_value) +{ + dzn_sync *dsync = container_of(sync, dzn_sync, vk); + dzn_device *ddev = container_of(device, dzn_device, vk); + + assert((void *)dsync == (void *)sync); + + try { + std::construct_at(dsync, ddev, initial_value); + } catch (VkResult error) { + return error; + } + + return VK_SUCCESS; +} + +static void +dzn_sync_finish(struct vk_device *device, + struct vk_sync *sync) +{ + dzn_sync *dsync = container_of(sync, dzn_sync, vk); + + std::destroy_at(dsync); +} + +static VkResult +dzn_sync_signal(struct vk_device *device, + struct vk_sync *sync, + uint64_t value) +{ + dzn_sync *dsync = container_of(sync, dzn_sync, vk); + + if (!(sync->flags & VK_SYNC_IS_TIMELINE)) + value = 1; + + return dsync->signal(value); +} + +static VkResult +dzn_sync_get_value(struct vk_device *device, + struct vk_sync *sync, + uint64_t *value) +{ + dzn_sync *dsync = container_of(sync, dzn_sync, vk); + + *value = dsync->get_value(); + return VK_SUCCESS; +} + +static VkResult +dzn_sync_reset(struct vk_device *device, + struct vk_sync *sync) +{ + dzn_sync *dsync = container_of(sync, dzn_sync, vk); + + dsync->signal(0); + return VK_SUCCESS; +} + +static VkResult +dzn_sync_move(struct vk_device *device, + struct vk_sync *dst, + struct vk_sync *src) +{ + dzn_device *ddev = container_of(device, dzn_device, vk); + dzn_sync *ddst = container_of(dst, dzn_sync, vk); + dzn_sync *dsrc = container_of(src, dzn_sync, vk); + + return dsrc->move(ddev, ddst); +} + +static VkResult +dzn_sync_wait(struct vk_device *device, + uint32_t wait_count, + const struct vk_sync_wait *waits, + enum vk_sync_wait_flags wait_flags, + uint64_t abs_timeout_ns) +{ + dzn_device *ddev = container_of(device, dzn_device, vk); + + return dzn_sync::wait(ddev, wait_count, waits, wait_flags, abs_timeout_ns); +} + +const struct vk_sync_type dzn_sync_type = { + .size = sizeof(dzn_sync), + .features = (enum vk_sync_features) + (VK_SYNC_FEATURE_BINARY | + VK_SYNC_FEATURE_TIMELINE | + VK_SYNC_FEATURE_GPU_WAIT | + VK_SYNC_FEATURE_GPU_MULTI_WAIT | + VK_SYNC_FEATURE_CPU_WAIT | + VK_SYNC_FEATURE_CPU_RESET | + VK_SYNC_FEATURE_CPU_SIGNAL | + VK_SYNC_FEATURE_WAIT_ANY | + VK_SYNC_FEATURE_WAIT_BEFORE_SIGNAL), + + .init = dzn_sync_init, + .finish = dzn_sync_finish, + .signal = dzn_sync_signal, + .get_value = dzn_sync_get_value, + .reset = dzn_sync_reset, + .move = dzn_sync_move, + .wait_many = dzn_sync_wait, +}; + +dzn_sync::dzn_sync(dzn_device *device, uint64_t initial_value) +{ + assert(!(vk.flags & VK_SYNC_IS_SHAREABLE)); + + HRESULT hres = + device->dev->CreateFence(initial_value, D3D12_FENCE_FLAG_NONE, + IID_PPV_ARGS(&fence)); + + if (FAILED(hres)) + throw vk_error(device, VK_ERROR_UNKNOWN); + +} + +VkResult +dzn_sync::signal(uint64_t value) +{ + HRESULT hres = fence->Signal(value); + if (FAILED(hres)) + return VK_ERROR_UNKNOWN; + + return VK_SUCCESS; +} + +uint64_t +dzn_sync::get_value() +{ + return fence->GetCompletedValue(); +} + +VkResult +dzn_sync::move(dzn_device *device, dzn_sync *dst) +{ + ComPtr<ID3D12Fence> new_fence; + + HRESULT hres = + device->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, + IID_PPV_ARGS(&new_fence)); + if (FAILED(hres)) + return VK_ERROR_UNKNOWN; + + dst->fence = fence; + fence = new_fence; + return VK_SUCCESS; +} + +VkResult +dzn_sync::wait(dzn_device *device, + uint32_t wait_count, + const struct vk_sync_wait *waits, + enum vk_sync_wait_flags wait_flags, + uint64_t abs_timeout_ns) +{ + struct { + dzn_transient_object<ID3D12Fence *> fences; + dzn_transient_object<uint64_t> values; + } heap_waits; + + struct { + ID3D12Fence *fences[STACK_ARRAY_SIZE]; + uint64_t values[STACK_ARRAY_SIZE]; + } stack_waits; + + ID3D12Fence **fences; + uint64_t *values; + + if (wait_count > STACK_ARRAY_SIZE) { + heap_waits.fences = dzn_transient_alloc<ID3D12Fence *>(wait_count, &device->vk.alloc); + heap_waits.values = dzn_transient_alloc<uint64_t>(wait_count, &device->vk.alloc); + fences = heap_waits.fences.get(); + values = heap_waits.values.get(); + } else { + fences = stack_waits.fences; + values = stack_waits.values; + } + + for (uint32_t i = 0; i < wait_count; i++) { + dzn_sync *sync = container_of(waits[i].sync, dzn_sync, vk); + + fences[i] = sync->fence.Get(); + values[i] = (sync->vk.flags & VK_SYNC_IS_TIMELINE) ? waits[i].wait_value : 1; + } + + HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); + if (event == NULL) + throw VK_ERROR_UNKNOWN; + + D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags = + (wait_flags & VK_SYNC_WAIT_ANY) ? + D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY : + D3D12_MULTIPLE_FENCE_WAIT_FLAG_ALL; + + device->dev->SetEventOnMultipleFenceCompletion(fences, values, + wait_count, flags, + event); + + DWORD timeout_ms; + + if (abs_timeout_ns == OS_TIMEOUT_INFINITE) { + timeout_ms = INFINITE; + } else { + uint64_t cur_time = os_time_get_nano(); + uint64_t rel_timeout_ns = + abs_timeout_ns > cur_time ? abs_timeout_ns - cur_time : 0; + + timeout_ms = (rel_timeout_ns / 1000000) + (rel_timeout_ns % 1000000 ? 1 : 0); + } + + DWORD res = + WaitForSingleObject(event, timeout_ms); + + CloseHandle(event); + + if (res == WAIT_TIMEOUT) + return VK_TIMEOUT; + else if (res != WAIT_OBJECT_0) + return VK_ERROR_UNKNOWN; + + return VK_SUCCESS; +} + +ID3D12Fence * +dzn_sync::get_fence() +{ + return fence.Get(); +} + +dzn_sync * +dzn_sync::to_dzn_sync(const struct vk_sync *sync) +{ + if (sync->type != &dzn_sync_type) + return NULL; + + return container_of(sync, dzn_sync, vk); +} + +const struct vk_sync_type * +dzn_sync::get_type() +{ + return &dzn_sync_type; +} diff --git a/src/microsoft/vulkan/meson.build b/src/microsoft/vulkan/meson.build index a55aa6cc7df59..a50a06a9a4a67 100644 --- a/src/microsoft/vulkan/meson.build +++ b/src/microsoft/vulkan/meson.build @@ -94,6 +94,7 @@ libdzn_files = files( 'dzn_query.cpp', 'dzn_semaphore.cpp', 'dzn_state.cpp', + 'dzn_sync.cpp', 'dzn_util.cpp', 'dzn_util.c', 'dzn_wsi.cpp', -- GitLab From 0a2b3821cbced07a5fe9215573908e8f2b678f5a Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Wed, 24 Nov 2021 18:44:40 +0100 Subject: [PATCH 3/3] dzn: Get rid of the custom semaphore/fence implementation And transition to the generic queue_submit() infrastructure. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> --- src/microsoft/vulkan/dzn_device.cpp | 200 +++++++++++++++---------- src/microsoft/vulkan/dzn_fence.cpp | 126 ---------------- src/microsoft/vulkan/dzn_private.h | 39 ++--- src/microsoft/vulkan/dzn_semaphore.cpp | 61 -------- src/microsoft/vulkan/meson.build | 2 - 5 files changed, 136 insertions(+), 292 deletions(-) delete mode 100644 src/microsoft/vulkan/dzn_fence.cpp delete mode 100644 src/microsoft/vulkan/dzn_semaphore.cpp diff --git a/src/microsoft/vulkan/dzn_device.cpp b/src/microsoft/vulkan/dzn_device.cpp index 8323309958a4d..e7dedff570b4e 100644 --- a/src/microsoft/vulkan/dzn_device.cpp +++ b/src/microsoft/vulkan/dzn_device.cpp @@ -195,6 +195,12 @@ dzn_physical_device::dzn_physical_device(dzn_instance *inst, } get_device_extensions(); + + uint32_t num_sync_types = 0; + sync_types[num_sync_types++] = dzn_sync::get_type(); + sync_types[num_sync_types] = NULL; + assert(num_sync_types <= MAX_SYNC_TYPES); + vk.supported_sync_types = sync_types; } dzn_physical_device::~dzn_physical_device() @@ -1353,6 +1359,15 @@ dzn_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount, return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT); } +static VkResult +dzn_queue_submit(struct vk_queue *queue, + struct vk_queue_submit *info) +{ + dzn_queue *dqueue = container_of(queue, dzn_queue, vk); + + return dqueue->submit(info); +} + dzn_queue::dzn_queue(dzn_device *dev, const VkDeviceQueueCreateInfo *pCreateInfo, const VkAllocationCallbacks *alloc) @@ -1361,6 +1376,7 @@ dzn_queue::dzn_queue(dzn_device *dev, if (result != VK_SUCCESS) throw result; + vk.driver_submit = dzn_queue_submit; device = dev; D3D12_COMMAND_QUEUE_DESC queue_desc = { @@ -1390,6 +1406,114 @@ dzn_queue::get_vk_allocator() return &device->vk.alloc; } +VkResult +dzn_queue::sync_wait(const struct vk_sync_wait &wait) +{ + dzn_sync *sync = dzn_sync::to_dzn_sync(wait.sync); + assert(sync != NULL); + + uint64_t value = + (sync->vk.flags & VK_SYNC_IS_TIMELINE) ? wait.wait_value : 1; + + ID3D12Fence *sync_fence = sync->get_fence(); + assert(sync_fence != NULL); + + if (value > 0 && FAILED(cmdqueue->Wait(sync_fence, value))) + return vk_error(device, VK_ERROR_UNKNOWN); + + return VK_SUCCESS; +} + +VkResult +dzn_queue::sync_signal(const struct vk_sync_signal &signal) +{ + dzn_sync *sync = dzn_sync::to_dzn_sync(signal.sync); + assert(sync != NULL); + + uint64_t value = + (sync->vk.flags & VK_SYNC_IS_TIMELINE) ? signal.signal_value : 1; + assert(value > 0); + + ID3D12Fence *sync_fence = sync->get_fence(); + assert(sync_fence != NULL); + HRESULT hres; + + hres = cmdqueue->Signal(sync_fence, value); + if (FAILED(hres)) + return vk_error(device, VK_ERROR_UNKNOWN); + + return VK_SUCCESS; +} + +VkResult +dzn_queue::submit(struct vk_queue_submit *info) +{ + VkResult result; + + for (uint32_t i = 0; i < info->wait_count; i++) { + result = sync_wait(info->waits[i]); + if (result != VK_SUCCESS) + return result; + } + + for (uint32_t i = 0; i < info->command_buffer_count; i++) { + dzn_cmd_buffer *cmd_buffer = + container_of(info->command_buffers[i], dzn_cmd_buffer, vk); + + for (auto &batch : cmd_buffer->batches) { + ID3D12CommandList *cmdlists[] = { batch->cmdlist.Get() }; + + for (auto &event : batch->wait) { + if (FAILED(cmdqueue->Wait(event->fence.Get(), 1))) + return VK_ERROR_UNKNOWN; + } + + for (auto &qop : batch->queries) { + auto &query = qop.qpool->queries[qop.query]; + ComPtr<ID3D12Fence> query_fence = query.fence; + uint64_t query_fence_val = query.fence_value.load(); + + if (qop.wait && query_fence.Get() && query_fence_val > 0) { + if (FAILED(cmdqueue->Wait(query_fence.Get(), query_fence_val))) + return VK_ERROR_UNKNOWN; + } + + if (qop.reset) { + query.fence = ComPtr<ID3D12Fence>(NULL); + query.fence_value = 0; + } + } + + cmdqueue->ExecuteCommandLists(1, cmdlists); + + for (auto &signal : batch->signal) { + if (FAILED(cmdqueue->Signal(signal.event->fence.Get(), signal.value ? 1 : 0))) + return VK_ERROR_UNKNOWN; + } + + for (auto &qop : batch->queries) { + if (qop.signal) { + auto &query = qop.qpool->queries[qop.query]; + + query.fence = fence; + query.fence_value = fence_point + 1; + } + } + } + } + + for (uint32_t i = 0; i < info->signal_count; i++) { + result = sync_signal(info->signals[i]); + if (result != VK_SUCCESS) + return result; + } + + if (FAILED(cmdqueue->Signal(fence.Get(), ++fence_point))) + return VK_ERROR_UNKNOWN; + + return VK_SUCCESS; +} + static VkResult check_physical_device_features(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceFeatures *features) @@ -1688,82 +1812,6 @@ dzn_DeviceWaitIdle(VkDevice _device) #endif } -VKAPI_ATTR VkResult VKAPI_CALL -dzn_QueueWaitIdle(VkQueue _queue) -{ - VK_FROM_HANDLE(dzn_queue, queue, _queue); - - if (FAILED(queue->fence->SetEventOnCompletion(queue->fence_point, NULL))) - return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY); - - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -dzn_QueueSubmit(VkQueue _queue, - uint32_t submitCount, - const VkSubmitInfo *pSubmits, - VkFence _fence) -{ - VK_FROM_HANDLE(dzn_queue, queue, _queue); - VK_FROM_HANDLE(dzn_fence, fence, _fence); - struct dzn_device *device = queue->device; - - /* TODO: execute an array of these instead of one at the time */ - for (uint32_t i = 0; i < submitCount; i++) { - for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j++) { - VK_FROM_HANDLE(dzn_cmd_buffer, cmd_buffer, - pSubmits[i].pCommandBuffers[j]); - assert(cmd_buffer->vk.level == VK_COMMAND_BUFFER_LEVEL_PRIMARY); - - for (auto &batch : cmd_buffer->batches) { - ID3D12CommandList *cmdlists[] = { batch->cmdlist.Get() }; - - for (auto &event : batch->wait) - queue->cmdqueue->Wait(event->fence.Get(), 1); - - for (auto &qop : batch->queries) { - auto &query = qop.qpool->queries[qop.query]; - ComPtr<ID3D12Fence> query_fence = query.fence; - uint64_t query_fence_val = query.fence_value.load(); - - if (qop.wait && query_fence.Get() && query_fence_val > 0) - queue->cmdqueue->Wait(query_fence.Get(), query_fence_val); - - if (qop.reset) { - query.fence = ComPtr<ID3D12Fence>(NULL); - query.fence_value = 0; - } - } - - queue->cmdqueue->ExecuteCommandLists(1, cmdlists); - - for (auto &signal : batch->signal) - queue->cmdqueue->Signal(signal.event->fence.Get(), signal.value ? 1 : 0); - - for (auto &qop : batch->queries) { - if (qop.signal) { - auto &query = qop.qpool->queries[qop.query]; - - query.fence = queue->fence; - query.fence_value = queue->fence_point + 1; - } - } - } - } - } - - if (fence) - queue->cmdqueue->Signal(fence->fence.Get(), 1); - - queue->cmdqueue->Signal(queue->fence.Get(), ++queue->fence_point); - - if (queue->device->physical_device->instance->debug_flags & DZN_DEBUG_SYNC) - dzn_QueueWaitIdle(_queue); - - return VK_SUCCESS; -} - dzn_device_memory::dzn_device_memory(dzn_device *device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator) diff --git a/src/microsoft/vulkan/dzn_fence.cpp b/src/microsoft/vulkan/dzn_fence.cpp deleted file mode 100644 index d7b43ed0edbff..0000000000000 --- a/src/microsoft/vulkan/dzn_fence.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright © Microsoft Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "dzn_private.h" - -#include "vk_alloc.h" -#include "vk_debug_report.h" -#include "vk_util.h" - -#include "util/macros.h" - -dzn_fence::dzn_fence(dzn_device *device, - const VkFenceCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator) -{ - BOOL initial_state = - pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT ? TRUE : FALSE; - - /* I suspect that this approach is bunk, and we should instead create the actual - * fence object on the cmdqueue and just signal things on the dzn_fence object - * instead. But I don't know yet, so let's just leave it like this for now... - */ - if (FAILED(device->dev->CreateFence(initial_state ? 1 : 0, D3D12_FENCE_FLAG_NONE, - IID_PPV_ARGS(&fence)))) - throw vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - - event = CreateEventA(NULL, TRUE, initial_state, NULL); - fence->SetEventOnCompletion(1, event); - - vk_object_base_init(&device->vk, &base, VK_OBJECT_TYPE_FENCE); -} - -dzn_fence::~dzn_fence() -{ - vk_object_base_finish(&base); - CloseHandle(event); -} - -VKAPI_ATTR VkResult VKAPI_CALL -dzn_CreateFence(VkDevice device, - const VkFenceCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkFence *pFence) -{ - return dzn_fence_factory::create(device, pCreateInfo, pAllocator, pFence); -} - -VKAPI_ATTR void VKAPI_CALL -dzn_DestroyFence(VkDevice device, - VkFence fence, - const VkAllocationCallbacks *pAllocator) -{ - return dzn_fence_factory::destroy(device, fence, pAllocator); -} - -VKAPI_ATTR VkResult VKAPI_CALL -dzn_GetFenceStatus(VkDevice _device, - VkFence _fence) -{ - VK_FROM_HANDLE(dzn_fence, fence, _fence); - - if (fence->fence->GetCompletedValue() != 1) - return VK_NOT_READY; - - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -dzn_ResetFences(VkDevice _device, - uint32_t fenceCount, - const VkFence *pFences) -{ - VK_FROM_HANDLE(dzn_device, device, _device); - - for (uint32_t i = 0; i < fenceCount; i++) { - VK_FROM_HANDLE(dzn_fence, fence, pFences[i]); - fence->fence->Signal(0); - ResetEvent(fence->event); - fence->fence->SetEventOnCompletion(1, fence->event); - } - - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -dzn_WaitForFences(VkDevice _device, - uint32_t fenceCount, - const VkFence *pFences, - VkBool32 waitAll, - uint64_t timeout) -{ - /* TODO: deal with more fences! */ - assert(fenceCount < MAXIMUM_WAIT_OBJECTS); - - HANDLE handles[MAXIMUM_WAIT_OBJECTS]; - for (int i = 0; i < fenceCount; ++i) { - VK_FROM_HANDLE(dzn_fence, fence, pFences[i]); - handles[i] = fence->event; - } - HRESULT hr = WaitForMultipleObjects(fenceCount, handles, waitAll, timeout / 1000000); - - if (hr == WAIT_TIMEOUT) - return VK_TIMEOUT; - - return VK_SUCCESS; -} diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 60574bf0b3875..f80592afb2ab4 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -334,6 +334,8 @@ struct dzn_meta_blits { std::hash<uint64_t>, std::equal_to<uint64_t>, contexts_allocator> contexts; }; +#define MAX_SYNC_TYPES 1 + struct dzn_physical_device { struct vk_physical_device vk; @@ -390,6 +392,7 @@ private: D3D12_FEATURE_DATA_D3D12_OPTIONS options = {}; VkPhysicalDeviceMemoryProperties memory = {}; D3D12_HEAP_FLAGS heap_flags_for_mem_type[VK_MAX_MEMORY_TYPES] = {}; + const struct vk_sync_type *sync_types[MAX_SYNC_TYPES + 1]; }; #define dzn_debug_ignored_stype(sType) \ @@ -424,14 +427,21 @@ struct dzn_queue { struct dzn_device *device; ComPtr<ID3D12CommandQueue> cmdqueue; - ComPtr<ID3D12Fence> fence; - uint64_t fence_point = 0; dzn_queue(dzn_device *device, const VkDeviceQueueCreateInfo *pCreateInfo, const VkAllocationCallbacks *alloc); ~dzn_queue(); + + VkResult submit(struct vk_queue_submit *info); + const VkAllocationCallbacks *get_vk_allocator(); + +private: + VkResult sync_wait(const struct vk_sync_wait &wait); + VkResult sync_signal(const struct vk_sync_signal &signal); + ComPtr<ID3D12Fence> fence; + uint64_t fence_point = 0; }; struct dzn_device { @@ -1545,27 +1555,6 @@ private: dzn_object_vector<dzn_physical_device> physical_devices; }; -struct dzn_semaphore { - struct vk_object_base base; - - dzn_semaphore(dzn_device *device, - const VkSemaphoreCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator); - ~dzn_semaphore(); -}; - -struct dzn_fence { - struct vk_object_base base; - - ComPtr<ID3D12Fence> fence; - HANDLE event; - - dzn_fence(dzn_device *device, - const VkFenceCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator); - ~dzn_fence(); -}; - struct dzn_event { struct vk_object_base base; @@ -1669,7 +1658,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_pool, base, VkDescriptorPool, VK_O VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set, base, VkDescriptorSet, VK_OBJECT_TYPE_DESCRIPTOR_SET) VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_descriptor_set_layout, base, VkDescriptorSetLayout, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT) VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_event, base, VkEvent, VK_OBJECT_TYPE_EVENT) -VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_fence, base, VkFence, VK_OBJECT_TYPE_FENCE) VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_framebuffer, base, VkFramebuffer, VK_OBJECT_TYPE_FRAMEBUFFER) VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE) VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_image_view, vk.base, VkImageView, VK_OBJECT_TYPE_IMAGE_VIEW) @@ -1681,7 +1669,6 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_pipeline_layout, base, VkPipelineLayout, VK_O VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_query_pool, base, VkQueryPool, VK_OBJECT_TYPE_QUERY_POOL) VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_render_pass, base, VkRenderPass, VK_OBJECT_TYPE_RENDER_PASS) VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_sampler, base, VkSampler, VK_OBJECT_TYPE_SAMPLER) -VK_DEFINE_NONDISP_HANDLE_CASTS(dzn_semaphore, base, VkSemaphore, VK_OBJECT_TYPE_SEMAPHORE) template <typename DT, typename VH, typename Conv, typename... CreateArgs> class dzn_object_factory { @@ -1865,7 +1852,6 @@ DZN_OBJ_FACTORY(dzn_descriptor_set_layout, VkDescriptorSetLayout, VkDevice, cons DZN_OBJ_FACTORY(dzn_device, VkDevice, VkPhysicalDevice, const VkDeviceCreateInfo *); DZN_OBJ_FACTORY(dzn_device_memory, VkDeviceMemory, VkDevice, const VkMemoryAllocateInfo *); DZN_OBJ_FACTORY(dzn_event, VkEvent, VkDevice, const VkEventCreateInfo *); -DZN_OBJ_FACTORY(dzn_fence, VkFence, VkDevice, const VkFenceCreateInfo *); DZN_OBJ_FACTORY(dzn_framebuffer, VkFramebuffer, VkDevice, const VkFramebufferCreateInfo *); DZN_OBJ_FACTORY(dzn_graphics_pipeline, VkPipeline, VkDevice, VkPipelineCache, const VkGraphicsPipelineCreateInfo *); DZN_OBJ_FACTORY(dzn_image, VkImage, VkDevice, const VkImageCreateInfo *); @@ -1878,6 +1864,5 @@ DZN_OBJ_FACTORY(dzn_queue, VkQueue, VkDevice, const VkDeviceQueueCreateInfo *); DZN_OBJ_FACTORY(dzn_query_pool, VkQueryPool, VkDevice, const VkQueryPoolCreateInfo *); DZN_OBJ_FACTORY(dzn_render_pass, VkRenderPass, VkDevice, const VkRenderPassCreateInfo2KHR *); DZN_OBJ_FACTORY(dzn_sampler, VkSampler, VkDevice, const VkSamplerCreateInfo *); -DZN_OBJ_FACTORY(dzn_semaphore, VkSemaphore, VkDevice, const VkSemaphoreCreateInfo *); #endif /* DZN_PRIVATE_H */ diff --git a/src/microsoft/vulkan/dzn_semaphore.cpp b/src/microsoft/vulkan/dzn_semaphore.cpp deleted file mode 100644 index 301c9fc30ee32..0000000000000 --- a/src/microsoft/vulkan/dzn_semaphore.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright © Microsoft Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "dzn_private.h" - -#include "vk_alloc.h" -#include "vk_debug_report.h" -#include "vk_util.h" - -#include "util/macros.h" - -dzn_semaphore::dzn_semaphore(dzn_device *device, - const VkSemaphoreCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator) -{ - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO); - vk_object_base_init(&device->vk, &base, VK_OBJECT_TYPE_SEMAPHORE); - /* TODO: do something useful ;) */ -} - -dzn_semaphore::~dzn_semaphore() -{ - vk_object_base_finish(&base); -} - -VKAPI_ATTR VkResult VKAPI_CALL -dzn_CreateSemaphore(VkDevice device, - const VkSemaphoreCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkSemaphore *pSemaphore) -{ - return dzn_semaphore_factory::create(device, pCreateInfo, pAllocator, pSemaphore); -} - -VKAPI_ATTR void VKAPI_CALL -dzn_DestroySemaphore(VkDevice device, - VkSemaphore semaphore, - const VkAllocationCallbacks *pAllocator) -{ - return dzn_semaphore_factory::destroy(device, semaphore, pAllocator); -} diff --git a/src/microsoft/vulkan/meson.build b/src/microsoft/vulkan/meson.build index a50a06a9a4a67..9f82c30eb6cff 100644 --- a/src/microsoft/vulkan/meson.build +++ b/src/microsoft/vulkan/meson.build @@ -84,7 +84,6 @@ libdzn_files = files( 'dzn_cmd_buffer.cpp', 'dzn_descriptor_set.cpp', 'dzn_device.cpp', - 'dzn_fence.cpp', 'dzn_image.cpp', 'dzn_meta.cpp', 'dzn_nir.c', @@ -92,7 +91,6 @@ libdzn_files = files( 'dzn_pipeline_cache.cpp', 'dzn_pipeline.cpp', 'dzn_query.cpp', - 'dzn_semaphore.cpp', 'dzn_state.cpp', 'dzn_sync.cpp', 'dzn_util.cpp', -- GitLab