vkd3d: Implement new interfaces required for DX12 DLSS support.

Adds ID3D12GraphicsCommandListExt and ID3D12DeviceExt interfaces.

Signed-off-by: Roshan Chaudhari <rochaudhari@nvidia.com>
This commit is contained in:
rochaudhari 2021-08-27 13:55:48 +05:30 committed by Hans-Kristian Arntzen
parent e9f04e8e0e
commit 0828aec4f6
12 changed files with 565 additions and 7 deletions

View File

@ -10,6 +10,8 @@ vkd3d_idl = [
'vkd3d_dxgiformat.idl',
'vkd3d_dxgitype.idl',
'vkd3d_swapchain_factory.idl',
'vkd3d_command_list_vkd3d_ext.idl',
'vkd3d_device_vkd3d_ext.idl'
]
vkd3d_header_files = idl_generator.process(vkd3d_idl)

View File

@ -0,0 +1,32 @@
/*
* * Copyright 2021 NVIDIA Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
import "vkd3d_d3d12.idl";
import "vkd3d_vk_includes.h";
[
uuid(77a86b09-2bea-4801-b89a-37648e104af1),
object,
local,
pointer_default(unique)
]
interface ID3D12GraphicsCommandListExt : IUnknown
{
HRESULT GetVulkanHandle(VkCommandBuffer *pVkCommandBuffer);
HRESULT LaunchCubinShader(D3D12_CUBIN_DATA_HANDLE *handle, UINT32 block_x, UINT32 block_y, UINT32 block_z, const void *params, UINT32 param_size);
}

View File

@ -0,0 +1,37 @@
/*
* * Copyright 2021 NVIDIA Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
import "vkd3d_d3d12.idl";
import "vkd3d_vk_includes.h";
[
uuid(11ea7a1a-0f6a-49bf-b612-3e30f8e201dd),
object,
local,
pointer_default(unique)
]
interface ID3D12DeviceExt : IUnknown
{
HRESULT GetVulkanHandles(VkInstance *vk_instance, VkPhysicalDevice *vk_physical_device, VkDevice *vk_device);
BOOL GetExtensionSupport(D3D12_VK_EXTENSION extension);
HRESULT CreateCubinComputeShaderWithName(const void *cubin_data, UINT32 cubin_size, UINT32 block_x, UINT32 block_y, UINT32 block_z, const char *shader_name, D3D12_CUBIN_DATA_HANDLE **handle);
HRESULT DestroyCubinComputeShader(D3D12_CUBIN_DATA_HANDLE *handle);
HRESULT GetCudaTextureObject(D3D12_CPU_DESCRIPTOR_HANDLE srv_handle, D3D12_CPU_DESCRIPTOR_HANDLE sampler_handle, UINT32 *cuda_texture_handle);
HRESULT GetCudaSurfaceObject(D3D12_CPU_DESCRIPTOR_HANDLE uav_handle, UINT32 *cuda_surface_handle);
HRESULT CaptureUAVInfo(D3D12_UAV_INFO *uav_info);
}

View File

@ -0,0 +1,58 @@
/*
* * Copyright 2021 NVIDIA Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __VKD3D_VK_INCLUDES_H
#define __VKD3D_VK_INCLUDES_H
#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
typedef struct VkCuFunctionNVX_T *VkCuFunctionNVX;
typedef struct VkCuModuleNVX_T *VkCuModuleNVX;
#else
typedef UINT64 VkCuFunctionNVX;
typedef UINT64 VkCuModuleNVX;
#endif
typedef struct VkPhysicalDevice_T *VkPhysicalDevice;
typedef struct VkCommandBuffer_T *VkCommandBuffer;
typedef struct VkInstance_T *VkInstance;
typedef struct VkDevice_T *VkDevice;
typedef enum D3D12_VK_EXTENSION
{
D3D12_VK_NVX_BINARY_IMPORT = 0x1,
D3D12_VK_NVX_IMAGE_VIEW_HANDLE = 0x2
} D3D12_VK_EXTENSION;
typedef struct D3D12_CUBIN_DATA_HANDLE
{
VkCuFunctionNVX vkCuFunction;
VkCuModuleNVX vkCuModule;
UINT32 blockX;
UINT32 blockY;
UINT32 blockZ;
} D3D12_CUBIN_DATA_HANDLE;
typedef struct D3D12_UAV_INFO
{
UINT32 version;
UINT32 surfaceHandle;
UINT64 gpuVAStart;
UINT64 gpuVASize;
} D3D12_UAV_INFO;
#endif // __VKD3D_VK_INCLUDES_H

View File

@ -68,6 +68,8 @@
#define __vkd3d_dxgi1_4_h__
#include <vkd3d_swapchain_factory.h>
#include <vkd3d_command_list_vkd3d_ext.h>
#include <vkd3d_device_vkd3d_ext.h>
#include <vkd3d_d3d12.h>
#include <vkd3d_d3d12sdklayers.h>

View File

@ -4002,7 +4002,9 @@ static void d3d12_command_list_track_query_heap(struct d3d12_command_list *list,
}
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(d3d12_command_list_iface *iface,
extern ULONG STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_AddRef(ID3D12GraphicsCommandListExt *iface);
HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(d3d12_command_list_iface *iface,
REFIID iid, void **object)
{
TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
@ -4023,13 +4025,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(d3d12_command
return S_OK;
}
if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandListExt))
{
struct d3d12_command_list *command_list = impl_from_ID3D12GraphicsCommandList(iface);
d3d12_command_list_vkd3d_ext_AddRef(&command_list->ID3D12GraphicsCommandListExt_iface);
*object = &command_list->ID3D12GraphicsCommandListExt_iface;
return S_OK;
}
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
*object = NULL;
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(d3d12_command_list_iface *iface)
ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(d3d12_command_list_iface *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
ULONG refcount = InterlockedIncrement(&list->refcount);
@ -4039,7 +4049,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(d3d12_command_list_ifac
return refcount;
}
static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(d3d12_command_list_iface *iface)
ULONG STDMETHODCALLTYPE d3d12_command_list_Release(d3d12_command_list_iface *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
ULONG refcount = InterlockedDecrement(&list->refcount);
@ -9756,6 +9766,8 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList_iface);
}
extern CONST_VTBL struct ID3D12GraphicsCommandListExtVtbl d3d12_command_list_vkd3d_ext_vtbl;
static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device,
D3D12_COMMAND_LIST_TYPE type)
{
@ -9776,6 +9788,8 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d
list->type = type;
list->ID3D12GraphicsCommandListExt_iface.lpVtbl = &d3d12_command_list_vkd3d_ext_vtbl;
if (FAILED(hr = vkd3d_private_store_init(&list->private_store)))
return hr;

View File

@ -0,0 +1,116 @@
/*
* * Copyright 2021 NVIDIA Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "vkd3d_private.h"
static inline struct d3d12_command_list *d3d12_command_list_from_ID3D12GraphicsCommandListExt(ID3D12GraphicsCommandListExt *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandListExt_iface);
}
extern ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(d3d12_command_list_iface *iface);
ULONG STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_AddRef(ID3D12GraphicsCommandListExt *iface)
{
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
return d3d12_command_list_AddRef(&command_list->ID3D12GraphicsCommandList_iface);
}
extern ULONG STDMETHODCALLTYPE d3d12_command_list_Release(d3d12_command_list_iface *iface);
static ULONG STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_Release(ID3D12GraphicsCommandListExt *iface)
{
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
return d3d12_command_list_Release(&command_list->ID3D12GraphicsCommandList_iface);
}
extern HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(d3d12_command_list_iface *iface,
REFIID iid, void **object);
static HRESULT STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_QueryInterface(ID3D12GraphicsCommandListExt *iface,
REFIID iid, void **out)
{
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
return d3d12_command_list_QueryInterface(&command_list->ID3D12GraphicsCommandList_iface, iid, out);
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_GetVulkanHandle(ID3D12GraphicsCommandListExt *iface,
VkCommandBuffer *pVkCommandBuffer)
{
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
TRACE("iface %p, pVkCommandBuffer %p.\n", iface, pVkCommandBuffer);
if (!pVkCommandBuffer)
return E_INVALIDARG;
*pVkCommandBuffer = command_list->vk_command_buffer;
return S_OK;
}
#define CU_LAUNCH_PARAM_BUFFER_POINTER (const void*)0x01
#define CU_LAUNCH_PARAM_BUFFER_SIZE (const void*)0x02
#define CU_LAUNCH_PARAM_END (const void*)0x00
static HRESULT STDMETHODCALLTYPE d3d12_command_list_vkd3d_ext_LaunchCubinShader(ID3D12GraphicsCommandListExt *iface, D3D12_CUBIN_DATA_HANDLE *handle, UINT32 block_x, UINT32 block_y, UINT32 block_z, const void *params, UINT32 param_size)
{
VkCuLaunchInfoNVX launchInfo = { VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX };
const struct vkd3d_vk_device_procs *vk_procs;
const void *config[] = {
CU_LAUNCH_PARAM_BUFFER_POINTER, params,
CU_LAUNCH_PARAM_BUFFER_SIZE, &param_size,
CU_LAUNCH_PARAM_END
};
struct d3d12_command_list *command_list = d3d12_command_list_from_ID3D12GraphicsCommandListExt(iface);
TRACE("iface %p, handle %p, block_x %u, block_y %u, block_z %u, params %p, param_size %u \n", iface, handle, block_x, block_y, block_z, params, param_size);
if (!handle || !block_x || !block_y || !block_z || !params || !param_size)
return E_INVALIDARG;
launchInfo.function = handle->vkCuFunction;
launchInfo.gridDimX = block_x;
launchInfo.gridDimY = block_y;
launchInfo.gridDimZ = block_z;
launchInfo.blockDimX = handle->blockX;
launchInfo.blockDimY = handle->blockY;
launchInfo.blockDimZ = handle->blockZ;
launchInfo.sharedMemBytes = 0;
launchInfo.paramCount = 0;
launchInfo.pParams = NULL;
launchInfo.extraCount = 1;
launchInfo.pExtras = config;
vk_procs = &command_list->device->vk_procs;
VK_CALL(vkCmdCuLaunchKernelNVX(command_list->vk_command_buffer, &launchInfo));
return S_OK;
}
CONST_VTBL struct ID3D12GraphicsCommandListExtVtbl d3d12_command_list_vkd3d_ext_vtbl =
{
/* IUnknown methods */
d3d12_command_list_vkd3d_ext_QueryInterface,
d3d12_command_list_vkd3d_ext_AddRef,
d3d12_command_list_vkd3d_ext_Release,
/* ID3D12GraphicsCommandListExt methods */
d3d12_command_list_vkd3d_ext_GetVulkanHandle,
d3d12_command_list_vkd3d_ext_LaunchCubinShader
};

