Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c8141df

Browse files
committedFeb 19, 2025·
frog
1 parent ee12388 commit c8141df

6 files changed

+256
-6
lines changed
 

‎src/interfaces/vkd3d-proton_interfaces.h

+49
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,39 @@ typedef struct D3D12_UAV_INFO {
5050
UINT64 gpuVASize;
5151
} D3D12_UAV_INFO;
5252

53+
typedef struct D3D12_CREATE_CUBIN_SHADER_PARAMS {
54+
void* pNext;
55+
const void* pCubin;
56+
UINT32 size;
57+
UINT32 blockX;
58+
UINT32 blockY;
59+
UINT32 blockZ;
60+
UINT32 dynSharedMemBytes;
61+
const char* pShaderName;
62+
UINT32 flags;
63+
D3D12_CUBIN_DATA_HANDLE* hShader;
64+
} D3D12_CREATE_CUBIN_SHADER_PARAMS;
65+
66+
typedef struct D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS {
67+
void* pNext;
68+
SIZE_T texDesc;
69+
SIZE_T smpDesc;
70+
UINT64 textureHandle;
71+
} D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS;
72+
73+
typedef enum D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_TYPE {
74+
D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_SURFACE = 0,
75+
D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_TEXTURE = 1,
76+
D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_SAMPLER = 2,
77+
} D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_TYPE;
78+
79+
typedef struct D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS {
80+
void* pNext;
81+
D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_TYPE type;
82+
SIZE_T desc;
83+
UINT64 handle;
84+
} D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS;
85+
5386
MIDL_INTERFACE("11ea7a1a-0f6a-49bf-b612-3e30f8e201dd")
5487
ID3D12DeviceExt : public IUnknown {
5588
virtual HRESULT STDMETHODCALLTYPE GetVulkanHandles(
@@ -85,6 +118,20 @@ ID3D12DeviceExt : public IUnknown {
85118
D3D12_UAV_INFO * uav_info) = 0;
86119
};
87120

121+
MIDL_INTERFACE("099a73fd-2199-4f45-bf48-0eb86f6fdb65")
122+
ID3D12DeviceExt1 : public ID3D12DeviceExt {
123+
virtual HRESULT CreateResourceFromBorrowedHandle(const D3D12_RESOURCE_DESC1* desc, UINT64 vk_handle, ID3D12Resource** resource) = 0;
124+
virtual HRESULT GetVulkanQueueInfoEx(ID3D12CommandQueue * queue, VkQueue * vk_queue, UINT32 * vk_queue_index, UINT32 * vk_queue_flags, UINT32 * vk_queue_family) = 0;
125+
};
126+
127+
MIDL_INTERFACE("e859c4ac-ba8f-41c4-8eac-1137fde6158d")
128+
ID3D12DeviceExt2 : public ID3D12DeviceExt1 {
129+
virtual BOOL SupportsCubin64bit() = 0;
130+
virtual HRESULT CreateCubinComputeShaderExV2(D3D12_CREATE_CUBIN_SHADER_PARAMS * params) = 0;
131+
virtual HRESULT GetCudaMergedTextureSamplerObject(D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS * params) = 0;
132+
virtual HRESULT GetCudaIndependentDescriptorObject(D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS * params) = 0;
133+
};
134+
88135
MIDL_INTERFACE("39da4e09-bd1c-4198-9fae-86bbe3be41fd")
89136
ID3D12DXVKInteropDevice : public IUnknown {
90137
virtual HRESULT STDMETHODCALLTYPE GetDXGIAdapter(
@@ -191,6 +238,8 @@ ID3D12CommandQueueExt : public IUnknown {
191238

192239
#ifndef _MSC_VER
193240
__CRT_UUID_DECL(ID3D12DeviceExt, 0x11ea7a1a, 0x0f6a, 0x49bf, 0xb6, 0x12, 0x3e, 0x30, 0xf8, 0xe2, 0x01, 0xdd);
241+
__CRT_UUID_DECL(ID3D12DeviceExt1, 0x099a73fd, 0x2199, 0x4f45, 0xbf, 0x48, 0x0e, 0xb8, 0x6f, 0x6f, 0xdb, 0x65);
242+
__CRT_UUID_DECL(ID3D12DeviceExt2, 0xe859c4ac, 0xba8f, 0x41c4, 0x8e, 0xac, 0x11, 0x37, 0xfd, 0xe6, 0x15, 0x8d);
194243
__CRT_UUID_DECL(ID3D12DXVKInteropDevice, 0x39da4e09, 0xbd1c, 0x4198, 0x9f, 0xae, 0x86, 0xbb, 0xe3, 0xbe, 0x41, 0xfd);
195244
__CRT_UUID_DECL(ID3D12DXVKInteropDevice1, 0x902d8115, 0x59eb, 0x4406, 0x95, 0x18, 0xfe, 0x00, 0xf9, 0x91, 0xee, 0x65);
196245
__CRT_UUID_DECL(ID3D12GraphicsCommandListExt, 0x77a86b09, 0x2bea, 0x4801, 0xb8, 0x9a, 0x37, 0x64, 0x8e, 0x10, 0x4a, 0xf1);

‎src/nvapi/nvapi_d3d12_device.cpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@ namespace dxvk {
4747
}
4848

4949
NvapiD3d12Device::NvapiD3d12Device(ID3D12DeviceExt* vkd3dDevice)
50-
: m_vkd3dDevice(vkd3dDevice) {
50+
: m_vkd3dDevice(static_cast<ID3D12DeviceExt2*>(vkd3dDevice)) {
5151
m_supportsNvxBinaryImport = vkd3dDevice->GetExtensionSupport(D3D12_VK_NVX_BINARY_IMPORT);
5252
m_supportsNvxImageViewHandle = vkd3dDevice->GetExtensionSupport(D3D12_VK_NVX_IMAGE_VIEW_HANDLE);
53+
54+
if (m_supportsNvxBinaryImport && m_supportsNvxImageViewHandle) {
55+
if (Com<ID3D12DeviceExt2> deviceExt2; SUCCEEDED(m_vkd3dDevice->QueryInterface(IID_PPV_ARGS(&deviceExt2)))) {
56+
m_supportsCubin64bit = deviceExt2->SupportsCubin64bit();
57+
}
58+
}
5359
}
5460

5561
bool NvapiD3d12Device::CreateCubinComputeShaderWithName(const void* cubinData, NvU32 cubinSize, NvU32 blockX, NvU32 blockY, NvU32 blockZ, const char* shaderName, NVDX_ObjectHandle* pShader) {
@@ -104,4 +110,32 @@ namespace dxvk {
104110
bool NvapiD3d12Device::IsFatbinPTXSupported() const {
105111
return m_vkd3dDevice && m_supportsNvxBinaryImport && m_supportsNvxImageViewHandle;
106112
}
113+
114+
HRESULT NvapiD3d12Device::CreateCubinComputeShaderExV2(D3D12_CREATE_CUBIN_SHADER_PARAMS* params) {
115+
if (!m_supportsCubin64bit)
116+
return E_NOTIMPL;
117+
118+
auto result = m_vkd3dDevice->CreateCubinComputeShaderExV2(params);
119+
120+
if (result == S_OK) {
121+
std::scoped_lock lock(m_cubinSmemMutex);
122+
m_cubinSmemMap.emplace(reinterpret_cast<NVDX_ObjectHandle>(params->hShader), params->dynSharedMemBytes);
123+
}
124+
125+
return result;
126+
}
127+
128+
HRESULT NvapiD3d12Device::GetCudaMergedTextureSamplerObject(D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS* params) const {
129+
if (!m_supportsCubin64bit)
130+
return E_NOTIMPL;
131+
132+
return m_vkd3dDevice->GetCudaMergedTextureSamplerObject(params);
133+
}
134+
135+
HRESULT NvapiD3d12Device::GetCudaIndependentDescriptorObject(D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS* params) const {
136+
if (!m_supportsCubin64bit)
137+
return E_NOTIMPL;
138+
139+
return m_vkd3dDevice->GetCudaIndependentDescriptorObject(params);
140+
}
107141
}

‎src/nvapi/nvapi_d3d12_device.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,19 @@ namespace dxvk {
2323
[[nodiscard]] bool CaptureUAVInfo(NVAPI_UAV_INFO* uavInfo) const;
2424
[[nodiscard]] bool IsFatbinPTXSupported() const;
2525

26+
[[nodiscard]] HRESULT CreateCubinComputeShaderExV2(D3D12_CREATE_CUBIN_SHADER_PARAMS* params);
27+
[[nodiscard]] HRESULT GetCudaMergedTextureSamplerObject(D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS* params) const;
28+
[[nodiscard]] HRESULT GetCudaIndependentDescriptorObject(D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS* params) const;
29+
2630
private:
2731
static std::unordered_map<ID3D12Device*, NvapiD3d12Device> m_nvapiDeviceMap;
2832
static std::mutex m_mutex;
2933

3034
static std::unordered_map<NVDX_ObjectHandle, NvU32> m_cubinSmemMap;
3135
static std::mutex m_cubinSmemMutex;
3236

33-
ID3D12DeviceExt* m_vkd3dDevice{};
37+
ID3D12DeviceExt2* m_vkd3dDevice{};
38+
bool m_supportsCubin64bit = false;
3439
bool m_supportsNvxBinaryImport = false;
3540
bool m_supportsNvxImageViewHandle = false;
3641
};

‎src/nvapi_d3d12.cpp

+138
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,144 @@ extern "C" {
174174
return Ok(n, alreadyLoggedOk);
175175
}
176176

177+
NvAPI_Status __cdecl NvAPI_D3D12_CreateCubinComputeShaderExV2(NVAPI_D3D12_CREATE_CUBIN_SHADER_PARAMS* pParams) {
178+
static constexpr auto V1StructSize = offsetof(NVAPI_D3D12_CREATE_CUBIN_SHADER_PARAMS, hShader) + sizeof(NVAPI_D3D12_CREATE_CUBIN_SHADER_PARAMS::hShader);
179+
// static_assert(V1StructSize == sizeof(NVAPI_D3D12_CREATE_CUBIN_SHADER_PARAMS));
180+
constexpr auto n = __func__;
181+
thread_local bool alreadyLoggedNoImplementation = false;
182+
thread_local bool alreadyLoggedError = false;
183+
thread_local bool alreadyLoggedOk = false;
184+
185+
if (log::tracing())
186+
log::trace(n, log::fmt::nvapi_d3d12_create_cubin_shader_params(pParams));
187+
188+
if (!pParams)
189+
return InvalidPointer(n);
190+
191+
pParams->structSizeOut = V1StructSize;
192+
193+
if (pParams->structSizeIn < V1StructSize)
194+
return IncompatibleStructVersion(n, pParams->structSizeIn);
195+
196+
if (!pParams->pDevice || !pParams->pShaderName)
197+
return InvalidArgument(n);
198+
199+
auto device = NvapiD3d12Device::GetOrCreate(pParams->pDevice);
200+
if (!device)
201+
return NoImplementation(n, alreadyLoggedNoImplementation);
202+
203+
D3D12_CREATE_CUBIN_SHADER_PARAMS params;
204+
params.pNext = nullptr;
205+
params.pCubin = pParams->pCubin;
206+
params.size = pParams->size;
207+
params.blockX = pParams->blockX;
208+
params.blockY = pParams->blockY;
209+
params.blockZ = pParams->blockZ;
210+
params.dynSharedMemBytes = pParams->dynSharedMemBytes;
211+
params.pShaderName = pParams->pShaderName;
212+
params.flags = pParams->flags;
213+
214+
switch (device->CreateCubinComputeShaderExV2(&params)) {
215+
case S_OK:
216+
pParams->hShader = reinterpret_cast<NVDX_ObjectHandle>(params.hShader);
217+
return Ok(n, alreadyLoggedOk);
218+
case E_INVALIDARG:
219+
return InvalidArgument(n);
220+
case E_NOTIMPL:
221+
return NoImplementation(n, alreadyLoggedNoImplementation);
222+
default:
223+
return Error(n, alreadyLoggedError);
224+
}
225+
}
226+
227+
NvAPI_Status __cdecl NvAPI_D3D12_GetCudaMergedTextureSamplerObject(NVAPI_D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS* pParams) {
228+
static constexpr auto V1StructSize = offsetof(NVAPI_D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS, textureHandle) + sizeof(NVAPI_D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS::textureHandle);
229+
// static_assert(V1StructSize == sizeof(NVAPI_D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS));
230+
constexpr auto n = __func__;
231+
thread_local bool alreadyLoggedNoImplementation = false;
232+
thread_local bool alreadyLoggedError = false;
233+
thread_local bool alreadyLoggedOk = false;
234+
235+
if (log::tracing())
236+
log::trace(n, log::fmt::nvapi_d3d12_get_cuda_merged_texture_sampler_object_params(pParams));
237+
238+
if (!pParams)
239+
return InvalidPointer(n);
240+
241+
pParams->structSizeOut = V1StructSize;
242+
243+
if (pParams->structSizeIn < V1StructSize)
244+
return IncompatibleStructVersion(n, pParams->structSizeIn);
245+
246+
if (!pParams->pDevice || !pParams->texDesc.ptr)
247+
return InvalidArgument(n);
248+
249+
auto device = NvapiD3d12Device::GetOrCreate(pParams->pDevice);
250+
if (!device)
251+
return NoImplementation(n, alreadyLoggedNoImplementation);
252+
253+
D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS params;
254+
params.pNext = nullptr;
255+
params.texDesc = pParams->texDesc.ptr;
256+
params.smpDesc = pParams->smpDesc.ptr;
257+
258+
switch (device->GetCudaMergedTextureSamplerObject(&params)) {
259+
case S_OK:
260+
pParams->textureHandle = params.textureHandle;
261+
return Ok(n, alreadyLoggedOk);
262+
case E_INVALIDARG:
263+
return InvalidArgument(n);
264+
case E_NOTIMPL:
265+
return NoImplementation(n, alreadyLoggedNoImplementation);
266+
default:
267+
return Error(n, alreadyLoggedError);
268+
}
269+
}
270+
271+
NvAPI_Status __cdecl NvAPI_D3D12_GetCudaIndependentDescriptorObject(NVAPI_D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS* pParams) {
272+
static constexpr auto V1StructSize = offsetof(NVAPI_D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS, handle) + sizeof(NVAPI_D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS::handle);
273+
// static_assert(V1StructSize == sizeof(NVAPI_D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS));
274+
constexpr auto n = __func__;
275+
thread_local bool alreadyLoggedNoImplementation = false;
276+
thread_local bool alreadyLoggedError = false;
277+
thread_local bool alreadyLoggedOk = false;
278+
279+
if (log::tracing())
280+
log::trace(n, log::fmt::nvapi_d3d12_get_cuda_independent_descriptor_object_params(pParams));
281+
282+
if (!pParams)
283+
return InvalidPointer(n);
284+
285+
pParams->structSizeOut = V1StructSize;
286+
287+
if (pParams->structSizeIn < V1StructSize)
288+
return IncompatibleStructVersion(n, pParams->structSizeIn);
289+
290+
if (!pParams->pDevice || !pParams->desc.ptr)
291+
return InvalidArgument(n);
292+
293+
auto device = NvapiD3d12Device::GetOrCreate(pParams->pDevice);
294+
if (!device)
295+
return NoImplementation(n, alreadyLoggedNoImplementation);
296+
297+
D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS params;
298+
params.pNext = nullptr;
299+
params.type = static_cast<D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_TYPE>(pParams->type);
300+
params.desc = pParams->desc.ptr;
301+
302+
switch (device->GetCudaIndependentDescriptorObject(&params)) {
303+
case S_OK:
304+
pParams->handle = params.handle;
305+
return Ok(n, alreadyLoggedOk);
306+
case E_INVALIDARG:
307+
return InvalidArgument(n);
308+
case E_NOTIMPL:
309+
return NoImplementation(n, alreadyLoggedNoImplementation);
310+
default:
311+
return Error(n, alreadyLoggedError);
312+
}
313+
}
314+
177315
NvAPI_Status __cdecl NvAPI_D3D12_LaunchCubinShader(ID3D12GraphicsCommandList* pCmdList, NVDX_ObjectHandle pShader, NvU32 blockX, NvU32 blockY, NvU32 blockZ, const void* params, NvU32 paramSize) {
178316
constexpr auto n = __func__;
179317
thread_local bool alreadyLoggedNoImplementation = false;

‎src/nvapi_interface.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,13 @@ extern "C" {
107107
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_SetDepthBoundsTestValues)
108108
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CreateCubinComputeShaderWithName)
109109
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CreateCubinComputeShaderEx)
110+
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CreateCubinComputeShaderExV2)
110111
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CreateCubinComputeShader)
111112
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_DestroyCubinComputeShader)
112113
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetCudaTextureObject)
113114
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetCudaSurfaceObject)
115+
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetCudaMergedTextureSamplerObject)
116+
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetCudaIndependentDescriptorObject)
114117
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_LaunchCubinShader)
115118
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_CaptureUAVInfo)
116119
INSERT_AND_RETURN_WHEN_EQUALS(NvAPI_D3D12_GetGraphicsCapabilities)

