From df3ecd7890eb675a67aaaf6e37588db34f1a2335 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:37:35 +0200 Subject: [PATCH 01/13] d3d12: Reject and log invalid OMM calls --- src/nvapi_d3d12.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index f82162c4..60b6b408 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -325,9 +325,14 @@ extern "C" { } static bool ConvertBuildRaytracingAccelerationStructureInputs(const NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX* nvDesc, std::vector& geometryDescs, D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS* d3dDesc) { + // assume that micromaps are not supported, allow only standard stuff to be passed + if ((nvDesc->flags & ~0x3f) != 0) { + log::info(str::format("Nonstandard flags passed to acceleration structure build: ", nvDesc->flags)); + return false; + } + d3dDesc->Type = nvDesc->type; - // assume that OMM via VK_EXT_opacity_micromap and DMM via VK_NV_displacement_micromap are not supported, allow only standard flags to be passed - d3dDesc->Flags = static_cast(nvDesc->flags & 0x3f); + d3dDesc->Flags = static_cast(nvDesc->flags); d3dDesc->NumDescs = nvDesc->numDescs; d3dDesc->DescsLayout = nvDesc->descsLayout; @@ -337,6 +342,13 @@ extern "C" { } if (d3dDesc->Type == D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL && d3dDesc->DescsLayout == D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS) { + for (unsigned i = 0; i < nvDesc->numDescs; ++i) { + if (auto desc = nvDesc->ppGeometryDescs[i]; desc->type != NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES_EX && desc->type != NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS_EX) { + log::info("Triangles with micromap attachment passed to acceleration structure build when micromaps are not supported"); + return false; + } + } + d3dDesc->ppGeometryDescs = reinterpret_cast(nvDesc->ppGeometryDescs); return true; } @@ -398,7 +410,7 @@ extern "C" { D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS desc{}; if (!ConvertBuildRaytracingAccelerationStructureInputs(pParams->pDesc, geometryDescs, &desc)) - return InvalidArgument(n); + return NotSupported(n); pDevice->GetRaytracingAccelerationStructurePrebuildInfo(&desc, pParams->pInfo); @@ -430,7 +442,7 @@ extern "C" { }; if (!ConvertBuildRaytracingAccelerationStructureInputs(&pParams->pDesc->inputs, geometryDescs, &desc.Inputs)) - return InvalidArgument(n); + return NotSupported(n); pCommandList->BuildRaytracingAccelerationStructure(&desc, pParams->numPostbuildInfoDescs, pParams->pPostbuildInfoDescs); From b58cdf9fb69014a03e81f452137278a1500534ee Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:40:45 +0200 Subject: [PATCH 02/13] d3d12: Define vkd3d-proton OMM interfaces --- src/interfaces/vkd3d-proton_interfaces.h | 49 ++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/interfaces/vkd3d-proton_interfaces.h b/src/interfaces/vkd3d-proton_interfaces.h index 24a2e960..8acaae6e 100644 --- a/src/interfaces/vkd3d-proton_interfaces.h +++ b/src/interfaces/vkd3d-proton_interfaces.h @@ -24,6 +24,7 @@ #endif // defined(__GNUC__) || defined(__clang__) enum D3D12_VK_EXTENSION : uint32_t { + D3D12_VK_EXT_OPACITY_MICROMAP = 0x0, D3D12_VK_NVX_BINARY_IMPORT = 0x1, D3D12_VK_NVX_IMAGE_VIEW_HANDLE = 0x2, D3D12_VK_NV_LOW_LATENCY_2 = 0x3, @@ -85,6 +86,36 @@ ID3D12DeviceExt : public IUnknown { D3D12_UAV_INFO * uav_info) = 0; }; +MIDL_INTERFACE("099a73fd-2199-4f45-bf48-0eb86f6fdb65") +ID3D12DeviceExt1 : public ID3D12DeviceExt { + virtual HRESULT STDMETHODCALLTYPE CreateResourceFromBorrowedHandle( + const D3D12_RESOURCE_DESC1* desc, + UINT64 vk_handle, + ID3D12Resource** resource) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetVulkanQueueInfoEx( + ID3D12CommandQueue * queue, + VkQueue * vk_queue, + UINT32 * vk_queue_index, + UINT32 * vk_queue_flags, + UINT32 * vk_queue_family) = 0; +}; + +MIDL_INTERFACE("099a73fd-2199-4f45-bf48-0eb86f6fdb66") +ID3D12DeviceExt2 : public ID3D12DeviceExt1 { + virtual HRESULT STDMETHODCALLTYPE SetCreatePipelineStateOptions( + const void* params) = 0; + + virtual HRESULT STDMETHODCALLTYPE CheckDriverMatchingIdentifierEx( + void* params) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRaytracingAccelerationStructurePrebuildInfoEx( + void* params) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRaytracingOpacityMicromapArrayPrebuildInfo( + void* params) = 0; +}; + MIDL_INTERFACE("39da4e09-bd1c-4198-9fae-86bbe3be41fd") ID3D12DXVKInteropDevice : public IUnknown { virtual HRESULT STDMETHODCALLTYPE GetDXGIAdapter( @@ -165,6 +196,21 @@ ID3D12GraphicsCommandListExt1 : public ID3D12GraphicsCommandListExt { UINT32 raw_params_count) = 0; }; +MIDL_INTERFACE("d53b0028-afb4-4b65-a4f1-7b0daaa65b50") +ID3D12GraphicsCommandListExt2 : public ID3D12GraphicsCommandListExt1 { + virtual HRESULT STDMETHODCALLTYPE BuildRaytracingAccelerationStructureEx( + const void* params) = 0; + + virtual HRESULT STDMETHODCALLTYPE BuildRaytracingOpacityMicromapArray( + void* params) = 0; + + virtual HRESULT STDMETHODCALLTYPE RelocateRaytracingOpacityMicromapArray( + const void* params) = 0; + + virtual HRESULT STDMETHODCALLTYPE EmitRaytracingOpacityMicromapArrayPostbuildInfo( + const void* params) = 0; +}; + MIDL_INTERFACE("40ed3f96-e773-e9bc-fc0c-e95560c99ad6") ID3D12CommandQueueExt : public IUnknown { virtual HRESULT STDMETHODCALLTYPE NotifyOutOfBandCommandQueue( @@ -173,9 +219,12 @@ ID3D12CommandQueueExt : public IUnknown { #ifndef _MSC_VER __CRT_UUID_DECL(ID3D12DeviceExt, 0x11ea7a1a, 0x0f6a, 0x49bf, 0xb6, 0x12, 0x3e, 0x30, 0xf8, 0xe2, 0x01, 0xdd); +__CRT_UUID_DECL(ID3D12DeviceExt1, 0x099a73fd, 0x2199, 0x4f45, 0xbf, 0x48, 0x0e, 0xb8, 0x6f, 0x6f, 0xdb, 0x65); +__CRT_UUID_DECL(ID3D12DeviceExt2, 0x099a73fd, 0x2199, 0x4f45, 0xbf, 0x48, 0x0e, 0xb8, 0x6f, 0x6f, 0xdb, 0x66); __CRT_UUID_DECL(ID3D12DXVKInteropDevice, 0x39da4e09, 0xbd1c, 0x4198, 0x9f, 0xae, 0x86, 0xbb, 0xe3, 0xbe, 0x41, 0xfd); __CRT_UUID_DECL(ID3D12DXVKInteropDevice1, 0x902d8115, 0x59eb, 0x4406, 0x95, 0x18, 0xfe, 0x00, 0xf9, 0x91, 0xee, 0x65); __CRT_UUID_DECL(ID3D12GraphicsCommandListExt, 0x77a86b09, 0x2bea, 0x4801, 0xb8, 0x9a, 0x37, 0x64, 0x8e, 0x10, 0x4a, 0xf1); __CRT_UUID_DECL(ID3D12GraphicsCommandListExt1, 0xd53b0028, 0xafb4, 0x4b65, 0xa4, 0xf1, 0x7b, 0x0d, 0xaa, 0xa6, 0x5b, 0x4f); +__CRT_UUID_DECL(ID3D12GraphicsCommandListExt2, 0xd53b0028, 0xafb4, 0x4b65, 0xa4, 0xf1, 0x7b, 0x0d, 0xaa, 0xa6, 0x5b, 0x50); __CRT_UUID_DECL(ID3D12CommandQueueExt, 0x40ed3f96, 0xe773, 0xe9bc, 0xfc, 0x0c, 0xe9, 0x55, 0x60, 0xc9, 0x9a, 0xd6); #endif From 5cbb30b5e9d1168f7cd13fed3f421ec512cf2371 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Sun, 21 May 2023 20:14:25 +0200 Subject: [PATCH 03/13] d3d12: Extend NvapiD3d12Device cache for OMM interfaces --- src/nvapi/nvapi_d3d12_device.cpp | 30 +++++++++++++++++++++++++----- src/nvapi/nvapi_d3d12_device.h | 9 +++++++-- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index cd63c848..54a6a2e6 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -136,15 +136,29 @@ namespace dxvk { if (it != m_cubinDeviceMap.end()) return it->second; - auto cubinDevice = GetDeviceExt(device, D3D12_VK_NVX_BINARY_IMPORT); + auto cubinDevice = GetDeviceExt(device, D3D12_VK_NVX_BINARY_IMPORT); if (cubinDevice != nullptr) m_cubinDeviceMap.emplace(device, cubinDevice.ptr()); return cubinDevice; } - Com NvapiD3d12Device::GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension) { - Com deviceExt; + Com NvapiD3d12Device::GetOmmDevice(ID3D12Device* device) { + std::scoped_lock lock(m_ommDeviceMutex); + auto it = m_ommDeviceMap.find(device); + if (it != m_ommDeviceMap.end()) + return it->second; + + auto ommDevice = GetDeviceExt(device, D3D12_VK_EXT_OPACITY_MICROMAP); + if (ommDevice != nullptr) + m_ommDeviceMap.emplace(device, ommDevice.ptr()); + + return ommDevice; + } + + template + Com NvapiD3d12Device::GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension) { + Com deviceExt; if (FAILED(device->QueryInterface(IID_PPV_ARGS(&deviceExt)))) return nullptr; @@ -176,15 +190,21 @@ namespace dxvk { if (it != m_commandListMap.end()) return it->second; + Com commandListExt2 = nullptr; + if (SUCCEEDED(commandList->QueryInterface(IID_PPV_ARGS(&commandListExt2)))) { + NvapiD3d12Device::CommandListExtWithVersion cmdListVer{commandListExt2.ptr(), 2}; + return std::make_optional(m_commandListMap.emplace(commandList, cmdListVer).first->second); + } + Com commandListExt1 = nullptr; if (SUCCEEDED(commandList->QueryInterface(IID_PPV_ARGS(&commandListExt1)))) { - NvapiD3d12Device::CommandListExtWithVersion cmdListVer{commandListExt1.ptr(), 1}; + NvapiD3d12Device::CommandListExtWithVersion cmdListVer{reinterpret_cast(commandListExt1.ptr()), 1}; return std::make_optional(m_commandListMap.emplace(commandList, cmdListVer).first->second); } Com commandListExt = nullptr; if (SUCCEEDED(commandList->QueryInterface(IID_PPV_ARGS(&commandListExt)))) { - NvapiD3d12Device::CommandListExtWithVersion cmdListVer{reinterpret_cast(commandListExt.ptr()), 0}; + NvapiD3d12Device::CommandListExtWithVersion cmdListVer{reinterpret_cast(commandListExt.ptr()), 0}; return std::make_optional(m_commandListMap.emplace(commandList, cmdListVer).first->second); } diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 32ae464f..3f5997d1 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -9,7 +9,7 @@ namespace dxvk { class NvapiD3d12Device { struct CommandListExtWithVersion { - ID3D12GraphicsCommandListExt1* CommandListExt; + ID3D12GraphicsCommandListExt2* CommandListExt; uint32_t InterfaceVersion; }; @@ -32,6 +32,7 @@ namespace dxvk { static void Reset(); private: + inline static std::unordered_map m_ommDeviceMap; inline static std::unordered_map m_cubinDeviceMap; inline static std::unordered_map m_commandQueueMap; inline static std::unordered_map m_commandListMap; @@ -39,12 +40,16 @@ namespace dxvk { inline static std::mutex m_commandListMutex; inline static std::mutex m_commandQueueMutex; + inline static std::mutex m_ommDeviceMutex; inline static std::mutex m_cubinDeviceMutex; inline static std::mutex m_cubinSmemMutex; + [[nodiscard]] static Com GetOmmDevice(ID3D12Device* device); [[nodiscard]] static Com GetCubinDevice(ID3D12Device* device); - [[nodiscard]] static Com GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension); [[nodiscard]] static Com GetCommandQueueExt(ID3D12CommandQueue* commandQueue); [[nodiscard]] static std::optional GetCommandListExt(ID3D12GraphicsCommandList* commandList); + + template + [[nodiscard]] static Com GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension); }; } From cdf4fbde2106c2bf82a3d9a1348a8aa31560918e Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:43:46 +0200 Subject: [PATCH 04/13] d3d12: Try using OMM device in GetRaytracingAccelerationStructurePrebuildInfoEx --- src/nvapi/nvapi_d3d12_device.cpp | 8 ++++++++ src/nvapi/nvapi_d3d12_device.h | 2 ++ src/nvapi_d3d12.cpp | 13 +++++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index 54a6a2e6..1163c28f 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -128,6 +128,14 @@ namespace dxvk { return cubinDevice != nullptr; } + std::optional NvapiD3d12Device::GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params) { + auto ommDevice = GetOmmDevice(device); + if (ommDevice == nullptr) + return std::nullopt; + + return static_cast(ommDevice->GetRaytracingAccelerationStructurePrebuildInfoEx(params)); + } + // We are going to have single map for storing devices with extensions D3D12_VK_NVX_BINARY_IMPORT & D3D12_VK_NVX_IMAGE_VIEW_HANDLE. // These are specific to NVIDIA and both of these extensions goes together. Com NvapiD3d12Device::GetCubinDevice(ID3D12Device* device) { diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 3f5997d1..2fb974ff 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -29,6 +29,8 @@ namespace dxvk { static bool CaptureUAVInfo(ID3D12Device* device, NVAPI_UAV_INFO* uavInfo); static bool IsFatbinPTXSupported(ID3D12Device* device); + static std::optional GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params); + static void Reset(); private: diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index 60b6b408..b83937cd 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -400,6 +400,19 @@ extern "C" { if (pDevice == nullptr || pParams == nullptr) return InvalidArgument(n); + if (auto result = NvapiD3d12Device::GetRaytracingAccelerationStructurePrebuildInfoEx(pDevice, pParams); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(n, alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pParams->version); + default: + log::info(str::format("<-", n, ": ", value)); + return value; + } + } + if (pParams->version != NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS_VER1) return IncompatibleStructVersion(n, pParams->version); From 90761a7ef476af0695dfd47020a19d7bee357cd9 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:44:13 +0200 Subject: [PATCH 05/13] d3d12: Try using OMM command list in BuildRaytracingAccelerationStructureEx --- src/nvapi/nvapi_d3d12_device.cpp | 12 ++++++++++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 13 +++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index 1163c28f..aab6c809 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -136,6 +136,18 @@ namespace dxvk { return static_cast(ommDevice->GetRaytracingAccelerationStructurePrebuildInfoEx(params)); } + std::optional NvapiD3d12Device::BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params) { + auto commandListExt = GetCommandListExt(commandList); + if (!commandListExt.has_value()) + return std::nullopt; + + auto commandListVer = commandListExt.value(); + if (commandListVer.InterfaceVersion < 2) + return std::nullopt; + + return static_cast(commandListVer.CommandListExt->BuildRaytracingAccelerationStructureEx(params)); + } + // We are going to have single map for storing devices with extensions D3D12_VK_NVX_BINARY_IMPORT & D3D12_VK_NVX_IMAGE_VIEW_HANDLE. // These are specific to NVIDIA and both of these extensions goes together. Com NvapiD3d12Device::GetCubinDevice(ID3D12Device* device) { diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 2fb974ff..34e04705 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -30,6 +30,7 @@ namespace dxvk { static bool IsFatbinPTXSupported(ID3D12Device* device); static std::optional GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params); + static std::optional BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params); static void Reset(); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index b83937cd..14e53cd4 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -440,6 +440,19 @@ extern "C" { if (pCommandList == nullptr || pParams == nullptr) return InvalidArgument(n); + if (auto result = NvapiD3d12Device::BuildRaytracingAccelerationStructureEx(pCommandList, pParams); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(n, alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pParams->version); + default: + log::info(str::format("<-", n, ": ", value)); + return value; + } + } + if (pParams->version != NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS_VER1) return IncompatibleStructVersion(n, pParams->version); From b6e82328f4934d8b69e5adeeb06cccdecca137b5 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:45:21 +0200 Subject: [PATCH 06/13] d3d12: Implement GetRaytracingOpacityMicromapArrayPrebuildInfo --- src/nvapi/nvapi_d3d12_device.cpp | 8 ++++++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 26 ++++++++++++++++++++++++++ src/nvapi_interface.cpp | 1 + 4 files changed, 36 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index aab6c809..971538b4 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -136,6 +136,14 @@ namespace dxvk { return static_cast(ommDevice->GetRaytracingAccelerationStructurePrebuildInfoEx(params)); } + std::optional NvapiD3d12Device::GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* device, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* params) { + auto ommDevice = GetOmmDevice(device); + if (ommDevice == nullptr) + return std::nullopt; + + return static_cast(ommDevice->GetRaytracingOpacityMicromapArrayPrebuildInfo(params)); + } + std::optional NvapiD3d12Device::BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params) { auto commandListExt = GetCommandListExt(commandList); if (!commandListExt.has_value()) diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 34e04705..278cd8dc 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -30,6 +30,7 @@ namespace dxvk { static bool IsFatbinPTXSupported(ID3D12Device* device); static std::optional GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params); + static std::optional GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* device, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* params); static std::optional BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params); static void Reset(); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index 14e53cd4..c9b00acb 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -324,6 +324,32 @@ extern "C" { return Ok(str::format(n, " (", type, ")")); } + NvAPI_Status __cdecl NvAPI_D3D12_GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* pDevice, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* pParams) { + constexpr auto n = __func__; + thread_local bool alreadyLoggedOk = false; + + if (log::tracing()) + log::trace(n, log::fmt::ptr(pDevice), log::fmt::ptr(pParams)); + + if (pDevice == nullptr || pParams == nullptr) + return InvalidArgument(n); + + if (auto result = NvapiD3d12Device::GetRaytracingOpacityMicromapArrayPrebuildInfo(pDevice, pParams); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(n, alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pParams->version); + default: + log::info(str::format("<-", n, ": ", value)); + return value; + } + } + + return NotSupported(n); + } + static bool ConvertBuildRaytracingAccelerationStructureInputs(const NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX* nvDesc, std::vector& geometryDescs, D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS* d3dDesc) { // assume that micromaps are not supported, allow only standard stuff to be passed if ((nvDesc->flags & ~0x3f) != 0) { diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index 460adfe0..09f7ba84 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -111,6 +111,7 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetGraphicsCapabilities) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_IsFatbinPTXSupported) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingCaps) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingOpacityMicromapArrayPrebuildInfo) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue) From a6525a38113537dca19b87bdc17ce68179a62193 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:48:01 +0200 Subject: [PATCH 07/13] d3d12: Implement SetCreatePipelineStateOptions --- src/nvapi/nvapi_d3d12_device.cpp | 8 ++++++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 26 ++++++++++++++++++++++++++ src/nvapi_interface.cpp | 1 + 4 files changed, 36 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index 971538b4..8a967c68 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -128,6 +128,14 @@ namespace dxvk { return cubinDevice != nullptr; } + std::optional NvapiD3d12Device::SetCreatePipelineStateOptions(ID3D12Device5* device, const NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS* params) { + auto ommDevice = GetOmmDevice(device); + if (ommDevice == nullptr) + return std::nullopt; + + return static_cast(ommDevice->SetCreatePipelineStateOptions(params)); + } + std::optional NvapiD3d12Device::GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params) { auto ommDevice = GetOmmDevice(device); if (ommDevice == nullptr) diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 278cd8dc..b6a99021 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -29,6 +29,7 @@ namespace dxvk { static bool CaptureUAVInfo(ID3D12Device* device, NVAPI_UAV_INFO* uavInfo); static bool IsFatbinPTXSupported(ID3D12Device* device); + static std::optional SetCreatePipelineStateOptions(ID3D12Device5* device, const NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS* params); static std::optional GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params); static std::optional GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* device, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* params); static std::optional BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index c9b00acb..e77166e1 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -350,6 +350,32 @@ extern "C" { return NotSupported(n); } + NvAPI_Status __cdecl NvAPI_D3D12_SetCreatePipelineStateOptions(ID3D12Device5* pDevice, const NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS* pState) { + constexpr auto n = __func__; + thread_local bool alreadyLoggedOk = false; + + if (log::tracing()) + log::trace(n, log::fmt::ptr(pDevice), log::fmt::ptr(pState)); + + if (pDevice == nullptr || pState == nullptr) + return InvalidArgument(n); + + if (auto result = NvapiD3d12Device::SetCreatePipelineStateOptions(pDevice, pState); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(str::format(n, "(", pState->flags, ")"), alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pState->version); + default: + log::info(str::format("<-", n, "(", pState->flags, "): ", value)); + return value; + } + } + + return NotSupported(n); + } + static bool ConvertBuildRaytracingAccelerationStructureInputs(const NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX* nvDesc, std::vector& geometryDescs, D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS* d3dDesc) { // assume that micromaps are not supported, allow only standard stuff to be passed if ((nvDesc->flags & ~0x3f) != 0) { diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index 09f7ba84..32b07cb1 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -112,6 +112,7 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_IsFatbinPTXSupported) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingCaps) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingOpacityMicromapArrayPrebuildInfo) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetCreatePipelineStateOptions) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue) From e1d0adf57d2747c6fe2f0ddd4941e74aff7949a5 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:48:29 +0200 Subject: [PATCH 08/13] d3d12: Implement CheckDriverMatchingIdentifierEx --- src/nvapi/nvapi_d3d12_device.cpp | 8 ++++++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 34 ++++++++++++++++++++++++++++++++ src/nvapi_interface.cpp | 1 + 4 files changed, 44 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index 8a967c68..e8d5a50d 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -136,6 +136,14 @@ namespace dxvk { return static_cast(ommDevice->SetCreatePipelineStateOptions(params)); } + std::optional NvapiD3d12Device::CheckDriverMatchingIdentifierEx(ID3D12Device5* device, NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS* params) { + auto ommDevice = GetOmmDevice(device); + if (ommDevice == nullptr) + return std::nullopt; + + return static_cast(ommDevice->CheckDriverMatchingIdentifierEx(params)); + } + std::optional NvapiD3d12Device::GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params) { auto ommDevice = GetOmmDevice(device); if (ommDevice == nullptr) diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index b6a99021..527f9bfe 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -30,6 +30,7 @@ namespace dxvk { static bool IsFatbinPTXSupported(ID3D12Device* device); static std::optional SetCreatePipelineStateOptions(ID3D12Device5* device, const NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS* params); + static std::optional CheckDriverMatchingIdentifierEx(ID3D12Device5* device, NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS* params); static std::optional GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params); static std::optional GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* device, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* params); static std::optional BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index e77166e1..3cb006c2 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -376,6 +376,40 @@ extern "C" { return NotSupported(n); } + NvAPI_Status __cdecl NvAPI_D3D12_CheckDriverMatchingIdentifierEx(ID3D12Device5* pDevice, NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS* pParams) { + constexpr auto n = __func__; + thread_local bool alreadyLoggedOk = false; + + if (log::tracing()) + log::trace(n, log::fmt::ptr(pDevice), log::fmt::ptr(pParams)); + + if (pDevice == nullptr || pParams == nullptr) + return InvalidArgument(n); + + if (auto result = NvapiD3d12Device::CheckDriverMatchingIdentifierEx(pDevice, pParams); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(n, alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pParams->version); + default: + log::info(str::format("<-", n, ": ", value)); + return value; + } + } + + if (pParams->version != NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_VER1) + return IncompatibleStructVersion(n, pParams->version); + + if (pParams->serializedDataType == NVAPI_D3D12_SERIALIZED_DATA_RAYTRACING_ACCELERATION_STRUCTURE_EX) { + pParams->checkStatus = pDevice->CheckDriverMatchingIdentifier(D3D12_SERIALIZED_DATA_RAYTRACING_ACCELERATION_STRUCTURE, pParams->pIdentifierToCheck); + return Ok(n, alreadyLoggedOk); + } + + return NotSupported(n); + } + static bool ConvertBuildRaytracingAccelerationStructureInputs(const NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX* nvDesc, std::vector& geometryDescs, D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS* d3dDesc) { // assume that micromaps are not supported, allow only standard stuff to be passed if ((nvDesc->flags & ~0x3f) != 0) { diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index 32b07cb1..39f7539e 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -113,6 +113,7 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingCaps) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingOpacityMicromapArrayPrebuildInfo) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetCreatePipelineStateOptions) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CheckDriverMatchingIdentifierEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue) From d3896ca768a3c611f6010bf53d01ac6190c8df81 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:49:38 +0200 Subject: [PATCH 09/13] d3d12: Implement BuildRaytracingOpacityMicromapArray --- src/nvapi/nvapi_d3d12_device.cpp | 12 ++++++++++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 26 ++++++++++++++++++++++++++ src/nvapi_interface.cpp | 1 + 4 files changed, 40 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index e8d5a50d..a0fccca3 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -172,6 +172,18 @@ namespace dxvk { return static_cast(commandListVer.CommandListExt->BuildRaytracingAccelerationStructureEx(params)); } + std::optional NvapiD3d12Device::BuildRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params) { + auto commandListExt = GetCommandListExt(commandList); + if (!commandListExt.has_value()) + return std::nullopt; + + auto commandListVer = commandListExt.value(); + if (commandListVer.InterfaceVersion < 2) + return std::nullopt; + + return static_cast(commandListVer.CommandListExt->BuildRaytracingOpacityMicromapArray(params)); + } + // We are going to have single map for storing devices with extensions D3D12_VK_NVX_BINARY_IMPORT & D3D12_VK_NVX_IMAGE_VIEW_HANDLE. // These are specific to NVIDIA and both of these extensions goes together. Com NvapiD3d12Device::GetCubinDevice(ID3D12Device* device) { diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 527f9bfe..1dbfc0d6 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -34,6 +34,7 @@ namespace dxvk { static std::optional GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params); static std::optional GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* device, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* params); static std::optional BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params); + static std::optional BuildRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params); static void Reset(); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index 3cb006c2..b3e6e98b 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -516,6 +516,32 @@ extern "C" { return Ok(n, alreadyLoggedOk); } + NvAPI_Status __cdecl NvAPI_D3D12_BuildRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* pCommandList, NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* pParams) { + constexpr auto n = __func__; + thread_local bool alreadyLoggedOk = false; + + if (log::tracing()) + log::trace(n, log::fmt::ptr(pCommandList), log::fmt::ptr(pParams)); + + if (pCommandList == nullptr || pParams == nullptr) + return InvalidArgument(n); + + if (auto result = NvapiD3d12Device::BuildRaytracingOpacityMicromapArray(pCommandList, pParams); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(n, alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pParams->version); + default: + log::info(str::format("<-", n, ": ", value)); + return value; + } + } + + return NotSupported(n); + } + NvAPI_Status __cdecl NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* pCommandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* pParams) { constexpr auto n = __func__; thread_local bool alreadyLoggedOk = false; diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index 39f7539e..e9c8dc6d 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -115,6 +115,7 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetCreatePipelineStateOptions) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CheckDriverMatchingIdentifierEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingOpacityMicromapArray) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetAsyncFrameMarker) From f225108110b3735ae3aa8ec58f749b85e856e7fe Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:50:59 +0200 Subject: [PATCH 10/13] d3d12: Implement RelocateRaytracingOpacityMicromapArray --- src/nvapi/nvapi_d3d12_device.cpp | 12 ++++++++++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 26 ++++++++++++++++++++++++++ src/nvapi_interface.cpp | 1 + 4 files changed, 40 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index a0fccca3..a0a2695c 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -184,6 +184,18 @@ namespace dxvk { return static_cast(commandListVer.CommandListExt->BuildRaytracingOpacityMicromapArray(params)); } + std::optional NvapiD3d12Device::RelocateRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, const NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params) { + auto commandListExt = GetCommandListExt(commandList); + if (!commandListExt.has_value()) + return std::nullopt; + + auto commandListVer = commandListExt.value(); + if (commandListVer.InterfaceVersion < 2) + return std::nullopt; + + return static_cast(commandListVer.CommandListExt->RelocateRaytracingOpacityMicromapArray(params)); + } + // We are going to have single map for storing devices with extensions D3D12_VK_NVX_BINARY_IMPORT & D3D12_VK_NVX_IMAGE_VIEW_HANDLE. // These are specific to NVIDIA and both of these extensions goes together. Com NvapiD3d12Device::GetCubinDevice(ID3D12Device* device) { diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 1dbfc0d6..1d0c895f 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -35,6 +35,7 @@ namespace dxvk { static std::optional GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* device, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* params); static std::optional BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params); static std::optional BuildRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params); + static std::optional RelocateRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, const NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params); static void Reset(); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index b3e6e98b..f1d200d1 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -542,6 +542,32 @@ extern "C" { return NotSupported(n); } + NvAPI_Status __cdecl NvAPI_D3D12_RelocateRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* pCommandList, const NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* pParams) { + constexpr auto n = __func__; + thread_local bool alreadyLoggedOk = false; + + if (log::tracing()) + log::trace(n, log::fmt::ptr(pCommandList), log::fmt::ptr(pParams)); + + if (pCommandList == nullptr || pParams == nullptr) + return InvalidArgument(n); + + if (auto result = NvapiD3d12Device::RelocateRaytracingOpacityMicromapArray(pCommandList, pParams); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(n, alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pParams->version); + default: + log::info(str::format("<-", n, ": ", value)); + return value; + } + } + + return NotSupported(n); + } + NvAPI_Status __cdecl NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* pCommandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* pParams) { constexpr auto n = __func__; thread_local bool alreadyLoggedOk = false; diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index e9c8dc6d..fefbb5c4 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -116,6 +116,7 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CheckDriverMatchingIdentifierEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingOpacityMicromapArray) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_RelocateRaytracingOpacityMicromapArray) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetAsyncFrameMarker) From 7a5069256ebc1137263ab554327519fed9e6fae8 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:51:23 +0200 Subject: [PATCH 11/13] d3d12: Implement EmitRaytracingOpacityMicromapArrayPostbuildInfo --- src/nvapi/nvapi_d3d12_device.cpp | 12 ++++++++++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 26 ++++++++++++++++++++++++++ src/nvapi_interface.cpp | 1 + 4 files changed, 40 insertions(+) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index a0a2695c..611aef51 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -196,6 +196,18 @@ namespace dxvk { return static_cast(commandListVer.CommandListExt->RelocateRaytracingOpacityMicromapArray(params)); } + std::optional NvapiD3d12Device::EmitRaytracingOpacityMicromapArrayPostbuildInfo(ID3D12GraphicsCommandList4* commandList, const NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS* params) { + auto commandListExt = GetCommandListExt(commandList); + if (!commandListExt.has_value()) + return std::nullopt; + + auto commandListVer = commandListExt.value(); + if (commandListVer.InterfaceVersion < 2) + return std::nullopt; + + return static_cast(commandListVer.CommandListExt->EmitRaytracingOpacityMicromapArrayPostbuildInfo(params)); + } + // We are going to have single map for storing devices with extensions D3D12_VK_NVX_BINARY_IMPORT & D3D12_VK_NVX_IMAGE_VIEW_HANDLE. // These are specific to NVIDIA and both of these extensions goes together. Com NvapiD3d12Device::GetCubinDevice(ID3D12Device* device) { diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index 1d0c895f..d3d77561 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -36,6 +36,7 @@ namespace dxvk { static std::optional BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params); static std::optional BuildRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params); static std::optional RelocateRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, const NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params); + static std::optional EmitRaytracingOpacityMicromapArrayPostbuildInfo(ID3D12GraphicsCommandList4* commandList, const NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS* params); static void Reset(); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index f1d200d1..6e1bf943 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -568,6 +568,32 @@ extern "C" { return NotSupported(n); } + NvAPI_Status __cdecl NvAPI_D3D12_EmitRaytracingOpacityMicromapArrayPostbuildInfo(ID3D12GraphicsCommandList4* pCommandList, const NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS* pParams) { + constexpr auto n = __func__; + thread_local bool alreadyLoggedOk = false; + + if (log::tracing()) + log::trace(n, log::fmt::ptr(pCommandList), log::fmt::ptr(pParams)); + + if (pCommandList == nullptr || pParams == nullptr) + return InvalidArgument(n); + + if (auto result = NvapiD3d12Device::EmitRaytracingOpacityMicromapArrayPostbuildInfo(pCommandList, pParams); result.has_value()) { + auto value = result.value(); + switch (value) { + case NVAPI_OK: + return Ok(n, alreadyLoggedOk); + case NVAPI_INCOMPATIBLE_STRUCT_VERSION: + return IncompatibleStructVersion(n, pParams->version); + default: + log::info(str::format("<-", n, ": ", value)); + return value; + } + } + + return NotSupported(n); + } + NvAPI_Status __cdecl NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* pCommandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* pParams) { constexpr auto n = __func__; thread_local bool alreadyLoggedOk = false; diff --git a/src/nvapi_interface.cpp b/src/nvapi_interface.cpp index fefbb5c4..f956cea6 100644 --- a/src/nvapi_interface.cpp +++ b/src/nvapi_interface.cpp @@ -117,6 +117,7 @@ extern "C" { INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingOpacityMicromapArray) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_RelocateRaytracingOpacityMicromapArray) + INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_EmitRaytracingOpacityMicromapArrayPostbuildInfo) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_NotifyOutOfBandCommandQueue) INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetAsyncFrameMarker) From 49628a443d3434d1073bedcc84dfbe8f93cb8046 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Fri, 19 May 2023 21:53:05 +0200 Subject: [PATCH 12/13] d3d12: Report OMM as supported if device ext and interface are found --- src/nvapi/nvapi_d3d12_device.cpp | 5 +++++ src/nvapi/nvapi_d3d12_device.h | 1 + src/nvapi_d3d12.cpp | 8 ++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/nvapi/nvapi_d3d12_device.cpp b/src/nvapi/nvapi_d3d12_device.cpp index 611aef51..853afa83 100644 --- a/src/nvapi/nvapi_d3d12_device.cpp +++ b/src/nvapi/nvapi_d3d12_device.cpp @@ -128,6 +128,11 @@ namespace dxvk { return cubinDevice != nullptr; } + bool NvapiD3d12Device::IsOpacityMicromapSupported(ID3D12Device* device) { + auto ommDevice = GetOmmDevice(device); + return ommDevice != nullptr; + } + std::optional NvapiD3d12Device::SetCreatePipelineStateOptions(ID3D12Device5* device, const NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS* params) { auto ommDevice = GetOmmDevice(device); if (ommDevice == nullptr) diff --git a/src/nvapi/nvapi_d3d12_device.h b/src/nvapi/nvapi_d3d12_device.h index d3d77561..0147fbdc 100644 --- a/src/nvapi/nvapi_d3d12_device.h +++ b/src/nvapi/nvapi_d3d12_device.h @@ -29,6 +29,7 @@ namespace dxvk { static bool CaptureUAVInfo(ID3D12Device* device, NVAPI_UAV_INFO* uavInfo); static bool IsFatbinPTXSupported(ID3D12Device* device); + static bool IsOpacityMicromapSupported(ID3D12Device* device); static std::optional SetCreatePipelineStateOptions(ID3D12Device5* device, const NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS* params); static std::optional CheckDriverMatchingIdentifierEx(ID3D12Device5* device, NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS* params); static std::optional GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params); diff --git a/src/nvapi_d3d12.cpp b/src/nvapi_d3d12.cpp index 6e1bf943..e1d52709 100644 --- a/src/nvapi_d3d12.cpp +++ b/src/nvapi_d3d12.cpp @@ -303,12 +303,16 @@ extern "C" { *(NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS*)pData = NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAP_NONE; break; - case NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP: + case NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP: { if (dataSize != sizeof(NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS)) return InvalidArgument(n); - *(NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS*)pData = NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE; + *(NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS*)pData = NvapiD3d12Device::IsOpacityMicromapSupported(pDevice) + ? NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_STANDARD + : NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE; + break; + } case NVAPI_D3D12_RAYTRACING_CAPS_TYPE_DISPLACEMENT_MICROMAP: if (dataSize != sizeof(NVAPI_D3D12_RAYTRACING_DISPLACEMENT_MICROMAP_CAPS)) From 9cd10b16da8cee930dd49f3daf6fe78d89511353 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Sun, 21 May 2023 23:28:19 +0200 Subject: [PATCH 13/13] tests: Update tests for OMM support --- tests/nvapi_d3d12.cpp | 455 +++++++++++++++++++++++++++++++++++++- tests/nvapi_d3d12_mocks.h | 14 +- 2 files changed, 461 insertions(+), 8 deletions(-) diff --git a/tests/nvapi_d3d12.cpp b/tests/nvapi_d3d12.cpp index 4b14f179..0a8e32e9 100644 --- a/tests/nvapi_d3d12.cpp +++ b/tests/nvapi_d3d12.cpp @@ -35,6 +35,14 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { .LR_SIDE_EFFECT(*_2 = static_cast(&device)) .LR_SIDE_EFFECT(deviceRefCount++) .RETURN(S_OK); + ALLOW_CALL(device, QueryInterface(__uuidof(ID3D12DeviceExt1), _)) + .LR_SIDE_EFFECT(*_2 = static_cast(&device)) + .LR_SIDE_EFFECT(deviceRefCount++) + .RETURN(S_OK); + ALLOW_CALL(device, QueryInterface(__uuidof(ID3D12DeviceExt2), _)) + .LR_SIDE_EFFECT(*_2 = static_cast(&device)) + .LR_SIDE_EFFECT(deviceRefCount++) + .RETURN(S_OK); ALLOW_CALL(device, AddRef()) .LR_SIDE_EFFECT(deviceRefCount++) .RETURN(deviceRefCount); @@ -57,7 +65,11 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { .LR_SIDE_EFFECT(commandListRefCount++) .RETURN(S_OK); ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt1), _)) - .LR_SIDE_EFFECT(*_2 = static_cast(&commandList)) + .LR_SIDE_EFFECT(*_2 = static_cast(&commandList)) + .LR_SIDE_EFFECT(commandListRefCount++) + .RETURN(S_OK); + ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt2), _)) + .LR_SIDE_EFFECT(*_2 = static_cast(&commandList)) .LR_SIDE_EFFECT(commandListRefCount++) .RETURN(S_OK); ALLOW_CALL(commandList, AddRef()) @@ -103,18 +115,34 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { SECTION("D3D12 methods without VKD3D-Proton return error") { ALLOW_CALL(device, QueryInterface(__uuidof(ID3D12DeviceExt), _)) .RETURN(E_NOINTERFACE); + ALLOW_CALL(device, QueryInterface(__uuidof(ID3D12DeviceExt1), _)) + .RETURN(E_NOINTERFACE); + ALLOW_CALL(device, QueryInterface(__uuidof(ID3D12DeviceExt2), _)) + .RETURN(E_NOINTERFACE); ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt), _)) .RETURN(E_NOINTERFACE); ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt1), _)) .RETURN(E_NOINTERFACE); + ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt2), _)) + .RETURN(E_NOINTERFACE); FORBID_CALL(device, CreateCubinComputeShaderWithName(_, _, _, _, _, _, _)); FORBID_CALL(device, DestroyCubinComputeShader(_)); FORBID_CALL(device, GetCudaTextureObject(_, _, _)); FORBID_CALL(device, GetCudaSurfaceObject(_, _)); FORBID_CALL(device, CaptureUAVInfo(_)); + FORBID_CALL(device, CreateResourceFromBorrowedHandle(_, _, _)); + FORBID_CALL(device, GetVulkanQueueInfoEx(_, _, _, _, _)); + FORBID_CALL(device, SetCreatePipelineStateOptions(_)); + FORBID_CALL(device, CheckDriverMatchingIdentifierEx(_)); + FORBID_CALL(device, GetRaytracingAccelerationStructurePrebuildInfoEx(_)); + FORBID_CALL(device, GetRaytracingOpacityMicromapArrayPrebuildInfo(_)); FORBID_CALL(commandList, LaunchCubinShader(_, _, _, _, _, _)); FORBID_CALL(commandList, LaunchCubinShaderEx(_, _, _, _, _, _, _, _, _)); + FORBID_CALL(commandList, BuildRaytracingAccelerationStructureEx(_)); + FORBID_CALL(commandList, BuildRaytracingOpacityMicromapArray(_)); + FORBID_CALL(commandList, RelocateRaytracingOpacityMicromapArray(_)); + FORBID_CALL(commandList, EmitRaytracingOpacityMicromapArrayPostbuildInfo(_)); const void* cubinData = nullptr; NVDX_ObjectHandle handle{}; @@ -135,11 +163,46 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { REQUIRE(NvAPI_D3D12_IsFatbinPTXSupported(static_cast(&device), &isPTXSupported) == NVAPI_ERROR); REQUIRE(NvAPI_D3D12_LaunchCubinShader(static_cast(&commandList), handle, 0, 0, 0, nullptr, 0) == NVAPI_ERROR); + + { + NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS caps = NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_STANDARD; + REQUIRE(NvAPI_D3D12_GetRaytracingCaps(static_cast(&device), NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP, &caps, sizeof(caps)) == NVAPI_OK); + REQUIRE(caps == NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE); + } + { + NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS params{}; + REQUIRE(NvAPI_D3D12_GetRaytracingOpacityMicromapArrayPrebuildInfo(static_cast(&device), ¶ms) != NVAPI_OK); + } + { + NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS params{}; + params.version = NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS_VER1; + params.flags = NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS_ENABLE_OMM_SUPPORT; + REQUIRE(NvAPI_D3D12_SetCreatePipelineStateOptions(static_cast(&device), ¶ms) != NVAPI_OK); + } + { + NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS params{}; + params.version = NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_VER1; + params.serializedDataType = NVAPI_D3D12_SERIALIZED_DATA_RAYTRACING_OPACITY_MICROMAP_ARRAY_EX; + REQUIRE(NvAPI_D3D12_CheckDriverMatchingIdentifierEx(static_cast(&device), ¶ms) != NVAPI_OK); + } + { + NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS params{}; + REQUIRE(NvAPI_D3D12_BuildRaytracingOpacityMicromapArray(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + { + NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS params{}; + REQUIRE(NvAPI_D3D12_RelocateRaytracingOpacityMicromapArray(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + { + NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS params{}; + REQUIRE(NvAPI_D3D12_EmitRaytracingOpacityMicromapArrayPostbuildInfo(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + REQUIRE(deviceRefCount == 0); REQUIRE(commandListRefCount == 0); } - SECTION("D3D12 methods without cubin extension return error") { + SECTION("D3D12 cubin methods without cubin extension return error") { ALLOW_CALL(device, GetExtensionSupport(D3D12_VK_NVX_BINARY_IMPORT)) .RETURN(false); @@ -170,6 +233,36 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { REQUIRE(commandListRefCount == 0); } + SECTION("D3D12 OMM methods without OMM extension return not-supported") { + ALLOW_CALL(device, GetExtensionSupport(D3D12_VK_EXT_OPACITY_MICROMAP)) + .RETURN(false); + + FORBID_CALL(device, SetCreatePipelineStateOptions(_)); + FORBID_CALL(device, CheckDriverMatchingIdentifierEx(_)); + FORBID_CALL(device, GetRaytracingAccelerationStructurePrebuildInfoEx(_)); + FORBID_CALL(device, GetRaytracingOpacityMicromapArrayPrebuildInfo(_)); + + { + NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS params{}; + REQUIRE(NvAPI_D3D12_GetRaytracingOpacityMicromapArrayPrebuildInfo(static_cast(&device), ¶ms) != NVAPI_OK); + } + { + NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS params{}; + params.version = NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS_VER1; + params.flags = NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS_ENABLE_OMM_SUPPORT; + REQUIRE(NvAPI_D3D12_SetCreatePipelineStateOptions(static_cast(&device), ¶ms) != NVAPI_OK); + } + { + NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS params{}; + params.version = NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_VER1; + params.serializedDataType = NVAPI_D3D12_SERIALIZED_DATA_RAYTRACING_OPACITY_MICROMAP_ARRAY_EX; + REQUIRE(NvAPI_D3D12_CheckDriverMatchingIdentifierEx(static_cast(&device), ¶ms) != NVAPI_OK); + } + + REQUIRE(deviceRefCount == 0); + REQUIRE(commandListRefCount == 0); + } + SECTION("IsNvShaderExtnOpCodeSupported returns OK") { auto supported = true; REQUIRE(NvAPI_D3D12_IsNvShaderExtnOpCodeSupported(&device, 1U, &supported) == NVAPI_OK); @@ -486,6 +579,8 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { SECTION("Launch CuBIN without ID3D12GraphicsCommandListExt1 returns OK") { ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt1), _)) .RETURN(E_NOINTERFACE); + ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt2), _)) + .RETURN(E_NOINTERFACE); auto shaderHandle = reinterpret_cast(0xbadcf00d); auto blockX = 1U; @@ -509,8 +604,20 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { REQUIRE(caps == NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAP_NONE); } - SECTION("GetRaytracingCaps returns OK and claims that Opacity Micromap is not supported") { - NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS caps; + SECTION("GetRaytracingCaps returns OK and claims that Opacity Micromaps are not supported if ID3D12DeviceExt2 interface can't be found") { + ALLOW_CALL(device, QueryInterface(__uuidof(ID3D12DeviceExt2), _)) + .RETURN(E_NOINTERFACE); + + NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS caps = NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_STANDARD; + REQUIRE(NvAPI_D3D12_GetRaytracingCaps(static_cast(&device), NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP, &caps, sizeof(caps)) == NVAPI_OK); + REQUIRE(caps == NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE); + } + + SECTION("GetRaytracingCaps returns OK and claims that Opacity Micromaps are not supported if OMM extension is not supported") { + ALLOW_CALL(device, GetExtensionSupport(D3D12_VK_EXT_OPACITY_MICROMAP)) + .RETURN(false); + + NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS caps = NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_STANDARD; REQUIRE(NvAPI_D3D12_GetRaytracingCaps(static_cast(&device), NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP, &caps, sizeof(caps)) == NVAPI_OK); REQUIRE(caps == NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE); } @@ -521,7 +628,10 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { REQUIRE(caps == NVAPI_D3D12_RAYTRACING_DISPLACEMENT_MICROMAP_CAP_NONE); } - SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx succeeds") { + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx succeeds when Opacity Micromaps are not supported") { + ALLOW_CALL(device, GetExtensionSupport(D3D12_VK_EXT_OPACITY_MICROMAP)) + .RETURN(false); + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx returns OK") { NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX desc{}; D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info{}; @@ -653,7 +763,182 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { } } - SECTION("BuildRaytracingAccelerationStructureEx succeeds") { + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx fails when Opacity Micromaps are used but they are not supported") { + ALLOW_CALL(device, GetExtensionSupport(D3D12_VK_EXT_OPACITY_MICROMAP)) + .RETURN(false); + + FORBID_CALL(device, GetRaytracingAccelerationStructurePrebuildInfo(_, _)); + FORBID_CALL(device, GetRaytracingAccelerationStructurePrebuildInfoEx(_)); + + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX geometryDescEx{}; + NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX desc{}; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info{}; + NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS params{}; + params.version = NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS_VER1; + params.pDesc = &desc; + params.pInfo = &info; + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with allow OMM update flag") { + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_UPDATE_EX; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) != NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with allow disable OMMs flag") { + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_DISABLE_OMMS_EX; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) != NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with allow OMM opacity states update flag") { + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_OPACITY_STATES_UPDATE_EX; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) != NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with BLAS for array and OMM triangles") { + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + desc.numDescs = 1; + desc.pGeometryDescs = &geometryDescEx; + desc.geometryDescStrideInBytes = sizeof(geometryDescEx); + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_OMM_TRIANGLES_EX; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) != NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with BLAS for pointer array and OMM triangles") { + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX* geometryDescExArray[] = {&geometryDescEx}; + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS; + desc.numDescs = 1; + desc.ppGeometryDescs = geometryDescExArray; + desc.geometryDescStrideInBytes = sizeof(geometryDescEx); + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_OMM_TRIANGLES_EX; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) != NVAPI_OK); + } + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx succeeds when Opacity Micromaps are supported") { + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx returns OK and calls to ID3D12DeviceExt2") { + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX geometryDescEx{}; + NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS_EX desc{}; + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO info{}; + NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS params{}; + params.version = NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS_VER1; + params.pDesc = &desc; + params.pInfo = &info; + + REQUIRE_CALL(device, GetRaytracingAccelerationStructurePrebuildInfoEx(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with TLAS") { + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.instanceDescs = D3D12_GPU_VIRTUAL_ADDRESS{}; + desc.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_UPDATE_EX; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) == NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with BLAS for pointer array") { + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX* geometryDescExArray[] = {&geometryDescEx}; + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS; + desc.ppGeometryDescs = geometryDescExArray; + desc.geometryDescStrideInBytes = sizeof(geometryDescEx); + desc.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_DISABLE_OMMS_EX; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) == NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with BLAS for array") { + desc.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + desc.numDescs = 1; + desc.pGeometryDescs = &geometryDescEx; + desc.geometryDescStrideInBytes = sizeof(geometryDescEx); + desc.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_OPACITY_STATES_UPDATE_EX; + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx for OMM triangles geometry") { + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_OMM_TRIANGLES_EX; + geometryDescEx.ommTriangles.triangles.IndexBuffer = D3D12_GPU_VIRTUAL_ADDRESS{}; + geometryDescEx.ommTriangles.ommAttachment.opacityMicromapArray = D3D12_GPU_VIRTUAL_ADDRESS{}; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) == NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx for triangles geometry") { + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES_EX; + geometryDescEx.triangles.IndexBuffer = D3D12_GPU_VIRTUAL_ADDRESS{}; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) == NVAPI_OK); + } + + SECTION("GetRaytracingAccelerationStructurePrebuildInfoEx with AABBs geometry") { + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS_EX; + geometryDescEx.aabbs.AABBCount = 3; + + REQUIRE(NvAPI_D3D12_GetRaytracingAccelerationStructurePrebuildInfoEx(static_cast(&device), ¶ms) == NVAPI_OK); + } + } + } + } + + SECTION("GetRaytracingOpacityMicromapArrayPrebuildInfo returns OK") { + NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS params{}; + + REQUIRE_CALL(device, GetRaytracingOpacityMicromapArrayPrebuildInfo(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + REQUIRE(NvAPI_D3D12_GetRaytracingOpacityMicromapArrayPrebuildInfo(static_cast(&device), ¶ms) == NVAPI_OK); + REQUIRE(deviceRefCount == 0); + REQUIRE(commandListRefCount == 0); + } + + SECTION("SetCreatePipelineStateOptions returns OK") { + NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS params{}; + params.version = NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS_VER1; + params.flags = NVAPI_D3D12_PIPELINE_CREATION_STATE_FLAGS_ENABLE_OMM_SUPPORT; + + REQUIRE_CALL(device, SetCreatePipelineStateOptions(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + REQUIRE(NvAPI_D3D12_SetCreatePipelineStateOptions(static_cast(&device), ¶ms) == NVAPI_OK); + REQUIRE(deviceRefCount == 0); + REQUIRE(commandListRefCount == 0); + } + + SECTION("CheckDriverMatchingIdentifierEx returns OK") { + NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS params{}; + params.version = NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS_VER1; + params.serializedDataType = NVAPI_D3D12_SERIALIZED_DATA_RAYTRACING_OPACITY_MICROMAP_ARRAY_EX; + + REQUIRE_CALL(device, CheckDriverMatchingIdentifierEx(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + REQUIRE(NvAPI_D3D12_CheckDriverMatchingIdentifierEx(static_cast(&device), ¶ms) == NVAPI_OK); + REQUIRE(deviceRefCount == 0); + REQUIRE(commandListRefCount == 0); + } + + SECTION("GetRaytracingCaps returns OK and claims that Opacity Micromaps are supported") { + NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS caps = NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE; + REQUIRE(NvAPI_D3D12_GetRaytracingCaps(static_cast(&device), NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP, &caps, sizeof(caps)) == NVAPI_OK); + REQUIRE(caps == NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_STANDARD); + } + + SECTION("BuildRaytracingAccelerationStructureEx succeeds when ID3D12GraphicsCommandListExt2 interface can't be found") { + ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt2), _)) + .RETURN(E_NOINTERFACE); + SECTION("BuildRaytracingAccelerationStructureEx returns OK") { NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC_EX desc{}; NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS params{}; @@ -801,6 +1086,164 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") { } } + SECTION("BuildRaytracingAccelerationStructureEx fails when Opacity Micromaps are used but ID3D12GraphicsCommandListExt2 interface can't be found") { + ALLOW_CALL(commandList, QueryInterface(__uuidof(ID3D12GraphicsCommandListExt2), _)) + .RETURN(E_NOINTERFACE); + + FORBID_CALL(commandList, BuildRaytracingAccelerationStructure(_, _, _)); + FORBID_CALL(commandList, BuildRaytracingAccelerationStructureEx(_)); + + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX geometryDescEx{}; + NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC_EX desc{}; + NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS params{}; + params.version = NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS_VER1; + params.pDesc = &desc; + + SECTION("BuildRaytracingAccelerationStructureEx with allow OMM update flag") { + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.inputs.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_UPDATE_EX; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx with allow disable OMMs flag") { + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.inputs.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_DISABLE_OMMS_EX; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx with allow OMM opacity states update flag") { + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.inputs.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_OPACITY_STATES_UPDATE_EX; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx with BLAS for array and OMM triangles") { + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.inputs.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + desc.inputs.numDescs = 1; + desc.inputs.pGeometryDescs = &geometryDescEx; + desc.inputs.geometryDescStrideInBytes = sizeof(geometryDescEx); + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_OMM_TRIANGLES_EX; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx with BLAS for pointer array and OMM triangles") { + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX* geometryDescExArray[] = {&geometryDescEx}; + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.inputs.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS; + desc.inputs.numDescs = 1; + desc.inputs.ppGeometryDescs = geometryDescExArray; + desc.inputs.geometryDescStrideInBytes = sizeof(geometryDescEx); + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_OMM_TRIANGLES_EX; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) != NVAPI_OK); + } + } + + SECTION("BuildRaytracingAccelerationStructureEx succeeds when ID3D12GraphicsCommandListExt2 interface can be found") { + SECTION("BuildRaytracingAccelerationStructureEx returns OK and calls to ID3D12GraphicsCommandListExt2") { + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX geometryDescEx{}; + NVAPI_D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC_EX desc{}; + NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS params{}; + params.version = NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS_VER1; + params.pDesc = &desc; + + REQUIRE_CALL(commandList, BuildRaytracingAccelerationStructureEx(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + SECTION("BuildRaytracingAccelerationStructureEx with TLAS") { + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL; + desc.inputs.instanceDescs = D3D12_GPU_VIRTUAL_ADDRESS{}; + desc.inputs.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_UPDATE_EX; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) == NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx with BLAS for pointer array") { + NVAPI_D3D12_RAYTRACING_GEOMETRY_DESC_EX* geometryDescExArray[] = {&geometryDescEx}; + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.inputs.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY_OF_POINTERS; + desc.inputs.ppGeometryDescs = geometryDescExArray; + desc.inputs.geometryDescStrideInBytes = sizeof(geometryDescEx); + desc.inputs.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_DISABLE_OMMS_EX; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) == NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx with BLAS for array") { + desc.inputs.type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL; + desc.inputs.descsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY; + desc.inputs.numDescs = 1; + desc.inputs.pGeometryDescs = &geometryDescEx; + desc.inputs.geometryDescStrideInBytes = sizeof(geometryDescEx); + desc.inputs.flags = NVAPI_D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG_ALLOW_OMM_OPACITY_STATES_UPDATE_EX; + + SECTION("BuildRaytracingAccelerationStructureEx for OMM triangles geometry") { + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_OMM_TRIANGLES_EX; + geometryDescEx.ommTriangles.triangles.IndexBuffer = D3D12_GPU_VIRTUAL_ADDRESS{}; + geometryDescEx.ommTriangles.ommAttachment.opacityMicromapArray = D3D12_GPU_VIRTUAL_ADDRESS{}; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) == NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx for triangles geometry") { + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES_EX; + geometryDescEx.triangles.IndexBuffer = D3D12_GPU_VIRTUAL_ADDRESS{}; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) == NVAPI_OK); + } + + SECTION("BuildRaytracingAccelerationStructureEx for AABBs geometry") { + geometryDescEx.type = NVAPI_D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS_EX; + geometryDescEx.aabbs.AABBCount = 3; + + REQUIRE(NvAPI_D3D12_BuildRaytracingAccelerationStructureEx(static_cast(&commandList), ¶ms) == NVAPI_OK); + } + } + } + } + + SECTION("BuildRaytracingOpacityMicromapArray returns OK") { + NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS params{}; + + REQUIRE_CALL(commandList, BuildRaytracingOpacityMicromapArray(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + REQUIRE(NvAPI_D3D12_BuildRaytracingOpacityMicromapArray(static_cast(&commandList), ¶ms) == NVAPI_OK); + REQUIRE(deviceRefCount == 0); + REQUIRE(commandListRefCount == 0); + } + + SECTION("RelocateRaytracingOpacityMicromapArray returns OK") { + NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS params{}; + + REQUIRE_CALL(commandList, RelocateRaytracingOpacityMicromapArray(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + REQUIRE(NvAPI_D3D12_RelocateRaytracingOpacityMicromapArray(static_cast(&commandList), ¶ms) == NVAPI_OK); + REQUIRE(deviceRefCount == 0); + REQUIRE(commandListRefCount == 0); + } + + SECTION("EmitRaytracingOpacityMicromapArrayPostbuildInfo returns OK") { + NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS params{}; + + REQUIRE_CALL(commandList, EmitRaytracingOpacityMicromapArrayPostbuildInfo(¶ms)) + .RETURN(NVAPI_OK) + .TIMES(1); + + REQUIRE(NvAPI_D3D12_EmitRaytracingOpacityMicromapArrayPostbuildInfo(static_cast(&commandList), ¶ms) == NVAPI_OK); + REQUIRE(deviceRefCount == 0); + REQUIRE(commandListRefCount == 0); + } + SECTION("D3DLowLatencyDevice methods succeed") { auto dxgiFactory = std::make_unique(); auto vk = std::make_unique(); diff --git a/tests/nvapi_d3d12_mocks.h b/tests/nvapi_d3d12_mocks.h index fc4472cb..af0983cc 100644 --- a/tests/nvapi_d3d12_mocks.h +++ b/tests/nvapi_d3d12_mocks.h @@ -3,7 +3,7 @@ #include "nvapi_tests_private.h" #include "../src/interfaces/vkd3d-proton_interfaces.h" -class ID3D12Vkd3dDevice : public ID3D12Device5, public ID3D12DeviceExt {}; +class ID3D12Vkd3dDevice : public ID3D12Device5, public ID3D12DeviceExt2 {}; class D3D12Vkd3dDeviceMock final : public trompeloeil::mock_interface { MAKE_MOCK2(QueryInterface, HRESULT(REFIID, void**), override); @@ -91,9 +91,15 @@ class D3D12Vkd3dDeviceMock final : public trompeloeil::mock_interface { MAKE_MOCK2(QueryInterface, HRESULT(REFIID, void**), override); @@ -176,6 +182,10 @@ class D3D12Vkd3dGraphicsCommandListMock final : public trompeloeil::mock_interfa IMPLEMENT_MOCK1(GetVulkanHandle); IMPLEMENT_MOCK6(LaunchCubinShader); IMPLEMENT_MOCK9(LaunchCubinShaderEx); + IMPLEMENT_MOCK1(BuildRaytracingAccelerationStructureEx); + IMPLEMENT_MOCK1(BuildRaytracingOpacityMicromapArray); + IMPLEMENT_MOCK1(RelocateRaytracingOpacityMicromapArray); + IMPLEMENT_MOCK1(EmitRaytracingOpacityMicromapArrayPostbuildInfo); }; class ID3D12Vkd3dCommandQueue : public ID3D12CommandQueue, public ID3D12CommandQueueExt {};