View File

@ -2416,7 +2416,9 @@ static inline struct d3d12_device *impl_from_ID3D12Device(d3d12_device_iface *if
return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device_iface);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(d3d12_device_iface *iface,
extern ULONG STDMETHODCALLTYPE d3d12_device_vkd3d_ext_AddRef(ID3D12DeviceExt *iface);
HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(d3d12_device_iface *iface,
REFIID riid, void **object)
{
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
@ -2436,6 +2438,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(d3d12_device_iface
return S_OK;
}
if (IsEqualGUID(riid, &IID_ID3D12DeviceExt))
{
struct d3d12_device *device = impl_from_ID3D12Device(iface);
d3d12_device_vkd3d_ext_AddRef(&device->ID3D12DeviceExt_iface);
*object = &device->ID3D12DeviceExt_iface;
return S_OK;
}
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
*object = NULL;
@ -3447,18 +3457,46 @@ static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(d3d12_device
device, unsafe_impl_from_ID3D12Resource(resource), desc);
}
__thread struct D3D12_UAV_INFO *d3d12_uav_info = NULL;
static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(d3d12_device_iface *iface,
ID3D12Resource *resource, ID3D12Resource *counter_resource,
const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
{
VkImageViewAddressPropertiesNVX out_info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX };
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX };
const struct vkd3d_vk_device_procs *vk_procs;
VkResult vr;
struct d3d12_resource *d3d12_resource_ = unsafe_impl_from_ID3D12Resource(resource);
struct d3d12_device *device = impl_from_ID3D12Device(iface);
struct d3d12_desc *d3d12_desc_cpu = d3d12_desc_from_cpu_handle(descriptor);
TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n",
iface, resource, counter_resource, desc, descriptor.ptr);
d3d12_desc_create_uav(d3d12_desc_from_cpu_handle(descriptor),
device, unsafe_impl_from_ID3D12Resource(resource),
d3d12_desc_create_uav(d3d12_desc_cpu,
device, d3d12_resource_,
unsafe_impl_from_ID3D12Resource(counter_resource), desc);
/* d3d12_uav_info stores the pointer to data from previous call to d3d12_device_vkd3d_ext_CaptureUAVInfo(). Below code will update the data. */
if (d3d12_uav_info)
{
imageViewHandleInfo.imageView = d3d12_desc_cpu->info.view->vk_image_view;
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
vk_procs = &device->vk_procs;
d3d12_uav_info->surfaceHandle = VK_CALL(vkGetImageViewHandleNVX(device->vk_device, &imageViewHandleInfo));
if ((vr = VK_CALL(vkGetImageViewAddressNVX(device->vk_device, imageViewHandleInfo.imageView, &out_info))) < 0)
{
ERR("Failed to get imageview address, vr %d.\n", vr);
return;
}
d3d12_uav_info->gpuVAStart = out_info.deviceAddress;
d3d12_uav_info->gpuVASize = out_info.size;
/* Set this to null so that subsequent calls to this API wont update the previous pointer. */
d3d12_uav_info = NULL;
}
}
static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(d3d12_device_iface *iface,
@ -5076,6 +5114,8 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device(d3d12_device_iface *iface)
return impl_from_ID3D12Device(iface);
}
extern CONST_VTBL struct ID3D12DeviceExtVtbl d3d12_device_vkd3d_ext_vtbl;
static HRESULT d3d12_device_init(struct d3d12_device *device,
struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info)
{
@ -5109,6 +5149,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
hr = hresult_from_errno(rc);
goto out_free_instance;
}
device->ID3D12DeviceExt_iface.lpVtbl = &d3d12_device_vkd3d_ext_vtbl;
if (FAILED(hr = vkd3d_create_vk_device(device, create_info)))
goto out_free_mutex;