‎src/util/util_log.h

+25-4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ namespace dxvk::log {
5050
return str::format("flags=0x", std::setfill('0'), std::setw(4), std::hex, h);
5151
}
5252

53+
inline std::string d3d12_cpu_descriptor_handle(D3D12_CPU_DESCRIPTOR_HANDLE h) {
54+
return str::format("{ptr=", hex_prefix, std::hex, h.ptr, "}");
55+
}
56+
5357
inline std::string nv_latency_marker_params(NV_LATENCY_MARKER_PARAMS* p) {
5458
if (!p)
5559
return "nullptr";
@@ -64,6 +68,27 @@ namespace dxvk::log {
6468
return str::format("{version=", p->version, ",frameID=", p->frameID, ",markerType=", fromLatencyMarkerType(p->markerType), ",presentFrameID=", p->presentFrameID, ",rsvd}");
6569
}
6670

71+
inline std::string nvapi_d3d12_create_cubin_shader_params(NVAPI_D3D12_CREATE_CUBIN_SHADER_PARAMS* p) {
72+
if (p == nullptr)
73+
return "nullptr";
74+
75+
return str::format("{structSizeIn=", p->structSizeIn, ",pDevice=", ptr(p->pDevice), ",pCubin=", ptr(p->pCubin), ",size=", p->size, ",blockX=", p->blockX, ",blockY=", p->blockY, ",blockZ=", p->blockZ, ",dynSharedMemBytes=", p->dynSharedMemBytes, ",pShaderName=", p->pShaderName, ",flags=", p->flags, "}");
76+
}
77+
78+
inline std::string nvapi_d3d12_get_cuda_merged_texture_sampler_object_params(NVAPI_D3D12_GET_CUDA_MERGED_TEXTURE_SAMPLER_OBJECT_PARAMS* p) {
79+
if (p == nullptr)
80+
return "nullptr";
81+
82+
return str::format("{structSizeIn=", p->structSizeIn, ",pDevice=", ptr(p->pDevice), ",texDesc=", d3d12_cpu_descriptor_handle(p->texDesc), ",smpDesc=", d3d12_cpu_descriptor_handle(p->smpDesc), "}");
83+
}
84+
85+
inline std::string nvapi_d3d12_get_cuda_independent_descriptor_object_params(NVAPI_D3D12_GET_CUDA_INDEPENDENT_DESCRIPTOR_OBJECT_PARAMS* p) {
86+
if (p == nullptr)
87+
return "nullptr";
88+
89+
return str::format("{structSizeIn=", p->structSizeIn, ",pDevice=", ptr(p->pDevice), ",type=", p->type, ",desc=", d3d12_cpu_descriptor_handle(p->desc), "}");
90+
}
91+
6792
inline std::string nv_vk_get_sleep_status_params(NV_VULKAN_GET_SLEEP_STATUS_PARAMS* p) {
6893
if (!p)
6994
return "nullptr";
@@ -92,10 +117,6 @@ namespace dxvk::log {
92117
return str::format("{version=", p->version, ",frameID=", p->frameID, ",markerType=", p->markerType, ",rsvd}");
93118
}
94119

95-
inline std::string d3d12_cpu_descriptor_handle(D3D12_CPU_DESCRIPTOR_HANDLE h) {
96-
return str::format("{ptr=", hex_prefix, std::hex, h.ptr, "}");
97-
}
98-
99120
inline std::string ngx_dlss_override_get_state_params(NV_NGX_DLSS_OVERRIDE_GET_STATE_PARAMS* p) {
100121
return str::format("{version=", p->version, ",processIdentifier=", p->processIdentifier, "}");
101122
}

0 commit comments

Comments
 (0)
Please sign in to comment.