From d40db556f08536657d399934104844c672fc4708 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Thu, 7 May 2026 19:53:01 -0400 Subject: [PATCH 1/3] Update DirectX-Headers to latest The version being used was from four years ago. Updating to upstream's main broke a lot of code because DirectX-Headers now has the equivalent of WinAdapter.h under `include/wsl` for non-Windows machines, and these collided with DXC's own definitions. I fixed this by including the relevant DirectX-Headers in WinAdapter.h, removed duplicate macros, and adapted some of the existing ones. Fixes #5079 --- CMakeLists.txt | 11 +- external/DirectX-Headers | 2 +- include/dxc/Support/Unicode.h | 14 +- include/dxc/WinAdapter.h | 228 ++++-------------- lib/DxcSupport/Unicode.cpp | 15 +- .../clang/tools/dxcvalidator/dxcvalidator.cpp | 2 +- 6 files changed, 68 insertions(+), 204 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5210718005..ea5e6da301 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -624,6 +624,13 @@ include_directories( ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR}) include_directories( ${LLVM_INCLUDE_DIR}/dxc/Tracing) # HLSL Change +# HLSL - Change Start - Make DirectX-Headers includes visible to all targets +if(EXISTS "${LLVM_MAIN_SRC_DIR}/external") + add_subdirectory(external) # SPIRV change +endif() +include_directories(AFTER ${DIRECTX_HEADER_INCLUDE_DIR}/directx ${DIRECTX_HEADER_INCLUDE_DIR}/wsl/stubs) +# HLSL Change Ends + # when crosscompiling import the executable targets from a file if(LLVM_USE_HOST_TOOLS) include(CrossCompile) @@ -679,10 +686,6 @@ list(APPEND LLVM_COMMON_DEPENDS HCTGen) add_subdirectory(utils/hct) -if(EXISTS "${LLVM_MAIN_SRC_DIR}/external") - add_subdirectory(external) # SPIRV change -endif() -include_directories(AFTER ${DIRECTX_HEADER_INCLUDE_DIR}/directx ${DIRECTX_HEADER_INCLUDE_DIR}/wsl/stubs) # HLSL - Change End diff --git a/external/DirectX-Headers b/external/DirectX-Headers index 980971e835..b773535f06 160000 --- a/external/DirectX-Headers +++ b/external/DirectX-Headers @@ -1 +1 @@ -Subproject commit 980971e835876dc0cde415e8f9bc646e64667bf7 +Subproject commit b773535f06f61bc95c39d29851a8d9845946779f diff --git a/include/dxc/Support/Unicode.h b/include/dxc/Support/Unicode.h index 64e3abccd8..174bab57af 100644 --- a/include/dxc/Support/Unicode.h +++ b/include/dxc/Support/Unicode.h @@ -19,18 +19,16 @@ // MultiByteToWideChar which is a Windows-specific method. // This is a very simplistic implementation for non-Windows platforms. This // implementation completely ignores CodePage and dwFlags. -int MultiByteToWideChar(uint32_t CodePage, uint32_t dwFlags, - const char *lpMultiByteStr, int cbMultiByte, - wchar_t *lpWideCharStr, int cchWideChar); +int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCCH lpMultiByteStr, + int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar); // WideCharToMultiByte is a Windows-specific method. // This is a very simplistic implementation for non-Windows platforms. This // implementation completely ignores CodePage and dwFlags. -int WideCharToMultiByte(uint32_t CodePage, uint32_t dwFlags, - const wchar_t *lpWideCharStr, int cchWideChar, - char *lpMultiByteStr, int cbMultiByte, - const char *lpDefaultChar = nullptr, - bool *lpUsedDefaultChar = nullptr); +int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, + int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, + LPCCH lpDefaultChar = nullptr, + LPBOOL lpUsedDefaultChar = nullptr); #endif // _WIN32 namespace Unicode { diff --git a/include/dxc/WinAdapter.h b/include/dxc/WinAdapter.h index 986149217f..e0e8de8a93 100644 --- a/include/dxc/WinAdapter.h +++ b/include/dxc/WinAdapter.h @@ -33,6 +33,28 @@ #include #endif // __cplusplus +// Include DirectX-Headers winadapter headers +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnewline-eof" +#pragma clang diagnostic ignored "-Wcast-qual" +#endif + +#include "basetsd.h" +#include "unknwn.h" + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// Undef certain macros from DirectX-Headers that collide with names used in the +// codebase +#undef OUT +#undef IN +#undef interface +#undef HeapAlloc +#undef HeapFree + #define COM_NO_WINDOWS_H // needed to inform d3d headers that this isn't windows //===----------------------------------------------------------------------===// @@ -40,7 +62,6 @@ // Begin: Macro Definitions // //===----------------------------------------------------------------------===// -#define C_ASSERT(expr) static_assert((expr), "") #define ATLASSERT assert #define CoTaskMemAlloc malloc @@ -66,14 +87,8 @@ #define uuid(id) #endif // __EMULATE_UUID -#define STDMETHODCALLTYPE #define STDMETHODIMP_(type) type STDMETHODCALLTYPE #define STDMETHODIMP STDMETHODIMP_(HRESULT) -#define STDMETHOD_(type, name) virtual STDMETHODIMP_(type) name -#define STDMETHOD(name) STDMETHOD_(HRESULT, name) -#define EXTERN_C extern "C" - -#define UNREFERENCED_PARAMETER(P) (void)(P) #define RtlEqualMemory(Destination, Source, Length) \ (!memcmp((Destination), (Source), (Length))) @@ -89,9 +104,6 @@ #define FillMemory RtlFillMemory #define ZeroMemory RtlZeroMemory -#define FALSE 0 -#define TRUE 1 - // We ignore the code page completely on Linux. #define GetConsoleOutputCP() 0 @@ -220,21 +232,9 @@ #define S_OK ((HRESULT)0L) #define S_FALSE ((HRESULT)1L) -#define E_ABORT (HRESULT)0x80004004 -#define E_ACCESSDENIED (HRESULT)0x80070005 #define E_BOUNDS (HRESULT)0x8000000B -#define E_FAIL (HRESULT)0x80004005 -#define E_HANDLE (HRESULT)0x80070006 -#define E_INVALIDARG (HRESULT)0x80070057 -#define E_NOINTERFACE (HRESULT)0x80004002 -#define E_NOTIMPL (HRESULT)0x80004001 #define E_NOT_VALID_STATE (HRESULT)0x8007139F -#define E_OUTOFMEMORY (HRESULT)0x8007000E -#define E_POINTER (HRESULT)0x80004003 -#define E_UNEXPECTED (HRESULT)0x8000FFFF -#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) -#define FAILED(hr) (((HRESULT)(hr)) < 0) #define DXC_FAILED(hr) (((HRESULT)(hr)) < 0) #define HRESULT_FROM_WIN32(x) \ @@ -270,10 +270,6 @@ #define _COM_Outptr_result_maybenull_ #define _COM_Outptr_opt_result_maybenull_ -#define THIS_ -#define THIS -#define PURE = 0 - #define _Maybenull_ #define __debugbreak() @@ -297,57 +293,17 @@ #ifdef __cplusplus -typedef unsigned char BYTE, UINT8; typedef unsigned char *LPBYTE; - -typedef BYTE BOOLEAN; -typedef BOOLEAN *PBOOLEAN; - -typedef bool BOOL; typedef BOOL *LPBOOL; - -typedef int INT; -typedef long LONG; -typedef unsigned int UINT; -typedef unsigned long ULONG; -typedef long long LONGLONG; -typedef long long LONG_PTR; -typedef unsigned long long ULONG_PTR; -typedef unsigned long long ULONGLONG; - -typedef uint16_t WORD; -typedef uint32_t DWORD; +typedef const char *LPCCH; +typedef const wchar_t *LPCWCH; typedef DWORD *LPDWORD; -typedef uint32_t UINT32; -typedef uint64_t UINT64; - -typedef signed char INT8, *PINT8; -typedef signed int INT32, *PINT32; - -typedef size_t SIZE_T; -typedef const char *LPCSTR; -typedef const char *PCSTR; - typedef int errno_t; -typedef wchar_t WCHAR; -typedef wchar_t *LPWSTR; -typedef wchar_t *PWCHAR; -typedef const wchar_t *LPCWSTR; -typedef const wchar_t *PCWSTR; - typedef WCHAR OLECHAR; typedef OLECHAR *BSTR; typedef OLECHAR *LPOLESTR; -typedef char *LPSTR; - -typedef void *LPVOID; -typedef const void *LPCVOID; - -typedef std::nullptr_t nullptr_t; - -typedef signed int HRESULT; //===--------------------- Handle Types -----------------------------------===// @@ -367,54 +323,12 @@ typedef void *HMODULE; #define STD_OUTPUT_HANDLE ((DWORD)-11) #define STD_ERROR_HANDLE ((DWORD)-12) -//===--------------------- ID Types and Macros for COM --------------------===// - -#ifdef __EMULATE_UUID -struct GUID -#else // __EMULATE_UUID -// These specific definitions are required by clang -fms-extensions. -typedef struct _GUID -#endif // __EMULATE_UUID -{ - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -} -#ifdef __EMULATE_UUID -; -#else // __EMULATE_UUID -GUID; -#endif // __EMULATE_UUID -typedef GUID CLSID; -typedef const GUID &REFGUID; -typedef const GUID &REFCLSID; - -typedef GUID IID; -typedef IID *LPIID; -typedef const IID &REFIID; -inline bool IsEqualGUID(REFGUID rguid1, REFGUID rguid2) { - // Optimization: - if (&rguid1 == &rguid2) - return true; - - return !memcmp(&rguid1, &rguid2, sizeof(GUID)); -} - -inline bool operator==(REFGUID guidOne, REFGUID guidOther) { - return !!IsEqualGUID(guidOne, guidOther); -} - -inline bool operator!=(REFGUID guidOne, REFGUID guidOther) { - return !(guidOne == guidOther); -} +//===--------------------- Functions for COM --------------------===// -inline bool IsEqualIID(REFIID riid1, REFIID riid2) { - return IsEqualGUID(riid1, riid2); -} +inline bool IsEqualIID(REFIID riid1, REFIID riid2) { return riid1 == riid2; } inline bool IsEqualCLSID(REFCLSID rclsid1, REFCLSID rclsid2) { - return IsEqualGUID(rclsid1, rclsid2); + return rclsid1 == rclsid2; } //===--------------------- Struct Types -----------------------------------===// @@ -451,27 +365,7 @@ typedef struct _WIN32_FIND_DATAW { WCHAR cAlternateFileName[14]; } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; -typedef union _LARGE_INTEGER { - struct { - DWORD LowPart; - DWORD HighPart; - } u; - LONGLONG QuadPart; -} LARGE_INTEGER; - -typedef LARGE_INTEGER *PLARGE_INTEGER; - -typedef union _ULARGE_INTEGER { - struct { - DWORD LowPart; - DWORD HighPart; - } u; - ULONGLONG QuadPart; -} ULARGE_INTEGER; - -typedef ULARGE_INTEGER *PULARGE_INTEGER; - -typedef struct tagSTATSTG { +struct STATSTG { LPOLESTR pwcsName; DWORD type; ULARGE_INTEGER cbSize; @@ -483,7 +377,7 @@ typedef struct tagSTATSTG { CLSID clsid; DWORD grfStateBits; DWORD reserved; -} STATSTG; +}; enum tagSTATFLAG { STATFLAG_DEFAULT = 0, @@ -514,36 +408,23 @@ constexpr uint8_t byte_from_hexstr(const char str[2]) { return nybble_from_hex(str[0]) << 4 | nybble_from_hex(str[1]); } -constexpr GUID guid_from_string(const char str[37]) { - return GUID{static_cast(byte_from_hexstr(str)) << 24 | - static_cast(byte_from_hexstr(str + 2)) << 16 | - static_cast(byte_from_hexstr(str + 4)) << 8 | - byte_from_hexstr(str + 6), - static_cast( - static_cast(byte_from_hexstr(str + 9)) << 8 | - byte_from_hexstr(str + 11)), - static_cast( - static_cast(byte_from_hexstr(str + 14)) << 8 | - byte_from_hexstr(str + 16)), - {byte_from_hexstr(str + 19), byte_from_hexstr(str + 21), - byte_from_hexstr(str + 24), byte_from_hexstr(str + 26), - byte_from_hexstr(str + 28), byte_from_hexstr(str + 30), - byte_from_hexstr(str + 32), byte_from_hexstr(str + 34)}}; -} - -template inline GUID __emulated_uuidof(); - -#define CROSS_PLATFORM_UUIDOF(interface, spec) \ +#define CROSS_PLATFORM_UUIDOF(interface, str) \ struct interface; \ - template <> inline GUID __emulated_uuidof() { \ - static const IID _IID = guid_from_string(spec); \ - return _IID; \ - } - -#define __uuidof(T) __emulated_uuidof::type>() - -#define IID_PPV_ARGS(ppType) \ - __uuidof(decltype(**(ppType))), reinterpret_cast(ppType) + __CRT_UUID_DECL( \ + interface, \ + static_cast(byte_from_hexstr(&(str)[2])) << 16 | \ + static_cast(byte_from_hexstr(&(str)[4])) << 8 | \ + byte_from_hexstr(&(str)[6]), \ + static_cast(static_cast(byte_from_hexstr(&(str)[9])) \ + << 8 | \ + byte_from_hexstr(&(str)[11])), \ + static_cast( \ + static_cast(byte_from_hexstr(&(str)[14])) << 8 | \ + byte_from_hexstr(&(str)[16])), \ + byte_from_hexstr(&(str)[19]), byte_from_hexstr(&(str)[21]), \ + byte_from_hexstr(&(str)[24]), byte_from_hexstr(&(str)[26]), \ + byte_from_hexstr(&(str)[28]), byte_from_hexstr(&(str)[30]), \ + byte_from_hexstr(&(str)[32]), byte_from_hexstr(&(str)[34])); #else // __EMULATE_UUID @@ -560,26 +441,9 @@ template inline void **IID_PPV_ARGS_Helper(T **pp) { #endif // __EMULATE_UUID -// Needed for d3d headers, but fail to create actual interfaces -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} -#define DECLSPEC_UUID(x) -#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) -#define DECLARE_INTERFACE(iface) struct iface -#define DECLARE_INTERFACE_(iface, parent) DECLARE_INTERFACE(iface) : parent - //===--------------------- COM Interfaces ---------------------------------===// -CROSS_PLATFORM_UUIDOF(IUnknown, "00000000-0000-0000-C000-000000000046") -struct IUnknown { - IUnknown(){}; - virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) = 0; - virtual ULONG AddRef() = 0; - virtual ULONG Release() = 0; - template HRESULT QueryInterface(Q **pp) { - return QueryInterface(__uuidof(Q), (void **)pp); - } -}; +// Note: IUknown UUID is defined in DirectX-Headers CROSS_PLATFORM_UUIDOF(INoMarshal, "ECC8691B-C1DB-4DC0-855E-65F6C551AF49") struct INoMarshal : public IUnknown {}; diff --git a/lib/DxcSupport/Unicode.cpp b/lib/DxcSupport/Unicode.cpp index ad397e7a25..e994fa06d7 100644 --- a/lib/DxcSupport/Unicode.cpp +++ b/lib/DxcSupport/Unicode.cpp @@ -25,9 +25,9 @@ // MultiByteToWideChar which is a Windows-specific method. // This is a very simplistic implementation for non-Windows platforms. This // implementation completely ignores CodePage and dwFlags. -int MultiByteToWideChar(uint32_t /*CodePage*/, uint32_t /*dwFlags*/, - const char *lpMultiByteStr, int cbMultiByte, - wchar_t *lpWideCharStr, int cchWideChar) { +int MultiByteToWideChar(UINT /*CodePage*/, DWORD /*dwFlags*/, + LPCCH lpMultiByteStr, int cbMultiByte, + LPWSTR lpWideCharStr, int cchWideChar) { // Check for invalid sizes or potential overflow. if (cbMultiByte == 0 || cbMultiByte < -1 || cbMultiByte == INT32_MAX || @@ -92,11 +92,10 @@ int MultiByteToWideChar(uint32_t /*CodePage*/, uint32_t /*dwFlags*/, // WideCharToMultiByte is a Windows-specific method. // This is a very simplistic implementation for non-Windows platforms. This // implementation completely ignores CodePage and dwFlags. -int WideCharToMultiByte(uint32_t /*CodePage*/, uint32_t /*dwFlags*/, - const wchar_t *lpWideCharStr, int cchWideChar, - char *lpMultiByteStr, int cbMultiByte, - const char * /*lpDefaultChar*/, - bool *lpUsedDefaultChar) { +int WideCharToMultiByte(UINT /*CodePage*/, DWORD /*dwFlags*/, + LPCWCH lpWideCharStr, int cchWideChar, + LPSTR lpMultiByteStr, int cbMultiByte, + LPCCH /*lpDefaultChar*/, LPBOOL lpUsedDefaultChar) { if (lpUsedDefaultChar) { *lpUsedDefaultChar = FALSE; } diff --git a/tools/clang/tools/dxcvalidator/dxcvalidator.cpp b/tools/clang/tools/dxcvalidator/dxcvalidator.cpp index 60ad35036f..e07bc59db6 100644 --- a/tools/clang/tools/dxcvalidator/dxcvalidator.cpp +++ b/tools/clang/tools/dxcvalidator/dxcvalidator.cpp @@ -77,7 +77,7 @@ static void HashAndUpdateOrCopy(uint32_t Flags, IDxcBlob *Shader, } else { CComPtr HashedBlobStream; IFT(CreateMemoryStream(DxcGetThreadMallocNoRef(), &HashedBlobStream)); - unsigned long CB; + ULONG CB; IFT(HashedBlobStream->Write(Shader->GetBufferPointer(), Shader->GetBufferSize(), &CB)); HashAndUpdate((DxilContainerHeader *)HashedBlobStream->GetPtr(), From feef8fe0aeecd51a248900ca17bfa603c0ae8189 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Fri, 8 May 2026 11:31:45 -0400 Subject: [PATCH 2/3] Simplify inclusion of DirectX-Headers winadapter.h Add root of DirectX-Headers/include to CMake include_directories, and only include 'wsl/winadapter.h' at the top of DXC's WinAdapter.h. This should make it easier for users of an installed DXC to add DirectX-Headers as a dep. --- CMakeLists.txt | 2 +- include/dxc/WinAdapter.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea5e6da301..465fd3a0bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -628,7 +628,7 @@ include_directories( ${LLVM_INCLUDE_DIR}/dxc/Tracing) # HLSL Change if(EXISTS "${LLVM_MAIN_SRC_DIR}/external") add_subdirectory(external) # SPIRV change endif() -include_directories(AFTER ${DIRECTX_HEADER_INCLUDE_DIR}/directx ${DIRECTX_HEADER_INCLUDE_DIR}/wsl/stubs) +include_directories(AFTER ${DIRECTX_HEADER_INCLUDE_DIR} ${DIRECTX_HEADER_INCLUDE_DIR}/directx ${DIRECTX_HEADER_INCLUDE_DIR}/wsl/stubs) # HLSL Change Ends # when crosscompiling import the executable targets from a file diff --git a/include/dxc/WinAdapter.h b/include/dxc/WinAdapter.h index e0e8de8a93..a21d4cc079 100644 --- a/include/dxc/WinAdapter.h +++ b/include/dxc/WinAdapter.h @@ -33,15 +33,15 @@ #include #endif // __cplusplus -// Include DirectX-Headers winadapter headers +// Include DirectX-Headers winadapter header. This is a required dependency on +// non-Windows. #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnewline-eof" #pragma clang diagnostic ignored "-Wcast-qual" #endif -#include "basetsd.h" -#include "unknwn.h" +#include "wsl/winadapter.h" #ifdef __clang__ #pragma clang diagnostic pop From 066598d4e34d39b5991188ec6bcb625e27f378f8 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Fri, 8 May 2026 16:14:58 -0400 Subject: [PATCH 3/3] Remove comment --- include/dxc/WinAdapter.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/dxc/WinAdapter.h b/include/dxc/WinAdapter.h index a21d4cc079..e230ddd510 100644 --- a/include/dxc/WinAdapter.h +++ b/include/dxc/WinAdapter.h @@ -443,8 +443,6 @@ template inline void **IID_PPV_ARGS_Helper(T **pp) { //===--------------------- COM Interfaces ---------------------------------===// -// Note: IUknown UUID is defined in DirectX-Headers - CROSS_PLATFORM_UUIDOF(INoMarshal, "ECC8691B-C1DB-4DC0-855E-65F6C551AF49") struct INoMarshal : public IUnknown {};