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 an optional path for using dxilconv #2236

Merged
merged 4 commits into from
Dec 4, 2024
Merged
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
25 changes: 25 additions & 0 deletions include/vkd3d_dxcapi.idl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef HRESULT (__stdcall *DxcCreateInstanceProc)(

cpp_quote("DEFINE_GUID(CLSID_DxcCompiler, 0x73e22d93, 0xe6ce, 0x47f3, 0xb5, 0xbf, 0xf0, 0x66, 0x4f, 0x39, 0xc1, 0xb0);")
cpp_quote("DEFINE_GUID(CLSID_DxcUtils, 0x6245d6af, 0x66e0, 0x48fd, 0x80, 0xb4, 0x4d, 0x27, 0x17, 0x96, 0x74, 0x8c);")
cpp_quote("DEFINE_GUID(CLSID_DxbcConverter, 0x4900391e, 0xb752, 0x4edd, 0xa8, 0x85, 0x6f, 0xb7, 0x6e, 0x25, 0xad, 0xdb);")

cpp_quote("#define DXC_CP_UTF8 65001")
cpp_quote("#define DXC_CP_UTF16 1200")
Expand Down Expand Up @@ -230,3 +231,27 @@ interface IDxcUtils : IUnknown
IDxcCompilerArgs **args);
HRESULT GetPDBContents(IDxcBlob *pdb_blob, IDxcBlob **hash, IDxcBlob **container);
}

[
local,
object,
uuid(5f956ed5-78d1-4b15-8247-f7187614a041),
pointer_default(unique)
]
interface IDxbcConverter : IUnknown
{
HRESULT Convert(
const void *pDxbc, UINT32 DxbcSize,
const WCHAR *pExtraOptions,
void **ppDxil, UINT32 *pDxilSize, WCHAR **ppDiag);

HRESULT ConvertInDriver(
const UINT32 *pBytecode,
const void *pInputSignature, UINT32 NumInputSignatureElements,
const void *pOutputSignature,
UINT32 NumOutputSignatureElements,
const void *pPatchConstantSignature,
UINT32 NumPatchConstantSignatureElements,
const WCHAR *pExtraOptions, IDxcBlob **ppDxilModule,
WCHAR **ppDiag);
}
24 changes: 24 additions & 0 deletions libs/vkd3d-common/guid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2024 Hans-Kristian Arntzen for Valve 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
*/

/* Need a common place to define these GUIDs, otherwise we have a mess with
* either double definitions or missing definitions in the programs/. */
#ifdef VKD3D_ENABLE_DXILCONV
#define INITGUID
#include "vkd3d_dxcapi.h"
#endif
1 change: 1 addition & 0 deletions libs/vkd3d-common/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ vkd3d_common_src = [
'string.c',
'file_utils.c',
'platform.c',
'guid.c',
]