View File

@ -0,0 +1,232 @@
/*
* * Copyright 2021 NVIDIA Corporation
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "vkd3d_private.h"
static inline struct d3d12_device *d3d12_device_from_ID3D12DeviceExt(ID3D12DeviceExt *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12DeviceExt_iface);
}
ULONG STDMETHODCALLTYPE d3d12_device_vkd3d_ext_AddRef(ID3D12DeviceExt *iface)
{
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
return d3d12_device_add_ref(device);
}
static ULONG STDMETHODCALLTYPE d3d12_device_vkd3d_ext_Release(ID3D12DeviceExt *iface)
{
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
return d3d12_device_release(device);
}
extern HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(d3d12_device_iface *iface,
REFIID riid, void **object);
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_QueryInterface(ID3D12DeviceExt *iface,
REFIID iid, void **out)
{
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
return d3d12_device_QueryInterface(&device->ID3D12Device_iface, iid, out);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetVulkanHandles(ID3D12DeviceExt *iface, VkInstance *vk_instance, VkPhysicalDevice *vk_physical_device, VkDevice *vk_device)
{
struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
TRACE("iface %p, vk_instance %p, vk_physical_device %u, vk_device %p \n", iface, vk_instance, vk_physical_device, vk_device);
if (!vk_device || !vk_instance || !vk_physical_device)
return E_INVALIDARG;
*vk_instance = device->vkd3d_instance->vk_instance;
*vk_physical_device = device->vk_physical_device;
*vk_device = device->vk_device;
return S_OK;
}
static BOOL STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetExtensionSupport(ID3D12DeviceExt *iface, D3D12_VK_EXTENSION extension)
{
const struct d3d12_device *device = d3d12_device_from_ID3D12DeviceExt(iface);
bool ret_val = false;
TRACE("iface %p, extension %u \n", iface, extension);
switch (extension)
{
case D3D12_VK_NVX_BINARY_IMPORT:
ret_val = device->vk_info.NVX_binary_import;
break;
case D3D12_VK_NVX_IMAGE_VIEW_HANDLE:
ret_val = device->vk_info.NVX_image_view_handle;
break;
default:
WARN("Invalid extension %x\n", extension);
}
return ret_val;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_CreateCubinComputeShaderWithName(ID3D12DeviceExt *iface, const void *cubin_data,
UINT32 cubin_size, UINT32 block_x, UINT32 block_y, UINT32 block_z, const char *shader_name, D3D12_CUBIN_DATA_HANDLE **out_handle)
{
VkCuFunctionCreateInfoNVX functionCreateInfo = { VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX };
VkCuModuleCreateInfoNVX moduleCreateInfo = { VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX };
const struct vkd3d_vk_device_procs *vk_procs;
D3D12_CUBIN_DATA_HANDLE *handle;
struct d3d12_device *device;
VkDevice vk_device;
VkResult vr;
TRACE("iface %p, cubin_data %p, cubin_size %u, shader_name %s \n", iface, cubin_data, cubin_size, shader_name);
if (!cubin_data || !cubin_size || !shader_name)
return E_INVALIDARG;
device = d3d12_device_from_ID3D12DeviceExt(iface);
vk_device = device->vk_device;
handle = vkd3d_calloc(1, sizeof(D3D12_CUBIN_DATA_HANDLE));
handle->blockX = block_x;
handle->blockY = block_y;
handle->blockZ = block_z;
moduleCreateInfo.pData = cubin_data;
moduleCreateInfo.dataSize = cubin_size;
vk_procs = &device->vk_procs;
if ((vr = VK_CALL(vkCreateCuModuleNVX(vk_device, &moduleCreateInfo, NULL, &handle->vkCuModule))) < 0)
{
ERR("Failed to create cubin shader, vr %d.\n", vr);
vkd3d_free(handle);
return hresult_from_vk_result(vr);
}
functionCreateInfo.module = handle->vkCuModule;
functionCreateInfo.pName = shader_name;
if ((vr = VK_CALL(vkCreateCuFunctionNVX(vk_device, &functionCreateInfo, NULL, &handle->vkCuFunction))) < 0)
{
ERR("Failed to create cubin function module, vr %d.\n", vr);
VK_CALL(vkDestroyCuModuleNVX(vk_device, handle->vkCuModule, NULL));
vkd3d_free(handle);
return hresult_from_vk_result(vr);
}
*out_handle = handle;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_DestroyCubinComputeShader(ID3D12DeviceExt *iface, D3D12_CUBIN_DATA_HANDLE *handle)
{
const struct vkd3d_vk_device_procs *vk_procs;
struct d3d12_device *device;
VkDevice vk_device;
TRACE("iface %p, handle %p \n", iface, handle);
if (!iface || !handle)
return E_INVALIDARG;
device = d3d12_device_from_ID3D12DeviceExt(iface);
vk_device = device->vk_device;
vk_procs = &device->vk_procs;
VK_CALL(vkDestroyCuFunctionNVX(vk_device, handle->vkCuFunction, NULL));
VK_CALL(vkDestroyCuModuleNVX(vk_device, handle->vkCuModule, NULL));
vkd3d_free(handle);
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetCudaTextureObject(ID3D12DeviceExt *iface, D3D12_CPU_DESCRIPTOR_HANDLE srv_handle,
D3D12_CPU_DESCRIPTOR_HANDLE sampler_handle, UINT32 *cuda_texture_handle)
{
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX };
const struct vkd3d_vk_device_procs *vk_procs;
struct d3d12_desc *sampler_desc;
struct d3d12_device *device;
struct d3d12_desc *srv_desc;
TRACE("iface %p, srv_handle %#x, sampler_handle %#x, cuda_texture_handle %p.\n", iface, srv_handle, sampler_handle, cuda_texture_handle);
if (!cuda_texture_handle)
return E_INVALIDARG;
device = d3d12_device_from_ID3D12DeviceExt(iface);
srv_desc = d3d12_desc_from_cpu_handle(srv_handle);
sampler_desc = d3d12_desc_from_cpu_handle(sampler_handle);
imageViewHandleInfo.imageView = srv_desc->info.view->vk_image_view;
imageViewHandleInfo.sampler = sampler_desc->info.view->vk_sampler;
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
vk_procs = &device->vk_procs;
*cuda_texture_handle = VK_CALL(vkGetImageViewHandleNVX(device->vk_device, &imageViewHandleInfo));
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_GetCudaSurfaceObject(ID3D12DeviceExt *iface, D3D12_CPU_DESCRIPTOR_HANDLE uav_handle,
UINT32 *cuda_surface_handle)
{
VkImageViewHandleInfoNVX imageViewHandleInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX };
const struct vkd3d_vk_device_procs *vk_procs;
struct d3d12_device *device;
struct d3d12_desc *uav_desc;
TRACE("iface %p, uav_handle %#x, cuda_surface_handle %p.\n", iface, uav_handle, cuda_surface_handle);
if (!cuda_surface_handle)
return E_INVALIDARG;
device = d3d12_device_from_ID3D12DeviceExt(iface);
uav_desc = d3d12_desc_from_cpu_handle(uav_handle);
imageViewHandleInfo.imageView = uav_desc->info.view->vk_image_view;
imageViewHandleInfo.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
vk_procs = &device->vk_procs;
*cuda_surface_handle = VK_CALL(vkGetImageViewHandleNVX(device->vk_device, &imageViewHandleInfo));
return S_OK;
}
extern __thread struct D3D12_UAV_INFO *d3d12_uav_info;
static HRESULT STDMETHODCALLTYPE d3d12_device_vkd3d_ext_CaptureUAVInfo(ID3D12DeviceExt *iface, D3D12_UAV_INFO *uav_info)
{
if (!uav_info)
return E_INVALIDARG;
TRACE("iface %p, uav_info %p.\n", iface, uav_info);
/* CaptureUAVInfo() supposed to capture the information from the next CreateUnorderedAccess() on the same thread.
We use d3d12_uav_info pointer to update the information in CreateUnorderedAccess() */
d3d12_uav_info = uav_info;
return S_OK;
}
CONST_VTBL struct ID3D12DeviceExtVtbl d3d12_device_vkd3d_ext_vtbl =
{
/* IUnknown methods */
d3d12_device_vkd3d_ext_QueryInterface,
d3d12_device_vkd3d_ext_AddRef,
d3d12_device_vkd3d_ext_Release,
/* ID3D12DeviceExt methods */
d3d12_device_vkd3d_ext_GetVulkanHandles,
d3d12_device_vkd3d_ext_GetExtensionSupport,
d3d12_device_vkd3d_ext_CreateCubinComputeShaderWithName,
d3d12_device_vkd3d_ext_DestroyCubinComputeShader,
d3d12_device_vkd3d_ext_GetCudaTextureObject,
d3d12_device_vkd3d_ext_GetCudaSurfaceObject,
d3d12_device_vkd3d_ext_CaptureUAVInfo
};

