diff --git a/JulietShaderCompiler/DXCompiler.h b/JulietShaderCompiler/DXCompiler.h new file mode 100644 index 0000000..b680a65 --- /dev/null +++ b/JulietShaderCompiler/DXCompiler.h @@ -0,0 +1,283 @@ +#pragma once + +/* Win32 Type Definitions */ + +using HRESULT = int; +using LPCVOID = const void*; +using SIZE_T = size_t; +using LPCSTR = const char*; +using UINT = unsigned int; +using ULONG = unsigned long; +using LPVOID = void*; +using REFIID = void*; + +/* dxcompiler Type Definitions */ +using BOOL = int; +using REFCLSID = void*; +using LPCWSTR = wchar_t*; +using IDxcBlobEncoding = void; /* hack, unused */ +using IDxcBlobWide = void; /* hack, unused */ +using IDxcIncludeHandler = void; /* hack, unused */ + +/* Unlike vkd3d-utils, libdxcompiler.so does not use msabi */ +#if !defined(_WIN32) +#define __stdcall +#endif + +/* Compiler Interface, _technically_ unofficial but it's MS C++, come on */ +using DXC_OUT_KIND = enum DXC_OUT_KIND { + DXC_OUT_NONE = 0, + DXC_OUT_OBJECT = 1, + DXC_OUT_ERRORS = 2, + DXC_OUT_PDB = 3, + DXC_OUT_SHADER_HASH = 4, + DXC_OUT_DISASSEMBLY = 5, + DXC_OUT_HLSL = 6, + DXC_OUT_TEXT = 7, + DXC_OUT_REFLECTION = 8, + DXC_OUT_ROOT_SIGNATURE = 9, + DXC_OUT_EXTRA_OUTPUTS = 10, + DXC_OUT_REMARKS = 11, + DXC_OUT_TIME_REPORT = 12, + DXC_OUT_TIME_TRACE = 13, + DXC_OUT_LAST = DXC_OUT_TIME_TRACE, + DXC_OUT_NUM_ENUMS, + // DXC_OUT_FORCE_DWORD = 0xFFFFFFFF +}; + +#define DXC_CP_UTF8 65001 +#define DXC_CP_UTF16 1200 +#define DXC_CP_UTF32 12000 +/* This is for binary, ANSI-text, or to tell the compiler to try autodetecting UTF using the BOM */ +#define DXC_CP_ACP 0 + +using DxcBuffer = struct DxcBuffer +{ + LPCVOID Ptr; + SIZE_T Size; + UINT Encoding; +}; + +/* *INDENT-OFF* */ // clang-format off + +static uint8 IID_IDxcBlob[] = { + 0x08, 0xFB, 0xA5, 0x8B, + 0x95, 0x51, + 0xE2, 0x40, + 0xAC, + 0x58, + 0x0D, + 0x98, + 0x9C, + 0x3A, + 0x01, + 0x02 +}; +using IDxcBlob = struct IDxcBlob; +using IDxcBlobVtbl = struct IDxcBlobVtbl +{ + HRESULT(__stdcall *QueryInterface)(IDxcBlob *This, REFIID riid, void **ppvObject); + ULONG(__stdcall *AddRef)(IDxcBlob *This); + ULONG(__stdcall *Release)(IDxcBlob *This); + + LPVOID(__stdcall *GetBufferPointer)(IDxcBlob *This); + SIZE_T(__stdcall *GetBufferSize)(IDxcBlob *This); +}; +struct IDxcBlob +{ + IDxcBlobVtbl *lpVtbl; +}; + +static uint8 IID_IDxcBlobUtf8[] = { + 0xC9, 0x36, 0xA6, 0x3D, + 0x71, 0xBA, + 0x24, 0x40, + 0xA3, + 0x01, + 0x30, + 0xCB, + 0xF1, + 0x25, + 0x30, + 0x5B +}; +using IDxcBlobUtf8 = struct IDxcBlobUtf8; +using IDxcBlobUtf8Vtbl = struct IDxcBlobUtf8Vtbl +{ + HRESULT(__stdcall *QueryInterface)(IDxcBlobUtf8 *This, REFIID riid, void **ppvObject); + ULONG(__stdcall *AddRef)(IDxcBlobUtf8 *This); + ULONG(__stdcall *Release)(IDxcBlobUtf8 *This); + + LPVOID(__stdcall *GetBufferPointer)(IDxcBlobUtf8 *This); + SIZE_T(__stdcall *GetBufferSize)(IDxcBlobUtf8 *This); + + HRESULT(__stdcall *GetEncoding)(IDxcBlobUtf8 *This, BOOL *pKnown, uint32 *pCodePage); + + LPCSTR(__stdcall *GetStringPointer)(IDxcBlobUtf8 *This); + SIZE_T(__stdcall *GetStringLength)(IDxcBlobUtf8 *This); +}; +struct IDxcBlobUtf8 +{ + IDxcBlobUtf8Vtbl *lpVtbl; +}; + +static uint8 IID_IDxcResult[] = { + 0xDA, 0x6C, 0x34, 0x58, + 0xE7, 0xDD, + 0x97, 0x44, + 0x94, + 0x61, + 0x6F, + 0x87, + 0xAF, + 0x5E, + 0x06, + 0x59 +}; +using IDxcResult = struct IDxcResult; +using IDxcResultVtbl = struct IDxcResultVtbl +{ + HRESULT(__stdcall *QueryInterface)(IDxcResult *This, REFIID riid, void **ppvObject); + ULONG(__stdcall *AddRef)(IDxcResult *This); + ULONG(__stdcall *Release)(IDxcResult *This); + + HRESULT(__stdcall *GetStatus)(IDxcResult *This, HRESULT *pStatus); + HRESULT(__stdcall *GetResult)(IDxcResult *This, IDxcBlob **ppResult); + HRESULT(__stdcall *GetErrorBuffer)(IDxcResult *This, IDxcBlobEncoding **ppErrors); + + BOOL(__stdcall *HasOutput)(IDxcResult *This, DXC_OUT_KIND dxcOutKind); + HRESULT(__stdcall *GetOutput)( + IDxcResult *This, + DXC_OUT_KIND dxcOutKind, + REFIID iid, + void **ppvObject, + IDxcBlobWide **ppOutputName + ); + uint32(__stdcall *GetNumOutputs)(IDxcResult *This); + DXC_OUT_KIND(__stdcall *GetOutputByIndex)(IDxcResult *This, uint32 Index); + DXC_OUT_KIND(__stdcall *PrimaryOutput)(IDxcResult *This); +}; +struct IDxcResult +{ + IDxcResultVtbl *lpVtbl; +}; + +static struct +{ + uint32 Data1; + uint16 Data2; + uint16 Data3; + uint8 Data4[8]; +} CLSID_DxcCompiler = { + .Data1 = 0x73e22d93, + .Data2 = 0xe6ce, + .Data3 = 0x47f3, + .Data4 = { 0xb5, 0xbf, 0xf0, 0x66, 0x4f, 0x39, 0xc1, 0xb0 } +}; +static uint8 IID_IDxcCompiler3[] = { + 0x87, 0x46, 0x8B, 0x22, + 0x6A, 0x5A, + 0x30, 0x47, + 0x90, + 0x0C, + 0x97, + 0x02, + 0xB2, + 0x20, + 0x3F, + 0x54 +}; +using IDxcCompiler3 = struct IDxcCompiler3; +using IDxcCompiler3Vtbl = struct IDxcCompiler3Vtbl +{ + HRESULT(__stdcall *QueryInterface)(IDxcCompiler3 *This, REFIID riid, void **ppvObject); + ULONG(__stdcall *AddRef)(IDxcCompiler3 *This); + ULONG(__stdcall *Release)(IDxcCompiler3 *This); + + HRESULT(__stdcall *Compile)( + IDxcCompiler3 *This, + const DxcBuffer *pSource, + LPCWSTR *pArguments, + uint32 argCount, + IDxcIncludeHandler *pIncludeHandler, + REFIID riid, + LPVOID *ppResult + ); + + HRESULT(__stdcall *Disassemble)( + IDxcCompiler3 *This, + const DxcBuffer *pObject, + REFIID riid, + LPVOID *ppResult + ); +}; +struct IDxcCompiler3 +{ + const IDxcCompiler3Vtbl *lpVtbl; +}; + +// We need all this DxcUtils garbage for DXC include dir support. Thanks Microsoft! +using IMalloc = struct IMalloc; +using IStream = struct IStream; +using DxcDefine = struct DxcDefine; +using IDxcCompilerArgs = struct IDxcCompilerArgs; + +static struct +{ + uint32 Data1; + uint16 Data2; + uint16 Data3; + uint8 Data4[8]; +} CLSID_DxcUtils = { + .Data1 = 0x6245d6af, + .Data2 = 0x66e0, + .Data3 = 0x48fd, + .Data4 = {0x80, 0xb4, 0x4d, 0x27, 0x17, 0x96, 0x74, 0x8c}}; +static uint8 IID_IDxcUtils[] = { + 0xcb, 0xc4, 0x05, 0x46, + 0x19, 0x20, + 0x2a, 0x49, + 0xad, + 0xa4, + 0x65, + 0xf2, + 0x0b, + 0xb7, + 0xd6, + 0x7f +}; +using IDxcUtilsVtbl = struct IDxcUtilsVtbl +{ + HRESULT (__stdcall *QueryInterface)(void *pSelf, REFIID riid, void **ppvObject); + ULONG (__stdcall *AddRef)(void *pSelf); + ULONG (__stdcall *Release)(void *pSelf); + + HRESULT (__stdcall *CreateBlobFromBlob)(void *pSelf, IDxcBlob *pBlob, UINT offset, UINT length, IDxcBlob **ppResult); + HRESULT (__stdcall *CreateBlobFromPinned)(void *pSelf, LPCVOID pData, UINT size, UINT codePage, IDxcBlobEncoding **pBlobEncoding); + HRESULT (__stdcall *MoveToBlob)(void *pSelf, LPCVOID pData, IMalloc *pIMalloc, UINT size, UINT codePage, IDxcBlobEncoding **pBlobEncoding); + HRESULT (__stdcall *CreateBlob)(void *pSelf, LPCVOID pData, UINT size, UINT codePage, IDxcBlobEncoding **pBlobEncoding); + HRESULT (__stdcall *LoadFile)(void *pSelf, LPCWSTR pFileName, UINT *pCodePage, IDxcBlobEncoding **pBlobEncoding); + HRESULT (__stdcall *CreateReadOnlyStreamFromBlob)(void *pSelf, IDxcBlob *pBlob, IStream **ppStream); + HRESULT (__stdcall *CreateDefaultIncludeHandler)(void *pSelf, IDxcIncludeHandler **ppResult); + HRESULT (__stdcall *GetBlobAsUtf8)(void *pSelf, IDxcBlob *pBlob, IDxcBlobUtf8 **pBlobEncoding); + HRESULT (__stdcall *GetBlobAsWide)(void *pSelf, IDxcBlob *pBlob, IDxcBlobWide **pBlobEncoding); + HRESULT (__stdcall *GetDxilContainerPart)(void *pSelf, const DxcBuffer *pShader, UINT DxcPart, void **ppPartData, UINT *pPartSizeInBytes); + HRESULT (__stdcall *CreateReflection)(void *pSelf, const DxcBuffer *pData, REFIID iid, void **ppvReflection); + HRESULT (__stdcall *BuildArguments)(void *pSelf, LPCWSTR pSourceName, LPCWSTR pEntryPoint, LPCWSTR pTargetProfile, LPCWSTR *pArguments, UINT argCount, const DxcDefine *pDefines, UINT defineCount, IDxcCompilerArgs **ppArgs); + HRESULT (__stdcall *GetPDBContents)(void *pSelf, IDxcBlob *pPDBBlob, IDxcBlob **ppHash, IDxcBlob **ppContainer); +}; + +using IDxcUtils = struct IDxcUtils; +struct IDxcUtils +{ + const IDxcUtilsVtbl *lpVtbl; +}; + +/* *INDENT-ON* */ // clang-format on + +/* DXCompiler */ +#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES) || defined(SDL_PLATFORM_WINDOWS) +extern "C" HRESULT __stdcall DxcCreateInstance(REFCLSID rclsid, REFIID riid, LPVOID* ppv); +#else +extern "C" HRESULT DxcCreateInstance(REFCLSID rclsid, REFIID riid, LPVOID* ppv); +#endif diff --git a/JulietShaderCompiler/JulietShaderCompiler.vcxproj b/JulietShaderCompiler/JulietShaderCompiler.vcxproj new file mode 100644 index 0000000..68be6e2 --- /dev/null +++ b/JulietShaderCompiler/JulietShaderCompiler.vcxproj @@ -0,0 +1,115 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {26880364-45F4-4817-BFD3-0ACC0958757D} + Win32Proj + JulietShaderCompiler + 10.0.26100.0 + + + + x64 + + + Application + true + ClangCL + Unicode + + + Application + false + ClangCL + true + Unicode + + + + + + + + + + + + + + + true + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)Intermediate\$(ProjectName)\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)Intermediate\$(ProjectName)\$(Platform)\$(Configuration)\ + + + + NotUsing + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + $(SolutionDir)Juliet\include\;$(SolutionDir)JulietShaderCompiler; + + + Console + true + $(SolutionDir)\lib\$(Platform)\$(Configuration)\ + Juliet.lib; $(CoreLibraryDependencies);%(AdditionalDependencies) + + + + + NotUsing + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + pch.h + + + Console + true + true + true + $(SolutionDir)\lib\$(Platform)\$(Configuration)\; + Juliet.lib; $(CoreLibraryDependencies);%(AdditionalDependencies) + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + + + \ No newline at end of file diff --git a/JulietShaderCompiler/JulietShaderCompiler.vcxproj.filters b/JulietShaderCompiler/JulietShaderCompiler.vcxproj.filters new file mode 100644 index 0000000..54afe9d --- /dev/null +++ b/JulietShaderCompiler/JulietShaderCompiler.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/JulietShaderCompiler/main.cpp b/JulietShaderCompiler/main.cpp new file mode 100644 index 0000000..09158c6 --- /dev/null +++ b/JulietShaderCompiler/main.cpp @@ -0,0 +1,49 @@ + +//#include +//#include +//#include + +// Must be before everything else. +// Cannot include DX12Includes because we redefine everything. +// TODO : Separate lib +// TODO : Only when not shipping +// Check if we just load the dll and not link against? + +//#include +//#pragma comment(lib, "dxcompiler.lib") + +//using namespace Juliet; + +void Compile() +{ + // IDxcCompiler3* compiler = nullptr; + // DxcCreateInstance(&CLSID_DxcCompiler, IID_IDxcCompiler3, reinterpret_cast(&compiler)); + // + // IDxcUtils* utils = nullptr; + // DxcCreateInstance(&CLSID_DxcUtils, &IID_IDxcUtils, reinterpret_cast(&utils)); + // + // if (compiler == nullptr) + // { + // Juliet::Log(LogLevel::Error, LogCategory::Graphics, "Cannot create DXCompiler instance"); + // } + // + // if (utils == nullptr) + // { + // Log(LogLevel::Error, LogCategory::Graphics, "Cannot create IDxcUtils instance"); + // compiler->lpVtbl->Release(compiler); + // } + // + // IDxcIncludeHandler* includeHandler; + // utils->lpVtbl->CreateDefaultIncludeHandler(utils, &includeHandler); + // if (includeHandler == nullptr) + // { + // compiler->lpVtbl->Release(compiler); + // utils->lpVtbl->Release(utils); + // } +} + +int main(int argc, char* argv[]) +{ + + return 0; +}