vkd3d_common_lib = static_library('vkd3d_common', vkd3d_common_src, vkd3d_header_files,
Expand Down
2 changes: 1 addition & 1 deletion libs/vkd3d-shader/dxil.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,8 +577,8 @@ int vkd3d_shader_compile_dxil(const struct vkd3d_shader_code *dxbc,

dxil_spv_set_thread_log_callback(vkd3d_dxil_log_callback, NULL);

hash = spirv->meta.hash == 0 ? vkd3d_shader_hash(dxbc) : spirv->meta.hash;
memset(&spirv->meta, 0, sizeof(spirv->meta));
hash = vkd3d_shader_hash(dxbc);
spirv->meta.hash = hash;

/* Cannot replace mesh shaders until we have reflected the IO layout. */
Expand Down
72 changes: 71 additions & 1 deletion libs/vkd3d-shader/vkd3d_shader_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
#include "vkd3d_string.h"

#include "vkd3d_platform.h"
#include "vkd3d_threads.h"

#include <stdio.h>
#include <inttypes.h>

#include "vkd3d_dxcapi.h"

static void vkd3d_shader_dump_blob(const char *path, vkd3d_shader_hash_t hash, const void *data, size_t size, const char *ext)
{
char filename[1024];
Expand Down Expand Up @@ -362,6 +365,37 @@ static int vkd3d_shader_validate_shader_type(enum vkd3d_shader_type type, VkShad
return 0;
}

#ifdef VKD3D_ENABLE_DXILCONV
static DxcCreateInstanceProc vkd3d_dxilconv_instance_proc;

static void dxilconv_init_once(void)
{
vkd3d_module_t module = vkd3d_dlopen("dxilconv.dll");
if (module)
vkd3d_dxilconv_instance_proc = vkd3d_dlsym(module, "DxcCreateInstance");

if (vkd3d_dxilconv_instance_proc)
INFO("Found dxilconv.dll. Will use that for DXBC.\n");
else
INFO("Did not find dxilconv.dll. Using built-in DXBC implementation.\n");
}

static IDxbcConverter *vkd3d_shader_compiler_create_dxbc_converter(void)
{
static pthread_once_t once_key = PTHREAD_ONCE_INIT;
IDxbcConverter *iface;

pthread_once(&once_key, dxilconv_init_once);
if (!vkd3d_dxilconv_instance_proc)
return NULL;

if (FAILED(vkd3d_dxilconv_instance_proc(&CLSID_DxbcConverter, &IID_IDxbcConverter, (void **)&iface)))
return NULL;

return iface;
}
#endif

int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_code *spirv,
struct vkd3d_shader_code_debug *spirv_debug,
Expand All @@ -374,6 +408,7 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_scan_info scan_info;
struct vkd3d_shader_parser parser;
vkd3d_shader_hash_t hash;
bool is_dxil;
int ret;

TRACE("dxbc {%p, %zu}, spirv %p, compiler_options %#x, shader_interface_info %p, compile_args %p.\n",
Expand All @@ -382,9 +417,39 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
if ((ret = vkd3d_shader_validate_compile_args(compile_args)) < 0)
return ret;

is_dxil = shader_is_dxil(dxbc->code, dxbc->size);

#ifdef VKD3D_ENABLE_DXILCONV
if (!is_dxil)
{
IDxbcConverter *conv = vkd3d_shader_compiler_create_dxbc_converter();
if (conv)
{
struct vkd3d_shader_code converted;
UINT32 dxil_size;
int ret = -1;
void *dxil;

if (SUCCEEDED(IDxbcConverter_Convert(conv, dxbc->code, dxbc->size, NULL, &dxil, &dxil_size, NULL)))
{
converted.code = dxil;
converted.size = dxil_size;
spirv->meta.hash = vkd3d_shader_hash(dxbc);
ret = vkd3d_shader_compile_dxil(&converted, spirv, spirv_debug, shader_interface_info, compile_args);
CoTaskMemFree(dxil);
}
IDxbcConverter_Release(conv);

if (ret == 0)
return ret;
}
}
#endif

/* DXIL is handled externally through dxil-spirv. */
if (shader_is_dxil(dxbc->code, dxbc->size))
if (is_dxil)
{
spirv->meta.hash = 0;
return vkd3d_shader_compile_dxil(dxbc, spirv, spirv_debug, shader_interface_info, compile_args);
}

Expand Down Expand Up @@ -871,7 +936,12 @@ uint64_t vkd3d_shader_get_revision(void)
* Might get nuked later ...
* It's not immediately useful for invalidating pipeline caches, since that would mostly be covered
* by vkd3d-proton Git hash. */
#ifdef VKD3D_ENABLE_DXILCONV
dxilconv_init_once();
return vkd3d_dxilconv_instance_proc ? 2 : 1;
#else
return 1;
#endif
}

struct vkd3d_shader_stage_io_entry *vkd3d_shader_stage_io_map_append(struct vkd3d_shader_stage_io_map *map,
Expand Down
5 changes: 5 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enable_profiling = get_option('enable_profiling')
enable_renderdoc = get_option('enable_renderdoc')
enable_descriptor_qa = get_option('enable_descriptor_qa')
enable_trace = get_option('enable_trace')
enable_dxilconv = get_option('enable_dxilconv')

if enable_trace == 'auto'
enable_trace = vkd3d_debug
Expand Down Expand Up @@ -53,6 +54,10 @@ if enable_breadcrumbs
add_project_arguments('-DVKD3D_ENABLE_BREADCRUMBS', language : 'c')
endif

if enable_dxilconv and vkd3d_platform == 'windows'
add_project_arguments('-DVKD3D_ENABLE_DXILCONV', language : 'c')
endif

vkd3d_external_includes = [ './khronos/Vulkan-Headers/include', './khronos/SPIRV-Headers/include' ]
vkd3d_public_includes = [ './include' ] + vkd3d_external_includes
vkd3d_private_includes = [ './include/private' ] + vkd3d_public_includes
Expand Down
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ option('enable_profiling', type : 'boolean', value : false)
option('enable_renderdoc', type : 'boolean', value : false)
option('enable_descriptor_qa', type : 'boolean', value : false)
option('enable_trace', type : 'combo', value : 'auto', choices : ['false', 'true', 'auto'])
option('enable_dxilconv', type : 'boolean', value : false)