View File

@ -32,7 +32,9 @@ vkd3d_src = [
'bundle.c',
'cache.c',
'command.c',
'command_list_vkd3d_ext.c',
'device.c',
'device_vkd3d_ext.c',
'heap.c',
'memory.c',
'meta.c',

View File

@ -36,6 +36,8 @@
#include "vkd3d_threads.h"
#include "vkd3d_platform.h"
#include "vkd3d_swapchain_factory.h"
#include "vkd3d_command_list_vkd3d_ext.h"
#include "vkd3d_device_vkd3d_ext.h"
#include "vkd3d_string.h"
#include <assert.h>
#include <inttypes.h>
@ -1746,6 +1748,9 @@ struct vkd3d_query_range
uint32_t flags;
};
/* ID3D12CommandListExt */
typedef ID3D12GraphicsCommandListExt d3d12_command_list_vkd3d_ext_iface;
struct d3d12_state_object;
struct d3d12_resource_tracking
@ -1757,6 +1762,7 @@ struct d3d12_resource_tracking
struct d3d12_command_list
{
d3d12_command_list_iface ID3D12GraphicsCommandList_iface;
d3d12_command_list_vkd3d_ext_iface ID3D12GraphicsCommandListExt_iface;
LONG refcount;
D3D12_COMMAND_LIST_TYPE type;
@ -2609,9 +2615,13 @@ typedef ID3D12Device6 d3d12_device_iface;
struct vkd3d_descriptor_qa_global_info;
struct vkd3d_descriptor_qa_heap_buffer_data;
/* ID3D12DeviceExt */
typedef ID3D12DeviceExt d3d12_device_vkd3d_ext_iface;
struct d3d12_device
{
d3d12_device_iface ID3D12Device_iface;
d3d12_device_vkd3d_ext_iface ID3D12DeviceExt_iface;
LONG refcount;
VkDevice vk_device;

View File

@ -277,6 +277,17 @@ VK_DEVICE_EXT_PFN(vkQueuePresentKHR)
/* VK_AMD_buffer_marker */
VK_DEVICE_EXT_PFN(vkCmdWriteBufferMarkerAMD)
/* VK_NVX_binary_import */
VK_DEVICE_EXT_PFN(vkCreateCuModuleNVX);
VK_DEVICE_EXT_PFN(vkCreateCuFunctionNVX);
VK_DEVICE_EXT_PFN(vkDestroyCuModuleNVX);
VK_DEVICE_EXT_PFN(vkDestroyCuFunctionNVX);
VK_DEVICE_EXT_PFN(vkCmdCuLaunchKernelNVX);
/* VK_NVX_image_view_handle */
VK_DEVICE_EXT_PFN(vkGetImageViewHandleNVX);
VK_DEVICE_EXT_PFN(vkGetImageViewAddressNVX);
#undef VK_INSTANCE_PFN
#undef VK_INSTANCE_EXT_PFN
#undef VK_DEVICE_PFN