Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Opacity Micromaps #125

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/interfaces/vkd3d-proton_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand All @@ -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
115 changes: 110 additions & 5 deletions src/nvapi/nvapi_d3d12_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,91 @@ namespace dxvk {
return cubinDevice != nullptr;
}

bool NvapiD3d12Device::IsOpacityMicromapSupported(ID3D12Device* device) {
auto ommDevice = GetOmmDevice(device);
return ommDevice != nullptr;
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(ommDevice->SetCreatePipelineStateOptions(params));
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(ommDevice->CheckDriverMatchingIdentifierEx(params));
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(ommDevice->GetRaytracingAccelerationStructurePrebuildInfoEx(params));
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(ommDevice->GetRaytracingOpacityMicromapArrayPrebuildInfo(params));
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(commandListVer.CommandListExt->BuildRaytracingAccelerationStructureEx(params));
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(commandListVer.CommandListExt->BuildRaytracingOpacityMicromapArray(params));
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(commandListVer.CommandListExt->RelocateRaytracingOpacityMicromapArray(params));
}

std::optional<NvAPI_Status> 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<NvAPI_Status>(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<ID3D12DeviceExt> NvapiD3d12Device::GetCubinDevice(ID3D12Device* device) {
Expand All @@ -136,15 +221,29 @@ namespace dxvk {
if (it != m_cubinDeviceMap.end())
return it->second;

auto cubinDevice = GetDeviceExt(device, D3D12_VK_NVX_BINARY_IMPORT);
auto cubinDevice = GetDeviceExt<ID3D12DeviceExt>(device, D3D12_VK_NVX_BINARY_IMPORT);
if (cubinDevice != nullptr)
m_cubinDeviceMap.emplace(device, cubinDevice.ptr());

return cubinDevice;
}

Com<ID3D12DeviceExt> NvapiD3d12Device::GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension) {
Com<ID3D12DeviceExt> deviceExt;
Com<ID3D12DeviceExt2> 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<ID3D12DeviceExt2>(device, D3D12_VK_EXT_OPACITY_MICROMAP);
if (ommDevice != nullptr)
m_ommDeviceMap.emplace(device, ommDevice.ptr());

return ommDevice;
}

template <typename T>
Com<T> NvapiD3d12Device::GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension) {
Com<T> deviceExt;
if (FAILED(device->QueryInterface(IID_PPV_ARGS(&deviceExt))))
return nullptr;

Expand Down Expand Up @@ -176,15 +275,21 @@ namespace dxvk {
if (it != m_commandListMap.end())
return it->second;

Com<ID3D12GraphicsCommandListExt2> 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<ID3D12GraphicsCommandListExt1> commandListExt1 = nullptr;
if (SUCCEEDED(commandList->QueryInterface(IID_PPV_ARGS(&commandListExt1)))) {
NvapiD3d12Device::CommandListExtWithVersion cmdListVer{commandListExt1.ptr(), 1};
NvapiD3d12Device::CommandListExtWithVersion cmdListVer{reinterpret_cast<ID3D12GraphicsCommandListExt2*>(commandListExt1.ptr()), 1};
return std::make_optional(m_commandListMap.emplace(commandList, cmdListVer).first->second);
}

Com<ID3D12GraphicsCommandListExt> commandListExt = nullptr;
if (SUCCEEDED(commandList->QueryInterface(IID_PPV_ARGS(&commandListExt)))) {
NvapiD3d12Device::CommandListExtWithVersion cmdListVer{reinterpret_cast<ID3D12GraphicsCommandListExt1*>(commandListExt.ptr()), 0};
NvapiD3d12Device::CommandListExtWithVersion cmdListVer{reinterpret_cast<ID3D12GraphicsCommandListExt2*>(commandListExt.ptr()), 0};
return std::make_optional(m_commandListMap.emplace(commandList, cmdListVer).first->second);
}

Expand Down
19 changes: 17 additions & 2 deletions src/nvapi/nvapi_d3d12_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace dxvk {
class NvapiD3d12Device {

struct CommandListExtWithVersion {
ID3D12GraphicsCommandListExt1* CommandListExt;
ID3D12GraphicsCommandListExt2* CommandListExt;
uint32_t InterfaceVersion;
};

Expand All @@ -29,22 +29,37 @@ namespace dxvk {
static bool CaptureUAVInfo(ID3D12Device* device, NVAPI_UAV_INFO* uavInfo);
static bool IsFatbinPTXSupported(ID3D12Device* device);

static bool IsOpacityMicromapSupported(ID3D12Device* device);
static std::optional<NvAPI_Status> SetCreatePipelineStateOptions(ID3D12Device5* device, const NVAPI_D3D12_SET_CREATE_PIPELINE_STATE_OPTIONS_PARAMS* params);
static std::optional<NvAPI_Status> CheckDriverMatchingIdentifierEx(ID3D12Device5* device, NVAPI_CHECK_DRIVER_MATCHING_IDENTIFIER_EX_PARAMS* params);
static std::optional<NvAPI_Status> GetRaytracingAccelerationStructurePrebuildInfoEx(ID3D12Device5* device, NVAPI_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_EX_PARAMS* params);
static std::optional<NvAPI_Status> GetRaytracingOpacityMicromapArrayPrebuildInfo(ID3D12Device5* device, NVAPI_GET_RAYTRACING_OPACITY_MICROMAP_ARRAY_PREBUILD_INFO_PARAMS* params);
static std::optional<NvAPI_Status> BuildRaytracingAccelerationStructureEx(ID3D12GraphicsCommandList4* commandList, const NVAPI_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_EX_PARAMS* params);
static std::optional<NvAPI_Status> BuildRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, NVAPI_BUILD_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params);
static std::optional<NvAPI_Status> RelocateRaytracingOpacityMicromapArray(ID3D12GraphicsCommandList4* commandList, const NVAPI_RELOCATE_RAYTRACING_OPACITY_MICROMAP_ARRAY_PARAMS* params);
static std::optional<NvAPI_Status> EmitRaytracingOpacityMicromapArrayPostbuildInfo(ID3D12GraphicsCommandList4* commandList, const NVAPI_EMIT_RAYTRACING_OPACITY_MICROMAP_ARRAY_POSTBUILD_INFO_PARAMS* params);

static void Reset();

private:
inline static std::unordered_map<ID3D12Device*, ID3D12DeviceExt2*> m_ommDeviceMap;
inline static std::unordered_map<ID3D12Device*, ID3D12DeviceExt*> m_cubinDeviceMap;
inline static std::unordered_map<ID3D12CommandQueue*, ID3D12CommandQueueExt*> m_commandQueueMap;
inline static std::unordered_map<ID3D12GraphicsCommandList*, CommandListExtWithVersion> m_commandListMap;
inline static std::unordered_map<NVDX_ObjectHandle, NvU32> m_cubinSmemMap;

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<ID3D12DeviceExt2> GetOmmDevice(ID3D12Device* device);
[[nodiscard]] static Com<ID3D12DeviceExt> GetCubinDevice(ID3D12Device* device);
[[nodiscard]] static Com<ID3D12DeviceExt> GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension);
[[nodiscard]] static Com<ID3D12CommandQueueExt> GetCommandQueueExt(ID3D12CommandQueue* commandQueue);
[[nodiscard]] static std::optional<CommandListExtWithVersion> GetCommandListExt(ID3D12GraphicsCommandList* commandList);

template <typename T>
[[nodiscard]] static Com<T> GetDeviceExt(ID3D12Device* device, D3D12_VK_EXTENSION extension);
};
}
Loading
Loading