From 72902a94ffa332bea32b3e06fddbb55d458cf553 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Mon, 3 Jul 2023 09:41:30 -0400 Subject: [PATCH 01/32] Setup for Implementing Acceleration Structures Just setup for acceleration structures by adding the definitions of the extension where it is needed. I also added the physical device features and properties that are needed. --- MoltenVK/MoltenVK.xcodeproj/project.pbxproj | 2 + .../GPUObjects/MVKAccelerationStructure.h | 38 +++++++++++++++++++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 9 +++++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 37 ++++++++++++++++++ MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 3 ++ MoltenVK/MoltenVK/Layers/MVKExtensions.def | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 20 ++++++++++ 7 files changed, 110 insertions(+) create mode 100644 MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj index ff2a8fdef..94b98b89a 100644 --- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj +++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj @@ -429,6 +429,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 019795132A5304D600C6CAD0 /* MVKAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKAccelerationStructure.h; sourceTree = ""; }; 2FEA0ABA24902F9F00EEF3AD /* libMoltenVK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVK.a; sourceTree = BUILT_PRODUCTS_DIR; }; 45003E6F214AD4C900E989CB /* MVKExtensions.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKExtensions.def; sourceTree = ""; }; 4536382D2508A4C6000EFFD3 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLRenderPassStencilAttachmentDescriptor+MoltenVK.h"; sourceTree = ""; }; @@ -631,6 +632,7 @@ A94FB77E1C7DFB4800632CA3 /* GPUObjects */ = { isa = PBXGroup; children = ( + 019795132A5304D600C6CAD0 /* MVKAccelerationStructure.h */, A94FB77F1C7DFB4800632CA3 /* MVKBuffer.h */, A94FB7801C7DFB4800632CA3 /* MVKBuffer.mm */, A966A5DC23C535D000BBF9B4 /* MVKDescriptor.h */, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h new file mode 100644 index 000000000..1556fecbb --- /dev/null +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -0,0 +1,38 @@ +/* + * MVKAccelerationStructure.h + * + * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "MVKVulkanAPIObject.h" + +#pragma mark MVKAccelerationStructure + +class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { + +public: + VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR; } + + VkDebugReportObjectTypeEXT getVkDebugReportObjectType() override { + return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT; + } + + MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} + ~MVKAccelerationStructure() {} +protected: + void propagateDebugName() override {} +}; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 5186fe4a0..9a432f2ce 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -71,6 +71,7 @@ class MVKCommandPool; class MVKCommandEncoder; class MVKCommandResourceFactory; class MVKPrivateDataSlot; +class MVKAccelerationStructure; // Not sure where to place, I'll move it there later /** The buffer index to use for vertex content. */ @@ -595,6 +596,14 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { const VkAllocationCallbacks* pAllocator); void destroyPipelineLayout(MVKPipelineLayout* mvkPLL, const VkAllocationCallbacks* pAllocator); + + MVKAccelerationStructure* createAccelerationStructure(VkDevice device, + const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureKHR* pAccelerationStructure); + void destroyAccelerationStructure(VkDevice device, + MVKAccelerationStructure* mvkAccStruct, + const VkAllocationCallbacks* pAllocator); /** * Template function that creates count number of pipelines of type PipelineType, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 3723a8f16..9daf813d2 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -33,6 +33,7 @@ #include "MVKFoundation.h" #include "MVKCodec.h" #include "MVKStrings.h" +#include "MVKAccelerationStructure.h" #include #import "CAMetalLayer+MoltenVK.h" @@ -202,6 +203,17 @@ storageFeatures->storagePushConstant8 = supportedFeats12.storagePushConstant8; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR: { + // In the future we should update this to allow for more advanced features if they can be supported. + auto* storageFeatures = (VkPhysicalDeviceAccelerationStructureFeaturesKHR*)next; + storageFeatures->accelerationStructure = true; + storageFeatures->accelerationStructure = false; + storageFeatures->accelerationStructureCaptureReplay = false; + storageFeatures->accelerationStructureIndirectBuild = false; + storageFeatures->accelerationStructureHostCommands = false; + storageFeatures->descriptorBindingAccelerationStructureUpdateAfterBind = false; + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES: case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: { auto* bufferDeviceAddressFeatures = (VkPhysicalDeviceBufferDeviceAddressFeatures*)next; @@ -554,6 +566,18 @@ *pProps12 = supportedProps12; break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR: { + /* + These are all magic numbers at the moment and should be probaly defined as constants, as well as that, there is an extended mode which allows for more geometry in the acceleration structures. If you're looking for a source here it is. https://developer.apple.com/documentation/metal/mtlaccelerationstructureusage/3750490-extendedlimits + */ + + auto* accelerationStructureProps = (VkPhysicalDeviceAccelerationStructurePropertiesKHR*)next; + accelerationStructureProps->maxGeometryCount = pow(2, 24); + accelerationStructureProps->maxInstanceCount = pow(2, 24); + accelerationStructureProps->maxPrimitiveCount = pow(2, 28); + // Other properties have not been figured out quite yet + break; + } case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: { auto* dvcIDProps = (VkPhysicalDeviceIDProperties*)next; mvkCopy(dvcIDProps->deviceUUID, supportedProps11.deviceUUID, VK_UUID_SIZE); @@ -3849,6 +3873,19 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope if (mvkPLL) { mvkPLL->destroy(); } } +MVKAccelerationStructure* MVKDevice::createAccelerationStructure(VkDevice device, + const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureKHR* pAccelerationStructure) { + return new MVKAccelerationStructure(this); +} + +void MVKDevice::destroyAccelerationStructure(VkDevice device, + MVKAccelerationStructure* mvkAccStruct, + const VkAllocationCallbacks* pAllocator) { + if(mvkAccStruct) { mvkAccStruct->destroy(); } +} + template VkResult MVKDevice::createPipelines(VkPipelineCache pipelineCache, uint32_t count, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index 5c6e6cb9b..8653b7c0f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -718,6 +718,9 @@ ADD_DVC_1_3_PROMOTED_ENTRY_POINT(vkSetPrivateData, EXT, EXT_PRIVATE_DATA); // Device extension functions. + ADD_DVC_EXT_ENTRY_POINT(vkCreateAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkDestroyAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkCreateDeferredOperationKHR, KHR_DEFERRED_HOST_OPERATIONS); ADD_DVC_EXT_ENTRY_POINT(vkDeferredOperationJoinKHR, KHR_DEFERRED_HOST_OPERATIONS); ADD_DVC_EXT_ENTRY_POINT(vkDestroyDeferredOperationKHR, KHR_DEFERRED_HOST_OPERATIONS); diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def index 4c6fe6f54..b0523a180 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def @@ -43,6 +43,7 @@ MVK_EXTENSION(KHR_16bit_storage, KHR_16BIT_STORAGE, DEVICE, 10.11, 8.0) MVK_EXTENSION(KHR_8bit_storage, KHR_8BIT_STORAGE, DEVICE, 10.11, 8.0) +MVK_EXTENSION(KHR_acceleration_structure, KHR_ACCELERATION_STRUCTURE, DEVICE, 11.0, 14.0) MVK_EXTENSION(KHR_bind_memory2, KHR_BIND_MEMORY_2, DEVICE, 10.11, 8.0) MVK_EXTENSION(KHR_buffer_device_address, KHR_BUFFER_DEVICE_ADDRESS, DEVICE, 13.0, 16.0) MVK_EXTENSION(KHR_copy_commands2, KHR_COPY_COMMANDS_2, DEVICE, 10.11, 8.0) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 44b0e5f69..c7a89e0a8 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2619,6 +2619,26 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdResolveImage2( MVK_PUBLIC_VULKAN_STUB_VKRESULT(vkQueueSubmit2, VkQueue, uint32_t, const VkSubmitInfo2*, VkFence) MVK_PUBLIC_VULKAN_STUB_VKRESULT(vkSetPrivateData, VkDevice, VkObjectType, uint64_t, VkPrivateDataSlot, uint64_t) +#pragma mark - +#pragma mark VK_KHR_acceleration_structure extension + +MVK_PUBLIC_VULKAN_SYMBOL VkResult vkCreateAccelerationStructureKHR( + VkDevice device, + const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureKHR* pAccelerationStructure) { + + return VK_SUCCESS; +} + +MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyAccelerationStructureKHR( + VkDevice device, + VkAccelerationStructureKHR accelerationStructure, + const VkAllocationCallbacks* pAllocator) { + + return; +} + #pragma mark - #pragma mark VK_KHR_bind_memory2 extension From 0cf8c174e5fc9812956524274afd2e38ce8638db Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Thu, 6 Jul 2023 11:23:56 -0400 Subject: [PATCH 02/32] Implemented Creation, Destruction, and Build sizes This commit adds a few items which are: * A list of functions that are needed to be implemented * An implementation of the vkGetAccelerationStructureBuildSizesKHR function * Fixed the parameters for the create and destroy acceleration structure in MVKDevice * Added the current functions in vulkan.mm --- MoltenVK/MoltenVK.xcodeproj/project.pbxproj | 8 +++++ .../GPUObjects/MVKAccelerationStructure.h | 23 +++++++++++- .../GPUObjects/MVKAccelerationStructure.mm | 35 +++++++++++++++++++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 9 ++--- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 9 ++--- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 29 +++++++++++++-- 6 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj index 94b98b89a..7e4743b61 100644 --- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj +++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 0197951B2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; + 0197951C2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; + 0197951D2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; 2FEA0A4124902F9F00EEF3AD /* MVKExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A909F65A213B190600FCD6BE /* MVKExtensions.h */; }; 2FEA0A4224902F9F00EEF3AD /* vk_mvk_moltenvk.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7691C7DFB4800632CA3 /* vk_mvk_moltenvk.h */; }; 2FEA0A4324902F9F00EEF3AD /* mvk_datatypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7671C7DFB4800632CA3 /* mvk_datatypes.h */; }; @@ -430,6 +433,7 @@ /* Begin PBXFileReference section */ 019795132A5304D600C6CAD0 /* MVKAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKAccelerationStructure.h; sourceTree = ""; }; + 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKAccelerationStructure.mm; sourceTree = ""; }; 2FEA0ABA24902F9F00EEF3AD /* libMoltenVK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVK.a; sourceTree = BUILT_PRODUCTS_DIR; }; 45003E6F214AD4C900E989CB /* MVKExtensions.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKExtensions.def; sourceTree = ""; }; 4536382D2508A4C6000EFFD3 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLRenderPassStencilAttachmentDescriptor+MoltenVK.h"; sourceTree = ""; }; @@ -633,6 +637,7 @@ isa = PBXGroup; children = ( 019795132A5304D600C6CAD0 /* MVKAccelerationStructure.h */, + 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */, A94FB77F1C7DFB4800632CA3 /* MVKBuffer.h */, A94FB7801C7DFB4800632CA3 /* MVKBuffer.mm */, A966A5DC23C535D000BBF9B4 /* MVKDescriptor.h */, @@ -1385,6 +1390,7 @@ 2FEA0AA124902F9F00EEF3AD /* MVKQueue.mm in Sources */, 2FEA0AA224902F9F00EEF3AD /* MTLSamplerDescriptor+MoltenVK.m in Sources */, 2FEA0AA324902F9F00EEF3AD /* MVKRenderPass.mm in Sources */, + 0197951C2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */, 2FEA0AA424902F9F00EEF3AD /* MVKCmdTransfer.mm in Sources */, 2FEA0AA524902F9F00EEF3AD /* MVKCmdQueries.mm in Sources */, 2FEA0AA624902F9F00EEF3AD /* mvk_api.mm in Sources */, @@ -1439,6 +1445,7 @@ A9653FBC24129C84005999D7 /* MVKPixelFormats.mm in Sources */, A94FB7E61C7DFB4800632CA3 /* MVKDevice.mm in Sources */, A9E53DF52100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */, + 0197951B2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */, A966A5E123C535D000BBF9B4 /* MVKDescriptor.mm in Sources */, A94FB7FA1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */, A94FB8021C7DFB4800632CA3 /* MVKQueue.mm in Sources */, @@ -1499,6 +1506,7 @@ A9653FBD24129C84005999D7 /* MVKPixelFormats.mm in Sources */, A94FB7E71C7DFB4800632CA3 /* MVKDevice.mm in Sources */, A9E53DF62100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */, + 0197951D2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */, A966A5E223C535D000BBF9B4 /* MVKDescriptor.mm in Sources */, A94FB7FB1C7DFB4800632CA3 /* MVKPipeline.mm in Sources */, A94FB8031C7DFB4800632CA3 /* MVKQueue.mm in Sources */, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 1556fecbb..e7a093a0c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -16,6 +16,23 @@ * limitations under the License. */ +/* + Commands that need to be implemented + + vkCmdBuildAccelerationStructuresIndirectKHR + vkCmdBuildAccelerationStructuresKHR + vkCmdCopyAccelerationStructureKHR + vkCmdCopyAccelerationStructureToMemoryKHR + vkCmdCopyMemoryToAccelerationStructureKHR + vkCmdWriteAccelerationStructuresPropertiesKHR + vkCreateAccelerationStructureKHR + vkDestroyAccelerationStructureKHR + vkGetAccelerationStructureBuildSizesKHR - DONE + vkGetAccelerationStructureDeviceAddressKHR + vkGetDeviceAccelerationStructureCompatibilityKHR + vkWriteAccelerationStructuresPropertiesKHR +*/ + #pragma once #include "MVKVulkanAPIObject.h" @@ -31,8 +48,12 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT; } + /** Gets the required build sizes for acceleration structure and scratch buffer*/ + static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(); + + +#pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} - ~MVKAccelerationStructure() {} protected: void propagateDebugName() override {} }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm new file mode 100644 index 000000000..3ae01466c --- /dev/null +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -0,0 +1,35 @@ +/* + * MVKAccelerationStructure.mm + * + * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MVKDevice.h" +#include "MVKAccelerationStructure.h" + +#pragma mark - +#pragma mark MVKAcceleration Structure + +VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes() +{ + VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; + + MTLAccelerationStructureSizes mtlBuildSizes; + vkBuildSizes.accelerationStructureSize = mtlBuildSizes.accelerationStructureSize; + vkBuildSizes.buildScratchSize = mtlBuildSizes.buildScratchBufferSize; + vkBuildSizes.updateScratchSize = mtlBuildSizes.refitScratchBufferSize; + + return vkBuildSizes; +} diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 9a432f2ce..90a7a578f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -597,12 +597,9 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { void destroyPipelineLayout(MVKPipelineLayout* mvkPLL, const VkAllocationCallbacks* pAllocator); - MVKAccelerationStructure* createAccelerationStructure(VkDevice device, - const VkAccelerationStructureCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkAccelerationStructureKHR* pAccelerationStructure); - void destroyAccelerationStructure(VkDevice device, - MVKAccelerationStructure* mvkAccStruct, + MVKAccelerationStructure* createAccelerationStructure(const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator); + void destroyAccelerationStructure(MVKAccelerationStructure* mvkAccStruct, const VkAllocationCallbacks* pAllocator); /** diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 94204d50a..6ec6ae7a3 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3894,15 +3894,12 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope if (mvkPLL) { mvkPLL->destroy(); } } -MVKAccelerationStructure* MVKDevice::createAccelerationStructure(VkDevice device, - const VkAccelerationStructureCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkAccelerationStructureKHR* pAccelerationStructure) { +MVKAccelerationStructure* MVKDevice::createAccelerationStructure(const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator) { return new MVKAccelerationStructure(this); } -void MVKDevice::destroyAccelerationStructure(VkDevice device, - MVKAccelerationStructure* mvkAccStruct, +void MVKDevice::destroyAccelerationStructure(MVKAccelerationStructure* mvkAccStruct, const VkAllocationCallbacks* pAllocator) { if(mvkAccStruct) { mvkAccStruct->destroy(); } } diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index c7a89e0a8..f492995d7 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -41,6 +41,7 @@ #include "MVKSurface.h" #include "MVKFoundation.h" #include "MVKOSExtensions.h" +#include "MVKAccelerationStructure.h" // I'll reposition this as well if it's needed #include @@ -2628,7 +2629,14 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkCreateAccelerationStructureKHR( const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure) { - return VK_SUCCESS; + MVKTraceVulkanCallStart(); + MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); + MVKAccelerationStructure* mvkAccelerationStructure = mvkDev->createAccelerationStructure(pCreateInfo, pAllocator); + *pAccelerationStructure = (VkAccelerationStructureKHR)mvkAccelerationStructure; + VkResult rslt = VK_SUCCESS; + MVKTraceVulkanCallEnd(); + + return rslt; } MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyAccelerationStructureKHR( @@ -2636,7 +2644,24 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyAccelerationStructureKHR( VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator) { - return; + MVKTraceVulkanCallStart(); + MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); + MVKAccelerationStructure* mvkAccelerationStructure = (MVKAccelerationStructure*)accelerationStructure; + mvkDev->destroyAccelerationStructure(mvkAccelerationStructure, pAllocator); + MVKTraceVulkanCallEnd(); +} + +MVK_PUBLIC_VULKAN_SYMBOL void vkGetAccelerationStructureBuildSizesKHR( + VkDevice device, + VkAccelerationStructureBuildTypeKHR buildType, + const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, + const uint32_t* pMaxPrimitiveCounts, + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo) { + + MVKTraceVulkanCallStart(); + VkAccelerationStructureBuildSizesInfoKHR buildSizes = MVKAccelerationStructure::getBuildSizes(); + pSizeInfo = &buildSizes; + MVKTraceVulkanCallEnd(); } #pragma mark - From a1b0961614bc7fcfb997b8e68dcadafa3dddb2d0 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Fri, 7 Jul 2023 12:38:49 -0400 Subject: [PATCH 03/32] Starting to Implement Acceleration Structure Commands This commit adds: * A .h and .mm file for Acceleration Structure commands * An acceleration structure command encoder into `MVKCommandBuffer` * An actual acceleration structure handle * And some other items that are not complete, or need to removed --- MoltenVK/MoltenVK.xcodeproj/project.pbxproj | 10 ++++++ .../Commands/MVKCmdAccelerationStructure.h | 32 +++++++++++++++++++ .../Commands/MVKCmdAccelerationStructure.mm | 30 +++++++++++++++++ MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h | 4 +++ .../MoltenVK/Commands/MVKCommandBuffer.mm | 21 ++++++++++++ .../GPUObjects/MVKAccelerationStructure.h | 15 +++++++-- .../GPUObjects/MVKAccelerationStructure.mm | 15 ++++++--- 7 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h create mode 100644 MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj index 7e4743b61..f2eda96df 100644 --- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj +++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj @@ -7,6 +7,9 @@ objects = { /* Begin PBXBuildFile section */ + 014702732A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; + 014702742A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; + 014702752A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; 0197951B2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; 0197951C2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; 0197951D2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; @@ -432,6 +435,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 014702702A5855F70040D02D /* MVKCmdAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdAccelerationStructure.h; sourceTree = ""; }; + 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdAccelerationStructure.mm; sourceTree = ""; }; 019795132A5304D600C6CAD0 /* MVKAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKAccelerationStructure.h; sourceTree = ""; }; 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKAccelerationStructure.mm; sourceTree = ""; }; 2FEA0ABA24902F9F00EEF3AD /* libMoltenVK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVK.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -599,6 +604,8 @@ A94FB76B1C7DFB4800632CA3 /* Commands */ = { isa = PBXGroup; children = ( + 014702702A5855F70040D02D /* MVKCmdAccelerationStructure.h */, + 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */, A99C90EC229455B200A061DA /* MVKCmdDebug.h */, A99C90ED229455B300A061DA /* MVKCmdDebug.mm */, A9096E5C1F81E16300DFBEA6 /* MVKCmdDispatch.h */, @@ -1406,6 +1413,7 @@ 2FEA0AB024902F9F00EEF3AD /* MVKFramebuffer.mm in Sources */, 2FEA0AB124902F9F00EEF3AD /* MVKMTLBufferAllocation.mm in Sources */, 2FEA0AB224902F9F00EEF3AD /* CAMetalLayer+MoltenVK.m in Sources */, + 014702742A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */, 2FEA0AB324902F9F00EEF3AD /* MVKCmdDispatch.mm in Sources */, 2FEA0AB424902F9F00EEF3AD /* MVKCmdDebug.mm in Sources */, ); @@ -1444,6 +1452,7 @@ A98149551FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */, A9653FBC24129C84005999D7 /* MVKPixelFormats.mm in Sources */, A94FB7E61C7DFB4800632CA3 /* MVKDevice.mm in Sources */, + 014702732A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */, A9E53DF52100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */, 0197951B2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */, A966A5E123C535D000BBF9B4 /* MVKDescriptor.mm in Sources */, @@ -1505,6 +1514,7 @@ A98149561FB6A3F7005F00B4 /* MVKFoundation.cpp in Sources */, A9653FBD24129C84005999D7 /* MVKPixelFormats.mm in Sources */, A94FB7E71C7DFB4800632CA3 /* MVKDevice.mm in Sources */, + 014702752A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */, A9E53DF62100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */, 0197951D2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */, A966A5E223C535D000BBF9B4 /* MVKDescriptor.mm in Sources */, diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h new file mode 100644 index 000000000..7d41b04e7 --- /dev/null +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -0,0 +1,32 @@ +/* + * MVKCmdAccelerationStructure.h + * + * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "MVKCommand.h" + +#pragma mark - +#pragma mark MVKCmdBuildAccelerationStructure + +class MVKCmdBuildAccelerationStructure : public MVKCommand { + +public: + void encode(MVKCommandEncoder* cmdEncoder) override; +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; +}; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm new file mode 100644 index 000000000..6eec99595 --- /dev/null +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -0,0 +1,30 @@ +/* + * MVKCmdAccelerationStructure.mm + * + * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MVKCmdAccelerationStructure.h" +#include "MVKCmdDebug.h" +#include "MVKCommandBuffer.h" +#include "MVKCommandPool.h" + +#import +#import +#import + +void MVKCmdBuildAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { + cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); +} diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index 76274dad8..cb37dc65f 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h @@ -352,6 +352,8 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { * the current encoder before beginning BLIT encoding. */ id getMTLBlitEncoder(MVKCommandUse cmdUse); + + id getMTLAccelerationStructureEncoder(MVKCommandUse cmdUse); // Write proper comment above /** * Returns the current Metal encoder, which may be any of the Metal render, @@ -515,6 +517,7 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { MVKSmallVector> _subpassSamplePositions; id _mtlComputeEncoder; id _mtlBlitEncoder; + id _mtlAccelerationStructureEncoder; id _stageCountersMTLFence; MVKPushConstantsCommandEncoderState _vertexPushConstants; MVKPushConstantsCommandEncoderState _tessCtlPushConstants; @@ -529,6 +532,7 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { uint32_t _flushCount; MVKCommandUse _mtlComputeEncoderUse; MVKCommandUse _mtlBlitEncoderUse; + MVKCommandUse _mtlAccelerationStructureUse; bool _isRenderingEntireAttachment; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index a58d6457d..84a23322b 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -846,6 +846,10 @@ if (_mtlBlitEncoder && _cmdBuffer->_hasStageCounterTimestampCommand) { [_mtlBlitEncoder updateFence: getStageCountersMTLFence()]; } endMetalEncoding(_mtlBlitEncoder); _mtlBlitEncoderUse = kMVKCommandUseNone; + + if (_mtlAccelerationStructureEncoder && _cmdBuffer->_hasStageCounterTimestampCommand) { [_mtlAccelerationStructureEncoder updateFence: getStageCountersMTLFence()]; } + endMetalEncoding(_mtlAccelerationStructureEncoder); + _mtlAccelerationStructureUse = kMVKCommandUseNone; encodeTimestampStageCounterSamples(); } @@ -883,10 +887,24 @@ return _mtlBlitEncoder; } +id MVKCommandEncoder::getMTLAccelerationStructureEncoder(MVKCommandUse cmdUse) { + if ( !_mtlAccelerationStructureEncoder ) { + endCurrentMetalEncoding(); + _mtlAccelerationStructureEncoder = [_mtlCmdBuffer accelerationStructureCommandEncoder]; + retainIfImmediatelyEncoding(_mtlAccelerationStructureEncoder); + } + if (_mtlAccelerationStructureUse != cmdUse) { + _mtlAccelerationStructureUse = cmdUse; + setLabelIfNotNil(_mtlAccelerationStructureEncoder, mvkMTLBlitCommandEncoderLabel(cmdUse)); + } + return _mtlAccelerationStructureEncoder; +} + id MVKCommandEncoder::getMTLEncoder(){ if (_mtlRenderEncoder) { return _mtlRenderEncoder; } if (_mtlComputeEncoder) { return _mtlComputeEncoder; } if (_mtlBlitEncoder) { return _mtlBlitEncoder; } + if (_mtlAccelerationStructureEncoder) { return _mtlAccelerationStructureEncoder; } return nil; } @@ -1149,6 +1167,8 @@ _mtlComputeEncoderUse = kMVKCommandUseNone; _mtlBlitEncoder = nil; _mtlBlitEncoderUse = kMVKCommandUseNone; + _mtlAccelerationStructureEncoder = nil; + _mtlAccelerationStructureUse = kMVKCommandUseNone; _pEncodingContext = nullptr; _stageCountersMTLFence = nil; _flushCount = 0; @@ -1158,6 +1178,7 @@ [_mtlRenderEncoder release]; [_mtlComputeEncoder release]; [_mtlBlitEncoder release]; + [_mtlAccelerationStructureEncoder release]; // _stageCountersMTLFence is released after Metal command buffer completion } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index e7a093a0c..e7c1e745a 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -25,8 +25,8 @@ vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyMemoryToAccelerationStructureKHR vkCmdWriteAccelerationStructuresPropertiesKHR - vkCreateAccelerationStructureKHR - vkDestroyAccelerationStructureKHR + vkCreateAccelerationStructureKHR - DONE + vkDestroyAccelerationStructureKHR - DONE vkGetAccelerationStructureBuildSizesKHR - DONE vkGetAccelerationStructureDeviceAddressKHR vkGetDeviceAccelerationStructureCompatibilityKHR @@ -37,6 +37,9 @@ #include "MVKVulkanAPIObject.h" +#import +#import + #pragma mark MVKAccelerationStructure class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { @@ -51,9 +54,17 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { /** Gets the required build sizes for acceleration structure and scratch buffer*/ static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(); + /** Gets the device address of the acceleration structure*/ + void getDeviceAddress(); + /** Builds the acceleration structure as a device command*/ + void build(); #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} protected: void propagateDebugName() override {} + + #if MVK_XCODE_12 + id _accelerationStructure; + #endif }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 3ae01466c..f1695fd01 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -26,10 +26,17 @@ { VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; - MTLAccelerationStructureSizes mtlBuildSizes; - vkBuildSizes.accelerationStructureSize = mtlBuildSizes.accelerationStructureSize; - vkBuildSizes.buildScratchSize = mtlBuildSizes.buildScratchBufferSize; - vkBuildSizes.updateScratchSize = mtlBuildSizes.refitScratchBufferSize; + #if MVK_XCODE_12 + MTLAccelerationStructureSizes mtlBuildSizes; + vkBuildSizes.accelerationStructureSize = mtlBuildSizes.accelerationStructureSize; + vkBuildSizes.buildScratchSize = mtlBuildSizes.buildScratchBufferSize; + vkBuildSizes.updateScratchSize = mtlBuildSizes.refitScratchBufferSize; + #endif return vkBuildSizes; } + +void MVKAccelerationStructure::getDeviceAddress() +{ + +} From d409fbf42091a3129a8a365e1ec1e98b600ba17a Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Sat, 8 Jul 2023 12:02:39 -0400 Subject: [PATCH 04/32] Fixed missing symbol for getPoolType in MVKCmdBuildAccelerationStructure Fixed the missing symbol for getPoolType in MVKCmdBuildAccelerationStructure by including it in MVKCommandPool.h. I also added the Build Acceleration structure command into definitions file. --- MoltenVK/MoltenVK/Commands/MVKCommandPool.h | 1 + MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandPool.h b/MoltenVK/MoltenVK/Commands/MVKCommandPool.h index f2cf1e66e..1d8406f23 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandPool.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandPool.h @@ -22,6 +22,7 @@ #include "MVKCommandBuffer.h" #include "MVKCommandEncodingPool.h" #include "MVKCommand.h" +#include "MVKCmdAccelerationStructure.h" #include "MVKCmdPipeline.h" #include "MVKCmdRenderPass.h" #include "MVKCmdDispatch.h" diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index f8f208b63..4fa58d1ab 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -125,7 +125,8 @@ MVK_CMD_TYPE_POOL(DebugMarkerEnd) MVK_CMD_TYPE_POOL(DebugMarkerInsert) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(WaitEvents, 1) MVK_CMD_TYPE_POOL(SetEvent) -MVK_CMD_TYPE_POOL_LAST(ResetEvent) +MVK_CMD_TYPE_POOL(ResetEvent) +MVK_CMD_TYPE_POOL_LAST(BuildAccelerationStructure) #undef MVK_CMD_TYPE_POOL #undef MVK_CMD_TYPE_POOL_LAST From 0e50b28e022ce9f4961092181c05800d80703dca Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Sat, 8 Jul 2023 19:20:11 -0400 Subject: [PATCH 05/32] Implemented the encoding for Building Acceleration Structures Finished up what was needed for the MVKCmdBuildAccelerationStructure. The only 2 issues at the moment are the scratch buffer and the scratch buffer offset, to which a solution has been proposed. I plan to discuss this in the PR thread before trying out anything. --- .../Commands/MVKCmdAccelerationStructure.h | 9 ++++++ .../Commands/MVKCmdAccelerationStructure.mm | 29 ++++++++++++++++++- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 11 +++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 7d41b04e7..69c414242 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -26,7 +26,16 @@ class MVKCmdBuildAccelerationStructure : public MVKCommand { public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); + void encode(MVKCommandEncoder* cmdEncoder) override; protected: MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + uint32_t _infoCount; + VkAccelerationStructureBuildGeometryInfoKHR _geometryInfos; + VkAccelerationStructureBuildRangeInfoKHR const* _buildRangeInfos; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 6eec99595..3d40a42c4 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -25,6 +25,33 @@ #import #import +VkResult MVKCmdBuildAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { + _infoCount = infoCount; + _geometryInfos = *pInfos; + _buildRangeInfos = *ppBuildRangeInfos; + + return VK_SUCCESS; +} + void MVKCmdBuildAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { - cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + id srcAccelerationStructure = (id)_geometryInfos.srcAccelerationStructure; + id dstAccelerationStructure = (id)_geometryInfos.dstAccelerationStructure; // Target acceleration Structure + + MTLAccelerationStructureDescriptor* accStructDescriptor = [MTLAccelerationStructureDescriptor new]; + accStructDescriptor.usage = MTLAccelerationStructureUsageNone; + /* + * The NVIDIA extension seemed to use to provide the scratch buffer offset, but not the KHR version + * However the KHR extension does not seem to have anything similar, for now I'll leave it 0, but + * it should be changed. + */ + int scratchBufferOffset = 0; + +// [accStructEncoder buildAccelerationStructure:dstAccelerationStructure +// descriptor:accStructDescriptor +// scratchBuffer:scratchBuffer +// scratchBufferOffset:scratchBufferOffset]; } diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index f492995d7..bd4d9305b 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2664,6 +2664,17 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkGetAccelerationStructureBuildSizesKHR( MVKTraceVulkanCallEnd(); } +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBuildAccelerationStructuresKHR( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(BuildAccelerationStructure, commandBuffer, infoCount, pInfos, ppBuildRangeInfos); + MVKTraceVulkanCallEnd(); +} + #pragma mark - #pragma mark VK_KHR_bind_memory2 extension From 0fb82af84fe094600aa7fa21be96ee9ed29f3505 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Mon, 10 Jul 2023 10:58:00 -0400 Subject: [PATCH 06/32] Added Copy acceleration structure command This commit adds the copy acceleration structure, but does not add the commands that copy memory to and from an acceleration structure. As well as that I've added 2 files for a map that will store the device address along with the buffer. This map will also come in handy when getting the device address for the acceleration structure --- MoltenVK/MoltenVK.xcodeproj/project.pbxproj | 12 +++++++- .../Commands/MVKCmdAccelerationStructure.h | 21 +++++++++++++- .../Commands/MVKCmdAccelerationStructure.mm | 28 +++++++++++++++---- .../MoltenVK/Commands/MVKCommandTypePools.def | 3 +- .../GPUObjects/MVKAccelerationStructure.h | 11 ++++---- .../GPUObjects/MVKAccelerationStructure.mm | 5 ++++ MoltenVK/MoltenVK/Utility/MVKMap.h | 27 ++++++++++++++++++ MoltenVK/MoltenVK/Utility/MVKMapAllocator.h | 25 +++++++++++++++++ MoltenVK/MoltenVK/Vulkan/vulkan.mm | 10 +++++++ 9 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 MoltenVK/MoltenVK/Utility/MVKMap.h create mode 100644 MoltenVK/MoltenVK/Utility/MVKMapAllocator.h diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj index f2eda96df..d3de7d08b 100644 --- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj +++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj @@ -10,6 +10,9 @@ 014702732A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; 014702742A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; 014702752A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; + 0147027B2A5B0C010040D02D /* MVKMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0147027A2A5AF1310040D02D /* MVKMap.h */; }; + 0147027C2A5B0C010040D02D /* MVKMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0147027A2A5AF1310040D02D /* MVKMap.h */; }; + 0147027D2A5B0C020040D02D /* MVKMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0147027A2A5AF1310040D02D /* MVKMap.h */; }; 0197951B2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; 0197951C2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; 0197951D2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; @@ -437,6 +440,8 @@ /* Begin PBXFileReference section */ 014702702A5855F70040D02D /* MVKCmdAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdAccelerationStructure.h; sourceTree = ""; }; 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdAccelerationStructure.mm; sourceTree = ""; }; + 0147027A2A5AF1310040D02D /* MVKMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKMap.h; sourceTree = ""; }; + 0147027E2A5B0C9A0040D02D /* MVKMapAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKMapAllocator.h; sourceTree = ""; }; 019795132A5304D600C6CAD0 /* MVKAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKAccelerationStructure.h; sourceTree = ""; }; 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKAccelerationStructure.mm; sourceTree = ""; }; 2FEA0ABA24902F9F00EEF3AD /* libMoltenVK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVK.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -727,13 +732,15 @@ A98149431FB6A3F7005F00B4 /* MVKEnvironment.h */, A98149451FB6A3F7005F00B4 /* MVKFoundation.cpp */, A98149441FB6A3F7005F00B4 /* MVKFoundation.h */, + 0147027A2A5AF1310040D02D /* MVKMap.h */, + 0147027E2A5B0C9A0040D02D /* MVKMapAllocator.h */, A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */, A9F3D9DB24732A4D00745190 /* MVKSmallVector.h */, A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */, A98149491FB6A3F7005F00B4 /* MVKWatermark.h */, A981494A1FB6A3F7005F00B4 /* MVKWatermark.mm */, - A981494B1FB6A3F7005F00B4 /* MVKWatermarkShaderSource.h */, A981494C1FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h */, + A981494B1FB6A3F7005F00B4 /* MVKWatermarkShaderSource.h */, ); path = Utility; sourceTree = ""; @@ -877,6 +884,7 @@ 2FEA0A7224902F9F00EEF3AD /* MVKCmdDraw.h in Headers */, A9B3D73C29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */, 2FEA0A7324902F9F00EEF3AD /* MVKCommandBuffer.h in Headers */, + 0147027C2A5B0C010040D02D /* MVKMap.h in Headers */, 2FEA0A7424902F9F00EEF3AD /* MTLRenderPassDescriptor+MoltenVK.h in Headers */, 2FEA0A7524902F9F00EEF3AD /* MVKCmdDebug.h in Headers */, 2FEA0A7624902F9F00EEF3AD /* MVKWatermarkTextureContent.h in Headers */, @@ -931,6 +939,7 @@ A94FB7D41C7DFB4800632CA3 /* MVKCommandPool.h in Headers */, A94FB80C1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */, A99C91042295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */, + 0147027B2A5B0C010040D02D /* MVKMap.h in Headers */, A94FB7C01C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */, A9B3D73B29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */, A94FB7CC1C7DFB4800632CA3 /* MVKCommand.h in Headers */, @@ -1008,6 +1017,7 @@ A94FB80D1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */, A99C91052295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */, A94FB7C11C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */, + 0147027D2A5B0C020040D02D /* MVKMap.h in Headers */, A94FB7CD1C7DFB4800632CA3 /* MVKCommand.h in Headers */, A9B3D73D29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */, A98149501FB6A3F7005F00B4 /* MVKBaseObject.h in Headers */, diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 69c414242..6643aaf2e 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -20,6 +20,10 @@ #include "MVKCommand.h" +#import +#import +#import + #pragma mark - #pragma mark MVKCmdBuildAccelerationStructure @@ -29,7 +33,7 @@ class MVKCmdBuildAccelerationStructure : public MVKCommand { VkResult setContent(MVKCommandBuffer* cmdBuff, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, - const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); void encode(MVKCommandEncoder* cmdEncoder) override; protected: @@ -39,3 +43,18 @@ class MVKCmdBuildAccelerationStructure : public MVKCommand { VkAccelerationStructureBuildGeometryInfoKHR _geometryInfos; VkAccelerationStructureBuildRangeInfoKHR const* _buildRangeInfos; }; + +class MVKCmdCopyAccelerationStructure : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkAccelerationStructureKHR srcAccelerationStructure, + VkAccelerationStructureKHR dstAccelerationStructure); + + void encode(MVKCommandEncoder* cmdEncoder) override; +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + id _srcAccelerationStructure; + id _dstAccelerationStructure; +}; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 3d40a42c4..36be8adef 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -21,14 +21,12 @@ #include "MVKCommandBuffer.h" #include "MVKCommandPool.h" -#import -#import -#import +#include "MVKAccelerationStructure.h" VkResult MVKCmdBuildAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, - const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { _infoCount = infoCount; _geometryInfos = *pInfos; _buildRangeInfos = *ppBuildRangeInfos; @@ -52,6 +50,26 @@ // [accStructEncoder buildAccelerationStructure:dstAccelerationStructure // descriptor:accStructDescriptor -// scratchBuffer:scratchBuffer +// scratchBuffer:nil // scratchBufferOffset:scratchBufferOffset]; } + +VkResult MVKCmdCopyAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, + VkAccelerationStructureKHR srcAccelerationStructure, + VkAccelerationStructureKHR dstAccelerationStructure) { + + MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; + MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; + + _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + _dstAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + return VK_SUCCESS; +} + +void MVKCmdCopyAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { + id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + + [accStructEncoder + copyAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; +} diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index 4fa58d1ab..a9c56eea1 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -126,7 +126,8 @@ MVK_CMD_TYPE_POOL(DebugMarkerInsert) MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(WaitEvents, 1) MVK_CMD_TYPE_POOL(SetEvent) MVK_CMD_TYPE_POOL(ResetEvent) -MVK_CMD_TYPE_POOL_LAST(BuildAccelerationStructure) +MVK_CMD_TYPE_POOL(BuildAccelerationStructure) +MVK_CMD_TYPE_POOL_LAST(CopyAccelerationStructure) #undef MVK_CMD_TYPE_POOL #undef MVK_CMD_TYPE_POOL_LAST diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index e7c1e745a..0d811225e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -20,8 +20,8 @@ Commands that need to be implemented vkCmdBuildAccelerationStructuresIndirectKHR - vkCmdBuildAccelerationStructuresKHR - vkCmdCopyAccelerationStructureKHR + vkCmdBuildAccelerationStructuresKHR - IN PROGRESS + vkCmdCopyAccelerationStructureKHR - DONE vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyMemoryToAccelerationStructureKHR vkCmdWriteAccelerationStructuresPropertiesKHR @@ -51,6 +51,8 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT; } + id getMTLAccelerationStructure(); + /** Gets the required build sizes for acceleration structure and scratch buffer*/ static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(); @@ -59,12 +61,11 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { /** Builds the acceleration structure as a device command*/ void build(); + #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} protected: void propagateDebugName() override {} - #if MVK_XCODE_12 - id _accelerationStructure; - #endif + id _accelerationStructure; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index f1695fd01..9397aec36 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -22,6 +22,11 @@ #pragma mark - #pragma mark MVKAcceleration Structure +id MVKAccelerationStructure::getMTLAccelerationStructure() +{ + return _accelerationStructure; +} + VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes() { VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; diff --git a/MoltenVK/MoltenVK/Utility/MVKMap.h b/MoltenVK/MoltenVK/Utility/MVKMap.h new file mode 100644 index 000000000..54e977351 --- /dev/null +++ b/MoltenVK/MoltenVK/Utility/MVKMap.h @@ -0,0 +1,27 @@ +/* + * MVKMap.h + * + * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "MVKFoundation.h" +#include "MVKMapAllocator.h" + +// Storage type, and Lookup Type +template +class MVKMapImpl : public MVKBaseObject { +}; diff --git a/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h b/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h new file mode 100644 index 000000000..1c626572f --- /dev/null +++ b/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h @@ -0,0 +1,25 @@ +/* + * MVKMap.h + * + * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "MVKFoundation.h" + +template +class mvk_unordered_map_allocator final { +}; diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index bd4d9305b..ecae600f7 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2675,6 +2675,16 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBuildAccelerationStructuresKHR( MVKTraceVulkanCallEnd(); } +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureInfoKHR* pInfo) { + + MVKTraceVulkanCallStart(); + // Currently were ignoring the copy mode + MVKAddCmd(CopyAccelerationStructure, commandBuffer, pInfo->src, pInfo->dst); + MVKTraceVulkanCallEnd(); +} + #pragma mark - #pragma mark VK_KHR_bind_memory2 extension From eab6f6f5eacea74a52119bc5ad599ba20fb7b385 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Mon, 10 Jul 2023 17:03:46 -0400 Subject: [PATCH 07/32] MVKMap half-done implementation A half done implementation of MVKMap. MVKMap aims to use the same API as std::unordered_map, and I used MVKSmallVector as an example of how to write MVKMap. I hope there aren't any bugs however, I'll probably do some tests off of the repository once I'm done --- MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h | 2 + MoltenVK/MoltenVK/Utility/MVKMap.h | 105 +++++++++++++++++++- MoltenVK/MoltenVK/Utility/MVKMapAllocator.h | 105 +++++++++++++++++++- 3 files changed, 207 insertions(+), 5 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h index 2e338ce7a..3fc5b0be2 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h @@ -21,6 +21,8 @@ #include "MVKResource.h" #include "MVKCommandBuffer.h" +#include "MVKMap.h" + class MVKCommandEncoder; diff --git a/MoltenVK/MoltenVK/Utility/MVKMap.h b/MoltenVK/MoltenVK/Utility/MVKMap.h index 54e977351..e0a752840 100644 --- a/MoltenVK/MoltenVK/Utility/MVKMap.h +++ b/MoltenVK/MoltenVK/Utility/MVKMap.h @@ -21,7 +21,106 @@ #include "MVKFoundation.h" #include "MVKMapAllocator.h" -// Storage type, and Lookup Type -template -class MVKMapImpl : public MVKBaseObject { +template, + class Hash = std::hash> +class MVKMapImpl { + +private: + Allocator alc; + + class iterator + { + const MVKMapImpl* map; + size_t index; + public: + using iterator_category = std::random_access_iterator_tag; + using difference_type = std::ptrdiff_t; + typedef difference_type diff_type; + + iterator() : map{ nullptr }, index{ 0 } { } + iterator(const size_t _index, const MVKMapImpl &_map) : map{ &_map }, index{ _index } { } + + iterator &operator=(const iterator &it) + { + map = it.map; + index = it.index; + return *this; + } + + T *operator->() { return &map->alc.ptr[index]; } + T &operator*() { return map->alc.ptr[index]; } + operator T*() { return &map->alc.ptr[index]; } + + bool operator==( const iterator &it ) const { return map == it.map && index == it.index; } + bool operator!=( const iterator &it ) const { return map != it.map || index != it.index; } + + iterator& operator++() { ++index; return *this; } + iterator operator++( int ) { auto t = *this; ++index; return t; } + iterator& operator--() { --index; return *this; } + iterator operator--( int ) { auto t = *this; --index; return t; } + + iterator operator+ (const diff_type n) { return iterator( index + n, *map ); } + iterator& operator+= (const diff_type n) { index += n; return *this; } + iterator operator- (const diff_type n) { return iterator( index - n, *map ); } + iterator& operator-= (const diff_type n) { index -= n; return *this; } + + diff_type operator- (const iterator& it) { return index - it.index; } + + bool operator< (const iterator& it) { return index < it.index; } + bool operator<= (const iterator& it) { return index <= it.index; } + bool operator> (const iterator& it) { return index > it.index; } + bool operator>= (const iterator& it) { return index >= it.index; } + + const T &operator[]( const diff_type i ) const { return map->alc.ptr[index + i]; } + T &operator[]( const diff_type i ) { return map->alc.ptr[index + i]; } + + bool is_valid() const { return index < map->alc.size(); } + size_t get_position() const { return index; } + }; +protected: + bool empty() { return alc.num_elements_used == 0;} + size_t size() { return alc.size(); } + + T* &at( const size_t i ) { return alc[i]; } + const T* const at(const size_t i) const { return alc[i]; } + + iterator begin() { return iterator(0, this); } + iterator end() { return iterator(size(), this); } + + void erase(const iterator it) + { + if(it.is_valid()) + { + --alc.num_elements_used; + + for(size_t i = it.get_position(); i < alc.num_elements_used; ++i) + { + alc.ptr[i] = alc.ptr[i + 1]; + } + } + } + + void erase(const iterator first, const iterator last) + { + if(first.is_valid()) + { + size_t last_pos = last.is_valid() ? last.get_position() : size(); + size_t n = last_pos - first.get_position(); + alc.num_elements_used -= n; + + for(size_t i = first.get_position(), e = last_pos; i < alc.num_elements_used && e < alc.num_elements_used + n; ++i, ++e) + { + alc.ptr[i] = alc.ptr[e]; + } + } + } + + std::pair insert(const T& value) + { + alc.re_allocate(size() + 1); + alc.ptr[size()] = value; + return std::make_pair(end(), true); + } }; diff --git a/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h b/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h index 1c626572f..6387e9d0c 100644 --- a/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h +++ b/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h @@ -19,7 +19,108 @@ #pragma once #include "MVKFoundation.h" +#include -template -class mvk_unordered_map_allocator final { +namespace mvk_map_memory_allocator +{ + inline char *alloc(const size_t num_bytes) + { + return new char[num_bytes]; + } + + inline void free(void *ptr) + { + delete[] (char*)ptr; + } +}; + +template +class mvk_map_allocator final { + +public: + std::pair* ptr; + size_t num_elements_used; +private: + static constexpr size_t CAP_CNT_SIZE = sizeof(size_t); + static constexpr size_t ALIGN_CNT = CAP_CNT_SIZE / sizeof(std::pair); + static constexpr size_t ALIGN_MASK = (ALIGN_CNT> 0) ? (ALIGN_CNT - 1) : 0; + + static constexpr size_t MIN_CNT = M> ALIGN_CNT ? M : ALIGN_CNT; + static constexpr size_t N = (MIN_CNT + ALIGN_MASK) & ~ALIGN_MASK; + + static constexpr size_t MIN_STACK_SIZE = (N * sizeof(std::pair)); + static constexpr size_t STACK_SIZE = MIN_STACK_SIZE> CAP_CNT_SIZE ? MIN_STACK_SIZE : CAP_CNT_SIZE; + alignas(alignof(std::pair)) unsigned char elements_stack[ STACK_SIZE ]; + + void set_num_elements_reserved(const size_t num_elements_reserved) + { + *reinterpret_cast(&elements_stack[0]) = num_elements_reserved; + } +public: + const T &operator[](const size_t i) const { return ptr[i]; } + T &operator[](const size_t i) { return ptr[i]; } + + size_t size() const { return num_elements_used; } + + constexpr T *get_default_ptr() const + { + return reinterpret_cast(const_cast(&elements_stack[0])); + } + + template typename std::enable_if::value>::type + construct(S *_ptr, Args&&... _args) + { + new (_ptr) S(std::forward(_args)...); + } + + template typename std::enable_if::value>::type + construct(S *_ptr, Args&&... _args) + { + *_ptr = S(std::forward(_args)...); + } + + template typename std::enable_if::value>::type + destruct(S *_ptr) + { + _ptr->~S(); + } + + template typename std::enable_if::value>::type + destruct(S *_ptr) {} + + template typename std::enable_if::value>::type + destruct_all() + { + for(size_t i = 0; i < num_elements_used; ++i) + { + ptr[i].~S(); + } + + num_elements_used = 0; + } + + template typename std::enable_if::value>::type + destruct_all() + { + num_elements_used = 0; + } + + void re_allocate(const size_t num_elements_to_reserve) + { + auto *new_ptr = reinterpret_cast(mvk_smallvector_memory_allocator::alloc(num_elements_to_reserve * sizeof(T))); + + for(size_t i = 0; i < num_elements_used; ++i) + { + construct(&new_ptr[i], std::move(ptr[i])); + destruct(&ptr[i]); + } + + if(ptr != get_default_ptr()) + { + mvk_smallvector_memory_allocator::free(ptr); + } + + ptr = new_ptr; + set_num_elements_reserved(num_elements_to_reserve); + } }; From 43a987c0c39fd60cc608d194426b89baf82807b1 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Mon, 10 Jul 2023 18:47:56 -0400 Subject: [PATCH 08/32] Using std::unordered_map to store the Buffer Device Addresses This commit finished off the build acceleration structure command. This is because in MVKDevice, we are now using a std::unordered_map instead of a custom map implementation. --- .../Commands/MVKCmdAccelerationStructure.mm | 22 +++++++++---------- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 4 ++++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 20 ++++++++++++++++- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 36be8adef..d0fb80332 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -37,21 +37,21 @@ void MVKCmdBuildAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); id srcAccelerationStructure = (id)_geometryInfos.srcAccelerationStructure; - id dstAccelerationStructure = (id)_geometryInfos.dstAccelerationStructure; // Target acceleration Structure + id dstAccelerationStructure = (id)_geometryInfos.dstAccelerationStructure; MTLAccelerationStructureDescriptor* accStructDescriptor = [MTLAccelerationStructureDescriptor new]; accStructDescriptor.usage = MTLAccelerationStructureUsageNone; - /* - * The NVIDIA extension seemed to use to provide the scratch buffer offset, but not the KHR version - * However the KHR extension does not seem to have anything similar, for now I'll leave it 0, but - * it should be changed. - */ + + MVKDevice* mvkDvc = cmdEncoder->getDevice(); + MVKBuffer* mvkBuffer = mvkDvc->getBufferAtAddress(_geometryInfos.scratchData.deviceAddress); + + id scratchBuffer = mvkBuffer->getMTLBuffer(); int scratchBufferOffset = 0; -// [accStructEncoder buildAccelerationStructure:dstAccelerationStructure -// descriptor:accStructDescriptor -// scratchBuffer:nil -// scratchBufferOffset:scratchBufferOffset]; + [accStructEncoder buildAccelerationStructure:dstAccelerationStructure + descriptor:accStructDescriptor + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; } VkResult MVKCmdCopyAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, @@ -62,7 +62,7 @@ MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); - _dstAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + _dstAccelerationStructure = mvkDstAccStruct->getMTLAccelerationStructure(); return VK_SUCCESS; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 90a7a578f..efa027767 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -524,6 +524,9 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { const VkCalibratedTimestampInfoEXT* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); + + /** Returns a pointer to the buffer at the provided address*/ + MVKBuffer* getBufferAtAddress(uint64_t address); #pragma mark Object lifecycle @@ -913,6 +916,7 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { MVKSmallVector, kMVKQueueFamilyCount> _queuesByQueueFamilyIndex; MVKSmallVector _resources; MVKSmallVector _gpuAddressableBuffers; + std::unordered_map _gpuBufferAddressMap; MVKSmallVector _privateDataSlots; MVKSmallVector _privateDataSlotsAvailability; MVKSmallVector _awaitingSemaphores; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 6ec6ae7a3..59074a71e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3640,6 +3640,20 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope *pMaxDeviation = cpuEnd - cpuStart; } +MVKBuffer* MVKDevice::getBufferAtAddress(uint64_t address) +{ + auto mvkBufIt = _gpuBufferAddressMap.find(address); + + if(mvkBufIt != _gpuBufferAddressMap.end()) + { + return mvkBufIt->second; + } + else + { + return nullptr; + } +} + #pragma mark Object lifecycle uint32_t MVKDevice::getVulkanMemoryTypeIndex(MTLStorageMode mtlStorageMode) { @@ -4132,7 +4146,9 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope _resources.push_back(mvkBuff); if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { _gpuAddressableBuffers.push_back(mvkBuff); - } + std::pair _bufferAddressPair = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff); + _gpuBufferAddressMap.insert(_bufferAddressPair); + } return mvkBuff; } @@ -4143,6 +4159,8 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope mvkRemoveFirstOccurance(_resources, mvkBuff); if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { mvkRemoveFirstOccurance(_gpuAddressableBuffers, mvkBuff); + auto bufferAddressIt = _gpuBufferAddressMap.find(mvkBuff->getMTLBufferGPUAddress()); + _gpuBufferAddressMap.erase(bufferAddressIt); } return mvkBuff; } From 555bf4780261c046bd5433c768c365639e106643 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Tue, 11 Jul 2023 10:27:33 -0400 Subject: [PATCH 09/32] Implemented Acceleration Structure Compatibility Added in a function to check for acceleration structure compatibility. Also made sure to properly add the device features for acceleration structures. --- .../GPUObjects/MVKAccelerationStructure.h | 9 +++------ .../GPUObjects/MVKAccelerationStructure.mm | 14 ++++++-------- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 5 ++++- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 16 ++++++++++++++-- .../GPUObjects/MVKDeviceFeatureStructs.def | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 11 +++++++++++ 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 0d811225e..bd27214b3 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -20,7 +20,7 @@ Commands that need to be implemented vkCmdBuildAccelerationStructuresIndirectKHR - vkCmdBuildAccelerationStructuresKHR - IN PROGRESS + vkCmdBuildAccelerationStructuresKHR - DONE vkCmdCopyAccelerationStructureKHR - DONE vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyMemoryToAccelerationStructureKHR @@ -29,7 +29,7 @@ vkDestroyAccelerationStructureKHR - DONE vkGetAccelerationStructureBuildSizesKHR - DONE vkGetAccelerationStructureDeviceAddressKHR - vkGetDeviceAccelerationStructureCompatibilityKHR + vkGetDeviceAccelerationStructureCompatibilityKHR - DONE vkWriteAccelerationStructuresPropertiesKHR */ @@ -57,10 +57,7 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(); /** Gets the device address of the acceleration structure*/ - void getDeviceAddress(); - - /** Builds the acceleration structure as a device command*/ - void build(); + uint64_t getDeviceAddress(); #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 9397aec36..3e462a00f 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -31,17 +31,15 @@ { VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; - #if MVK_XCODE_12 - MTLAccelerationStructureSizes mtlBuildSizes; - vkBuildSizes.accelerationStructureSize = mtlBuildSizes.accelerationStructureSize; - vkBuildSizes.buildScratchSize = mtlBuildSizes.buildScratchBufferSize; - vkBuildSizes.updateScratchSize = mtlBuildSizes.refitScratchBufferSize; - #endif + MTLAccelerationStructureSizes mtlBuildSizes; + vkBuildSizes.accelerationStructureSize = mtlBuildSizes.accelerationStructureSize; + vkBuildSizes.buildScratchSize = mtlBuildSizes.buildScratchBufferSize; + vkBuildSizes.updateScratchSize = mtlBuildSizes.refitScratchBufferSize; return vkBuildSizes; } -void MVKAccelerationStructure::getDeviceAddress() +uint64_t MVKAccelerationStructure::getDeviceAddress() { - + return 0; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index efa027767..1016b7d52 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -526,7 +526,10 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { uint64_t* pMaxDeviation); /** Returns a pointer to the buffer at the provided address*/ - MVKBuffer* getBufferAtAddress(uint64_t address); + MVKBuffer* getBufferAtAddress(uint64_t address); // Unsure where to place + + /** Returns whether or not the device supports acceleration structures*/ + VkAccelerationStructureCompatibilityKHR getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo); #pragma mark Object lifecycle diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 59074a71e..5129f8c58 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -206,8 +206,7 @@ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR: { // In the future we should update this to allow for more advanced features if they can be supported. auto* storageFeatures = (VkPhysicalDeviceAccelerationStructureFeaturesKHR*)next; - storageFeatures->accelerationStructure = true; - storageFeatures->accelerationStructure = false; + storageFeatures->accelerationStructure = mvkOSVersionIsAtLeast(11.0, 14.0); storageFeatures->accelerationStructureCaptureReplay = false; storageFeatures->accelerationStructureIndirectBuild = false; storageFeatures->accelerationStructureHostCommands = false; @@ -3654,6 +3653,19 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope } } +VkAccelerationStructureCompatibilityKHR MVKDevice::getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo) +{ + VkAccelerationStructureCompatibilityKHR compat = VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR; + + if(_enabledAccelerationStructureFeatures.accelerationStructure) + { + compat = VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR; + } + + return compat; +} + + #pragma mark Object lifecycle uint32_t MVKDevice::getVulkanMemoryTypeIndex(MTLStorageMode mtlStorageMode) { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def index c0bbb4816..1bc0acfff 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceFeatureStructs.def @@ -60,6 +60,7 @@ MVK_DEVICE_FEATURE(TimelineSemaphore, TIMELINE_SEMAPHORE, MVK_DEVICE_FEATURE(UniformBufferStandardLayout, UNIFORM_BUFFER_STANDARD_LAYOUT, 1) MVK_DEVICE_FEATURE(VariablePointer, VARIABLE_POINTER, 2) MVK_DEVICE_FEATURE(VulkanMemoryModel, VULKAN_MEMORY_MODEL, 3) +MVK_DEVICE_FEATURE_EXTN(AccelerationStructure, ACCELERATION_STRUCTURE, KHR, 5) MVK_DEVICE_FEATURE_EXTN(FragmentShaderBarycentric, FRAGMENT_SHADER_BARYCENTRIC, KHR, 1) MVK_DEVICE_FEATURE_EXTN(PortabilitySubset, PORTABILITY_SUBSET, KHR, 15) MVK_DEVICE_FEATURE_EXTN(4444Formats, 4444_FORMATS, EXT, 2) diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index ecae600f7..2926aafc1 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2685,6 +2685,17 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyAccelerationStructureKHR( MVKTraceVulkanCallEnd(); } +MVK_PUBLIC_VULKAN_SYMBOL void vkGetDeviceAccelerationStructureCompatibilityKHR( + VkDevice device, + const VkAccelerationStructureVersionInfoKHR* pVersionInfo, + VkAccelerationStructureCompatibilityKHR* pCompatibility) { + + MVKTraceVulkanCallStart(); + MVKDevice* mvkDev = (MVKDevice*)device; + *pCompatibility = mvkDev->getAccelerationStructureCompatibility(pVersionInfo); + MVKTraceVulkanCallEnd(); +} + #pragma mark - #pragma mark VK_KHR_bind_memory2 extension From b4d977bfba66755bf6dc2d1c6940c4ca4c1da0fc Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Wed, 12 Jul 2023 12:20:46 -0400 Subject: [PATCH 10/32] Fixed getBufferAtAddress to allow for offsets This commit fixes getBufferAtAddress, because the address could be offset, however that was not valid before. Something to keep in mind is that the performance maybe really bad, however I believe that until we start running Ray queries or Raytracing Pipelines, we can keep the find function as it is. Note that we're also using a custom hash function because std::pair does not have a default hash. I'm to worried about collisions because only one buffer can occupy between these 2 addresses. --- .../Commands/MVKCmdAccelerationStructure.h | 3 ++ .../Commands/MVKCmdAccelerationStructure.mm | 6 ++++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 3 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 29 +++++++++++++------ MoltenVK/MoltenVK/Utility/MVKMap.h | 7 +++++ 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 6643aaf2e..85a3c895e 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -44,6 +44,9 @@ class MVKCmdBuildAccelerationStructure : public MVKCommand { VkAccelerationStructureBuildRangeInfoKHR const* _buildRangeInfos; }; +#pragma mark - +#pragma mark MVKCmdCopyAccelerationStructure + class MVKCmdCopyAccelerationStructure : public MVKCommand { public: diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index d0fb80332..725751371 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -23,6 +23,9 @@ #include "MVKAccelerationStructure.h" +#pragma mark - +#pragma mark MVKCmdBuildAccelerationStructure + VkResult MVKCmdBuildAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, @@ -54,6 +57,9 @@ scratchBufferOffset:scratchBufferOffset]; } +#pragma mark - +#pragma mark MVKCmdCopyAccelerationStructure + VkResult MVKCmdCopyAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, VkAccelerationStructureKHR srcAccelerationStructure, VkAccelerationStructureKHR dstAccelerationStructure) { diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 1016b7d52..946a883f6 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -28,6 +28,7 @@ #include "MVKOSExtensions.h" #include "mvk_private_api.h" #include "mvk_datatypes.hpp" +#include "MVKMap.h" #include #include @@ -919,7 +920,7 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { MVKSmallVector, kMVKQueueFamilyCount> _queuesByQueueFamilyIndex; MVKSmallVector _resources; MVKSmallVector _gpuAddressableBuffers; - std::unordered_map _gpuBufferAddressMap; + std::unordered_map, MVKBuffer*, MVKHash_uint64_t_pair> _gpuBufferAddressMap; MVKSmallVector _privateDataSlots; MVKSmallVector _privateDataSlotsAvailability; MVKSmallVector _awaitingSemaphores; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 5129f8c58..8aad78c07 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3641,16 +3641,24 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope MVKBuffer* MVKDevice::getBufferAtAddress(uint64_t address) { - auto mvkBufIt = _gpuBufferAddressMap.find(address); + lock_guard lock(_rezLock); - if(mvkBufIt != _gpuBufferAddressMap.end()) + std::unordered_map, MVKBuffer*>::iterator it; + // Super inefficent but this can be fixed in the future + for(it = _gpuBufferAddressMap.begin(); it != _gpuBufferAddressMap.end(); it++) { - return mvkBufIt->second; - } - else - { - return nullptr; + // If the beginning address is bigger than, or the ending address is smaller than the passed address, then skip this it + if(it->first.first > address || it->first.second < address) + { + continue; + } + break; } + + // Couldn't find the buffer at address + if (it == _gpuBufferAddressMap.end()) { return nullptr;} + + return it->second; } VkAccelerationStructureCompatibilityKHR MVKDevice::getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo) @@ -4158,7 +4166,9 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope _resources.push_back(mvkBuff); if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { _gpuAddressableBuffers.push_back(mvkBuff); - std::pair _bufferAddressPair = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff); + + std::pair bdaRange = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff->getMTLBufferGPUAddress() + (uint64_t)mvkBuff->getByteCount()); + std::pair, MVKBuffer*> _bufferAddressPair = std::make_pair(bdaRange, mvkBuff); _gpuBufferAddressMap.insert(_bufferAddressPair); } return mvkBuff; @@ -4171,7 +4181,8 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope mvkRemoveFirstOccurance(_resources, mvkBuff); if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { mvkRemoveFirstOccurance(_gpuAddressableBuffers, mvkBuff); - auto bufferAddressIt = _gpuBufferAddressMap.find(mvkBuff->getMTLBufferGPUAddress()); + std::pair bdaRange = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff->getMTLBufferGPUAddress() + (uint64_t)mvkBuff->getByteCount()); + auto bufferAddressIt = _gpuBufferAddressMap.find(bdaRange); _gpuBufferAddressMap.erase(bufferAddressIt); } return mvkBuff; diff --git a/MoltenVK/MoltenVK/Utility/MVKMap.h b/MoltenVK/MoltenVK/Utility/MVKMap.h index e0a752840..19ceaf24b 100644 --- a/MoltenVK/MoltenVK/Utility/MVKMap.h +++ b/MoltenVK/MoltenVK/Utility/MVKMap.h @@ -21,6 +21,13 @@ #include "MVKFoundation.h" #include "MVKMapAllocator.h" + +struct MVKHash_uint64_t_pair { // Change the naming style? + size_t operator()(std::pair p) const noexcept { + return size_t(p.first) << 32 | p.second; // Hopefully this is unique enough of a hash, anyway only 1 buffer can ocupy between these 2 memory addreses + } +}; + template, From 28a5c0a7f833e0b16c633e58d12ba580d00bd738 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Wed, 12 Jul 2023 15:11:50 -0400 Subject: [PATCH 11/32] Update to xrOS versioning system from main This commit just adds the xrOS version to the MVK_EXTENSION and to mvkOSVersionIsAtLeast --- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 2 +- MoltenVK/MoltenVK/Layers/MVKExtensions.def | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index e58fad951..f3cc2bc1e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -206,7 +206,7 @@ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR: { // In the future we should update this to allow for more advanced features if they can be supported. auto* storageFeatures = (VkPhysicalDeviceAccelerationStructureFeaturesKHR*)next; - storageFeatures->accelerationStructure = mvkOSVersionIsAtLeast(11.0, 14.0); + storageFeatures->accelerationStructure = mvkOSVersionIsAtLeast(11.0, 14.0, 1.0); storageFeatures->accelerationStructureCaptureReplay = false; storageFeatures->accelerationStructureIndirectBuild = false; storageFeatures->accelerationStructureHostCommands = false; diff --git a/MoltenVK/MoltenVK/Layers/MVKExtensions.def b/MoltenVK/MoltenVK/Layers/MVKExtensions.def index 74a006290..a187bdfea 100644 --- a/MoltenVK/MoltenVK/Layers/MVKExtensions.def +++ b/MoltenVK/MoltenVK/Layers/MVKExtensions.def @@ -43,6 +43,7 @@ MVK_EXTENSION(KHR_16bit_storage, KHR_16BIT_STORAGE, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(KHR_8bit_storage, KHR_8BIT_STORAGE, DEVICE, 10.11, 8.0, 1.0) +MVK_EXTENSION(KHR_acceleration_structure, KHR_ACCELERATION_STRUCTURE, DEVICE, 11.0, 14.0, 1.0) MVK_EXTENSION(KHR_bind_memory2, KHR_BIND_MEMORY_2, DEVICE, 10.11, 8.0, 1.0) MVK_EXTENSION(KHR_buffer_device_address, KHR_BUFFER_DEVICE_ADDRESS, DEVICE, 13.0, 16.0, 1.0) MVK_EXTENSION(KHR_copy_commands2, KHR_COPY_COMMANDS_2, DEVICE, 10.11, 8.0, 1.0) From 257a75ff0682e2e15c658ae48cafc0ac193731bc Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Wed, 12 Jul 2023 18:55:33 -0400 Subject: [PATCH 12/32] Take in more parameters for CmdBuildAccelerationStructure This commit just changes build acceleration structure, to allow for the different options/parameters to be take into account. I plan to amend this commit. --- .../Commands/MVKCmdAccelerationStructure.mm | 58 ++++++++++++++++--- .../GPUObjects/MVKAccelerationStructure.h | 7 +++ 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 725751371..4e1787e45 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -39,22 +39,62 @@ void MVKCmdBuildAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); - id srcAccelerationStructure = (id)_geometryInfos.srcAccelerationStructure; - id dstAccelerationStructure = (id)_geometryInfos.dstAccelerationStructure; - MTLAccelerationStructureDescriptor* accStructDescriptor = [MTLAccelerationStructureDescriptor new]; - accStructDescriptor.usage = MTLAccelerationStructureUsageNone; + MVKAccelerationStructure* mvkSrcAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos.srcAccelerationStructure; + MVKAccelerationStructure* mvkDstAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos.dstAccelerationStructure; + + id srcAccelerationStructure = (id)mvkSrcAccelerationStructure->getMTLAccelerationStructure(); + id dstAccelerationStructure = (id)mvkDstAccelerationStructure->getMTLAccelerationStructure(); + + if(_geometryInfos.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && !mvkDstAccelerationStructure->getAllowUpdate()) + { + return; + } MVKDevice* mvkDvc = cmdEncoder->getDevice(); MVKBuffer* mvkBuffer = mvkDvc->getBufferAtAddress(_geometryInfos.scratchData.deviceAddress); id scratchBuffer = mvkBuffer->getMTLBuffer(); - int scratchBufferOffset = 0; + NSInteger scratchBufferOffset = mvkBuffer->getMTLBufferOffset(); + + if(_geometryInfos.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) + { + MTLAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos.flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + mvkDstAccelerationStructure->setAllowUpdate(true); + }else if(mvkIsAnyFlagEnabled(_geometryInfos.flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + + [accStructEncoder buildAccelerationStructure:dstAccelerationStructure + descriptor:accStructBuildDescriptor + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; + return; + } + + if(_geometryInfos.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) + { + MTLAccelerationStructureDescriptor* accStructRefitDescriptor = [MTLAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos.flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructRefitDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + } + + [accStructEncoder refitAccelerationStructure:srcAccelerationStructure + descriptor:accStructRefitDescriptor + destination:dstAccelerationStructure + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; + + return; + } - [accStructEncoder buildAccelerationStructure:dstAccelerationStructure - descriptor:accStructDescriptor - scratchBuffer:scratchBuffer - scratchBufferOffset:scratchBufferOffset]; + return; } #pragma mark - diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index bd27214b3..823711648 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -58,6 +58,12 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { /** Gets the device address of the acceleration structure*/ uint64_t getDeviceAddress(); + + /** Used when building the acceleration structure, to mark whether or not an acceleration structure can be updated*/ + void setAllowUpdate(bool value) { _allowUpdate = value; } + + /** Checks if this acceleration structure is allowed to be updated*/ + bool getAllowUpdate() { return _allowUpdate; } #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} @@ -65,4 +71,5 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { void propagateDebugName() override {} id _accelerationStructure; + bool _allowUpdate = false; }; From 5a85fdd1c34f0222bb5bc68a3fa1d744c6600457 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Fri, 14 Jul 2023 10:03:28 -0400 Subject: [PATCH 13/32] Implemented GPU addresses for Acceleration Structures This commit adds "imaginary" gpu addresses for acceleration structures. This allows us to easily implement the rest of the copy commands, as well as the get address function that are required for this vulkan extension. The only thing I'm worried about is how to defragment the memory, because when we destroy an acceleration structure, pushing all the keys can be costly. Hopefully we find a better way to store addresses. --- .../Commands/MVKCmdAccelerationStructure.h | 2 +- .../Commands/MVKCmdAccelerationStructure.mm | 94 ++++++++++--------- .../GPUObjects/MVKAccelerationStructure.h | 21 ++++- .../GPUObjects/MVKAccelerationStructure.mm | 6 ++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 12 ++- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 36 +++++-- 6 files changed, 114 insertions(+), 57 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 85a3c895e..c15075075 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -40,7 +40,7 @@ class MVKCmdBuildAccelerationStructure : public MVKCommand { MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; uint32_t _infoCount; - VkAccelerationStructureBuildGeometryInfoKHR _geometryInfos; + VkAccelerationStructureBuildGeometryInfoKHR* _geometryInfos; VkAccelerationStructureBuildRangeInfoKHR const* _buildRangeInfos; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 4e1787e45..cce837931 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -30,8 +30,10 @@ uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { + VkAccelerationStructureBuildGeometryInfoKHR geoInfo = *pInfos; + _infoCount = infoCount; - _geometryInfos = *pInfos; + _geometryInfos = &geoInfo; _buildRangeInfos = *ppBuildRangeInfos; return VK_SUCCESS; @@ -40,58 +42,58 @@ void MVKCmdBuildAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); - MVKAccelerationStructure* mvkSrcAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos.srcAccelerationStructure; - MVKAccelerationStructure* mvkDstAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos.dstAccelerationStructure; - - id srcAccelerationStructure = (id)mvkSrcAccelerationStructure->getMTLAccelerationStructure(); - id dstAccelerationStructure = (id)mvkDstAccelerationStructure->getMTLAccelerationStructure(); - - if(_geometryInfos.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && !mvkDstAccelerationStructure->getAllowUpdate()) - { - return; - } - - MVKDevice* mvkDvc = cmdEncoder->getDevice(); - MVKBuffer* mvkBuffer = mvkDvc->getBufferAtAddress(_geometryInfos.scratchData.deviceAddress); - - id scratchBuffer = mvkBuffer->getMTLBuffer(); - NSInteger scratchBufferOffset = mvkBuffer->getMTLBufferOffset(); - - if(_geometryInfos.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) + for(int i = 0; i < _infoCount; i++) { - MTLAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLAccelerationStructureDescriptor new]; + MVKAccelerationStructure* mvkSrcAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos[i].srcAccelerationStructure; + MVKAccelerationStructure* mvkDstAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos[i].dstAccelerationStructure; - if(mvkIsAnyFlagEnabled(_geometryInfos.flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - mvkDstAccelerationStructure->setAllowUpdate(true); - }else if(mvkIsAnyFlagEnabled(_geometryInfos.flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + id srcAccelerationStructure = (id)mvkSrcAccelerationStructure->getMTLAccelerationStructure(); + id dstAccelerationStructure = (id)mvkDstAccelerationStructure->getMTLAccelerationStructure(); + + if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && !mvkDstAccelerationStructure->getAllowUpdate()) + { + continue; } - [accStructEncoder buildAccelerationStructure:dstAccelerationStructure - descriptor:accStructBuildDescriptor - scratchBuffer:scratchBuffer - scratchBufferOffset:scratchBufferOffset]; - return; - } - - if(_geometryInfos.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) - { - MTLAccelerationStructureDescriptor* accStructRefitDescriptor = [MTLAccelerationStructureDescriptor new]; + MVKDevice* mvkDvc = cmdEncoder->getDevice(); + MVKBuffer* mvkBuffer = mvkDvc->getBufferAtAddress(_geometryInfos[i].scratchData.deviceAddress); - if(mvkIsAnyFlagEnabled(_geometryInfos.flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructRefitDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - } + id scratchBuffer = mvkBuffer->getMTLBuffer(); + NSInteger scratchBufferOffset = mvkBuffer->getMTLBufferOffset(); - [accStructEncoder refitAccelerationStructure:srcAccelerationStructure - descriptor:accStructRefitDescriptor - destination:dstAccelerationStructure - scratchBuffer:scratchBuffer - scratchBufferOffset:scratchBufferOffset]; + if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) + { + MTLAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + mvkDstAccelerationStructure->setAllowUpdate(true); + }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + + [accStructEncoder buildAccelerationStructure:dstAccelerationStructure + descriptor:accStructBuildDescriptor + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; + } - return; + if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) + { + MTLAccelerationStructureDescriptor* accStructRefitDescriptor = [MTLAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructRefitDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + } + + [accStructEncoder refitAccelerationStructure:srcAccelerationStructure + descriptor:accStructRefitDescriptor + destination:dstAccelerationStructure + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; + } } return; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 823711648..3920729eb 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -56,20 +56,35 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { /** Gets the required build sizes for acceleration structure and scratch buffer*/ static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(); - /** Gets the device address of the acceleration structure*/ - uint64_t getDeviceAddress(); + /** Gets the actual size of the acceleration structure*/ + uint64_t getMTLSize(); /** Used when building the acceleration structure, to mark whether or not an acceleration structure can be updated*/ void setAllowUpdate(bool value) { _allowUpdate = value; } /** Checks if this acceleration structure is allowed to be updated*/ bool getAllowUpdate() { return _allowUpdate; } - + + /** Only to be called by the MVKCmdBuildAccelerationStructure, and sets the build status*/ + void setBuildStatus(bool value) { _built = value; } + + /** Checks if this acceleration structure has been built*/ + bool getBuildStatus() { return _built; } + + /** Sets the address of the acceleration structure, only to be used by MVKDevice*/ + void setDeviceAddress(uint64_t address) { _address = address; } + + /** Gets the address of the acceleration structure*/ + uint64_t getDeviceAddress() { return _address; } #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} + + void destroy() override; protected: void propagateDebugName() override {} id _accelerationStructure; bool _allowUpdate = false; + bool _built = false; + uint64_t _address; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 3e462a00f..2068dfd65 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -43,3 +43,9 @@ { return 0; } + +uint64_t MVKAccelerationStructure::getMTLSize() +{ + if(!_built) { return 0; } + return _accelerationStructure.size; +} diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 946a883f6..abe850f68 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -458,6 +458,8 @@ typedef struct MVKMTLBlitEncoder { id mtlCmdBuffer = nil; } MVKMTLBlitEncoder; +typedef std::pair MVKBufferAddressRange; + /** Represents a Vulkan logical GPU device, associated with a physical device. */ class MVKDevice : public MVKDispatchableVulkanAPIObject { @@ -699,6 +701,12 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { /** Removes the specified timeline semaphore. */ void removeTimelineSemaphore(MVKTimelineSemaphore* sem4, uint64_t value); + + /** Adds the specified acceleration structure to the address map, so it can be referenced else where*/ + MVKAccelerationStructure* addAccelerationStructure(MVKAccelerationStructure* accStruct); + + /** Removes the specified accelerations from the address map */ + void removeAccelerationStructure(MVKAccelerationStructure* accStruct); /** Applies the specified global memory barrier to all resource issued by this device. */ void applyMemoryBarrier(VkPipelineStageFlags srcStageMask, @@ -920,7 +928,9 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { MVKSmallVector, kMVKQueueFamilyCount> _queuesByQueueFamilyIndex; MVKSmallVector _resources; MVKSmallVector _gpuAddressableBuffers; - std::unordered_map, MVKBuffer*, MVKHash_uint64_t_pair> _gpuBufferAddressMap; + std::unordered_map _gpuBufferAddressMap; + std::unordered_map _gpuAccStructAddressMap; + uint64_t _nextValidAccStructureAddress; MVKSmallVector _privateDataSlots; MVKSmallVector _privateDataSlotsAvailability; MVKSmallVector _awaitingSemaphores; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index f3cc2bc1e..343dfaba1 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3645,7 +3645,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope { lock_guard lock(_rezLock); - std::unordered_map, MVKBuffer*>::iterator it; + std::unordered_map::iterator it; // Super inefficent but this can be fixed in the future for(it = _gpuBufferAddressMap.begin(); it != _gpuBufferAddressMap.end(); it++) { @@ -3932,12 +3932,14 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope MVKAccelerationStructure* MVKDevice::createAccelerationStructure(const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator) { - return new MVKAccelerationStructure(this); + return addAccelerationStructure(new MVKAccelerationStructure(this)); } void MVKDevice::destroyAccelerationStructure(MVKAccelerationStructure* mvkAccStruct, const VkAllocationCallbacks* pAllocator) { - if(mvkAccStruct) { mvkAccStruct->destroy(); } + if(!mvkAccStruct) { return; } + removeAccelerationStructure(mvkAccStruct); + mvkAccStruct->destroy();k } template @@ -4169,8 +4171,8 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { _gpuAddressableBuffers.push_back(mvkBuff); - std::pair bdaRange = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff->getMTLBufferGPUAddress() + (uint64_t)mvkBuff->getByteCount()); - std::pair, MVKBuffer*> _bufferAddressPair = std::make_pair(bdaRange, mvkBuff); + MVKBufferAddressRange bdaRange = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff->getMTLBufferGPUAddress() + (uint64_t)mvkBuff->getByteCount()); + std::pair _bufferAddressPair = std::make_pair(bdaRange, mvkBuff); _gpuBufferAddressMap.insert(_bufferAddressPair); } return mvkBuff; @@ -4183,7 +4185,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope mvkRemoveFirstOccurance(_resources, mvkBuff); if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { mvkRemoveFirstOccurance(_gpuAddressableBuffers, mvkBuff); - std::pair bdaRange = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff->getMTLBufferGPUAddress() + (uint64_t)mvkBuff->getByteCount()); + MVKBufferAddressRange bdaRange = std::make_pair(mvkBuff->getMTLBufferGPUAddress(), mvkBuff->getMTLBufferGPUAddress() + (uint64_t)mvkBuff->getByteCount()); auto bufferAddressIt = _gpuBufferAddressMap.find(bdaRange); _gpuBufferAddressMap.erase(bufferAddressIt); } @@ -4240,6 +4242,28 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope mvkRemoveFirstOccurance(_awaitingTimelineSem4s, make_pair(sem4, value)); } +MVKAccelerationStructure* MVKDevice::addAccelerationStructure(MVKAccelerationStructure* accStruct) { + std::pair accStructMemoryPair = std::make_pair(_nextValidAccStructureAddress, accStruct); + _gpuAccStructAddressMap.insert(accStructMemoryPair); + accStruct->setDeviceAddress(_nextValidAccStructureAddress); + _nextValidAccStructureAddress += accStruct->getMTLSize(); + return accStruct; +} + +void MVKDevice::removeAccelerationStructure(MVKAccelerationStructure* accStruct) { + std::unordered_map::iterator accStructIt = _gpuAccStructAddressMap.find(accStruct->getDeviceAddress()); + uint64_t addressOffset = accStructIt->second->getMTLSize(); + _gpuAccStructAddressMap.erase(accStructIt); + + // This can lead to fragmentation over time, so I'll just push all keys after this back + for(auto it = accStructIt; it != _gpuAccStructAddressMap.end(); it++) + { + auto extractedAccStruct = _gpuAccStructAddressMap.extract(it->first); + extractedAccStruct.key() = it->first - addressOffset; + _gpuAccStructAddressMap.insert(std::move(extractedAccStruct)); + } +} + void MVKDevice::applyMemoryBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, MVKPipelineBarrier& barrier, From 6c7aa5d71db06de4f98e1c73241c19bc2602b9e0 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Fri, 14 Jul 2023 10:21:14 -0400 Subject: [PATCH 14/32] Added Get Acceleration structure function Simply added the vulkan function GetAccelerationStructureDeviceAddress, next I'll be adding 2 more copy commands. --- .../MoltenVK/GPUObjects/MVKAccelerationStructure.h | 10 +++++++--- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 2 +- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 13 +++++++------ 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 3920729eb..9511bc0b7 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -28,7 +28,7 @@ vkCreateAccelerationStructureKHR - DONE vkDestroyAccelerationStructureKHR - DONE vkGetAccelerationStructureBuildSizesKHR - DONE - vkGetAccelerationStructureDeviceAddressKHR + vkGetAccelerationStructureDeviceAddressKHR - DONE vkGetDeviceAccelerationStructureCompatibilityKHR - DONE vkWriteAccelerationStructuresPropertiesKHR */ @@ -40,6 +40,7 @@ #import #import +#pragma mark - #pragma mark MVKAccelerationStructure class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { @@ -58,7 +59,9 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { /** Gets the actual size of the acceleration structure*/ uint64_t getMTLSize(); - + +#pragma mark - +#pragma mark Getters and Setters /** Used when building the acceleration structure, to mark whether or not an acceleration structure can be updated*/ void setAllowUpdate(bool value) { _allowUpdate = value; } @@ -76,6 +79,7 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { /** Gets the address of the acceleration structure*/ uint64_t getDeviceAddress() { return _address; } +#pragma mark - #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} @@ -86,5 +90,5 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { id _accelerationStructure; bool _allowUpdate = false; bool _built = false; - uint64_t _address; + uint64_t _address = 0; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 343dfaba1..042ae997b 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3939,7 +3939,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope const VkAllocationCallbacks* pAllocator) { if(!mvkAccStruct) { return; } removeAccelerationStructure(mvkAccStruct); - mvkAccStruct->destroy();k + mvkAccStruct->destroy(); } template diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 2926aafc1..b8f6e450e 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2639,16 +2639,17 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkCreateAccelerationStructureKHR( return rslt; } -MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyAccelerationStructureKHR( - VkDevice device, - VkAccelerationStructureKHR accelerationStructure, - const VkAllocationCallbacks* pAllocator) { +MVK_PUBLIC_VULKAN_SYMBOL VkDeviceAddress vkGetAccelerationStructureDeviceAddressKHR( + VkDevice device, + const VkAccelerationStructureDeviceAddressInfoKHR* pInfo) { MVKTraceVulkanCallStart(); MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); - MVKAccelerationStructure* mvkAccelerationStructure = (MVKAccelerationStructure*)accelerationStructure; - mvkDev->destroyAccelerationStructure(mvkAccelerationStructure, pAllocator); + MVKAccelerationStructure* mvkAccelerationStructure = (MVKAccelerationStructure*)pInfo->accelerationStructure; + uint64_t result = mvkAccelerationStructure->getDeviceAddress(); MVKTraceVulkanCallEnd(); + + return (VkDeviceAddress)result; } MVK_PUBLIC_VULKAN_SYMBOL void vkGetAccelerationStructureBuildSizesKHR( From be2aca6401c0234f1f11a1d801f150a1b15764f5 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Fri, 14 Jul 2023 14:09:29 -0400 Subject: [PATCH 15/32] Copy Acceleration Structure to Memory This commit adds a command which allows for copying of acceleration structures to another memory address, which contains an acceleration structure. This commit also adds all needed functions into MVKInstance.mm so that they can be used. --- .../Commands/MVKCmdAccelerationStructure.h | 21 +++++++++++ .../Commands/MVKCmdAccelerationStructure.mm | 30 ++++++++++++++- .../MoltenVK/Commands/MVKCommandTypePools.def | 3 +- .../GPUObjects/MVKAccelerationStructure.mm | 10 ++--- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 4 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 8 ++++ MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 6 +++ MoltenVK/MoltenVK/Vulkan/vulkan.mm | 37 +++++++++++++++---- 8 files changed, 103 insertions(+), 16 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index c15075075..89ac45d4d 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -18,6 +18,7 @@ #pragma once +#include "MVKDevice.h" #include "MVKCommand.h" #import @@ -61,3 +62,23 @@ class MVKCmdCopyAccelerationStructure : public MVKCommand { id _srcAccelerationStructure; id _dstAccelerationStructure; }; + +#pragma mark - +#pragma mark MVKCmdCopyAccelerationStructureToMemory + +class MVKCmdCopyAccelerationStructureToMemory : public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + VkAccelerationStructureKHR srcAccelerationStructure, + uint64_t dstAddress); + + void encode(MVKCommandEncoder* cmdEncoder) override; +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + uint64_t _dstAddress; + MVKDevice* _mvkDevice; + id _srcAccelerationStructure; + id _dstAccelerationStructure; +}; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index cce837931..2dbcfed60 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -103,8 +103,8 @@ #pragma mark MVKCmdCopyAccelerationStructure VkResult MVKCmdCopyAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, - VkAccelerationStructureKHR srcAccelerationStructure, - VkAccelerationStructureKHR dstAccelerationStructure) { + VkAccelerationStructureKHR srcAccelerationStructure, + VkAccelerationStructureKHR dstAccelerationStructure) { MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; @@ -121,3 +121,29 @@ copyAccelerationStructure:_srcAccelerationStructure toAccelerationStructure:_dstAccelerationStructure]; } + +#pragma mark - +#pragma mark MVKCmdCopyAccelerationStructureToMemory + +VkResult MVKCmdCopyAccelerationStructureToMemory::setContent(MVKCommandBuffer* cmdBuff, + VkAccelerationStructureKHR srcAccelerationStructure, + uint64_t dstAddress) { + + MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; + _mvkDevice = mvkSrcAccStruct->getDevice(); + _dstAddress = dstAddress; + + MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)_mvkDevice->getAccelerationStructureAtAddress(_dstAddress); + + _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + _dstAccelerationStructure = mvkDstAccStruct->getMTLAccelerationStructure(); + return VK_SUCCESS; +} + +void MVKCmdCopyAccelerationStructureToMemory::encode(MVKCommandEncoder* cmdEncoder) { + id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + + [accStructEncoder + copyAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; +} diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index a9c56eea1..1387d9b2e 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -127,7 +127,8 @@ MVK_CMD_TYPE_POOLS_FROM_THRESHOLD(WaitEvents, 1) MVK_CMD_TYPE_POOL(SetEvent) MVK_CMD_TYPE_POOL(ResetEvent) MVK_CMD_TYPE_POOL(BuildAccelerationStructure) -MVK_CMD_TYPE_POOL_LAST(CopyAccelerationStructure) +MVK_CMD_TYPE_POOL(CopyAccelerationStructure) +MVK_CMD_TYPE_POOL_LAST(CopyAccelerationStructureToMemory) #undef MVK_CMD_TYPE_POOL #undef MVK_CMD_TYPE_POOL_LAST diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 2068dfd65..f68e635d7 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -39,13 +39,13 @@ return vkBuildSizes; } -uint64_t MVKAccelerationStructure::getDeviceAddress() -{ - return 0; -} - uint64_t MVKAccelerationStructure::getMTLSize() { if(!_built) { return 0; } return _accelerationStructure.size; } + +void MVKAccelerationStructure::destroy() +{ + // TODO +} diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index abe850f68..f562f28cc 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -531,6 +531,8 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { /** Returns a pointer to the buffer at the provided address*/ MVKBuffer* getBufferAtAddress(uint64_t address); // Unsure where to place + MVKAccelerationStructure* getAccelerationStructureAtAddress(uint64_t address); + /** Returns whether or not the device supports acceleration structures*/ VkAccelerationStructureCompatibilityKHR getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo); @@ -707,7 +709,7 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { /** Removes the specified accelerations from the address map */ void removeAccelerationStructure(MVKAccelerationStructure* accStruct); - + /** Applies the specified global memory barrier to all resource issued by this device. */ void applyMemoryBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 042ae997b..8b8a73c21 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3663,6 +3663,14 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope return it->second; } +MVKAccelerationStructure* MVKDevice::getAccelerationStructureAtAddress(uint64_t address) +{ + std::unordered_map::iterator accStructIt = _gpuAccStructAddressMap.find(address); + if(accStructIt == _gpuAccStructAddressMap.end()) { return nullptr; } + + return accStructIt->second; +} + VkAccelerationStructureCompatibilityKHR MVKDevice::getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo) { VkAccelerationStructureCompatibilityKHR compat = VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index 8653b7c0f..ab14778b9 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -720,6 +720,12 @@ // Device extension functions. ADD_DVC_EXT_ENTRY_POINT(vkCreateAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkDestroyAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkGetAccelerationStructureDeviceAddressKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkGetAccelerationStructureBuildSizesKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkGetDeviceAccelerationStructureCompatibilityKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkCmdBuildAccelerationStructuresKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyAccelerationStructureToMemoryKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkCreateDeferredOperationKHR, KHR_DEFERRED_HOST_OPERATIONS); ADD_DVC_EXT_ENTRY_POINT(vkDeferredOperationJoinKHR, KHR_DEFERRED_HOST_OPERATIONS); diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index b8f6e450e..0d56320e8 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2639,12 +2639,24 @@ MVK_PUBLIC_VULKAN_SYMBOL VkResult vkCreateAccelerationStructureKHR( return rslt; } +MVK_PUBLIC_VULKAN_SYMBOL void vkDestroyAccelerationStructureKHR( + VkDevice device, + VkAccelerationStructureKHR accelerationStructure, + const VkAllocationCallbacks* pAllocator) { + + MVKTraceVulkanCallStart(); + MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); + MVKAccelerationStructure* mvkAccelerationStructure = (MVKAccelerationStructure*)accelerationStructure; + mvkDev->destroyAccelerationStructure(mvkAccelerationStructure, pAllocator); + MVKTraceVulkanCallEnd(); +} + + MVK_PUBLIC_VULKAN_SYMBOL VkDeviceAddress vkGetAccelerationStructureDeviceAddressKHR( VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo) { MVKTraceVulkanCallStart(); - MVKDevice* mvkDev = MVKDevice::getMVKDevice(device); MVKAccelerationStructure* mvkAccelerationStructure = (MVKAccelerationStructure*)pInfo->accelerationStructure; uint64_t result = mvkAccelerationStructure->getDeviceAddress(); MVKTraceVulkanCallEnd(); @@ -2665,6 +2677,17 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkGetAccelerationStructureBuildSizesKHR( MVKTraceVulkanCallEnd(); } +MVK_PUBLIC_VULKAN_SYMBOL void vkGetDeviceAccelerationStructureCompatibilityKHR( + VkDevice device, + const VkAccelerationStructureVersionInfoKHR* pVersionInfo, + VkAccelerationStructureCompatibilityKHR* pCompatibility) { + + MVKTraceVulkanCallStart(); + MVKDevice* mvkDev = (MVKDevice*)device; + *pCompatibility = mvkDev->getAccelerationStructureCompatibility(pVersionInfo); + MVKTraceVulkanCallEnd(); +} + MVK_PUBLIC_VULKAN_SYMBOL void vkCmdBuildAccelerationStructuresKHR( VkCommandBuffer commandBuffer, uint32_t infoCount, @@ -2686,17 +2709,17 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyAccelerationStructureKHR( MVKTraceVulkanCallEnd(); } -MVK_PUBLIC_VULKAN_SYMBOL void vkGetDeviceAccelerationStructureCompatibilityKHR( - VkDevice device, - const VkAccelerationStructureVersionInfoKHR* pVersionInfo, - VkAccelerationStructureCompatibilityKHR* pCompatibility) { +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyAccelerationStructureToMemoryKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo) { MVKTraceVulkanCallStart(); - MVKDevice* mvkDev = (MVKDevice*)device; - *pCompatibility = mvkDev->getAccelerationStructureCompatibility(pVersionInfo); + // Currently were ignoring the copy mode + MVKAddCmd(CopyAccelerationStructureToMemory, commandBuffer, pInfo->src, pInfo->dst.deviceAddress); MVKTraceVulkanCallEnd(); } + #pragma mark - #pragma mark VK_KHR_bind_memory2 extension From 96f89a5bd6104924096377545082bc0504556d69 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Fri, 14 Jul 2023 18:45:17 -0400 Subject: [PATCH 16/32] Code Cleanup and Copy modes for Acceleration Structures This commit cleans up the code, and now accepts copy modes for acceleration structures. However, only 2 copy modes are supported which are clone, and compact. --- .../Commands/MVKCmdAccelerationStructure.h | 12 ++++-- .../Commands/MVKCmdAccelerationStructure.mm | 42 ++++++++++++++----- MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h | 2 - MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 3 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 3 ++ MoltenVK/MoltenVK/Vulkan/vulkan.mm | 6 +-- 6 files changed, 47 insertions(+), 21 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 89ac45d4d..2ddeda75a 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -53,7 +53,8 @@ class MVKCmdCopyAccelerationStructure : public MVKCommand { public: VkResult setContent(MVKCommandBuffer* cmdBuff, VkAccelerationStructureKHR srcAccelerationStructure, - VkAccelerationStructureKHR dstAccelerationStructure); + VkAccelerationStructureKHR dstAccelerationStructure, + VkCopyAccelerationStructureModeKHR copyMode); void encode(MVKCommandEncoder* cmdEncoder) override; protected: @@ -61,6 +62,7 @@ class MVKCmdCopyAccelerationStructure : public MVKCommand { id _srcAccelerationStructure; id _dstAccelerationStructure; + VkCopyAccelerationStructureModeKHR _copyMode; }; #pragma mark - @@ -71,14 +73,16 @@ class MVKCmdCopyAccelerationStructureToMemory : public MVKCommand { public: VkResult setContent(MVKCommandBuffer* cmdBuff, VkAccelerationStructureKHR srcAccelerationStructure, - uint64_t dstAddress); + uint64_t dstAddress, + VkCopyAccelerationStructureModeKHR copyMode); void encode(MVKCommandEncoder* cmdEncoder) override; protected: MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - uint64_t _dstAddress; - MVKDevice* _mvkDevice; id _srcAccelerationStructure; id _dstAccelerationStructure; + uint64_t _dstAddress; + MVKDevice* _mvkDevice; + VkCopyAccelerationStructureModeKHR _copyMode; }; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 2dbcfed60..dd452e8bf 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -102,36 +102,49 @@ #pragma mark - #pragma mark MVKCmdCopyAccelerationStructure -VkResult MVKCmdCopyAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, - VkAccelerationStructureKHR srcAccelerationStructure, - VkAccelerationStructureKHR dstAccelerationStructure) { +VkResult MVKCmdCopyAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, + VkAccelerationStructureKHR srcAccelerationStructure, + VkAccelerationStructureKHR dstAccelerationStructure, + VkCopyAccelerationStructureModeKHR copyMode) { MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); _dstAccelerationStructure = mvkDstAccStruct->getMTLAccelerationStructure(); + _copyMode = copyMode; return VK_SUCCESS; } void MVKCmdCopyAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + if(_copyMode == VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR) + { + [accStructEncoder + copyAndCompactAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; + + return; + } + [accStructEncoder - copyAccelerationStructure:_srcAccelerationStructure - toAccelerationStructure:_dstAccelerationStructure]; + copyAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; } #pragma mark - #pragma mark MVKCmdCopyAccelerationStructureToMemory -VkResult MVKCmdCopyAccelerationStructureToMemory::setContent(MVKCommandBuffer* cmdBuff, - VkAccelerationStructureKHR srcAccelerationStructure, - uint64_t dstAddress) { +VkResult MVKCmdCopyAccelerationStructureToMemory::setContent(MVKCommandBuffer* cmdBuff, + VkAccelerationStructureKHR srcAccelerationStructure, + uint64_t dstAddress, + VkCopyAccelerationStructureModeKHR copyMode) { MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; _mvkDevice = mvkSrcAccStruct->getDevice(); _dstAddress = dstAddress; + _copyMode = copyMode; MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)_mvkDevice->getAccelerationStructureAtAddress(_dstAddress); @@ -143,7 +156,16 @@ void MVKCmdCopyAccelerationStructureToMemory::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + if(_copyMode == VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR) + { + [accStructEncoder + copyAndCompactAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; + + return; + } + [accStructEncoder - copyAccelerationStructure:_srcAccelerationStructure - toAccelerationStructure:_dstAccelerationStructure]; + copyAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h index 3fc5b0be2..2e338ce7a 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h @@ -21,8 +21,6 @@ #include "MVKResource.h" #include "MVKCommandBuffer.h" -#include "MVKMap.h" - class MVKCommandEncoder; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index f562f28cc..18bd1490c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -529,8 +529,9 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { uint64_t* pMaxDeviation); /** Returns a pointer to the buffer at the provided address*/ - MVKBuffer* getBufferAtAddress(uint64_t address); // Unsure where to place + MVKBuffer* getBufferAtAddress(uint64_t address); // Unsure where to place within the file + /** Returns a pointer to the acceleration structure at the provided address*/ MVKAccelerationStructure* getAccelerationStructureAtAddress(uint64_t address); /** Returns whether or not the device supports acceleration structures*/ diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 8b8a73c21..b60476180 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -574,6 +574,7 @@ accelerationStructureProps->maxGeometryCount = pow(2, 24); accelerationStructureProps->maxInstanceCount = pow(2, 24); accelerationStructureProps->maxPrimitiveCount = pow(2, 28); + accelerationStructureProps->minAccelerationStructureScratchOffsetAlignment = _metalFeatures.mtlBufferAlignment; // Other properties have not been figured out quite yet break; } @@ -4264,11 +4265,13 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope _gpuAccStructAddressMap.erase(accStructIt); // This can lead to fragmentation over time, so I'll just push all keys after this back + // This, however is also another performance issue for(auto it = accStructIt; it != _gpuAccStructAddressMap.end(); it++) { auto extractedAccStruct = _gpuAccStructAddressMap.extract(it->first); extractedAccStruct.key() = it->first - addressOffset; _gpuAccStructAddressMap.insert(std::move(extractedAccStruct)); + _gpuAccStructAddressMap.erase(it->first); } } diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 0d56320e8..f42994043 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2704,8 +2704,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyAccelerationStructureKHR( const VkCopyAccelerationStructureInfoKHR* pInfo) { MVKTraceVulkanCallStart(); - // Currently were ignoring the copy mode - MVKAddCmd(CopyAccelerationStructure, commandBuffer, pInfo->src, pInfo->dst); + MVKAddCmd(CopyAccelerationStructure, commandBuffer, pInfo->src, pInfo->dst, pInfo->mode); MVKTraceVulkanCallEnd(); } @@ -2714,8 +2713,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyAccelerationStructureToMemoryKHR( const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo) { MVKTraceVulkanCallStart(); - // Currently were ignoring the copy mode - MVKAddCmd(CopyAccelerationStructureToMemory, commandBuffer, pInfo->src, pInfo->dst.deviceAddress); + MVKAddCmd(CopyAccelerationStructureToMemory, commandBuffer, pInfo->src, pInfo->dst.deviceAddress, pInfo->mode); MVKTraceVulkanCallEnd(); } From 94c62f5e27091e409d83254f63c22119a089e03d Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Sat, 15 Jul 2023 11:36:50 -0400 Subject: [PATCH 17/32] Copy Memory to Acceleration Structure This commit adds the last copy command, that being copy memory to acceleration structure. This command is almost the same as the other copy commands, and I'm getting close to finishing up this PR. --- .../Commands/MVKCmdAccelerationStructure.h | 24 +++++++++++++ .../Commands/MVKCmdAccelerationStructure.mm | 36 +++++++++++++++++++ .../MoltenVK/Commands/MVKCommandTypePools.def | 3 +- .../GPUObjects/MVKAccelerationStructure.h | 4 +-- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 9 +++++ 7 files changed, 75 insertions(+), 4 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 2ddeda75a..8ebfd5218 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -86,3 +86,27 @@ class MVKCmdCopyAccelerationStructureToMemory : public MVKCommand { MVKDevice* _mvkDevice; VkCopyAccelerationStructureModeKHR _copyMode; }; + +#pragma mark - +#pragma mark MVKCmdCopyMemoryToAccelerationStructure + +class MVKCmdCopyMemoryToAccelerationStructure: public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + uint64_t srcAddress, + VkAccelerationStructureKHR dstAccelerationStructure, + VkCopyAccelerationStructureModeKHR copyMode); + + void encode(MVKCommandEncoder* cmdEncoder) override; +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + id _srcAccelerationStructure; + id _dstAccelerationStructure; + uint64_t _srcAddress; + MVKDevice* _mvkDevice; + VkCopyAccelerationStructureModeKHR _copyMode; +}; + + diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index dd452e8bf..d501c1e9a 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -169,3 +169,39 @@ copyAccelerationStructure:_srcAccelerationStructure toAccelerationStructure:_dstAccelerationStructure]; } + +#pragma mark - +#pragma mark MVKCmdCopyMemoryToAccelerationStructure + +VkResult MVKCmdCopyMemoryToAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, + uint64_t srcAddress, + VkAccelerationStructureKHR dstAccelerationStructure, + VkCopyAccelerationStructureModeKHR copyMode) { + MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; + _mvkDevice = mvkDstAccStruct->getDevice(); + _srcAddress = srcAddress; + _copyMode = copyMode; + + MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)_mvkDevice->getAccelerationStructureAtAddress(_srcAddress); + + _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + _dstAccelerationStructure = mvkDstAccStruct->getMTLAccelerationStructure(); + return VK_SUCCESS; +} + +void MVKCmdCopyMemoryToAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { + id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + + if(_copyMode == VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR) + { + [accStructEncoder + copyAndCompactAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; + + return; + } + + [accStructEncoder + copyAccelerationStructure:_srcAccelerationStructure + toAccelerationStructure:_dstAccelerationStructure]; +} diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index 1387d9b2e..002b34a44 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -128,7 +128,8 @@ MVK_CMD_TYPE_POOL(SetEvent) MVK_CMD_TYPE_POOL(ResetEvent) MVK_CMD_TYPE_POOL(BuildAccelerationStructure) MVK_CMD_TYPE_POOL(CopyAccelerationStructure) -MVK_CMD_TYPE_POOL_LAST(CopyAccelerationStructureToMemory) +MVK_CMD_TYPE_POOL(CopyAccelerationStructureToMemory) +MVK_CMD_TYPE_POOL_LAST(CopyMemoryToAccelerationStructure) #undef MVK_CMD_TYPE_POOL #undef MVK_CMD_TYPE_POOL_LAST diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 9511bc0b7..5f3cdc41a 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -22,8 +22,8 @@ vkCmdBuildAccelerationStructuresIndirectKHR vkCmdBuildAccelerationStructuresKHR - DONE vkCmdCopyAccelerationStructureKHR - DONE - vkCmdCopyAccelerationStructureToMemoryKHR - vkCmdCopyMemoryToAccelerationStructureKHR + vkCmdCopyAccelerationStructureToMemoryKHR - DONE + vkCmdCopyMemoryToAccelerationStructureKHR - DONE vkCmdWriteAccelerationStructuresPropertiesKHR vkCreateAccelerationStructureKHR - DONE vkDestroyAccelerationStructureKHR - DONE diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index b60476180..54b64cbcf 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -574,7 +574,7 @@ accelerationStructureProps->maxGeometryCount = pow(2, 24); accelerationStructureProps->maxInstanceCount = pow(2, 24); accelerationStructureProps->maxPrimitiveCount = pow(2, 28); - accelerationStructureProps->minAccelerationStructureScratchOffsetAlignment = _metalFeatures.mtlBufferAlignment; + accelerationStructureProps->minAccelerationStructureScratchOffsetAlignment = (uint32_t)_metalFeatures.mtlBufferAlignment; // Other properties have not been figured out quite yet break; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index ab14778b9..4f0846d39 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -726,6 +726,7 @@ ADD_DVC_EXT_ENTRY_POINT(vkCmdBuildAccelerationStructuresKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyAccelerationStructureToMemoryKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyMemoryToAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkCreateDeferredOperationKHR, KHR_DEFERRED_HOST_OPERATIONS); ADD_DVC_EXT_ENTRY_POINT(vkDeferredOperationJoinKHR, KHR_DEFERRED_HOST_OPERATIONS); diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index f42994043..5132827ef 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2717,6 +2717,15 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyAccelerationStructureToMemoryKHR( MVKTraceVulkanCallEnd(); } +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyMemoryToAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(CopyMemoryToAccelerationStructure, commandBuffer, pInfo->src.deviceAddress, pInfo->dst, pInfo->mode); + MVKTraceVulkanCallEnd(); +} + #pragma mark - #pragma mark VK_KHR_bind_memory2 extension From df8d8b391ae9c7d86297ca178810a34e044570f3 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Mon, 17 Jul 2023 15:43:14 -0400 Subject: [PATCH 18/32] Fixed Copy Memory to Acceleration Structure This commit fixes a glaring issue with copying accelerations structures to memory. Previously, I would copy the acceleration structure to another acceleration structure, however the proper thing to do was to copy a buffer to an acceleration structure. This however has not fixed copy acceleration structure to memory. --- .../Commands/MVKCmdAccelerationStructure.h | 7 ++- .../Commands/MVKCmdAccelerationStructure.mm | 45 ++++++++----------- 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 8ebfd5218..db943199f 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -62,6 +62,7 @@ class MVKCmdCopyAccelerationStructure : public MVKCommand { id _srcAccelerationStructure; id _dstAccelerationStructure; + VkCopyAccelerationStructureModeKHR _copyMode; }; @@ -81,7 +82,8 @@ class MVKCmdCopyAccelerationStructureToMemory : public MVKCommand { MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; id _srcAccelerationStructure; - id _dstAccelerationStructure; + MVKBuffer* _dstBuffer; + uint64_t _dstAddress; MVKDevice* _mvkDevice; VkCopyAccelerationStructureModeKHR _copyMode; @@ -102,8 +104,9 @@ class MVKCmdCopyMemoryToAccelerationStructure: public MVKCommand { protected: MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - id _srcAccelerationStructure; + MVKBuffer* _srcBuffer; id _dstAccelerationStructure; + uint64_t _srcAddress; MVKDevice* _mvkDevice; VkCopyAccelerationStructureModeKHR _copyMode; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index d501c1e9a..8a749d7e0 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -140,34 +140,23 @@ VkAccelerationStructureKHR srcAccelerationStructure, uint64_t dstAddress, VkCopyAccelerationStructureModeKHR copyMode) { - - MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; - _mvkDevice = mvkSrcAccStruct->getDevice(); _dstAddress = dstAddress; _copyMode = copyMode; - MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)_mvkDevice->getAccelerationStructureAtAddress(_dstAddress); - + MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); - _dstAccelerationStructure = mvkDstAccStruct->getMTLAccelerationStructure(); + + _dstBuffer = _mvkDevice->getBufferAtAddress(_dstAddress); return VK_SUCCESS; } void MVKCmdCopyAccelerationStructureToMemory::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + _mvkDevice = cmdEncoder->getDevice(); - if(_copyMode == VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR) - { - [accStructEncoder - copyAndCompactAccelerationStructure:_srcAccelerationStructure - toAccelerationStructure:_dstAccelerationStructure]; - + if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR){ return; } - - [accStructEncoder - copyAccelerationStructure:_srcAccelerationStructure - toAccelerationStructure:_dstAccelerationStructure]; } #pragma mark - @@ -177,31 +166,33 @@ uint64_t srcAddress, VkAccelerationStructureKHR dstAccelerationStructure, VkCopyAccelerationStructureModeKHR copyMode) { - MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; - _mvkDevice = mvkDstAccStruct->getDevice(); _srcAddress = srcAddress; _copyMode = copyMode; - MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)_mvkDevice->getAccelerationStructureAtAddress(_srcAddress); + _srcBuffer = _mvkDevice->getBufferAtAddress(_srcAddress); - _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; _dstAccelerationStructure = mvkDstAccStruct->getMTLAccelerationStructure(); return VK_SUCCESS; } void MVKCmdCopyMemoryToAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + _mvkDevice = cmdEncoder->getDevice(); - if(_copyMode == VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR) - { - [accStructEncoder - copyAndCompactAccelerationStructure:_srcAccelerationStructure - toAccelerationStructure:_dstAccelerationStructure]; - + if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR){ return; } + void* serializedAccStruct = _srcBuffer->getHostMemoryAddress(); + if(!serializedAccStruct){ + return; // Should I remove this? For this to work, the memory can't be device only, but the spec does not seem to restrict this + } + + MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)serializedAccStruct; + id srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + [accStructEncoder - copyAccelerationStructure:_srcAccelerationStructure + copyAccelerationStructure:srcAccelerationStructure toAccelerationStructure:_dstAccelerationStructure]; } From 89a92fb9a8be655215a4a88c6fed552d3b5af03c Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Tue, 18 Jul 2023 09:50:30 -0400 Subject: [PATCH 19/32] Fixed Copy Acceleration Structure to Memory This commit quickly fixes copying acceleration structures to memory, however I'm not sure if my implementation is right. --- MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 8a749d7e0..df9a4cd98 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -154,9 +154,11 @@ id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); _mvkDevice = cmdEncoder->getDevice(); - if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR){ + if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR || !_dstBuffer->getDeviceMemory()->isMemoryHostAccessible()){ return; } + + memcpy(_dstBuffer->getDeviceMemory()->getHostMemoryAddress(), (void*)_srcAccelerationStructure, sizeof(_srcAccelerationStructure)); } #pragma mark - From c6d97c29ba378cda38fc82a73dab431e6542cf96 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Tue, 18 Jul 2023 19:58:37 -0400 Subject: [PATCH 20/32] Acceleration structures with Levels This commit adds the functionality for a bottom and top level acceleration structure, which are not quite finished, but I'm pushing this because I'm unable to stash this. --- .../Commands/MVKCmdAccelerationStructure.h | 3 +- .../Commands/MVKCmdAccelerationStructure.mm | 118 ++++++++++++++++-- .../GPUObjects/MVKAccelerationStructure.h | 1 - 3 files changed, 107 insertions(+), 15 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index db943199f..488f5332b 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -40,6 +40,7 @@ class MVKCmdBuildAccelerationStructure : public MVKCommand { protected: MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + MVKDevice* _mvkDevice; uint32_t _infoCount; VkAccelerationStructureBuildGeometryInfoKHR* _geometryInfos; VkAccelerationStructureBuildRangeInfoKHR const* _buildRangeInfos; @@ -59,7 +60,7 @@ class MVKCmdCopyAccelerationStructure : public MVKCommand { void encode(MVKCommandEncoder* cmdEncoder) override; protected: MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - + id _srcAccelerationStructure; id _dstAccelerationStructure; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index df9a4cd98..f3837e80e 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -32,6 +32,7 @@ const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { VkAccelerationStructureBuildGeometryInfoKHR geoInfo = *pInfos; + _mvkDevice = cmdBuff->getDevice(); _infoCount = infoCount; _geometryInfos = &geoInfo; _buildRangeInfos = *ppBuildRangeInfos; @@ -63,21 +64,113 @@ if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) { - MTLAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLAccelerationStructureDescriptor new]; + if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR) + { + MTLAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + mvkDstAccelerationStructure->setAllowUpdate(true); + }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + + [accStructEncoder buildAccelerationStructure:dstAccelerationStructure + descriptor:accStructBuildDescriptor + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; + } - if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - mvkDstAccelerationStructure->setAllowUpdate(true); - }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) + { + if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) { return; } + + if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) + { + MTLPrimitiveAccelerationStructureDescriptor* accStructTriangleBuildDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + mvkDstAccelerationStructure->setAllowUpdate(true); + }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructTriangleBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + + VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = _geometryInfos[i].pGeometries->geometry.triangles; + uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; + uint64_t indexBDA = triangleGeometryData.indexData.deviceAddress; + MVKBuffer* mvkVertexBuffer = _mvkDevice->getBufferAtAddress(vertexBDA); + MVKBuffer* mvkIndexBuffer = _mvkDevice->getBufferAtAddress(indexBDA); + + MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; + geometryTriangles.triangleCount = _geometryInfos[i].geometryCount; + geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); + geometryTriangles.vertexBufferOffset = _buildRangeInfos[i].primitiveOffset; + + geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); + geometryTriangles.indexBufferOffset = 0; // Need to get this value + geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); + accStructTriangleBuildDescriptor.geometryDescriptors = @[geometryTriangles]; + + [accStructEncoder buildAccelerationStructure:dstAccelerationStructure + descriptor:accStructTriangleBuildDescriptor + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; + } + // Need to implement AABBS + if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) + { + MTLPrimitiveAccelerationStructureDescriptor* accStructTriangleBuildDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + mvkDstAccelerationStructure->setAllowUpdate(true); + }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructTriangleBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + + VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = _geometryInfos[i].pGeometries->geometry.triangles; + uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; + uint64_t indexBDA = triangleGeometryData.indexData.deviceAddress; + MVKBuffer* mvkVertexBuffer = _mvkDevice->getBufferAtAddress(vertexBDA); + MVKBuffer* mvkIndexBuffer = _mvkDevice->getBufferAtAddress(indexBDA); + + MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; + geometryTriangles.triangleCount = _geometryInfos[i].geometryCount; + geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); + geometryTriangles.vertexBufferOffset = _buildRangeInfos[i].primitiveOffset; + + geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); + geometryTriangles.indexBufferOffset = 0; // Need to get this value + geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); + accStructTriangleBuildDescriptor.geometryDescriptors = @[geometryTriangles]; + + [accStructEncoder buildAccelerationStructure:dstAccelerationStructure + descriptor:accStructTriangleBuildDescriptor + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; + } } - [accStructEncoder buildAccelerationStructure:dstAccelerationStructure - descriptor:accStructBuildDescriptor - scratchBuffer:scratchBuffer - scratchBufferOffset:scratchBufferOffset]; + if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) + { + MTLInstanceAccelerationStructureDescriptor* accStructInstanceBuildDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + mvkDstAccelerationStructure->setAllowUpdate(true); + }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructInstanceBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + } } if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) @@ -151,7 +244,6 @@ } void MVKCmdCopyAccelerationStructureToMemory::encode(MVKCommandEncoder* cmdEncoder) { - id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); _mvkDevice = cmdEncoder->getDevice(); if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR || !_dstBuffer->getDeviceMemory()->isMemoryHostAccessible()){ diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 5f3cdc41a..d2078c4b9 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -30,7 +30,6 @@ vkGetAccelerationStructureBuildSizesKHR - DONE vkGetAccelerationStructureDeviceAddressKHR - DONE vkGetDeviceAccelerationStructureCompatibilityKHR - DONE - vkWriteAccelerationStructuresPropertiesKHR */ #pragma once From 1cf021e29b03a57793863916a9d465e7c255fb4e Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Wed, 26 Jul 2023 11:14:45 -0400 Subject: [PATCH 21/32] Added command uses and MTLHeaps This commit does not do much, however I'm updating to the next macos update, so I'd like to push so I don't lose everything. --- .../Commands/MVKCmdAccelerationStructure.mm | 6 +- .../GPUObjects/MVKAccelerationStructure.h | 11 ++- .../GPUObjects/MVKAccelerationStructure.mm | 8 ++- MoltenVK/MoltenVK/Utility/MVKFoundation.h | 70 ++++++++++--------- 4 files changed, 56 insertions(+), 39 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index f3837e80e..6a15fb57b 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -41,7 +41,7 @@ } void MVKCmdBuildAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { - id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseBuildAccelerationStructure); for(int i = 0; i < _infoCount; i++) { @@ -210,7 +210,7 @@ } void MVKCmdCopyAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { - id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseCopyAccelerationStructure); if(_copyMode == VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR) { @@ -271,7 +271,7 @@ } void MVKCmdCopyMemoryToAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { - id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseNone); + id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseCopyMemoryToAccelerationStructure); _mvkDevice = cmdEncoder->getDevice(); if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR){ diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index d2078c4b9..b4715e87e 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -61,7 +61,7 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { #pragma mark - #pragma mark Getters and Setters - /** Used when building the acceleration structure, to mark whether or not an acceleration structure can be updated*/ + /** Used when building the acceleration structure, to mark whether or not an acceleration structure can be updated, only to be set by MVKCmdBuildAccelerationStructure*/ void setAllowUpdate(bool value) { _allowUpdate = value; } /** Checks if this acceleration structure is allowed to be updated*/ @@ -78,6 +78,12 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { /** Gets the address of the acceleration structure*/ uint64_t getDeviceAddress() { return _address; } + + /** Returns the Metal buffer using the same memory as the acceleration structure*/ + MVKBuffer* getMVKBuffer() { return _buffer; } + + /** Gets the heap allocation that the acceleration structure, and buffer share*/ + id getMTLHeap() { return _heap; } #pragma mark - #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} @@ -87,6 +93,9 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { void propagateDebugName() override {} id _accelerationStructure; + MVKBuffer* _buffer; + id _heap; + bool _allowUpdate = false; bool _built = false; uint64_t _address = 0; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index f68e635d7..6397fa213 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -22,11 +22,14 @@ #pragma mark - #pragma mark MVKAcceleration Structure -id MVKAccelerationStructure::getMTLAccelerationStructure() -{ +id MVKAccelerationStructure::getMTLAccelerationStructure() { return _accelerationStructure; } +MVKBuffer* MVKAccelerationStructure::getMVKBuffer() { + return _buffer; +} + VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes() { VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; @@ -48,4 +51,5 @@ void MVKAccelerationStructure::destroy() { // TODO + _built = false; } diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index b8f10720f..d4427fb7e 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -62,39 +62,43 @@ typedef struct { /** Tracks the Vulkan command currently being used. */ typedef enum : uint8_t { - kMVKCommandUseNone = 0, /**< No use defined. */ - kMVKCommandUseEndCommandBuffer, /**< vkEndCommandBuffer (prefilled VkCommandBuffer). */ - kMVKCommandUseQueueSubmit, /**< vkQueueSubmit. */ - kMVKCommandUseAcquireNextImage, /**< vkAcquireNextImageKHR. */ - kMVKCommandUseQueuePresent, /**< vkQueuePresentKHR. */ - kMVKCommandUseQueueWaitIdle, /**< vkQueueWaitIdle. */ - kMVKCommandUseDeviceWaitIdle, /**< vkDeviceWaitIdle. */ - kMVKCommandUseInvalidateMappedMemoryRanges, /**< vkInvalidateMappedMemoryRanges. */ - kMVKCommandUseBeginRendering, /**< vkCmdBeginRendering. */ - kMVKCommandUseBeginRenderPass, /**< vkCmdBeginRenderPass. */ - kMVKCommandUseNextSubpass, /**< vkCmdNextSubpass. */ - kMVKCommandUseRestartSubpass, /**< Restart a subpass because of explicit or implicit barrier. */ - kMVKCommandUsePipelineBarrier, /**< vkCmdPipelineBarrier. */ - kMVKCommandUseBlitImage, /**< vkCmdBlitImage. */ - kMVKCommandUseCopyImage, /**< vkCmdCopyImage. */ - kMVKCommandUseResolveImage, /**< vkCmdResolveImage - resolve stage. */ - kMVKCommandUseResolveExpandImage, /**< vkCmdResolveImage - expand stage. */ - kMVKCommandUseResolveCopyImage, /**< vkCmdResolveImage - copy stage. */ - kMVKCommandUseCopyBuffer, /**< vkCmdCopyBuffer. */ - kMVKCommandUseCopyBufferToImage, /**< vkCmdCopyBufferToImage. */ - kMVKCommandUseCopyImageToBuffer, /**< vkCmdCopyImageToBuffer. */ - kMVKCommandUseFillBuffer, /**< vkCmdFillBuffer. */ - kMVKCommandUseUpdateBuffer, /**< vkCmdUpdateBuffer. */ - kMVKCommandUseClearAttachments, /**< vkCmdClearAttachments. */ - kMVKCommandUseClearColorImage, /**< vkCmdClearColorImage. */ - kMVKCommandUseClearDepthStencilImage, /**< vkCmdClearDepthStencilImage. */ - kMVKCommandUseResetQueryPool, /**< vkCmdResetQueryPool. */ - kMVKCommandUseDispatch, /**< vkCmdDispatch. */ - kMVKCommandUseTessellationVertexTessCtl, /**< vkCmdDraw* - vertex and tessellation control stages. */ - kMVKCommandUseDrawIndirectConvertBuffers, /**< vkCmdDrawIndirect* convert indirect buffers. */ - kMVKCommandUseCopyQueryPoolResults, /**< vkCmdCopyQueryPoolResults. */ - kMVKCommandUseAccumOcclusionQuery, /**< Any command terminating a Metal render pass with active visibility buffer. */ - kMVKCommandUseRecordGPUCounterSample /**< Any command triggering the recording of a GPU counter sample. */ + kMVKCommandUseNone = 0, /**< No use defined. */ + kMVKCommandUseEndCommandBuffer, /**< vkEndCommandBuffer (prefilled VkCommandBuffer). */ + kMVKCommandUseQueueSubmit, /**< vkQueueSubmit. */ + kMVKCommandUseAcquireNextImage, /**< vkAcquireNextImageKHR. */ + kMVKCommandUseQueuePresent, /**< vkQueuePresentKHR. */ + kMVKCommandUseQueueWaitIdle, /**< vkQueueWaitIdle. */ + kMVKCommandUseDeviceWaitIdle, /**< vkDeviceWaitIdle. */ + kMVKCommandUseInvalidateMappedMemoryRanges, /**< vkInvalidateMappedMemoryRanges. */ + kMVKCommandUseBeginRendering, /**< vkCmdBeginRendering. */ + kMVKCommandUseBeginRenderPass, /**< vkCmdBeginRenderPass. */ + kMVKCommandUseNextSubpass, /**< vkCmdNextSubpass. */ + kMVKCommandUseRestartSubpass, /**< Restart a subpass because of explicit or implicit barrier. */ + kMVKCommandUsePipelineBarrier, /**< vkCmdPipelineBarrier. */ + kMVKCommandUseBlitImage, /**< vkCmdBlitImage. */ + kMVKCommandUseCopyImage, /**< vkCmdCopyImage. */ + kMVKCommandUseResolveImage, /**< vkCmdResolveImage - resolve stage. */ + kMVKCommandUseResolveExpandImage, /**< vkCmdResolveImage - expand stage. */ + kMVKCommandUseResolveCopyImage, /**< vkCmdResolveImage - copy stage. */ + kMVKCommandUseCopyBuffer, /**< vkCmdCopyBuffer. */ + kMVKCommandUseCopyBufferToImage, /**< vkCmdCopyBufferToImage. */ + kMVKCommandUseCopyImageToBuffer, /**< vkCmdCopyImageToBuffer. */ + kMVKCommandUseFillBuffer, /**< vkCmdFillBuffer. */ + kMVKCommandUseUpdateBuffer, /**< vkCmdUpdateBuffer. */ + kMVKCommandUseClearAttachments, /**< vkCmdClearAttachments. */ + kMVKCommandUseClearColorImage, /**< vkCmdClearColorImage. */ + kMVKCommandUseClearDepthStencilImage, /**< vkCmdClearDepthStencilImage. */ + kMVKCommandUseResetQueryPool, /**< vkCmdResetQueryPool. */ + kMVKCommandUseDispatch, /**< vkCmdDispatch. */ + kMVKCommandUseTessellationVertexTessCtl, /**< vkCmdDraw* - vertex and tessellation control stages. */ + kMVKCommandUseDrawIndirectConvertBuffers, /**< vkCmdDrawIndirect* convert indirect buffers. */ + kMVKCommandUseCopyQueryPoolResults, /**< vkCmdCopyQueryPoolResults. */ + kMVKCommandUseAccumOcclusionQuery, /**< Any command terminating a Metal render pass with active visibility buffer. */ + kMVKCommandUseRecordGPUCounterSample, /**< Any command triggering the recording of a GPU counter sample. */ + kMVKCommandUseBuildAccelerationStructure, /**< vkCmdBuiildAccelerationStructure - Builds an acceleration structure */ + kMVKCommandUseCopyAccelerationStructure, /**< vkCmdCopyAccelerationStructure- Copies an acceleration structure to another acceleration structure*/ + kMVKCommandUseCopyAccelerationStructureToMemory,/**< vkCmdCopyAccelerationStructureToMemory - Copies and serializes an acceleration structure to a buffer*/ + kMVKCommandUseCopyMemoryToAccelerationStructure,/**< vkCmdCopyMemoryToAccelerationStructure - Copies and deserializes an acceleration structure from a buffer*/ } MVKCommandUse; /** Represents a given stage of a graphics pipeline. */ From 333f41b2253fa97ebe582b9531a9db7534167079 Mon Sep 17 00:00:00 2001 From: Nitish Prakash Date: Sun, 12 Nov 2023 12:36:42 -0500 Subject: [PATCH 22/32] Corrected Some Simple Build Errors --- MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h | 2 +- MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index b4715e87e..5b58c2407 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -83,7 +83,7 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { MVKBuffer* getMVKBuffer() { return _buffer; } /** Gets the heap allocation that the acceleration structure, and buffer share*/ - id getMTLHeap() { return _heap; } + id getMTLHeap() { return _heap; } #pragma mark - #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 6397fa213..55ccca098 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -26,10 +26,6 @@ return _accelerationStructure; } -MVKBuffer* MVKAccelerationStructure::getMVKBuffer() { - return _buffer; -} - VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes() { VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; From 1696c18faaa24fbb218040448687d3cb75e39338 Mon Sep 17 00:00:00 2001 From: Nitish Prakash Date: Sun, 12 Nov 2023 12:47:43 -0500 Subject: [PATCH 23/32] Correcting Build Errors due to Merge --- MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm | 1 - MoltenVK/MoltenVK/Utility/MVKFoundation.h | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 6a15fb57b..28e3b8be5 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -211,7 +211,6 @@ void MVKCmdCopyAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseCopyAccelerationStructure); - if(_copyMode == VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR) { [accStructEncoder diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index f5820721a..78839243b 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -97,7 +97,11 @@ typedef enum : uint8_t { kMVKCommandUseDrawIndirectConvertBuffers, /**< vkCmdDrawIndirect* convert indirect buffers. */ kMVKCommandUseCopyQueryPoolResults, /**< vkCmdCopyQueryPoolResults. */ kMVKCommandUseAccumOcclusionQuery, /**< Any command terminating a Metal render pass with active visibility buffer. */ - kMVKCommandUseRecordGPUCounterSample /**< Any command triggering the recording of a GPU counter sample. */ + kMVKCommandUseRecordGPUCounterSample, /**< Any command triggering the recording of a GPU counter sample. */ + kMVKCommandUseBuildAccelerationStructure, /**< vkCmdBuiildAccelerationStructure - Builds an acceleration structure */ + kMVKCommandUseCopyAccelerationStructure, /**< vkCmdCopyAccelerationStructure- Copies an acceleration structure to another acceleration structure*/ + kMVKCommandUseCopyAccelerationStructureToMemory,/**< vkCmdCopyAccelerationStructureToMemory - Copies and serializes an acceleration structure to a buffer*/ + kMVKCommandUseCopyMemoryToAccelerationStructure,/**< vkCmdCopyMemoryToAccelerationStructure - Copies and deserializes an acceleration structure from a buffer*/ } MVKCommandUse; /** Represents a given stage of a graphics pipeline. */ From 3937822ad9608127ec44b9817bbd7d299517440b Mon Sep 17 00:00:00 2001 From: Nitish Prakash Date: Sun, 3 Dec 2023 12:40:10 -0500 Subject: [PATCH 24/32] Added Function Definitions for Overwritten Functions --- .../MoltenVK/Commands/MVKCommandBuffer.mm | 13 +++ MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 79 +++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index 44f0204e1..12806ed35 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -865,6 +865,19 @@ return _mtlBlitEncoder; } +id MVKCommandEncoder::getMTLAccelerationStructureEncoder(MVKCommandUse cmdUse) { + if ( !_mtlAccelerationStructureEncoder ) { + endCurrentMetalEncoding(); + _mtlAccelerationStructureEncoder = [_mtlCmdBuffer accelerationStructureCommandEncoder]; + retainIfImmediatelyEncoding(_mtlAccelerationStructureEncoder); + } + if (_mtlAccelerationStructureUse != cmdUse) { + _mtlAccelerationStructureUse = cmdUse; + setLabelIfNotNil(_mtlAccelerationStructureEncoder, mvkMTLBlitCommandEncoderLabel(cmdUse)); + } + return _mtlAccelerationStructureEncoder; +} + id MVKCommandEncoder::getMTLEncoder(){ if (_mtlRenderEncoder) { return _mtlRenderEncoder; } if (_mtlComputeEncoder) { return _mtlComputeEncoder; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index dfad9cf0b..8c55e4943 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -33,6 +33,7 @@ #include "MVKFoundation.h" #include "MVKCodec.h" #include "MVKStrings.h" +#include "MVKAccelerationStructure.h" #include #import "CAMetalLayer+MoltenVK.h" @@ -3696,6 +3697,48 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope *pMaxDeviation = cpuEnd - cpuStart; } +MVKBuffer* MVKDevice::getBufferAtAddress(uint64_t address) +{ + lock_guard lock(_rezLock); + + std::unordered_map::iterator it; + // Super inefficent but this can be fixed in the future + for(it = _gpuBufferAddressMap.begin(); it != _gpuBufferAddressMap.end(); it++) + { + // If the beginning address is bigger than, or the ending address is smaller than the passed address, then skip this it + if(it->first.first > address || it->first.second < address) + { + continue; + } + break; + } + + // Couldn't find the buffer at address + if (it == _gpuBufferAddressMap.end()) { return nullptr;} + + return it->second; +} + +MVKAccelerationStructure* MVKDevice::getAccelerationStructureAtAddress(uint64_t address) +{ + std::unordered_map::iterator accStructIt = _gpuAccStructAddressMap.find(address); + if(accStructIt == _gpuAccStructAddressMap.end()) { return nullptr; } + + return accStructIt->second; +} + +VkAccelerationStructureCompatibilityKHR MVKDevice::getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo) +{ + VkAccelerationStructureCompatibilityKHR compat = VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR; + + if(_enabledAccelerationStructureFeatures.accelerationStructure) + { + compat = VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR; + } + + return compat; +} + #pragma mark Object lifecycle uint32_t MVKDevice::getVulkanMemoryTypeIndex(MTLStorageMode mtlStorageMode) { @@ -3950,6 +3993,18 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope if (mvkPLL) { mvkPLL->destroy(); } } +MVKAccelerationStructure* MVKDevice::createAccelerationStructure(const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator) { + return addAccelerationStructure(new MVKAccelerationStructure(this)); +} + +void MVKDevice::destroyAccelerationStructure(MVKAccelerationStructure* mvkAccStruct, + const VkAllocationCallbacks* pAllocator) { + if(!mvkAccStruct) { return; } + removeAccelerationStructure(mvkAccStruct); + mvkAccStruct->destroy(); +} + template VkResult MVKDevice::createPipelines(VkPipelineCache pipelineCache, uint32_t count, @@ -4243,6 +4298,30 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope mvkRemoveFirstOccurance(_awaitingTimelineSem4s, make_pair(sem4, value)); } +MVKAccelerationStructure* MVKDevice::addAccelerationStructure(MVKAccelerationStructure* accStruct) { + std::pair accStructMemoryPair = std::make_pair(_nextValidAccStructureAddress, accStruct); + _gpuAccStructAddressMap.insert(accStructMemoryPair); + accStruct->setDeviceAddress(_nextValidAccStructureAddress); + _nextValidAccStructureAddress += accStruct->getMTLSize(); + return accStruct; +} + +void MVKDevice::removeAccelerationStructure(MVKAccelerationStructure* accStruct) { + std::unordered_map::iterator accStructIt = _gpuAccStructAddressMap.find(accStruct->getDeviceAddress()); + uint64_t addressOffset = accStructIt->second->getMTLSize(); + _gpuAccStructAddressMap.erase(accStructIt); + + // This can lead to fragmentation over time, so I'll just push all keys after this back + // This, however is also another performance issue + for(auto it = accStructIt; it != _gpuAccStructAddressMap.end(); it++) + { + auto extractedAccStruct = _gpuAccStructAddressMap.extract(it->first); + extractedAccStruct.key() = it->first - addressOffset; + _gpuAccStructAddressMap.insert(std::move(extractedAccStruct)); + _gpuAccStructAddressMap.erase(it->first); + } +} + void MVKDevice::applyMemoryBarrier(MVKPipelineBarrier& barrier, MVKCommandEncoder* cmdEncoder, MVKCommandUse cmdUse) { From 4664dadfbf3c3e26973f5f7723972a789ece26b4 Mon Sep 17 00:00:00 2001 From: Nitish Prakash Date: Tue, 9 Jan 2024 19:58:44 -0500 Subject: [PATCH 25/32] Quick Save --- .../Commands/MVKCmdAccelerationStructure.mm | 17 +++++++++++------ .../GPUObjects/MVKAccelerationStructure.h | 1 + .../GPUObjects/MVKAccelerationStructure.mm | 6 ++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 28e3b8be5..7869835ae 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -51,6 +51,9 @@ id srcAccelerationStructure = (id)mvkSrcAccelerationStructure->getMTLAccelerationStructure(); id dstAccelerationStructure = (id)mvkDstAccelerationStructure->getMTLAccelerationStructure(); + id srcAccelerationStructureHeap = mvkSrcAccelerationStructure->getMTLHeap(); + id dstAccelerationStructureHeap = mvkDstAccelerationStructure->getMTLHeap(); + if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && !mvkDstAccelerationStructure->getAllowUpdate()) { continue; @@ -77,10 +80,14 @@ accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; } + // What would the offset be? + [dstAccelerationStructureHeap newAccelerationStructureWithDescriptor:accStructBuildDescriptor]; + [accStructEncoder buildAccelerationStructure:dstAccelerationStructure descriptor:accStructBuildDescriptor scratchBuffer:scratchBuffer scratchBufferOffset:scratchBufferOffset]; + } if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) @@ -122,6 +129,7 @@ scratchBufferOffset:scratchBufferOffset]; } // Need to implement AABBS + // This is just a dummy copy of Bottom Level if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) { MTLPrimitiveAccelerationStructureDescriptor* accStructTriangleBuildDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; @@ -237,19 +245,16 @@ MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); - + _dstBuffer = _mvkDevice->getBufferAtAddress(_dstAddress); return VK_SUCCESS; } void MVKCmdCopyAccelerationStructureToMemory::encode(MVKCommandEncoder* cmdEncoder) { + id blitEncoder = cmdEncoder->getMTLBlitEncoder(kMVKCommandUseCopyAccelerationStructureToMemory); _mvkDevice = cmdEncoder->getDevice(); - if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR || !_dstBuffer->getDeviceMemory()->isMemoryHostAccessible()){ - return; - } - - memcpy(_dstBuffer->getDeviceMemory()->getHostMemoryAddress(), (void*)_srcAccelerationStructure, sizeof(_srcAccelerationStructure)); + [_srcAccelerationStructure] } #pragma mark - diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 5b58c2407..08cf7faed 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -88,6 +88,7 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { #pragma mark Construction MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} + void create(); void destroy() override; protected: void propagateDebugName() override {} diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 55ccca098..495ea923c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -44,6 +44,12 @@ return _accelerationStructure.size; } +void MVKAccelerationStructure::create() +{ + [_accelerationStructure makeAliasable]; + [_heap newAccelerationStructureWithSize:getBuildSizes().accelerationStructureSize]; +} + void MVKAccelerationStructure::destroy() { // TODO From 4362ea1cbd6a481418696ba5694a72743c9d36a1 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Wed, 29 May 2024 12:22:43 -0400 Subject: [PATCH 26/32] Buggy Implementation on Get Build Sizes Still not finished, just quickly saving my work on get build sizes --- .../Commands/MVKCmdAccelerationStructure.h | 4 + .../Commands/MVKCmdAccelerationStructure.mm | 53 +--------- .../GPUObjects/MVKAccelerationStructure.h | 20 ++-- .../GPUObjects/MVKAccelerationStructure.mm | 99 +++++++++++++++++-- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 6 +- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 5 +- 6 files changed, 113 insertions(+), 74 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 488f5332b..e9eb11a55 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -83,7 +83,9 @@ class MVKCmdCopyAccelerationStructureToMemory : public MVKCommand { MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; id _srcAccelerationStructure; + id _srcAccelerationStructureBuffer; MVKBuffer* _dstBuffer; + uint64_t _copySize; uint64_t _dstAddress; MVKDevice* _mvkDevice; @@ -107,6 +109,8 @@ class MVKCmdCopyMemoryToAccelerationStructure: public MVKCommand { MVKBuffer* _srcBuffer; id _dstAccelerationStructure; + id _dstAccelerationStructureBuffer; + uint32_t _copySize; uint64_t _srcAddress; MVKDevice* _mvkDevice; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 7869835ae..87c9ae576 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -132,37 +132,6 @@ // This is just a dummy copy of Bottom Level if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) { - MTLPrimitiveAccelerationStructureDescriptor* accStructTriangleBuildDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; - - if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - mvkDstAccelerationStructure->setAllowUpdate(true); - }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructTriangleBuildDescriptor.usage = MTLAccelerationStructureUsageNone; - } - - VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = _geometryInfos[i].pGeometries->geometry.triangles; - uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; - uint64_t indexBDA = triangleGeometryData.indexData.deviceAddress; - MVKBuffer* mvkVertexBuffer = _mvkDevice->getBufferAtAddress(vertexBDA); - MVKBuffer* mvkIndexBuffer = _mvkDevice->getBufferAtAddress(indexBDA); - - MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; - geometryTriangles.triangleCount = _geometryInfos[i].geometryCount; - geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); - geometryTriangles.vertexBufferOffset = _buildRangeInfos[i].primitiveOffset; - - geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); - geometryTriangles.indexBufferOffset = 0; // Need to get this value - geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); - accStructTriangleBuildDescriptor.geometryDescriptors = @[geometryTriangles]; - - [accStructEncoder buildAccelerationStructure:dstAccelerationStructure - descriptor:accStructTriangleBuildDescriptor - scratchBuffer:scratchBuffer - scratchBufferOffset:scratchBufferOffset]; } } @@ -245,6 +214,7 @@ MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)srcAccelerationStructure; _srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); + _dstBuffer = _mvkDevice->getBufferAtAddress(_dstAddress); return VK_SUCCESS; @@ -254,7 +224,7 @@ id blitEncoder = cmdEncoder->getMTLBlitEncoder(kMVKCommandUseCopyAccelerationStructureToMemory); _mvkDevice = cmdEncoder->getDevice(); - [_srcAccelerationStructure] + [blitEncoder copyFromBuffer:_srcAccelerationStructureBuffer sourceOffset:0 toBuffer:_dstBuffer->getMTLBuffer() destinationOffset:0 size:_copySize]; } #pragma mark - @@ -271,26 +241,13 @@ MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)dstAccelerationStructure; _dstAccelerationStructure = mvkDstAccStruct->getMTLAccelerationStructure(); + _dstAccelerationStructureBuffer = mvkDstAccStruct->getMTLBuffer(); return VK_SUCCESS; } void MVKCmdCopyMemoryToAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { - id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseCopyMemoryToAccelerationStructure); + id blitEncoder = cmdEncoder->getMTLBlitEncoder(kMVKCommandUseCopyAccelerationStructureToMemory); _mvkDevice = cmdEncoder->getDevice(); - if(_copyMode != VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR){ - return; - } - - void* serializedAccStruct = _srcBuffer->getHostMemoryAddress(); - if(!serializedAccStruct){ - return; // Should I remove this? For this to work, the memory can't be device only, but the spec does not seem to restrict this - } - - MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)serializedAccStruct; - id srcAccelerationStructure = mvkSrcAccStruct->getMTLAccelerationStructure(); - - [accStructEncoder - copyAccelerationStructure:srcAccelerationStructure - toAccelerationStructure:_dstAccelerationStructure]; + [blitEncoder copyFromBuffer:_srcBuffer->getMTLBuffer() sourceOffset:0 toBuffer:_dstAccelerationStructureBuffer destinationOffset:0 size:_copySize]; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 08cf7faed..b3f87de8d 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -27,7 +27,7 @@ vkCmdWriteAccelerationStructuresPropertiesKHR vkCreateAccelerationStructureKHR - DONE vkDestroyAccelerationStructureKHR - DONE - vkGetAccelerationStructureBuildSizesKHR - DONE + vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureDeviceAddressKHR - DONE vkGetDeviceAccelerationStructureCompatibilityKHR - DONE */ @@ -43,7 +43,7 @@ #pragma mark MVKAccelerationStructure class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { - + public: VkObjectType getVkObjectType() override { return VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR; } @@ -54,11 +54,11 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { id getMTLAccelerationStructure(); /** Gets the required build sizes for acceleration structure and scratch buffer*/ - static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(); + static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(MVKDevice* device, VkAccelerationStructureBuildTypeKHR buildType, const VkAccelerationStructureBuildGeometryInfoKHR* buildInfo); /** Gets the actual size of the acceleration structure*/ uint64_t getMTLSize(); - + #pragma mark - #pragma mark Getters and Setters /** Used when building the acceleration structure, to mark whether or not an acceleration structure can be updated, only to be set by MVKCmdBuildAccelerationStructure*/ @@ -80,22 +80,22 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { uint64_t getDeviceAddress() { return _address; } /** Returns the Metal buffer using the same memory as the acceleration structure*/ - MVKBuffer* getMVKBuffer() { return _buffer; } + id getMTLBuffer() { return _buffer; } /** Gets the heap allocation that the acceleration structure, and buffer share*/ id getMTLHeap() { return _heap; } + + MTLAccelerationStructureTriangleGeometryDescriptor* getTriangleDescriptor(); #pragma mark - #pragma mark Construction - MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {} - - void create(); + MVKAccelerationStructure(MVKDevice* device); void destroy() override; protected: void propagateDebugName() override {} - id _accelerationStructure; - MVKBuffer* _buffer; id _heap; + id _accelerationStructure; + id _buffer; bool _allowUpdate = false; bool _built = false; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 495ea923c..e2cb50933 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -17,6 +17,7 @@ */ #include "MVKDevice.h" +#include "MVKBuffer.h" #include "MVKAccelerationStructure.h" #pragma mark - @@ -26,14 +27,87 @@ return _accelerationStructure; } -VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes() +VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes(MVKDevice* device, VkAccelerationStructureBuildTypeKHR type, const VkAccelerationStructureBuildGeometryInfoKHR* info) { VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; - - MTLAccelerationStructureSizes mtlBuildSizes; - vkBuildSizes.accelerationStructureSize = mtlBuildSizes.accelerationStructureSize; - vkBuildSizes.buildScratchSize = mtlBuildSizes.buildScratchBufferSize; - vkBuildSizes.updateScratchSize = mtlBuildSizes.refitScratchBufferSize; + MTLAccelerationStructureDescriptor* accStructDescriptor; + + if(type == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR) { + // We can't do that, throw an error? + return vkBuildSizes; + } + + switch (info->type) + { + case VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR: + { + accStructDescriptor = [MTLAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructDescriptor.usage += MTLAccelerationStructureUsageRefit; + }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructDescriptor.usage = MTLAccelerationStructureUsageNone; + } + break; + } + + case VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR: + { + if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) { return vkBuildSizes; } + if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) { return vkBuildSizes; } + + if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) + { + accStructDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructDescriptor.usage += MTLAccelerationStructureUsageRefit; + }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructDescriptor.usage = MTLAccelerationStructureUsageNone; + } + + VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = info->pGeometries->geometry.triangles; + uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; + uint64_t indexBDA = triangleGeometryData.indexData.deviceAddress; + MVKBuffer* mvkVertexBuffer = device->getBufferAtAddress(vertexBDA); + MVKBuffer* mvkIndexBuffer = device->getBufferAtAddress(indexBDA); + + MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; + geometryTriangles.triangleCount = info->geometryCount; + geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); +// geometryTriangles.vertexBufferOffset = _buildRangeInfos[i].primitiveOffset; + + geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); + geometryTriangles.indexBufferOffset = 0; // Need to get this value + geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); +// accStructDescriptor.geometryDescriptors = @[geometryTriangles]; + } + break; + } + case VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR: + { + MTLInstanceAccelerationStructureDescriptor* accStructInstanceBuildDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructInstanceBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + } + default: + break; + } + +// MTLAccelerationStructureSizes sizes = [device->getMTLDevi ce() accelerationStructureSizesWithDescriptor:accelerationStructureDescriptor]; +// vkBuildSizes.accelerationStructureSize = sizes.accelerationStructureSize; +// vkBuildSizes.buildScratchSize = sizes.buildScratchBufferSize; +// vkBuildSizes.updateScratchSize = sizes.refitScratchBufferSize; return vkBuildSizes; } @@ -44,14 +118,19 @@ return _accelerationStructure.size; } -void MVKAccelerationStructure::create() +MVKAccelerationStructure::MVKAccelerationStructure(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) { - [_accelerationStructure makeAliasable]; - [_heap newAccelerationStructureWithSize:getBuildSizes().accelerationStructureSize]; + MTLHeapDescriptor* heapDescriptor = [MTLHeapDescriptor new]; + heapDescriptor.storageMode = MTLStorageModePrivate; +// heapDescriptor.size = getBuildSizes().accelerationStructureSize; + _heap = [getMTLDevice() newHeapWithDescriptor:heapDescriptor]; + +// _accelerationStructure = [_heap newAccelerationStructureWithSize:getBuildSizes().accelerationStructureSize]; +// _buffer = [_heap newBufferWithLength:getBuildSizes().accelerationStructureSize options:MTLResourceOptionCPUCacheModeDefault]; } void MVKAccelerationStructure::destroy() { - // TODO + [_heap release]; _built = false; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 4a4a0669a..0fab842f6 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3814,14 +3814,12 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope VkAccelerationStructureCompatibilityKHR MVKDevice::getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo) { - VkAccelerationStructureCompatibilityKHR compat = VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR; - if(_enabledAccelerationStructureFeatures.accelerationStructure) { - compat = VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR; + return VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR; } - return compat; + return VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR; } #pragma mark Object lifecycle diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 35b1505ea..6ec16ba9c 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -41,7 +41,7 @@ #include "MVKSurface.h" #include "MVKFoundation.h" #include "MVKOSExtensions.h" -#include "MVKAccelerationStructure.h" // I'll reposition this as well if it's needed +#include "MVKAccelerationStructure.h" // I'll reposition this if needed #include @@ -2918,7 +2918,8 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkGetAccelerationStructureBuildSizesKHR( VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo) { MVKTraceVulkanCallStart(); - VkAccelerationStructureBuildSizesInfoKHR buildSizes = MVKAccelerationStructure::getBuildSizes(); + MVKDevice* mvkDev = (MVKDevice*)device; + VkAccelerationStructureBuildSizesInfoKHR buildSizes = MVKAccelerationStructure::getBuildSizes(mvkDev, buildType, pBuildInfo); pSizeInfo = &buildSizes; MVKTraceVulkanCallEnd(); } From 3f1fbde3218a1435192f796f966f41e590c35915 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Wed, 26 Jun 2024 15:40:12 -0400 Subject: [PATCH 27/32] Implemented AABB Geometry for Build and Get Sizes This commit is pretty small and just adds AABBs to be allowed to be pushed to the acceleration structure. --- .../Commands/MVKCmdAccelerationStructure.mm | 53 +++++++------ .../GPUObjects/MVKAccelerationStructure.h | 20 ++--- .../GPUObjects/MVKAccelerationStructure.mm | 75 +++++++++++-------- 3 files changed, 79 insertions(+), 69 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 87c9ae576..50ff7bf38 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -80,7 +80,6 @@ accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; } - // What would the offset be? [dstAccelerationStructureHeap newAccelerationStructureWithDescriptor:accStructBuildDescriptor]; [accStructEncoder buildAccelerationStructure:dstAccelerationStructure @@ -92,21 +91,21 @@ if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) { + MTLPrimitiveAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; + + if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; + mvkDstAccelerationStructure->setAllowUpdate(true); + }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; + } + if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) { return; } if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) { - MTLPrimitiveAccelerationStructureDescriptor* accStructTriangleBuildDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; - - if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - mvkDstAccelerationStructure->setAllowUpdate(true); - }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructTriangleBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructTriangleBuildDescriptor.usage = MTLAccelerationStructureUsageNone; - } - VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = _geometryInfos[i].pGeometries->geometry.triangles; uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; uint64_t indexBDA = triangleGeometryData.indexData.deviceAddress; @@ -116,37 +115,37 @@ MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; geometryTriangles.triangleCount = _geometryInfos[i].geometryCount; geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); - geometryTriangles.vertexBufferOffset = _buildRangeInfos[i].primitiveOffset; + geometryTriangles.vertexBufferOffset = mvkVertexBuffer->getMTLBufferOffset(); geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); - geometryTriangles.indexBufferOffset = 0; // Need to get this value + geometryTriangles.indexBufferOffset = mvkIndexBuffer->getMTLBufferOffset(); geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); - accStructTriangleBuildDescriptor.geometryDescriptors = @[geometryTriangles]; + accStructBuildDescriptor.geometryDescriptors = @[geometryTriangles]; [accStructEncoder buildAccelerationStructure:dstAccelerationStructure - descriptor:accStructTriangleBuildDescriptor + descriptor:accStructBuildDescriptor scratchBuffer:scratchBuffer scratchBufferOffset:scratchBufferOffset]; } - // Need to implement AABBS - // This is just a dummy copy of Bottom Level + if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) { + VkAccelerationStructureGeometryAabbsDataKHR aabbGeometryData = _geometryInfos[i].pGeometries->geometry.aabbs; + uint64_t boundingBoxBDA = aabbGeometryData.data.deviceAddress; + MVKBuffer* mvkBoundingBoxBuffer = _mvkDevice->getBufferAtAddress(boundingBoxBDA); + + MTLAccelerationStructureBoundingBoxGeometryDescriptor* geometryAABBs = [MTLAccelerationStructureBoundingBoxGeometryDescriptor new]; + geometryAABBs.boundingBoxCount = _geometryInfos[i].geometryCount; + geometryAABBs.boundingBoxBuffer = mvkBoundingBoxBuffer->getMTLBuffer(); + geometryAABBs.boundingBoxStride = 0; // Need to get this + geometryAABBs.boundingBoxBufferOffset = mvkBoundingBoxBuffer->getMTLBufferOffset(); + accStructBuildDescriptor.geometryDescriptors = @[geometryAABBs]; } } if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) { MTLInstanceAccelerationStructureDescriptor* accStructInstanceBuildDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; - - if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - mvkDstAccelerationStructure->setAllowUpdate(true); - }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructInstanceBuildDescriptor.usage = MTLAccelerationStructureUsageNone; - } } } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index b3f87de8d..965a7d2ab 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -11,7 +11,7 @@ * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + vkGetDeviceAccelerationStructureCompatibilityKHR * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ @@ -20,16 +20,16 @@ Commands that need to be implemented vkCmdBuildAccelerationStructuresIndirectKHR - vkCmdBuildAccelerationStructuresKHR - DONE - vkCmdCopyAccelerationStructureKHR - DONE - vkCmdCopyAccelerationStructureToMemoryKHR - DONE - vkCmdCopyMemoryToAccelerationStructureKHR - DONE + vkCmdBuildAccelerationStructuresKHR + vkCmdCopyAccelerationStructureKHR + vkCmdCopyAccelerationStructureToMemoryKHR + vkCmdCopyMemoryToAccelerationStructureKHR vkCmdWriteAccelerationStructuresPropertiesKHR - vkCreateAccelerationStructureKHR - DONE - vkDestroyAccelerationStructureKHR - DONE - vkGetAccelerationStructureBuildSizesKHR - vkGetAccelerationStructureDeviceAddressKHR - DONE - vkGetDeviceAccelerationStructureCompatibilityKHR - DONE + vkCreateAccelerationStructureKHR - Complete + vkDestroyAccelerationStructureKHR - Complete + vkGetAccelerationStructureBuildSizesKHR + vkGetAccelerationStructureDeviceAddressKHR - Complete + vkGetDeviceAccelerationStructureCompatibilityKHR - Complete */ #pragma once diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index e2cb50933..4852c27dd 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -42,33 +42,35 @@ case VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR: { accStructDescriptor = [MTLAccelerationStructureDescriptor new]; - - if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructDescriptor.usage += MTLAccelerationStructureUsageRefit; - }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructDescriptor.usage = MTLAccelerationStructureUsageNone; - } break; } case VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR: { - if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) { return vkBuildSizes; } + if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) + { + accStructDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; + MTLPrimitiveAccelerationStructureDescriptor* primitiveAccStructDescriptor = (MTLPrimitiveAccelerationStructureDescriptor*)accStructDescriptor; + + VkAccelerationStructureGeometryAabbsDataKHR aabbGeometryData = info->pGeometries->geometry.aabbs; + uint64_t boundingBoxBDA = aabbGeometryData.data.deviceAddress; + MVKBuffer* mvkBoundingBoxBuffer = device->getBufferAtAddress(boundingBoxBDA); + + MTLAccelerationStructureBoundingBoxGeometryDescriptor* geometryAABBs = [MTLAccelerationStructureBoundingBoxGeometryDescriptor new]; + geometryAABBs.boundingBoxCount = info->geometryCount; + geometryAABBs.boundingBoxBuffer = mvkBoundingBoxBuffer->getMTLBuffer(); + geometryAABBs.boundingBoxStride = 0; // Need to get this + geometryAABBs.boundingBoxBufferOffset = mvkBoundingBoxBuffer->getMTLBufferOffset(); + primitiveAccStructDescriptor.geometryDescriptors = @[geometryAABBs]; + break; + + } if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) { return vkBuildSizes; } if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) { accStructDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; - - if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructDescriptor.usage += MTLAccelerationStructureUsageRefit; - }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructDescriptor.usage = MTLAccelerationStructureUsageNone; - } + MTLPrimitiveAccelerationStructureDescriptor* primitiveAccStructDescriptor = (MTLPrimitiveAccelerationStructureDescriptor*)accStructDescriptor; VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = info->pGeometries->geometry.triangles; uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; @@ -79,35 +81,44 @@ MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; geometryTriangles.triangleCount = info->geometryCount; geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); -// geometryTriangles.vertexBufferOffset = _buildRangeInfos[i].primitiveOffset; + geometryTriangles.vertexBufferOffset = mvkVertexBuffer->getMTLBufferOffset(); geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); - geometryTriangles.indexBufferOffset = 0; // Need to get this value + geometryTriangles.indexBufferOffset = mvkIndexBuffer->getMTLBufferOffset(); geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); -// accStructDescriptor.geometryDescriptors = @[geometryTriangles]; + primitiveAccStructDescriptor.geometryDescriptors = @[geometryTriangles]; + break; + } + else + { + accStructDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; } break; } case VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR: { - MTLInstanceAccelerationStructureDescriptor* accStructInstanceBuildDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; + accStructDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; + MTLInstanceAccelerationStructureDescriptor* instanceAccStructDescriptor = (MTLInstanceAccelerationStructureDescriptor*)accStructDescriptor; - if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructInstanceBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructInstanceBuildDescriptor.usage = MTLAccelerationStructureUsageNone; - } + instanceAccStructDescriptor.instanceDescriptorType = MTLAccelerationStructureInstanceDescriptorTypeDefault; } default: + accStructDescriptor = [MTLAccelerationStructureDescriptor new]; break; } -// MTLAccelerationStructureSizes sizes = [device->getMTLDevi ce() accelerationStructureSizesWithDescriptor:accelerationStructureDescriptor]; -// vkBuildSizes.accelerationStructureSize = sizes.accelerationStructureSize; -// vkBuildSizes.buildScratchSize = sizes.buildScratchBufferSize; -// vkBuildSizes.updateScratchSize = sizes.refitScratchBufferSize; + if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ + accStructDescriptor.usage += MTLAccelerationStructureUsageRefit; + }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ + accStructDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + }else{ + accStructDescriptor.usage = MTLAccelerationStructureUsageNone; + } + + MTLAccelerationStructureSizes sizes = [device->getMTLDevice() accelerationStructureSizesWithDescriptor: accStructDescriptor]; + vkBuildSizes.accelerationStructureSize = sizes.accelerationStructureSize; + vkBuildSizes.buildScratchSize = sizes.buildScratchBufferSize; + vkBuildSizes.updateScratchSize = sizes.refitScratchBufferSize; return vkBuildSizes; } From 2ab8afbd54aab4821ed684ad52c80be07e4353b8 Mon Sep 17 00:00:00 2001 From: TheApplePieGod Date: Wed, 24 Jul 2024 14:55:29 -0500 Subject: [PATCH 28/32] Implement new address map for buffers --- MoltenVK/MoltenVK.xcodeproj/project.pbxproj | 30 ++- MoltenVK/MoltenVK/GPUObjects/MVKDevice.h | 21 +- MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm | 35 ++-- MoltenVK/MoltenVK/Utility/MVKAddressMap.cpp | 211 ++++++++++++++++++++ MoltenVK/MoltenVK/Utility/MVKAddressMap.h | 149 ++++++++++++++ MoltenVK/MoltenVK/Utility/MVKMap.h | 133 ------------ MoltenVK/MoltenVK/Utility/MVKMapAllocator.h | 126 ------------ 7 files changed, 408 insertions(+), 297 deletions(-) create mode 100644 MoltenVK/MoltenVK/Utility/MVKAddressMap.cpp create mode 100644 MoltenVK/MoltenVK/Utility/MVKAddressMap.h delete mode 100644 MoltenVK/MoltenVK/Utility/MVKMap.h delete mode 100644 MoltenVK/MoltenVK/Utility/MVKMapAllocator.h diff --git a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj index 445e4deac..aa52865db 100644 --- a/MoltenVK/MoltenVK.xcodeproj/project.pbxproj +++ b/MoltenVK/MoltenVK.xcodeproj/project.pbxproj @@ -10,12 +10,17 @@ 014702732A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; 014702742A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; 014702752A5857600040D02D /* MVKCmdAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */; }; - 0147027B2A5B0C010040D02D /* MVKMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0147027A2A5AF1310040D02D /* MVKMap.h */; }; - 0147027C2A5B0C010040D02D /* MVKMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0147027A2A5AF1310040D02D /* MVKMap.h */; }; - 0147027D2A5B0C020040D02D /* MVKMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0147027A2A5AF1310040D02D /* MVKMap.h */; }; 0197951B2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; 0197951C2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; 0197951D2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */; }; + 1155DEB12C50C1BC009D70F8 /* MVKAddressMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1155DEAF2C50C1BC009D70F8 /* MVKAddressMap.h */; }; + 1155DEB22C50C1BC009D70F8 /* MVKAddressMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1155DEAF2C50C1BC009D70F8 /* MVKAddressMap.h */; }; + 1155DEB32C50C1BC009D70F8 /* MVKAddressMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1155DEAF2C50C1BC009D70F8 /* MVKAddressMap.h */; }; + 1155DEB42C50C1BC009D70F8 /* MVKAddressMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1155DEAF2C50C1BC009D70F8 /* MVKAddressMap.h */; }; + 1155DEB52C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1155DEB02C50C1BC009D70F8 /* MVKAddressMap.cpp */; }; + 1155DEB62C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1155DEB02C50C1BC009D70F8 /* MVKAddressMap.cpp */; }; + 1155DEB72C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1155DEB02C50C1BC009D70F8 /* MVKAddressMap.cpp */; }; + 1155DEB82C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1155DEB02C50C1BC009D70F8 /* MVKAddressMap.cpp */; }; 2FEA0A4124902F9F00EEF3AD /* MVKExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A909F65A213B190600FCD6BE /* MVKExtensions.h */; }; 2FEA0A4224902F9F00EEF3AD /* vk_mvk_moltenvk.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7691C7DFB4800632CA3 /* vk_mvk_moltenvk.h */; }; 2FEA0A4324902F9F00EEF3AD /* mvk_datatypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A94FB7671C7DFB4800632CA3 /* mvk_datatypes.h */; }; @@ -665,10 +670,10 @@ /* Begin PBXFileReference section */ 014702702A5855F70040D02D /* MVKCmdAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKCmdAccelerationStructure.h; sourceTree = ""; }; 014702722A5857600040D02D /* MVKCmdAccelerationStructure.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKCmdAccelerationStructure.mm; sourceTree = ""; }; - 0147027A2A5AF1310040D02D /* MVKMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKMap.h; sourceTree = ""; }; - 0147027E2A5B0C9A0040D02D /* MVKMapAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKMapAllocator.h; sourceTree = ""; }; 019795132A5304D600C6CAD0 /* MVKAccelerationStructure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVKAccelerationStructure.h; sourceTree = ""; }; 0197951A2A56F8AF00C6CAD0 /* MVKAccelerationStructure.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKAccelerationStructure.mm; sourceTree = ""; }; + 1155DEAF2C50C1BC009D70F8 /* MVKAddressMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKAddressMap.h; sourceTree = ""; }; + 1155DEB02C50C1BC009D70F8 /* MVKAddressMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKAddressMap.cpp; sourceTree = ""; }; 2FEA0ABA24902F9F00EEF3AD /* libMoltenVK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVK.a; sourceTree = BUILT_PRODUCTS_DIR; }; 45003E6F214AD4C900E989CB /* MVKExtensions.def */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = MVKExtensions.def; sourceTree = ""; }; 4536382D2508A4C6000EFFD3 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLRenderPassStencilAttachmentDescriptor+MoltenVK.h"; sourceTree = ""; }; @@ -1045,6 +1050,8 @@ A98149401FB6A3F7005F00B4 /* Utility */ = { isa = PBXGroup; children = ( + 1155DEB02C50C1BC009D70F8 /* MVKAddressMap.cpp */, + 1155DEAF2C50C1BC009D70F8 /* MVKAddressMap.h */, A98149421FB6A3F7005F00B4 /* MVKBaseObject.h */, A98149411FB6A3F7005F00B4 /* MVKBaseObject.mm */, A9D7104E25CDE05E00E38106 /* MVKBitArray.h */, @@ -1060,8 +1067,6 @@ A98149441FB6A3F7005F00B4 /* MVKFoundation.h */, A9AB95292B3EDFCC00C4E967 /* MVKInflectionMap.h */, A9F0429E1FB4CF82009FCCB8 /* MVKLogging.h */, - 0147027A2A5AF1310040D02D /* MVKMap.h */, - 0147027E2A5B0C9A0040D02D /* MVKMapAllocator.h */, A98149461FB6A3F7005F00B4 /* MVKObjectPool.h */, A9F3D9DB24732A4D00745190 /* MVKSmallVector.h */, A9F3D9D924732A4C00745190 /* MVKSmallVectorAllocator.h */, @@ -1223,6 +1228,7 @@ 2FEA0A6224902F9F00EEF3AD /* MVKMTLBufferAllocation.h in Headers */, 2FEA0A6324902F9F00EEF3AD /* MVKObjectPool.h in Headers */, 2FEA0A6424902F9F00EEF3AD /* MVKSwapchain.h in Headers */, + 1155DEB32C50C1BC009D70F8 /* MVKAddressMap.h in Headers */, 2FEA0A6524902F9F00EEF3AD /* MVKGPUCapture.h in Headers */, 2FEA0A6624902F9F00EEF3AD /* MVKBuffer.h in Headers */, 2FEA0A6724902F9F00EEF3AD /* MVKCommonEnvironment.h in Headers */, @@ -1239,7 +1245,6 @@ 2FEA0A7224902F9F00EEF3AD /* MVKCmdDraw.h in Headers */, A9B3D73C29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */, 2FEA0A7324902F9F00EEF3AD /* MVKCommandBuffer.h in Headers */, - 0147027C2A5B0C010040D02D /* MVKMap.h in Headers */, 2FEA0A7424902F9F00EEF3AD /* MTLRenderPassDescriptor+MoltenVK.h in Headers */, 2FEA0A7524902F9F00EEF3AD /* MVKCmdDebug.h in Headers */, 2FEA0A7624902F9F00EEF3AD /* MVKWatermarkTextureContent.h in Headers */, @@ -1303,9 +1308,9 @@ A94FB80C1C7DFB4800632CA3 /* MVKShaderModule.h in Headers */, A9AB952B2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */, A99C91042295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */, - 0147027B2A5B0C010040D02D /* MVKMap.h in Headers */, A94FB7C01C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */, A9B3D73B29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */, + 1155DEB22C50C1BC009D70F8 /* MVKAddressMap.h in Headers */, A94FB7CC1C7DFB4800632CA3 /* MVKCommand.h in Headers */, A981494F1FB6A3F7005F00B4 /* MVKBaseObject.h in Headers */, A9C96DD01DDC20C20053187F /* MVKMTLBufferAllocation.h in Headers */, @@ -1384,9 +1389,9 @@ A99C91052295FAC600A061DA /* MVKVulkanAPIObject.h in Headers */, A9AB952D2B3EDFCC00C4E967 /* MVKInflectionMap.h in Headers */, A94FB7C11C7DFB4800632CA3 /* MVKCmdQueries.h in Headers */, - 0147027D2A5B0C020040D02D /* MVKMap.h in Headers */, A94FB7CD1C7DFB4800632CA3 /* MVKCommand.h in Headers */, A9B3D73D29F9B3B100745CD4 /* mvk_deprecated_api.h in Headers */, + 1155DEB12C50C1BC009D70F8 /* MVKAddressMap.h in Headers */, A98149501FB6A3F7005F00B4 /* MVKBaseObject.h in Headers */, A9C96DD11DDC20C20053187F /* MVKMTLBufferAllocation.h in Headers */, A98149581FB6A3F7005F00B4 /* MVKObjectPool.h in Headers */, @@ -1507,6 +1512,7 @@ DCFD7F0F2A45BC6E007BBBF7 /* MVKCmdPipeline.h in Headers */, DCFD7F102A45BC6E007BBBF7 /* MVKSmallVectorAllocator.h in Headers */, DCFD7F112A45BC6E007BBBF7 /* MVKPipeline.h in Headers */, + 1155DEB42C50C1BC009D70F8 /* MVKAddressMap.h in Headers */, DCFD7F122A45BC6E007BBBF7 /* MVKImage.h in Headers */, DCFD7F132A45BC6E007BBBF7 /* MVKBlockObserver.h in Headers */, DCFD7F142A45BC6E007BBBF7 /* MVKCmdTransfer.h in Headers */, @@ -2097,6 +2103,7 @@ 2FEA0A9324902F9F00EEF3AD /* MVKImage.mm in Sources */, 2FEA0A9424902F9F00EEF3AD /* MVKCommandPool.mm in Sources */, 2FEA0A9524902F9F00EEF3AD /* MVKCmdDraw.mm in Sources */, + 1155DEB72C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */, 2FEA0A9624902F9F00EEF3AD /* MVKCommandBuffer.mm in Sources */, 2FEA0A9724902F9F00EEF3AD /* MVKCmdRendering.mm in Sources */, 2FEA0A9824902F9F00EEF3AD /* MVKBuffer.mm in Sources */, @@ -2200,6 +2207,7 @@ A9C96DD21DDC20C20053187F /* MVKMTLBufferAllocation.mm in Sources */, A9E53DE92100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */, A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */, + 1155DEB62C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */, A99C90F0229455B300A061DA /* MVKCmdDebug.mm in Sources */, 45E3A40D2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m in Sources */, ); @@ -2263,6 +2271,7 @@ A9C96DD31DDC20C20053187F /* MVKMTLBufferAllocation.mm in Sources */, A9E53DEA2100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */, A9096E5F1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */, + 1155DEB52C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */, A99C90F1229455B300A061DA /* MVKCmdDebug.mm in Sources */, 45E3A40E2166B923005E3E38 /* MTLRenderPipelineColorAttachmentDescriptor+MoltenVK.m in Sources */, ); @@ -2318,6 +2327,7 @@ DCFD7F372A45BC6E007BBBF7 /* MVKInstance.mm in Sources */, DCFD7F382A45BC6E007BBBF7 /* MVKDeviceMemory.mm in Sources */, DCFD7F392A45BC6E007BBBF7 /* MVKImage.mm in Sources */, + 1155DEB82C50C1BC009D70F8 /* MVKAddressMap.cpp in Sources */, DCFD7F3A2A45BC6E007BBBF7 /* MVKCommandPool.mm in Sources */, DCFD7F3B2A45BC6E007BBBF7 /* MVKCmdDraw.mm in Sources */, DCFD7F3C2A45BC6E007BBBF7 /* MVKCommandBuffer.mm in Sources */, diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h index 4a18f622a..03f4e2ab5 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h @@ -26,8 +26,8 @@ #include "MVKSmallVector.h" #include "MVKPixelFormats.h" #include "MVKOSExtensions.h" +#include "MVKAddressMap.h" #include "mvk_datatypes.hpp" -#include "MVKMap.h" #include #include @@ -529,16 +529,11 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { const VkCalibratedTimestampInfoEXT* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); - - /** Returns a pointer to the buffer at the provided address*/ - MVKBuffer* getBufferAtAddress(uint64_t address); // Unsure where to place within the file - - /** Returns a pointer to the acceleration structure at the provided address*/ - MVKAccelerationStructure* getAccelerationStructureAtAddress(uint64_t address); - + /** Returns whether or not the device supports acceleration structures*/ VkAccelerationStructureCompatibilityKHR getAccelerationStructureCompatibility(const VkAccelerationStructureVersionInfoKHR* pVersionInfo); + #pragma mark Object lifecycle MVKBuffer* createBuffer(const VkBufferCreateInfo* pCreateInfo, @@ -770,6 +765,12 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { /** Log all performance statistics. */ void logPerformanceSummary(); + + /** Returns a pointer to the buffer at the provided address*/ + MVKBuffer* getBufferAtAddress(uint64_t address); + + /** Returns a pointer to the acceleration structure at the provided address*/ + MVKAccelerationStructure* getAccelerationStructureAtAddress(uint64_t address); #pragma mark Metal @@ -937,9 +938,9 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject { MVKSmallVector, kMVKQueueFamilyCount> _queuesByQueueFamilyIndex; MVKSmallVector _resources; MVKSmallVector _gpuAddressableBuffers; - std::unordered_map _gpuBufferAddressMap; + MVKAddressMap* _gpuBufferAddressMap; + uint64_t _nextValidAccStructureAddress = 0; std::unordered_map _gpuAccStructAddressMap; - uint64_t _nextValidAccStructureAddress; MVKSmallVector _privateDataSlots; MVKSmallVector _privateDataSlotsAvailability; MVKSmallVector _awaitingSemaphores; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm index 0fab842f6..cdb875f60 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm @@ -3784,24 +3784,9 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope MVKBuffer* MVKDevice::getBufferAtAddress(uint64_t address) { - lock_guard lock(_rezLock); - - std::unordered_map::iterator it; - // Super inefficent but this can be fixed in the future - for(it = _gpuBufferAddressMap.begin(); it != _gpuBufferAddressMap.end(); it++) - { - // If the beginning address is bigger than, or the ending address is smaller than the passed address, then skip this it - if(it->first.first > address || it->first.second < address) - { - continue; - } - break; - } - - // Couldn't find the buffer at address - if (it == _gpuBufferAddressMap.end()) { return nullptr;} - - return it->second; + void* value = nullptr; + _gpuBufferAddressMap->getValue(address, value); + return (MVKBuffer*)value; } MVKAccelerationStructure* MVKDevice::getAccelerationStructureAtAddress(uint64_t address) @@ -4316,6 +4301,11 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope _resources.push_back(mvkBuff); if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { _gpuAddressableBuffers.push_back(mvkBuff); + _gpuBufferAddressMap->addEntry({ + mvkBuff->getMTLBufferGPUAddress(), + mvkBuff->getByteCount(), + mvkBuff + }); } return mvkBuff; } @@ -4327,6 +4317,11 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope mvkRemoveFirstOccurance(_resources, mvkBuff); if (mvkIsAnyFlagEnabled(mvkBuff->getUsage(), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) { mvkRemoveFirstOccurance(_gpuAddressableBuffers, mvkBuff); + _gpuBufferAddressMap->removeEntry({ + mvkBuff->getMTLBufferGPUAddress(), + mvkBuff->getByteCount(), + mvkBuff + }); } return mvkBuff; } @@ -4872,6 +4867,8 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope _commandResourceFactory = new MVKCommandResourceFactory(this); + _gpuBufferAddressMap = new MVKAddressMap(); + startAutoGPUCapture(MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_DEVICE, getMTLDevice()); MVKLogInfo("Created VkDevice to run on GPU %s with the following %d Vulkan extensions enabled:%s", @@ -5198,6 +5195,8 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope if (_commandResourceFactory) { _commandResourceFactory->destroy(); } + if (_gpuBufferAddressMap) { delete _gpuBufferAddressMap; } + [_globalVisibilityResultMTLBuffer release]; [_defaultMTLSamplerState release]; [_dummyBlitMTLBuffer release]; diff --git a/MoltenVK/MoltenVK/Utility/MVKAddressMap.cpp b/MoltenVK/MoltenVK/Utility/MVKAddressMap.cpp new file mode 100644 index 000000000..3f59b1477 --- /dev/null +++ b/MoltenVK/MoltenVK/Utility/MVKAddressMap.cpp @@ -0,0 +1,211 @@ +/* + * MVKAddressMap.cpp + * + * Copyright (c) 2015-2024 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MVKAddressMap.h" +#include + +/** + * Loads the value of an atomic pointer or allocates if it is null in a thread-safe way. + * Returned pointer will never be null. + */ +template +T* loadAtomic(std::atomic& ptr) +{ + T* obj = ptr.load(std::memory_order_acquire); + if (!obj) + { + T* newObj = new T(); + + bool swapped = ptr.compare_exchange_strong(obj, newObj, std::memory_order_release, std::memory_order_acquire); + if (swapped) + obj = newObj; + else + // Someone else allocated, so a new object is no longer needed + delete newObj; + } + + return obj; +} + +MVKAddressMap::~MVKAddressMap() +{ + for (uint64_t i = 0; i < NodeCount; i++) + { + Node* node = _nodes[i].load(std::memory_order_acquire); + if (!node) continue; + + for (uint64_t j = 0; j < BlockCount; j++) + { + SmallStorage* small = node->blocks[j].small.load(std::memory_order_acquire); + if (!small) continue; + + delete small; + } + + delete node; + } +} + +MVKAddressMap::Block* MVKAddressMap::loadBlock(uint64_t addr) +{ + uint64_t blockIdx = getBlockIndex(addr); + uint64_t nodeIdx = getNodeIndex(addr); + + Node* node = loadAtomic(_nodes[nodeIdx]); + + return &node->blocks[blockIdx]; +} + +MVKAddressMap::Block* MVKAddressMap::getBlock(uint64_t addr) const +{ + uint64_t nodeIdx = getNodeIndex(addr); + + Node* node = _nodes[nodeIdx].load(std::memory_order_acquire); + if (!node) + return nullptr; + + uint64_t blockIdx = getBlockIndex(addr); + + return &node->blocks[blockIdx]; +} + +void MVKAddressMap::processEntry(const Entry& entry, bool add) +{ + if (entry.size >= BlockSize) + { + uint64_t low = entry.baseAddress; + uint64_t high = low + entry.size; + + Entry empty{}; + while (low <= high) + { + Block* block = loadBlock(low); + + // If we are adding, insert right only on the first entry, and otherwise + // insert left. If we are removing, we should always reset right and left + // if the value matches. + if (add) + { + if (low == entry.baseAddress) + block->right.store(entry, std::memory_order_relaxed); + else + block->left.store(entry, std::memory_order_relaxed); + } + else + { + if (block->right.load(std::memory_order_relaxed).value == entry.value) + block->right.store(empty, std::memory_order_relaxed); + else if (block->left.load(std::memory_order_relaxed).value == entry.value) + block->left.store(empty, std::memory_order_relaxed); + } + + low += BlockSize; + } + } + else + { + // If the entry is smaller than BlockSize, it is not well-defined to + // mark blocks since one could have multiple small ranges within the same + // block. Thus, these must be stored separately. We will assume that most + // allocations are larger and thus this path is less common. We could optimize + // here and store in a sorted order and binary search later, but that may + // be an unnecessary optimization. + + Block* block = loadBlock(entry.baseAddress); + + SmallStorage* small = loadAtomic(block->small); + + auto lock = std::lock_guard(small->lock); + if (add) + small->entries.emplace_back(entry); + else + { + auto found = std::find_if( + small->entries.begin(), + small->entries.end(), + [&entry](Entry& e) { return e.value == entry.value; } + ); + if (found != small->entries.end()) + small->entries.erase(found); + } + } +} + +void MVKAddressMap::addEntry(const Entry& entry) +{ + processEntry(entry, true); +} + +void MVKAddressMap::removeEntry(const Entry& entry) +{ + processEntry(entry, false); +} + +bool MVKAddressMap::getEntry(uint64_t addr, Entry& outEntry) const +{ + Block* block = getBlock(addr); + + // First check left. This means the address is within the range and the base + // address is to the left. + Entry left = block->left.load(std::memory_order_relaxed); + if (left.baseAddress && addr < left.baseAddress + left.size) + { + outEntry = left; + return true; + } + + // Next check right. This means the base address is within the same block. + Entry right = block->right.load(std::memory_order_relaxed); + if (right.baseAddress && addr >= right.baseAddress) + { + outEntry = right; + return true; + } + + // Otherwise, we need to search for small entries. + SmallStorage* small = block->small.load(std::memory_order_acquire); + if (!small) + return false; + + // Find the small entry where the address is within the range. + auto lock = std::lock_guard(small->lock); + auto found = std::find_if( + small->entries.begin(), + small->entries.end(), + [addr](Entry& e) { return addr >= e.baseAddress && addr < e.baseAddress + e.size; } + ); + if (found != small->entries.end()) + { + outEntry = *found; + return true; + } + + return false; +} + +bool MVKAddressMap::getValue(uint64_t addr, void*& outValue) const +{ + Entry entry; + if (getEntry(addr, entry)) + { + outValue = entry.value; + return true; + } + + return false; +} diff --git a/MoltenVK/MoltenVK/Utility/MVKAddressMap.h b/MoltenVK/MoltenVK/Utility/MVKAddressMap.h new file mode 100644 index 000000000..5402aa801 --- /dev/null +++ b/MoltenVK/MoltenVK/Utility/MVKAddressMap.h @@ -0,0 +1,149 @@ +/* + * MVKAddressMap.h + * + * Copyright (c) 2015-2024 The Brenwill Workshop Ltd. (http://www.brenwill.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "MVKFoundation.h" +#include "MVKSmallVector.h" +#include + +/** + * Maintains a mapping from memory address ranges as keys to arbitrary pointer values. + * + * This data structure is thread-safe. + * + * The map can be queried with any arbitrary address within an inserted range's min and max, + * and they will all map to the same value. + * + * Because not all bits are used in 64-bit memory addresses, this map may not work with + * any arbitrary 64-bit integer range. However, it can always be used with 32-bit integers + * for more generalized use cases. + */ +class MVKAddressMap +{ +public: + + /** + * A key-value entry for the map + */ + struct Entry + { + uint64_t baseAddress; + uint64_t size; + + void* value; + }; + +public: + + /** + * Add an entry to the map. Thread-safe. + * + * The address range must not overlap an existing range, otherwise removal + * and querying are no longer well-defined. + */ + void addEntry(const Entry& entry); + + /** + * Remove an entry to the map. Thread-safe. + * + * The address range must exactly match an existing range, otherwise removal + * and querying are no longer well-defined. + */ + void removeEntry(const Entry& entry); + + /** + * Query the map given an arbitrary address, and return true if it exists. Thread-safe. + * + * Sets outEntry with the queried entry if it exists + */ + bool getEntry(uint64_t addr, Entry& outEntry) const; + + /** + * Query the map given an arbitrary address, and return true if it exists. Thread-safe. + * + * Sets outValue with the queried value if it exists + */ + bool getValue(uint64_t addr, void*& outValue) const; + + ~MVKAddressMap(); + +private: + + static constexpr uint64_t BlockSizeBits = 21; // 2mb + static constexpr uint64_t BlockSize = 1 << BlockSizeBits; + + static constexpr uint64_t BlockCountBits = 18; + static constexpr uint64_t BlockCount = 1 << BlockCountBits; + static constexpr uint64_t BlockCountMask = BlockCount - 1; + + static constexpr uint64_t NodeCountBits = 12; + static constexpr uint64_t NodeCount = 1 << NodeCountBits; + static constexpr uint64_t NodeCountMask = NodeCount - 1; + +private: + + /** Dynamically allocated storage for memory blocks smaller than BlockSize */ + struct SmallStorage + { + std::mutex lock; + MVKSmallVector entries; + }; + + /** Storage for one contiguous memory block of size BlockSize */ + struct Block + { + std::atomic left; + std::atomic right; + + std::atomic small; + }; + + /** Dynamically allocated region with all blocks for that region */ + struct Node + { + Block blocks[BlockCount] = {}; + }; + +private: + + /** + * Load corresponding block where addr is located. Will never return nullptr + * and will allocate if the block was not previously allocated. + */ + Block* loadBlock(uint64_t addr); + + /** + * Get corresponding block where addr is located. Will return nullptr if the + * block was not previously allocated. + */ + Block* getBlock(uint64_t addr) const; + + /** Adds or removes an entry from the map, depending on the value of 'add' */ + void processEntry(const Entry& entry, bool add); + + /** Gets the node index associated with the provided address */ + inline uint64_t getNodeIndex(uint64_t addr) const { return (addr >> (BlockSizeBits + BlockCountBits)) & NodeCountMask; } + + /** Gets the block index associated with the provided address */ + inline uint64_t getBlockIndex(uint64_t addr) const { return (addr >> BlockSizeBits) & BlockCountMask; } + +private: + std::atomic _nodes[NodeCount] = {}; +}; + diff --git a/MoltenVK/MoltenVK/Utility/MVKMap.h b/MoltenVK/MoltenVK/Utility/MVKMap.h deleted file mode 100644 index 19ceaf24b..000000000 --- a/MoltenVK/MoltenVK/Utility/MVKMap.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * MVKMap.h - * - * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "MVKFoundation.h" -#include "MVKMapAllocator.h" - - -struct MVKHash_uint64_t_pair { // Change the naming style? - size_t operator()(std::pair p) const noexcept { - return size_t(p.first) << 32 | p.second; // Hopefully this is unique enough of a hash, anyway only 1 buffer can ocupy between these 2 memory addreses - } -}; - -template, - class Hash = std::hash> -class MVKMapImpl { - -private: - Allocator alc; - - class iterator - { - const MVKMapImpl* map; - size_t index; - public: - using iterator_category = std::random_access_iterator_tag; - using difference_type = std::ptrdiff_t; - typedef difference_type diff_type; - - iterator() : map{ nullptr }, index{ 0 } { } - iterator(const size_t _index, const MVKMapImpl &_map) : map{ &_map }, index{ _index } { } - - iterator &operator=(const iterator &it) - { - map = it.map; - index = it.index; - return *this; - } - - T *operator->() { return &map->alc.ptr[index]; } - T &operator*() { return map->alc.ptr[index]; } - operator T*() { return &map->alc.ptr[index]; } - - bool operator==( const iterator &it ) const { return map == it.map && index == it.index; } - bool operator!=( const iterator &it ) const { return map != it.map || index != it.index; } - - iterator& operator++() { ++index; return *this; } - iterator operator++( int ) { auto t = *this; ++index; return t; } - iterator& operator--() { --index; return *this; } - iterator operator--( int ) { auto t = *this; --index; return t; } - - iterator operator+ (const diff_type n) { return iterator( index + n, *map ); } - iterator& operator+= (const diff_type n) { index += n; return *this; } - iterator operator- (const diff_type n) { return iterator( index - n, *map ); } - iterator& operator-= (const diff_type n) { index -= n; return *this; } - - diff_type operator- (const iterator& it) { return index - it.index; } - - bool operator< (const iterator& it) { return index < it.index; } - bool operator<= (const iterator& it) { return index <= it.index; } - bool operator> (const iterator& it) { return index > it.index; } - bool operator>= (const iterator& it) { return index >= it.index; } - - const T &operator[]( const diff_type i ) const { return map->alc.ptr[index + i]; } - T &operator[]( const diff_type i ) { return map->alc.ptr[index + i]; } - - bool is_valid() const { return index < map->alc.size(); } - size_t get_position() const { return index; } - }; -protected: - bool empty() { return alc.num_elements_used == 0;} - size_t size() { return alc.size(); } - - T* &at( const size_t i ) { return alc[i]; } - const T* const at(const size_t i) const { return alc[i]; } - - iterator begin() { return iterator(0, this); } - iterator end() { return iterator(size(), this); } - - void erase(const iterator it) - { - if(it.is_valid()) - { - --alc.num_elements_used; - - for(size_t i = it.get_position(); i < alc.num_elements_used; ++i) - { - alc.ptr[i] = alc.ptr[i + 1]; - } - } - } - - void erase(const iterator first, const iterator last) - { - if(first.is_valid()) - { - size_t last_pos = last.is_valid() ? last.get_position() : size(); - size_t n = last_pos - first.get_position(); - alc.num_elements_used -= n; - - for(size_t i = first.get_position(), e = last_pos; i < alc.num_elements_used && e < alc.num_elements_used + n; ++i, ++e) - { - alc.ptr[i] = alc.ptr[e]; - } - } - } - - std::pair insert(const T& value) - { - alc.re_allocate(size() + 1); - alc.ptr[size()] = value; - return std::make_pair(end(), true); - } -}; diff --git a/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h b/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h deleted file mode 100644 index 6387e9d0c..000000000 --- a/MoltenVK/MoltenVK/Utility/MVKMapAllocator.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * MVKMap.h - * - * Copyright (c) 2015-2023 The Brenwill Workshop Ltd. (http://www.brenwill.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "MVKFoundation.h" -#include - -namespace mvk_map_memory_allocator -{ - inline char *alloc(const size_t num_bytes) - { - return new char[num_bytes]; - } - - inline void free(void *ptr) - { - delete[] (char*)ptr; - } -}; - -template -class mvk_map_allocator final { - -public: - std::pair* ptr; - size_t num_elements_used; -private: - static constexpr size_t CAP_CNT_SIZE = sizeof(size_t); - static constexpr size_t ALIGN_CNT = CAP_CNT_SIZE / sizeof(std::pair); - static constexpr size_t ALIGN_MASK = (ALIGN_CNT> 0) ? (ALIGN_CNT - 1) : 0; - - static constexpr size_t MIN_CNT = M> ALIGN_CNT ? M : ALIGN_CNT; - static constexpr size_t N = (MIN_CNT + ALIGN_MASK) & ~ALIGN_MASK; - - static constexpr size_t MIN_STACK_SIZE = (N * sizeof(std::pair)); - static constexpr size_t STACK_SIZE = MIN_STACK_SIZE> CAP_CNT_SIZE ? MIN_STACK_SIZE : CAP_CNT_SIZE; - alignas(alignof(std::pair)) unsigned char elements_stack[ STACK_SIZE ]; - - void set_num_elements_reserved(const size_t num_elements_reserved) - { - *reinterpret_cast(&elements_stack[0]) = num_elements_reserved; - } -public: - const T &operator[](const size_t i) const { return ptr[i]; } - T &operator[](const size_t i) { return ptr[i]; } - - size_t size() const { return num_elements_used; } - - constexpr T *get_default_ptr() const - { - return reinterpret_cast(const_cast(&elements_stack[0])); - } - - template typename std::enable_if::value>::type - construct(S *_ptr, Args&&... _args) - { - new (_ptr) S(std::forward(_args)...); - } - - template typename std::enable_if::value>::type - construct(S *_ptr, Args&&... _args) - { - *_ptr = S(std::forward(_args)...); - } - - template typename std::enable_if::value>::type - destruct(S *_ptr) - { - _ptr->~S(); - } - - template typename std::enable_if::value>::type - destruct(S *_ptr) {} - - template typename std::enable_if::value>::type - destruct_all() - { - for(size_t i = 0; i < num_elements_used; ++i) - { - ptr[i].~S(); - } - - num_elements_used = 0; - } - - template typename std::enable_if::value>::type - destruct_all() - { - num_elements_used = 0; - } - - void re_allocate(const size_t num_elements_to_reserve) - { - auto *new_ptr = reinterpret_cast(mvk_smallvector_memory_allocator::alloc(num_elements_to_reserve * sizeof(T))); - - for(size_t i = 0; i < num_elements_used; ++i) - { - construct(&new_ptr[i], std::move(ptr[i])); - destruct(&ptr[i]); - } - - if(ptr != get_default_ptr()) - { - mvk_smallvector_memory_allocator::free(ptr); - } - - ptr = new_ptr; - set_num_elements_reserved(num_elements_to_reserve); - } -}; From 4dea75cc4d275752b5bf9359f8f8001cecbe37c5 Mon Sep 17 00:00:00 2001 From: Antarctic Coder Date: Thu, 25 Jul 2024 01:37:36 -0400 Subject: [PATCH 29/32] Implement Write Acc Structure Properties - WIP This commit adds the device command 'kCmdWriteAccelerationStructuresPropertiesKHR'. --- .../Commands/MVKCmdAccelerationStructure.h | 22 ++++++++++ .../Commands/MVKCmdAccelerationStructure.mm | 44 +++++++++++++++++++ .../MoltenVK/Commands/MVKCommandTypePools.def | 3 +- .../GPUObjects/MVKAccelerationStructure.h | 10 ++--- .../GPUObjects/MVKAccelerationStructure.mm | 1 + MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm | 1 + MoltenVK/MoltenVK/Utility/MVKFoundation.h | 1 + MoltenVK/MoltenVK/Vulkan/vulkan.mm | 13 ++++++ 8 files changed, 89 insertions(+), 6 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index e9eb11a55..4971f1efe 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -117,4 +117,26 @@ class MVKCmdCopyMemoryToAccelerationStructure: public MVKCommand { VkCopyAccelerationStructureModeKHR _copyMode; }; +#pragma mark - +#pragma mark MVKCmdWriteAccelerationStructuresProperties +class MVKCmdWriteAccelerationStructuresProperties: public MVKCommand { + +public: + VkResult setContent(MVKCommandBuffer* cmdBuff, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery); + + void encode(MVKCommandEncoder* cmdEncoder) override; +protected: + MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; + + uint32_t _accelerationStructureCount; + const MVKAccelerationStructure* _pAccelerationStructures; + VkQueryType _queryType; + VkQueryPool _queryPool; + uint32_t _firstQuery; +}; diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 50ff7bf38..2943f718c 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -250,3 +250,47 @@ [blitEncoder copyFromBuffer:_srcBuffer->getMTLBuffer() sourceOffset:0 toBuffer:_dstAccelerationStructureBuffer destinationOffset:0 size:_copySize]; } + +#pragma mark - +#pragma mark MVKCmdWriteAccelerationStructuresProperties + +VkResult MVKCmdWriteAccelerationStructuresProperties::setContent(MVKCommandBuffer* cmdBuff, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery) { + + _accelerationStructureCount = accelerationStructureCount; + _pAccelerationStructures = (const MVKAccelerationStructure*)pAccelerationStructures; + _queryType = queryType; + _queryPool = queryPool; + _firstQuery = firstQuery; + return VK_SUCCESS; +} + +void MVKCmdWriteAccelerationStructuresProperties::encode(MVKCommandEncoder* cmdEncoder) { + + for(int i = 0; i < _accelerationStructureCount; i++) + { + if(!_pAccelerationStructures[i].getBuildStatus()) { + return; + } + + // actually finish up the meat of the code here + } + + switch(_queryType) + { + case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR: + break; + case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR: + break; + case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR: + break; + case VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR: + break; + default: + break; + } +} diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def index 6b2e1b90f..dea1ade84 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def +++ b/MoltenVK/MoltenVK/Commands/MVKCommandTypePools.def @@ -145,7 +145,8 @@ MVK_CMD_TYPE_POOL(ResetEvent) MVK_CMD_TYPE_POOL(BuildAccelerationStructure) MVK_CMD_TYPE_POOL(CopyAccelerationStructure) MVK_CMD_TYPE_POOL(CopyAccelerationStructureToMemory) -MVK_CMD_TYPE_POOL_LAST(CopyMemoryToAccelerationStructure) +MVK_CMD_TYPE_POOL(CopyMemoryToAccelerationStructure) +MVK_CMD_TYPE_POOL_LAST(WriteAccelerationStructuresProperties) #undef MVK_CMD_TYPE_POOL #undef MVK_CMD_TYPE_POOL_LAST diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 965a7d2ab..159a45087 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -65,25 +65,25 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { void setAllowUpdate(bool value) { _allowUpdate = value; } /** Checks if this acceleration structure is allowed to be updated*/ - bool getAllowUpdate() { return _allowUpdate; } + bool getAllowUpdate() const { return _allowUpdate; } /** Only to be called by the MVKCmdBuildAccelerationStructure, and sets the build status*/ void setBuildStatus(bool value) { _built = value; } /** Checks if this acceleration structure has been built*/ - bool getBuildStatus() { return _built; } + bool getBuildStatus() const { return _built; } /** Sets the address of the acceleration structure, only to be used by MVKDevice*/ void setDeviceAddress(uint64_t address) { _address = address; } /** Gets the address of the acceleration structure*/ - uint64_t getDeviceAddress() { return _address; } + uint64_t getDeviceAddress() const { return _address; } /** Returns the Metal buffer using the same memory as the acceleration structure*/ - id getMTLBuffer() { return _buffer; } + id getMTLBuffer() const { return _buffer; } /** Gets the heap allocation that the acceleration structure, and buffer share*/ - id getMTLHeap() { return _heap; } + id getMTLHeap() const { return _heap; } MTLAccelerationStructureTriangleGeometryDescriptor* getTriangleDescriptor(); #pragma mark - diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index 4852c27dd..b94b64800 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -99,6 +99,7 @@ { accStructDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; MTLInstanceAccelerationStructureDescriptor* instanceAccStructDescriptor = (MTLInstanceAccelerationStructureDescriptor*)accStructDescriptor; + // add bottom level acceleration structures instanceAccStructDescriptor.instanceDescriptorType = MTLAccelerationStructureInstanceDescriptorTypeDefault; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm index ae1940115..a1364331c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm @@ -721,6 +721,7 @@ ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyAccelerationStructureToMemoryKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyMemoryToAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); + ADD_DVC_EXT_ENTRY_POINT(vkCmdCopyMemoryToAccelerationStructureKHR, KHR_ACCELERATION_STRUCTURE); ADD_DVC_EXT_ENTRY_POINT(vkCreateDeferredOperationKHR, KHR_DEFERRED_HOST_OPERATIONS); ADD_DVC_EXT_ENTRY_POINT(vkDeferredOperationJoinKHR, KHR_DEFERRED_HOST_OPERATIONS); diff --git a/MoltenVK/MoltenVK/Utility/MVKFoundation.h b/MoltenVK/MoltenVK/Utility/MVKFoundation.h index cb7294bfb..0d1c23cf8 100644 --- a/MoltenVK/MoltenVK/Utility/MVKFoundation.h +++ b/MoltenVK/MoltenVK/Utility/MVKFoundation.h @@ -102,6 +102,7 @@ typedef enum : uint8_t { kMVKCommandUseCopyAccelerationStructure, /**< vkCmdCopyAccelerationStructure- Copies an acceleration structure to another acceleration structure*/ kMVKCommandUseCopyAccelerationStructureToMemory,/**< vkCmdCopyAccelerationStructureToMemory - Copies and serializes an acceleration structure to a buffer*/ kMVKCommandUseCopyMemoryToAccelerationStructure,/**< vkCmdCopyMemoryToAccelerationStructure - Copies and deserializes an acceleration structure from a buffer*/ + kMVKCommandUseWriteAccelerationStructuresProperties, } MVKCommandUse; /** Represents a given stage of a graphics pipeline. */ diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index 6ec16ba9c..cedb0cc87 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2973,6 +2973,19 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkCmdCopyMemoryToAccelerationStructureKHR( MVKTraceVulkanCallEnd(); } +MVK_PUBLIC_VULKAN_SYMBOL void vkCmdWriteAccelerationStructuresPropertiesKHR( + VkCommandBuffer commandBuffer, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery) { + + MVKTraceVulkanCallStart(); + MVKAddCmd(WriteAccelerationStructuresProperties, commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, queryPool, firstQuery); + MVKTraceVulkanCallEnd(); +} + #pragma mark - #pragma mark VK_KHR_bind_memory2 extension From b61a72c9d74c2cfa7da212253f15eaca1d800c81 Mon Sep 17 00:00:00 2001 From: TheApplePieGod Date: Sat, 27 Jul 2024 12:11:58 -0500 Subject: [PATCH 30/32] Refactor acc structure build & get build sizes --- .../Commands/MVKCmdAccelerationStructure.h | 13 +- .../Commands/MVKCmdAccelerationStructure.mm | 172 +++++--------- .../GPUObjects/MVKAccelerationStructure.h | 13 +- .../GPUObjects/MVKAccelerationStructure.mm | 223 ++++++++++++------ 4 files changed, 224 insertions(+), 197 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h index 4971f1efe..a09154bdc 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.h @@ -20,6 +20,7 @@ #include "MVKDevice.h" #include "MVKCommand.h" +#include "MVKSmallVector.h" #import #import @@ -37,13 +38,17 @@ class MVKCmdBuildAccelerationStructure : public MVKCommand { const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); void encode(MVKCommandEncoder* cmdEncoder) override; +protected: + struct MVKAccelerationStructureBuildInfo + { + VkAccelerationStructureBuildGeometryInfoKHR info; + MVKSmallVector geometries; + MVKSmallVector ranges; + }; protected: MVKCommandTypePool* getTypePool(MVKCommandPool* cmdPool) override; - MVKDevice* _mvkDevice; - uint32_t _infoCount; - VkAccelerationStructureBuildGeometryInfoKHR* _geometryInfos; - VkAccelerationStructureBuildRangeInfoKHR const* _buildRangeInfos; + MVKSmallVector _buildInfos; }; #pragma mark - diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm index 2943f718c..0748c31c3 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCmdAccelerationStructure.mm @@ -20,9 +20,10 @@ #include "MVKCmdDebug.h" #include "MVKCommandBuffer.h" #include "MVKCommandPool.h" - #include "MVKAccelerationStructure.h" +#include + #pragma mark - #pragma mark MVKCmdBuildAccelerationStructure @@ -30,142 +31,81 @@ uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) { - VkAccelerationStructureBuildGeometryInfoKHR geoInfo = *pInfos; - - _mvkDevice = cmdBuff->getDevice(); - _infoCount = infoCount; - _geometryInfos = &geoInfo; - _buildRangeInfos = *ppBuildRangeInfos; - + _buildInfos.reserve(infoCount); + for (uint32_t i = 0; i < infoCount; i++) + { + MVKAccelerationStructureBuildInfo& info = _buildInfos.emplace_back(); + info.info = pInfos[i]; + + // TODO: ppGeometries + info.geometries.reserve(pInfos[i].geometryCount); + info.ranges.reserve(pInfos[i].geometryCount); + memcpy(info.geometries.data(), pInfos[i].pGeometries, pInfos[i].geometryCount); + memcpy(info.ranges.data(), ppBuildRangeInfos[i], pInfos[i].geometryCount); + + info.info.pGeometries = info.geometries.data(); + } + return VK_SUCCESS; } void MVKCmdBuildAccelerationStructure::encode(MVKCommandEncoder* cmdEncoder) { id accStructEncoder = cmdEncoder->getMTLAccelerationStructureEncoder(kMVKCommandUseBuildAccelerationStructure); - for(int i = 0; i < _infoCount; i++) + for (MVKAccelerationStructureBuildInfo& entry : _buildInfos) { - MVKAccelerationStructure* mvkSrcAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos[i].srcAccelerationStructure; - MVKAccelerationStructure* mvkDstAccelerationStructure = (MVKAccelerationStructure*)_geometryInfos[i].dstAccelerationStructure; - - id srcAccelerationStructure = (id)mvkSrcAccelerationStructure->getMTLAccelerationStructure(); - id dstAccelerationStructure = (id)mvkDstAccelerationStructure->getMTLAccelerationStructure(); + VkAccelerationStructureBuildGeometryInfoKHR& buildInfo = entry.info; + + MVKAccelerationStructure* mvkSrcAccStruct = (MVKAccelerationStructure*)buildInfo.srcAccelerationStructure; + MVKAccelerationStructure* mvkDstAccStruct = (MVKAccelerationStructure*)buildInfo.dstAccelerationStructure; + + id srcAccStruct = mvkSrcAccStruct->getMTLAccelerationStructure(); + id dstAccStruct = mvkDstAccStruct->getMTLAccelerationStructure(); - id srcAccelerationStructureHeap = mvkSrcAccelerationStructure->getMTLHeap(); - id dstAccelerationStructureHeap = mvkDstAccelerationStructure->getMTLHeap(); + id srcAccStructHeap = mvkSrcAccStruct->getMTLHeap(); + id dstAccStructHeap = mvkDstAccStruct->getMTLHeap(); - if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && !mvkDstAccelerationStructure->getAllowUpdate()) - { + // Should we throw an error here? + // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdBuildAccelerationStructuresKHR.html#VUID-vkCmdBuildAccelerationStructuresKHR-pInfos-03667 + if(buildInfo.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR && !mvkDstAccStruct->getAllowUpdate()) continue; - } - MVKDevice* mvkDvc = cmdEncoder->getDevice(); - MVKBuffer* mvkBuffer = mvkDvc->getBufferAtAddress(_geometryInfos[i].scratchData.deviceAddress); + MVKDevice* mvkDevice = cmdEncoder->getDevice(); + MVKBuffer* mvkBuffer = mvkDevice->getBufferAtAddress(buildInfo.scratchData.deviceAddress); + + // TODO: throw error if mvkBuffer is null? id scratchBuffer = mvkBuffer->getMTLBuffer(); NSInteger scratchBufferOffset = mvkBuffer->getMTLBufferOffset(); - if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) + if (buildInfo.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) { - if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR) - { - MTLAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLAccelerationStructureDescriptor new]; - - if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - mvkDstAccelerationStructure->setAllowUpdate(true); - }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; - } - - [dstAccelerationStructureHeap newAccelerationStructureWithDescriptor:accStructBuildDescriptor]; - - [accStructEncoder buildAccelerationStructure:dstAccelerationStructure - descriptor:accStructBuildDescriptor - scratchBuffer:scratchBuffer - scratchBufferOffset:scratchBufferOffset]; - - } - - if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) - { - MTLPrimitiveAccelerationStructureDescriptor* accStructBuildDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; - - if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsageRefit; - mvkDstAccelerationStructure->setAllowUpdate(true); - }else if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructBuildDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructBuildDescriptor.usage = MTLAccelerationStructureUsageNone; - } - - if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) { return; } - - if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) - { - VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = _geometryInfos[i].pGeometries->geometry.triangles; - uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; - uint64_t indexBDA = triangleGeometryData.indexData.deviceAddress; - MVKBuffer* mvkVertexBuffer = _mvkDevice->getBufferAtAddress(vertexBDA); - MVKBuffer* mvkIndexBuffer = _mvkDevice->getBufferAtAddress(indexBDA); - - MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; - geometryTriangles.triangleCount = _geometryInfos[i].geometryCount; - geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); - geometryTriangles.vertexBufferOffset = mvkVertexBuffer->getMTLBufferOffset(); - - geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); - geometryTriangles.indexBufferOffset = mvkIndexBuffer->getMTLBufferOffset(); - geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); - accStructBuildDescriptor.geometryDescriptors = @[geometryTriangles]; - - [accStructEncoder buildAccelerationStructure:dstAccelerationStructure - descriptor:accStructBuildDescriptor - scratchBuffer:scratchBuffer - scratchBufferOffset:scratchBufferOffset]; - } - - if(_geometryInfos[i].pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) - { - VkAccelerationStructureGeometryAabbsDataKHR aabbGeometryData = _geometryInfos[i].pGeometries->geometry.aabbs; - uint64_t boundingBoxBDA = aabbGeometryData.data.deviceAddress; - MVKBuffer* mvkBoundingBoxBuffer = _mvkDevice->getBufferAtAddress(boundingBoxBDA); - - MTLAccelerationStructureBoundingBoxGeometryDescriptor* geometryAABBs = [MTLAccelerationStructureBoundingBoxGeometryDescriptor new]; - geometryAABBs.boundingBoxCount = _geometryInfos[i].geometryCount; - geometryAABBs.boundingBoxBuffer = mvkBoundingBoxBuffer->getMTLBuffer(); - geometryAABBs.boundingBoxStride = 0; // Need to get this - geometryAABBs.boundingBoxBufferOffset = mvkBoundingBoxBuffer->getMTLBufferOffset(); - accStructBuildDescriptor.geometryDescriptors = @[geometryAABBs]; - } - } - - if(_geometryInfos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) - { - MTLInstanceAccelerationStructureDescriptor* accStructInstanceBuildDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; - } + MTLAccelerationStructureDescriptor* descriptor = mvkDstAccStruct->populateMTLDescriptor( + mvkDevice, + buildInfo, + entry.ranges.data(), + nullptr + ); + + [accStructEncoder buildAccelerationStructure:dstAccStruct + descriptor:descriptor + scratchBuffer:scratchBuffer + scratchBufferOffset:scratchBufferOffset]; } - - if(_geometryInfos[i].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) + else if (buildInfo.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) { - MTLAccelerationStructureDescriptor* accStructRefitDescriptor = [MTLAccelerationStructureDescriptor new]; + MTLAccelerationStructureDescriptor* descriptor = [MTLAccelerationStructureDescriptor new]; - if(mvkIsAnyFlagEnabled(_geometryInfos[i].flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructRefitDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - } + if (mvkIsAnyFlagEnabled(buildInfo.flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)) + descriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - [accStructEncoder refitAccelerationStructure:srcAccelerationStructure - descriptor:accStructRefitDescriptor - destination:dstAccelerationStructure + [accStructEncoder refitAccelerationStructure:srcAccStruct + descriptor:descriptor + destination:dstAccStruct scratchBuffer:scratchBuffer scratchBufferOffset:scratchBufferOffset]; } } - - return; } #pragma mark - @@ -230,9 +170,9 @@ #pragma mark MVKCmdCopyMemoryToAccelerationStructure VkResult MVKCmdCopyMemoryToAccelerationStructure::setContent(MVKCommandBuffer* cmdBuff, - uint64_t srcAddress, - VkAccelerationStructureKHR dstAccelerationStructure, - VkCopyAccelerationStructureModeKHR copyMode) { + uint64_t srcAddress, + VkAccelerationStructureKHR dstAccelerationStructure, + VkCopyAccelerationStructureModeKHR copyMode) { _srcAddress = srcAddress; _copyMode = copyMode; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h index 159a45087..35d166e62 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.h @@ -34,7 +34,7 @@ #pragma once -#include "MVKVulkanAPIObject.h" +#include "MVKDevice.h" #import #import @@ -53,8 +53,17 @@ class MVKAccelerationStructure : public MVKVulkanAPIDeviceObject { id getMTLAccelerationStructure(); + /** Populates a MTL acceleration structure descriptor given a vulkan descriptor */ + static MTLAccelerationStructureDescriptor* populateMTLDescriptor(MVKDevice* device, + const VkAccelerationStructureBuildGeometryInfoKHR& buildInfo, + const VkAccelerationStructureBuildRangeInfoKHR* rangeInfos, + const uint32_t* maxPrimitiveCounts); + /** Gets the required build sizes for acceleration structure and scratch buffer*/ - static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(MVKDevice* device, VkAccelerationStructureBuildTypeKHR buildType, const VkAccelerationStructureBuildGeometryInfoKHR* buildInfo); + static VkAccelerationStructureBuildSizesInfoKHR getBuildSizes(MVKDevice* device, + VkAccelerationStructureBuildTypeKHR buildType, + const VkAccelerationStructureBuildGeometryInfoKHR* buildInfo, + const uint32_t* maxPrimitiveCounts); /** Gets the actual size of the acceleration structure*/ uint64_t getMTLSize(); diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index b94b64800..b0996a3c3 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -20,81 +20,139 @@ #include "MVKBuffer.h" #include "MVKAccelerationStructure.h" +#include + #pragma mark - #pragma mark MVKAcceleration Structure -id MVKAccelerationStructure::getMTLAccelerationStructure() { +id MVKAccelerationStructure::getMTLAccelerationStructure() +{ return _accelerationStructure; } - -VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes(MVKDevice* device, VkAccelerationStructureBuildTypeKHR type, const VkAccelerationStructureBuildGeometryInfoKHR* info) -{ - VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; - MTLAccelerationStructureDescriptor* accStructDescriptor; - if(type == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR) { - // We can't do that, throw an error? - return vkBuildSizes; - } - - switch (info->type) +MTLAccelerationStructureDescriptor* MVKAccelerationStructure::populateMTLDescriptor(MVKDevice* device, + const VkAccelerationStructureBuildGeometryInfoKHR& buildInfo, + const VkAccelerationStructureBuildRangeInfoKHR* rangeInfos, + const uint32_t* maxPrimitiveCounts) +{ + MTLAccelerationStructureDescriptor* descriptor = nullptr; + + switch (buildInfo.type) { + default: + break; // TODO: throw error case VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR: { - accStructDescriptor = [MTLAccelerationStructureDescriptor new]; - break; - } - + // TODO: should building generic not be allowed? + // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkAccelerationStructureTypeKHR.html + } break; + case VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR: { - if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_AABBS_KHR) - { - accStructDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; - MTLPrimitiveAccelerationStructureDescriptor* primitiveAccStructDescriptor = (MTLPrimitiveAccelerationStructureDescriptor*)accStructDescriptor; - - VkAccelerationStructureGeometryAabbsDataKHR aabbGeometryData = info->pGeometries->geometry.aabbs; - uint64_t boundingBoxBDA = aabbGeometryData.data.deviceAddress; - MVKBuffer* mvkBoundingBoxBuffer = device->getBufferAtAddress(boundingBoxBDA); - - MTLAccelerationStructureBoundingBoxGeometryDescriptor* geometryAABBs = [MTLAccelerationStructureBoundingBoxGeometryDescriptor new]; - geometryAABBs.boundingBoxCount = info->geometryCount; - geometryAABBs.boundingBoxBuffer = mvkBoundingBoxBuffer->getMTLBuffer(); - geometryAABBs.boundingBoxStride = 0; // Need to get this - geometryAABBs.boundingBoxBufferOffset = mvkBoundingBoxBuffer->getMTLBufferOffset(); - primitiveAccStructDescriptor.geometryDescriptors = @[geometryAABBs]; - break; - - } - if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) { return vkBuildSizes; } - - if(info->pGeometries->geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) - { - accStructDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; - MTLPrimitiveAccelerationStructureDescriptor* primitiveAccStructDescriptor = (MTLPrimitiveAccelerationStructureDescriptor*)accStructDescriptor; - - VkAccelerationStructureGeometryTrianglesDataKHR triangleGeometryData = info->pGeometries->geometry.triangles; - uint64_t vertexBDA = triangleGeometryData.vertexData.deviceAddress; - uint64_t indexBDA = triangleGeometryData.indexData.deviceAddress; - MVKBuffer* mvkVertexBuffer = device->getBufferAtAddress(vertexBDA); - MVKBuffer* mvkIndexBuffer = device->getBufferAtAddress(indexBDA); - - MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; - geometryTriangles.triangleCount = info->geometryCount; - geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); - geometryTriangles.vertexBufferOffset = mvkVertexBuffer->getMTLBufferOffset(); - - geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); - geometryTriangles.indexBufferOffset = mvkIndexBuffer->getMTLBufferOffset(); - geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleGeometryData.indexType); - primitiveAccStructDescriptor.geometryDescriptors = @[geometryTriangles]; - break; - } - else + MTLPrimitiveAccelerationStructureDescriptor* primitive = [MTLPrimitiveAccelerationStructureDescriptor new]; + + NSMutableArray* geoms = [NSMutableArray arrayWithCapacity:buildInfo.geometryCount]; + for (uint32_t i = 0; i < buildInfo.geometryCount; i++) { - accStructDescriptor = [MTLPrimitiveAccelerationStructureDescriptor new]; + // TODO: buildInfo.ppGeometries + + const VkAccelerationStructureGeometryKHR& geom = buildInfo.pGeometries[i]; + switch (geom.geometryType) + { + default: + break; + + case VK_GEOMETRY_TYPE_INSTANCES_KHR: + break; + + case VK_GEOMETRY_TYPE_TRIANGLES_KHR: + { + const VkAccelerationStructureGeometryTrianglesDataKHR& triangleData = geom.geometry.triangles; + uint64_t vertexBDA = triangleData.vertexData.deviceAddress; + uint64_t indexBDA = triangleData.indexData.deviceAddress; + uint64_t transformBDA = triangleData.transformData.deviceAddress; + MVKBuffer* mvkVertexBuffer = device->getBufferAtAddress(vertexBDA); + MVKBuffer* mvkIndexBuffer = device->getBufferAtAddress(indexBDA); + MVKBuffer* mvkTransformBuffer = device->getBufferAtAddress(transformBDA); + + // TODO: should validate that buffer->getMTLBufferOffset is a multiple of vertexStride. This could cause issues + NSUInteger vbOffset = (vertexBDA - mvkVertexBuffer->getMTLBufferGPUAddress()) + mvkVertexBuffer->getMTLBufferOffset(); + NSUInteger ibOffset = 0; + NSUInteger tfOffset = 0; + + MTLAccelerationStructureTriangleGeometryDescriptor* geometryTriangles = [MTLAccelerationStructureTriangleGeometryDescriptor new]; + geometryTriangles.vertexBuffer = mvkVertexBuffer->getMTLBuffer(); + geometryTriangles.vertexStride = triangleData.vertexStride; + + if (transformBDA && mvkTransformBuffer) + { + tfOffset = (transformBDA - mvkTransformBuffer->getMTLBufferGPUAddress()) + mvkTransformBuffer->getMTLBufferOffset(); + geometryTriangles.transformationMatrixBuffer = mvkTransformBuffer->getMTLBuffer(); + } + + bool useIndices = indexBDA && mvkIndexBuffer && triangleData.indexType != VK_INDEX_TYPE_NONE_KHR; + if (useIndices) + { + ibOffset = (indexBDA - mvkIndexBuffer->getMTLBufferGPUAddress()) + mvkIndexBuffer->getMTLBufferOffset(); + geometryTriangles.indexBuffer = mvkIndexBuffer->getMTLBuffer(); + geometryTriangles.indexType = mvkMTLIndexTypeFromVkIndexType(triangleData.indexType); + } + + if (rangeInfos) + { + // Utilize range information during build time + + geometryTriangles.triangleCount = rangeInfos[i].primitiveCount; + geometryTriangles.transformationMatrixBufferOffset = tfOffset + rangeInfos[i].transformOffset; + geometryTriangles.vertexBufferOffset = vbOffset; + geometryTriangles.indexBufferOffset = ibOffset + rangeInfos[i].primitiveOffset; + + if (!useIndices) + geometryTriangles.vertexBufferOffset += rangeInfos[i].primitiveOffset + rangeInfos[i].firstVertex * triangleData.vertexStride; + } + else + { + // Less information required when computing size + + geometryTriangles.vertexBufferOffset = vbOffset; + geometryTriangles.triangleCount = maxPrimitiveCounts[i]; + geometryTriangles.indexBufferOffset = ibOffset; + geometryTriangles.transformationMatrixBufferOffset = 0; + } + + [geoms addObject:geometryTriangles]; + } break; + + case VK_GEOMETRY_TYPE_AABBS_KHR: + { + const VkAccelerationStructureGeometryAabbsDataKHR& aabbData = geom.geometry.aabbs; + uint64_t boundingBoxBDA = aabbData.data.deviceAddress; + MVKBuffer* mvkBoundingBoxBuffer = device->getBufferAtAddress(boundingBoxBDA); + + NSUInteger bOffset = (boundingBoxBDA - mvkBoundingBoxBuffer->getMTLBufferGPUAddress()) + mvkBoundingBoxBuffer->getMTLBufferOffset(); + + MTLAccelerationStructureBoundingBoxGeometryDescriptor* geometryAABBs = [MTLAccelerationStructureBoundingBoxGeometryDescriptor new]; + geometryAABBs.boundingBoxStride = aabbData.stride; + geometryAABBs.boundingBoxBuffer = mvkBoundingBoxBuffer->getMTLBuffer(); + geometryAABBs.boundingBoxBufferOffset = bOffset; + + if (rangeInfos) + { + geometryAABBs.boundingBoxCount = rangeInfos[i].primitiveCount; + geometryAABBs.boundingBoxBufferOffset += rangeInfos[i].primitiveOffset; + } + else + geometryAABBs.boundingBoxCount = maxPrimitiveCounts[i]; + + [geoms addObject:geometryAABBs]; + } break; + } } - break; - } + + primitive.geometryDescriptors = geoms; + descriptor = primitive; + } break; + case VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR: { accStructDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; @@ -102,21 +160,36 @@ // add bottom level acceleration structures instanceAccStructDescriptor.instanceDescriptorType = MTLAccelerationStructureInstanceDescriptorTypeDefault; - } - default: - accStructDescriptor = [MTLAccelerationStructureDescriptor new]; - break; + } break; } + + if (!descriptor) + return nullptr; + + if (mvkIsAnyFlagEnabled(buildInfo.flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)) + descriptor.usage += MTLAccelerationStructureUsageRefit; + else if (mvkIsAnyFlagEnabled(buildInfo.flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)) + descriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; + else + descriptor.usage = MTLAccelerationStructureUsageNone; + + return descriptor; +} + +VkAccelerationStructureBuildSizesInfoKHR MVKAccelerationStructure::getBuildSizes(MVKDevice* device, + VkAccelerationStructureBuildTypeKHR type, + const VkAccelerationStructureBuildGeometryInfoKHR* info, + const uint32_t* maxPrimitiveCounts) +{ + VkAccelerationStructureBuildSizesInfoKHR vkBuildSizes{}; - if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR)){ - accStructDescriptor.usage += MTLAccelerationStructureUsageRefit; - }else if(mvkIsAnyFlagEnabled(info->flags, VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR)){ - accStructDescriptor.usage += MTLAccelerationStructureUsagePreferFastBuild; - }else{ - accStructDescriptor.usage = MTLAccelerationStructureUsageNone; - } + // TODO: We can't perform host builds, throw an error? + if (type == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR) + return vkBuildSizes; - MTLAccelerationStructureSizes sizes = [device->getMTLDevice() accelerationStructureSizesWithDescriptor: accStructDescriptor]; + MTLAccelerationStructureDescriptor* descriptor = populateMTLDescriptor(device, *info, maxPrimitiveCounts); + + MTLAccelerationStructureSizes sizes = [device->getMTLDevice() accelerationStructureSizesWithDescriptor:descriptor]; vkBuildSizes.accelerationStructureSize = sizes.accelerationStructureSize; vkBuildSizes.buildScratchSize = sizes.buildScratchBufferSize; vkBuildSizes.updateScratchSize = sizes.refitScratchBufferSize; @@ -126,7 +199,7 @@ uint64_t MVKAccelerationStructure::getMTLSize() { - if(!_built) { return 0; } + if (!_built) { return 0; } return _accelerationStructure.size; } From 562a9fda5d8c600582c40cdda52436bc1cb79b41 Mon Sep 17 00:00:00 2001 From: TheApplePieGod Date: Sat, 27 Jul 2024 12:13:51 -0500 Subject: [PATCH 31/32] Finish acc structure command encoder impl --- MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h | 5 ++++- .../MoltenVK/Commands/MVKCommandBuffer.mm | 20 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h index 9903938a1..e3bb6094b 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h @@ -526,7 +526,7 @@ class MVKCommandEncoder : public MVKBaseDeviceObject { uint32_t _flushCount; MVKCommandUse _mtlComputeEncoderUse; MVKCommandUse _mtlBlitEncoderUse; - MVKCommandUse _mtlAccelerationStructureUse; + MVKCommandUse _mtlAccelerationStructureEncoderUse; bool _isRenderingEntireAttachment; }; @@ -542,3 +542,6 @@ NSString* mvkMTLBlitCommandEncoderLabel(MVKCommandUse cmdUse); /** Returns a name, suitable for use as a MTLComputeCommandEncoder label, based on the MVKCommandUse. */ NSString* mvkMTLComputeCommandEncoderLabel(MVKCommandUse cmdUse); + +/** Returns a name, suitable for use as a MTLAccelerationStructureCommandEncoder label, based on the MVKCommandUse. */ +NSString* mvkMTLAccelerationStructureCommandEncoderLabel(MVKCommandUse cmdUse); diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm index 1ce74816b..9ad80d7a0 100644 --- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm +++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm @@ -831,6 +831,10 @@ endMetalEncoding(_mtlBlitEncoder); _mtlBlitEncoderUse = kMVKCommandUseNone; + if (_mtlAccelerationStructureEncoder && _cmdBuffer->_hasStageCounterTimestampCommand) { [_mtlAccelerationStructureEncoder updateFence: getStageCountersMTLFence()]; } + endMetalEncoding(_mtlAccelerationStructureEncoder); + _mtlAccelerationStructureEncoderUse = kMVKCommandUseNone; + encodeTimestampStageCounterSamples(); } @@ -873,9 +877,9 @@ _mtlAccelerationStructureEncoder = [_mtlCmdBuffer accelerationStructureCommandEncoder]; retainIfImmediatelyEncoding(_mtlAccelerationStructureEncoder); } - if (_mtlAccelerationStructureUse != cmdUse) { - _mtlAccelerationStructureUse = cmdUse; - setLabelIfNotNil(_mtlAccelerationStructureEncoder, mvkMTLBlitCommandEncoderLabel(cmdUse)); + if (_mtlAccelerationStructureEncoderUse != cmdUse) { + _mtlAccelerationStructureEncoderUse = cmdUse; + setLabelIfNotNil(_mtlAccelerationStructureEncoder, mvkMTLAccelerationStructureCommandEncoderLabel(cmdUse)); } return _mtlAccelerationStructureEncoder; } @@ -1243,3 +1247,13 @@ default: return @"Unknown Use ComputeEncoder"; } } + +NSString* mvkMTLAccelerationStructureCommandEncoderLabel(MVKCommandUse cmdUse) { + switch (cmdUse) { + case kMVKCommandUseBuildAccelerationStructure: return @"vkCmdBuildAccelerationStructuresKHR AccelerationStructureEncoder"; + case kMVKCommandUseCopyAccelerationStructure: return @"vkCmdCopyAccelerationStructureKHR AccelerationStructureEncoder"; + case kMVKCommandUseCopyAccelerationStructureToMemory: return @"vkCmdCopyAccelerationStructureToMemoryKHR AccelerationStructureEncoder"; + case kMVKCommandUseCopyMemoryToAccelerationStructure: return @"vkCmdCopyMemoryToAccelerationStructureKHR AccelerationStructureEncoder"; + default: return @"Unknown Use AccelerationStructureEncoder"; + } +} From abcf618359169e475b1fd5d5136057c0a159a349 Mon Sep 17 00:00:00 2001 From: TheApplePieGod Date: Sat, 27 Jul 2024 12:19:34 -0500 Subject: [PATCH 32/32] Fix compilation errors from build refactor --- MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm | 9 +++++---- MoltenVK/MoltenVK/Vulkan/vulkan.mm | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm index b0996a3c3..0052623bd 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKAccelerationStructure.mm @@ -155,11 +155,12 @@ case VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR: { - accStructDescriptor = [MTLInstanceAccelerationStructureDescriptor new]; - MTLInstanceAccelerationStructureDescriptor* instanceAccStructDescriptor = (MTLInstanceAccelerationStructureDescriptor*)accStructDescriptor; + MTLInstanceAccelerationStructureDescriptor* instance = [MTLInstanceAccelerationStructureDescriptor new]; // add bottom level acceleration structures - instanceAccStructDescriptor.instanceDescriptorType = MTLAccelerationStructureInstanceDescriptorTypeDefault; + instance.instanceDescriptorType = MTLAccelerationStructureInstanceDescriptorTypeDefault; + + descriptor = instance; } break; } @@ -187,7 +188,7 @@ if (type == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR) return vkBuildSizes; - MTLAccelerationStructureDescriptor* descriptor = populateMTLDescriptor(device, *info, maxPrimitiveCounts); + MTLAccelerationStructureDescriptor* descriptor = populateMTLDescriptor(device, *info, nullptr, maxPrimitiveCounts); MTLAccelerationStructureSizes sizes = [device->getMTLDevice() accelerationStructureSizesWithDescriptor:descriptor]; vkBuildSizes.accelerationStructureSize = sizes.accelerationStructureSize; diff --git a/MoltenVK/MoltenVK/Vulkan/vulkan.mm b/MoltenVK/MoltenVK/Vulkan/vulkan.mm index cedb0cc87..675f95d98 100644 --- a/MoltenVK/MoltenVK/Vulkan/vulkan.mm +++ b/MoltenVK/MoltenVK/Vulkan/vulkan.mm @@ -2919,7 +2919,7 @@ MVK_PUBLIC_VULKAN_SYMBOL void vkGetAccelerationStructureBuildSizesKHR( MVKTraceVulkanCallStart(); MVKDevice* mvkDev = (MVKDevice*)device; - VkAccelerationStructureBuildSizesInfoKHR buildSizes = MVKAccelerationStructure::getBuildSizes(mvkDev, buildType, pBuildInfo); + VkAccelerationStructureBuildSizesInfoKHR buildSizes = MVKAccelerationStructure::getBuildSizes(mvkDev, buildType, pBuildInfo, pMaxPrimitiveCounts); pSizeInfo = &buildSizes; MVKTraceVulkanCallEnd(); }