diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 01661b827..484cdfdaa 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -88,6 +88,13 @@ jobs: cd build cmake .. -DCMAKE_BUILD_TYPE=Release make + echo "---Generating Shader Dump---" + cd WickedEngine + ./offlineshadercompiler spirv rebuild shaderdump + mv wiShaderDump.h ../../WickedEngine/ + cd .. + echo "---Rebuilding with ShaderDump---" + make -B - name: Move binaries run: | @@ -99,7 +106,6 @@ jobs: with: name: Editor (Ubuntu 20.04) path: | - Editor/shaders/spirv/*.cso Content/ README.md LICENSE.md @@ -117,7 +123,6 @@ jobs: with: name: Tests (Ubuntu 20.04) path: | - Tests/shaders/spirv/*.cso Content/ README.md LICENSE.md diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 351dca698..06511dce3 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -87,6 +87,13 @@ jobs: cd build cmake .. -DCMAKE_BUILD_TYPE=Release make + echo "---Generating Shader Dump---" + cd WickedEngine + ./offlineshadercompiler spirv rebuild shaderdump + mv wiShaderDump.h ../../WickedEngine/ + cd .. + echo "---Rebuilding with ShaderDump---" + make -B - name: Move binaries run: | @@ -98,7 +105,6 @@ jobs: with: name: Editor (Ubuntu 20.04) path: | - Editor/shaders/spirv/*.cso Content/ README.md LICENSE.md @@ -116,7 +122,6 @@ jobs: with: name: Tests (Ubuntu 20.04) path: | - Tests/shaders/spirv/*.cso Content/ README.md LICENSE.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9cb4b69ed..de4e01111 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -88,6 +88,14 @@ jobs: cd build cmake .. -DCMAKE_BUILD_TYPE=Release make + echo "---Generating Shader Dump---" + cd WickedEngine + ./offlineshadercompiler spirv rebuild shaderdump + mv wiShaderDump.h ../../WickedEngine/ + cd .. + echo "---Rebuilding with ShaderDump---" + make -B + - name: Move binaries run: | @@ -99,7 +107,6 @@ jobs: with: name: Editor (Ubuntu 20.04) path: | - Editor/shaders/spirv/*.cso Content/ README.md LICENSE.md @@ -117,7 +124,6 @@ jobs: with: name: Tests (Ubuntu 20.04) path: | - Tests/shaders/spirv/*.cso Content/ README.md LICENSE.md diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index 2bcb72f14..9a5ccd3d0 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -1,6 +1,3 @@ -if (NOT WIN32) - find_package(Threads REQUIRED) -endif () set (SOURCE_FILES main_${PLATFORM}.cpp @@ -49,27 +46,23 @@ if (WIN32) ) set_property(TARGET WickedEngineEditor PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + set(LIB_DXCOMPILER "dxcompiler.dll") else () add_executable(WickedEngineEditor ${SOURCE_FILES}) target_link_libraries(WickedEngineEditor PUBLIC - WickedEngine - Threads::Threads + WickedEngine meshoptimizer ) - - # Copy shaders to build and source folders just to be safe: - add_custom_command( - TARGET WickedEngineEditor POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/WickedEngine/shaders/spirv ${CMAKE_CURRENT_SOURCE_DIR}/shaders/spirv - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/WickedEngine/shaders/spirv ${CMAKE_CURRENT_BINARY_DIR}/shaders/spirv - ) + set(LIB_DXCOMPILER "libdxcompiler.so") endif () # Copy content to build folder: add_custom_command( TARGET WickedEngineEditor POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_BINARY_DIR}/images + # Copy shader compiler library in the source folder + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/WickedEngine/${LIB_DXCOMPILER} ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_BINARY_DIR}/images ) diff --git a/Example_ImGui/CMakeLists.txt b/Example_ImGui/CMakeLists.txt index 20b83ca20..a58c05652 100644 --- a/Example_ImGui/CMakeLists.txt +++ b/Example_ImGui/CMakeLists.txt @@ -47,8 +47,8 @@ else() # Copy shaders to build and source folders just to be safe: add_custom_command( TARGET Example_ImGui POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/WickedEngine/shaders/spirv ${CMAKE_CURRENT_SOURCE_DIR}/shaders/spirv - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/WickedEngine/shaders/spirv ${CMAKE_CURRENT_BINARY_DIR}/shaders/spirv + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/ImGuiPS.hlsl ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/ImGuiVS.hlsl ${CMAKE_CURRENT_BINARY_DIR} ) endif () @@ -62,5 +62,5 @@ endif () add_custom_command( TARGET Example_ImGui POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/WickedEngine/${LIB_DXCOMPILER} ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/Content ${CMAKE_CURRENT_BINARY_DIR}/../Content + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/Content ${CMAKE_CURRENT_BINARY_DIR}/../Content ) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index b838befd7..8f4b158b0 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1,6 +1,4 @@ -if (NOT WIN32) - find_package(Threads REQUIRED) -endif () + set (SOURCE_FILES stdafx.cpp @@ -21,6 +19,8 @@ if (WIN32) target_link_libraries(Tests PUBLIC WickedEngine_Windows ) + + set(LIB_DXCOMPILER "dxcompiler.dll") else() list (APPEND SOURCE_FILES main_SDL2.cpp @@ -30,16 +30,9 @@ else() target_link_libraries(Tests PUBLIC WickedEngine - Threads::Threads ) - - # Copy shaders to build and source folders just to be safe: - add_custom_command( - TARGET Tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/WickedEngine/shaders/spirv ${CMAKE_CURRENT_SOURCE_DIR}/shaders/spirv - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/WickedEngine/shaders/spirv ${CMAKE_CURRENT_BINARY_DIR}/shaders/spirv - ) - + + set(LIB_DXCOMPILER "libdxcompiler.so") endif () if (MSVC) @@ -50,7 +43,10 @@ endif () # Copy content to build folder: add_custom_command( TARGET Tests POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_BINARY_DIR}/images + # Copy the shader library next to the executable + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/WickedEngine/${LIB_DXCOMPILER} ${CMAKE_CURRENT_BINARY_DIR} + # Copy the resources + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/images ${CMAKE_CURRENT_BINARY_DIR}/images COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/sound ${CMAKE_CURRENT_BINARY_DIR}/sound COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/Content ${CMAKE_CURRENT_BINARY_DIR}/../Content ) diff --git a/WickedEngine/CMakeLists.txt b/WickedEngine/CMakeLists.txt index 100c6ed34..9980320e4 100644 --- a/WickedEngine/CMakeLists.txt +++ b/WickedEngine/CMakeLists.txt @@ -7,6 +7,7 @@ else () find_package(Vulkan REQUIRED) find_package(SDL2 REQUIRED) find_package(OpenImageDenoise QUIET) + find_package(Threads REQUIRED) if(NOT ${OpenImageDenoise_FOUND}) message("OpenImageDenoise not found, it will be disabled.") else() @@ -31,7 +32,6 @@ endif() add_subdirectory(BULLET) add_subdirectory(LUA) add_subdirectory(Utility) -add_subdirectory(shaders) add_library(${TARGET_NAME} STATIC LoadingScreen.cpp @@ -118,9 +118,11 @@ if (WIN32) target_compile_definitions(${TARGET_NAME} PUBLIC UNICODE _UNICODE ) - + + set(LIBDXCOMPILER "dxcompiler.dll") else () target_link_libraries(${TARGET_NAME} PUBLIC + Threads::Threads Vulkan::Vulkan SDL2::SDL2 $<$:OpenImageDenoise> # links OpenImageDenoise only if it's found @@ -129,12 +131,26 @@ else () target_link_libraries(${TARGET_NAME} PRIVATE dl) - add_dependencies(${TARGET_NAME} - Shaders_SPIRV - ) + set(LIBDXCOMPILER "libdxcompiler.so") endif() if (PLATFORM MATCHES "SDL2") target_compile_definitions(${TARGET_NAME} PUBLIC SDL2=1) endif() + +# Copy the shader library next to the executable +add_custom_command( + TARGET ${TARGET_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/WickedEngine/${LIBDXCOMPILER} ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/WickedEngine/shaders ${CMAKE_CURRENT_BINARY_DIR}/shaders/ +) + + +# OFFLINE SHADER COMPILER +add_executable(offlineshadercompiler + offlineshadercompiler.cpp +) + +target_link_libraries(offlineshadercompiler + PUBLIC ${TARGET_NAME}) diff --git a/WickedEngine/Utility/dxc/Support/WinAdapter.h b/WickedEngine/Utility/dxc/Support/WinAdapter.h new file mode 100644 index 000000000..25f82b92f --- /dev/null +++ b/WickedEngine/Utility/dxc/Support/WinAdapter.h @@ -0,0 +1,1029 @@ +//===- WinAdapter.h - Windows Adapter for non-Windows platforms -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines Windows-specific types, macros, and SAL annotations used +// in the codebase for non-Windows platforms. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_WIN_ADAPTER_H +#define LLVM_SUPPORT_WIN_ADAPTER_H + +#ifndef _WIN32 + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // __cplusplus + +//===----------------------------------------------------------------------===// +// +// Begin: Macro Definitions +// +//===----------------------------------------------------------------------===// +#define C_ASSERT(expr) static_assert((expr), "") +#define ATLASSERT assert + +#define CoTaskMemAlloc malloc +#define CoTaskMemFree free + +#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0])) + +#define _countof(a) (sizeof(a) / sizeof(*(a))) + +// If it is GCC, there is no UUID support and we must emulate it. +#ifndef __clang__ +#define __EMULATE_UUID 1 +#endif // __clang__ + +#ifdef __EMULATE_UUID +#define __declspec(x) +#endif // __EMULATE_UUID + +#define DECLSPEC_SELECTANY + +#ifdef __EMULATE_UUID +#define uuid(id) +#endif // __EMULATE_UUID + +#define STDMETHODCALLTYPE +#define STDAPI extern "C" HRESULT STDAPICALLTYPE +#define STDAPI_(type) extern "C" type STDAPICALLTYPE +#define STDMETHODIMP HRESULT STDMETHODCALLTYPE +#define STDMETHODIMP_(type) type STDMETHODCALLTYPE + +#define UNREFERENCED_PARAMETER(P) (void)(P) + +#define RtlEqualMemory(Destination, Source, Length) \ + (!memcmp((Destination), (Source), (Length))) +#define RtlMoveMemory(Destination, Source, Length) \ + memmove((Destination), (Source), (Length)) +#define RtlCopyMemory(Destination, Source, Length) \ + memcpy((Destination), (Source), (Length)) +#define RtlFillMemory(Destination, Length, Fill) \ + memset((Destination), (Fill), (Length)) +#define RtlZeroMemory(Destination, Length) memset((Destination), 0, (Length)) +#define MoveMemory RtlMoveMemory +#define CopyMemory RtlCopyMemory +#define FillMemory RtlFillMemory +#define ZeroMemory RtlZeroMemory + +#define FALSE 0 +#define TRUE 1 + +#define REGDB_E_CLASSNOTREG 1 + +// We ignore the code page completely on Linux. +#define GetConsoleOutputCP() 0 + +#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) +#define DISP_E_BADINDEX _HRESULT_TYPEDEF_(0x8002000BL) + +// This is an unsafe conversion. If needed, we can later implement a safe +// conversion that throws exceptions for overflow cases. +#define UIntToInt(uint_arg, int_ptr_arg) *int_ptr_arg = uint_arg + +#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) + +// Use errno to implement {Get|Set}LastError +#define GetLastError() errno +#define SetLastError(ERR) errno = ERR + +// Map these errors to equivalent errnos. +#define ERROR_SUCCESS 0L +#define ERROR_ARITHMETIC_OVERFLOW EOVERFLOW +#define ERROR_FILE_NOT_FOUND ENOENT +#define ERROR_FUNCTION_NOT_CALLED ENOSYS +#define ERROR_IO_DEVICE EIO +#define ERROR_INSUFFICIENT_BUFFER ENOBUFS +#define ERROR_INVALID_HANDLE EBADF +#define ERROR_INVALID_PARAMETER EINVAL +#define ERROR_OUT_OF_STRUCTURES ENOMEM +#define ERROR_NOT_CAPABLE EPERM +#define ERROR_NOT_FOUND ENOTSUP +#define ERROR_UNHANDLED_EXCEPTION EINTR + +// Used by HRESULT <--> WIN32 error code conversion +#define SEVERITY_ERROR 1 +#define FACILITY_WIN32 7 +#define HRESULT_CODE(hr) ((hr)&0xFFFF) +#define MAKE_HRESULT(severity, facility, code) \ + ((HRESULT)(((unsigned long)(severity) << 31) | \ + ((unsigned long)(facility) << 16) | ((unsigned long)(code)))) + +#define FILE_TYPE_UNKNOWN 0x0000 +#define FILE_TYPE_DISK 0x0001 +#define FILE_TYPE_CHAR 0x0002 +#define FILE_TYPE_PIPE 0x0003 +#define FILE_TYPE_REMOTE 0x8000 + +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +// STGTY ENUMS +#define STGTY_STORAGE 1 +#define STGTY_STREAM 2 +#define STGTY_LOCKBYTES 3 +#define STGTY_PROPERTY 4 + +// Storage errors +#define STG_E_INVALIDFUNCTION 1L +#define STG_E_ACCESSDENIED 2L + +#define STREAM_SEEK_SET 0 +#define STREAM_SEEK_CUR 1 +#define STREAM_SEEK_END 2 + +#define HEAP_NO_SERIALIZE 0x1 +#define HEAP_ZERO_MEMORY 0x8 + +#define MB_ERR_INVALID_CHARS 0x00000008 // error for invalid chars + +// File IO + +#define CREATE_ALWAYS 2 +#define CREATE_NEW 1 +#define OPEN_ALWAYS 4 +#define OPEN_EXISTING 3 +#define TRUNCATE_EXISTING 5 + +#define FILE_SHARE_DELETE 0x00000004 +#define FILE_SHARE_READ 0x00000001 +#define FILE_SHARE_WRITE 0x00000002 + +#define GENERIC_READ 0x80000000 +#define GENERIC_WRITE 0x40000000 + +#define _atoi64 atoll +#define sprintf_s snprintf +#define _strdup strdup +#define _strnicmp strnicmp + +#define vsprintf_s vsprintf +#define strcat_s strcat +#define strcpy_s(dst, n, src) strncpy(dst, src, n) +#define _vscwprintf vwprintf +#define vswprintf_s vswprintf +#define swprintf_s swprintf + +#define StringCchCopyW(dst, n, src) wcsncpy(dst, src, n) + +#define OutputDebugStringW(msg) fputws(msg, stderr) + +#define OutputDebugStringA(msg) fputs(msg, stderr) +#define OutputDebugFormatA(...) fprintf(stderr, __VA_ARGS__) + +// Event Tracing for Windows (ETW) provides application programmers the ability +// to start and stop event tracing sessions, instrument an application to +// provide trace events, and consume trace events. +#define DxcEtw_DXCompilerCreateInstance_Start() +#define DxcEtw_DXCompilerCreateInstance_Stop(hr) +#define DxcEtw_DXCompilerCompile_Start() +#define DxcEtw_DXCompilerCompile_Stop(hr) +#define DxcEtw_DXCompilerDisassemble_Start() +#define DxcEtw_DXCompilerDisassemble_Stop(hr) +#define DxcEtw_DXCompilerPreprocess_Start() +#define DxcEtw_DXCompilerPreprocess_Stop(hr) +#define DxcEtw_DxcValidation_Start() +#define DxcEtw_DxcValidation_Stop(hr) + +#define UInt32Add UIntAdd +#define Int32ToUInt32 IntToUInt + +//===--------------------- HRESULT Related Macros -------------------------===// + +#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) \ + (HRESULT)(x) <= 0 ? (HRESULT)(x) \ + : (HRESULT)(((x)&0x0000FFFF) | (7 << 16) | 0x80000000) + +//===----------------------------------------------------------------------===// +// +// Begin: Disable SAL Annotations +// +//===----------------------------------------------------------------------===// +#define _In_ +#define _In_z_ +#define _In_opt_ +#define _In_opt_count_(size) +#define _In_opt_z_ +#define _In_reads_(size) +#define _In_reads_bytes_(size) +#define _In_reads_bytes_opt_(size) +#define _In_reads_opt_(size) +#define _In_reads_to_ptr_(ptr) +#define _In_count_(size) +#define _In_range_(lb, ub) +#define _In_bytecount_(size) +#define _In_opt_bytecount_(size) +#define _In_NLS_string_(size) +#define __in_bcount(size) + +#define _Out_ +#define _Out_bytecap_(nbytes) +#define _Out_writes_to_(a, b) +#define _Out_writes_to_opt_(a, b) +#define _Outptr_ +#define _Outptr_opt_ +#define _Outptr_opt_result_z_ +#define _Out_opt_ +#define _Out_writes_(size) +#define _Out_write_bytes_(size) +#define _Out_writes_z_(size) +#define _Out_writes_all_(size) +#define _Out_writes_bytes_(size) +#define _Outref_result_buffer_(size) +#define _Outptr_result_buffer_(size) +#define _Out_cap_(size) +#define _Out_cap_x_(size) +#define _Out_range_(lb, ub) +#define _Outptr_result_z_ +#define _Outptr_result_buffer_maybenull_(ptr) +#define _Outptr_result_maybenull_ +#define _Outptr_result_nullonfailure_ + +#define __out_ecount_part(a, b) + +#define _Inout_ +#define _Inout_z_ +#define _Inout_opt_ +#define _Inout_cap_(size) +#define _Inout_count_(size) +#define _Inout_count_c_(size) +#define _Inout_opt_count_c_(size) +#define _Inout_bytecount_c_(size) +#define _Inout_opt_bytecount_c_(size) + +#define _Ret_maybenull_ +#define _Ret_notnull_ +#define _Ret_opt_ + +#define _Use_decl_annotations_ +#define __analysis_assume(expr) +#define _Analysis_assume_(expr) +#define _Analysis_assume_nullterminated_(x) +#define _Success_(expr) + +#define __inexpressible_readableTo(size) +#define __inexpressible_writableTo(size) + +#define _Printf_format_string_ +#define _Null_terminated_ +#define __fallthrough + +#define _Field_size_(size) +#define _Field_size_full_(size) +#define _Field_size_opt_(size) +#define _Post_writable_byte_size_(size) +#define _Post_readable_byte_size_(size) +#define __drv_allocatesMem(mem) + +#define _COM_Outptr_ +#define _COM_Outptr_opt_ +#define _COM_Outptr_result_maybenull_ +#define _COM_Outptr_opt_result_maybenull_ + +#define _Null_ +#define _Notnull_ +#define _Maybenull_ + +#define _Outptr_result_bytebuffer_(size) + +#define __debugbreak() + +// GCC produces erros on calling convention attributes. +#ifdef __GNUC__ +#define __cdecl +#define __CRTDECL +#define __stdcall +#define __vectorcall +#define __thiscall +#define __fastcall +#define __clrcall +#endif // __GNUC__ + +//===----------------------------------------------------------------------===// +// +// Begin: Type Definitions +// +//===----------------------------------------------------------------------===// + +#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 ULONGLONG; + +typedef uint16_t WORD; +typedef uint32_t DWORD; +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 -----------------------------------===// + +typedef void *HANDLE; + +#define DECLARE_HANDLE(name) \ + struct name##__ { \ + int unused; \ + }; \ + typedef struct name##__ *name +DECLARE_HANDLE(HINSTANCE); + +typedef void *HMODULE; + +#define STD_INPUT_HANDLE ((DWORD)-10) +#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); +} + +inline bool IsEqualIID(REFIID riid1, REFIID riid2) { + return IsEqualGUID(riid1, riid2); +} + +inline bool IsEqualCLSID(REFCLSID rclsid1, REFCLSID rclsid2) { + return IsEqualGUID(rclsid1, rclsid2); +} + +//===--------------------- Struct Types -----------------------------------===// + +typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME, *PFILETIME, *LPFILETIME; + +typedef struct _BY_HANDLE_FILE_INFORMATION { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD dwVolumeSerialNumber; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD nNumberOfLinks; + DWORD nFileIndexHigh; + DWORD nFileIndexLow; +} BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, + *LPBY_HANDLE_FILE_INFORMATION; + +typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[260]; + 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 { + LPOLESTR pwcsName; + DWORD type; + ULARGE_INTEGER cbSize; + FILETIME mtime; + FILETIME ctime; + FILETIME atime; + DWORD grfMode; + DWORD grfLocksSupported; + CLSID clsid; + DWORD grfStateBits; + DWORD reserved; +} STATSTG; + +enum tagSTATFLAG { + STATFLAG_DEFAULT = 0, + STATFLAG_NONAME = 1, + STATFLAG_NOOPEN = 2 +}; + +//===--------------------- UUID Related Macros ----------------------------===// + +#ifdef __EMULATE_UUID + +// The following macros are defined to facilitate the lack of 'uuid' on Linux. + +constexpr uint8_t nybble_from_hex(char c) { + return ((c >= '0' && c <= '9') + ? (c - '0') + : ((c >= 'a' && c <= 'f') + ? (c - 'a' + 10) + : ((c >= 'A' && c <= 'F') ? (c - 'A' + 10) + : /* Should be an error */ -1))); +} + +constexpr uint8_t byte_from_hex(char c1, char c2) { + return nybble_from_hex(c1) << 4 | nybble_from_hex(c2); +} + +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) \ + 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) + +#else // __EMULATE_UUID + +#ifndef CROSS_PLATFORM_UUIDOF +// Warning: This macro exists in dxcapi.h as well +#define CROSS_PLATFORM_UUIDOF(interface, spec) \ + struct __declspec(uuid(spec)) interface; +#endif + +template inline void **IID_PPV_ARGS_Helper(T **pp) { + return reinterpret_cast(pp); +} +#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType) + +#endif // __EMULATE_UUID + +//===--------------------- COM Interfaces ---------------------------------===// + +CROSS_PLATFORM_UUIDOF(IUnknown, "00000000-0000-0000-C000-000000000046") +struct IUnknown { + IUnknown() : m_count(0) {}; + virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) = 0; + virtual ULONG AddRef() = 0; + virtual ULONG Release() = 0; + virtual ~IUnknown() = default; + template HRESULT QueryInterface(Q **pp) { + return QueryInterface(__uuidof(Q), (void **)pp); + } + +private: + std::atomic m_count; +}; + +CROSS_PLATFORM_UUIDOF(INoMarshal, "ECC8691B-C1DB-4DC0-855E-65F6C551AF49") +struct INoMarshal : public IUnknown {}; + +CROSS_PLATFORM_UUIDOF(IMalloc, "00000002-0000-0000-C000-000000000046") +struct IMalloc : public IUnknown { + virtual void *Alloc(size_t size); + virtual void *Realloc(void *ptr, size_t size); + virtual void Free(void *ptr); + virtual HRESULT QueryInterface(REFIID riid, void **ppvObject); +}; + +CROSS_PLATFORM_UUIDOF(ISequentialStream, "0C733A30-2A1C-11CE-ADE5-00AA0044773D") +struct ISequentialStream : public IUnknown { + virtual HRESULT Read(void *pv, ULONG cb, ULONG *pcbRead) = 0; + virtual HRESULT Write(const void *pv, ULONG cb, ULONG *pcbWritten) = 0; +}; + +CROSS_PLATFORM_UUIDOF(IStream, "0000000c-0000-0000-C000-000000000046") +struct IStream : public ISequentialStream { + virtual HRESULT Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER *plibNewPosition) = 0; + virtual HRESULT SetSize(ULARGE_INTEGER libNewSize) = 0; + virtual HRESULT CopyTo(IStream *pstm, ULARGE_INTEGER cb, + ULARGE_INTEGER *pcbRead, + ULARGE_INTEGER *pcbWritten) = 0; + + virtual HRESULT Commit(DWORD grfCommitFlags) = 0; + + virtual HRESULT Revert(void) = 0; + + virtual HRESULT LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) = 0; + + virtual HRESULT UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) = 0; + + virtual HRESULT Stat(STATSTG *pstatstg, DWORD grfStatFlag) = 0; + + virtual HRESULT Clone(IStream **ppstm) = 0; +}; + +//===--------------------- COM Pointer Types ------------------------------===// + +class CAllocator { +public: + static void *Reallocate(void *p, size_t nBytes) throw(); + static void *Allocate(size_t nBytes) throw(); + static void Free(void *p) throw(); +}; + +template class CComPtrBase { +protected: + CComPtrBase() throw() { p = nullptr; } + CComPtrBase(T *lp) throw() { + p = lp; + if (p != nullptr) + p->AddRef(); + } + void Swap(CComPtrBase &other) { + T *pTemp = p; + p = other.p; + other.p = pTemp; + } + +public: + ~CComPtrBase() throw() { + if (p) { + p->Release(); + p = nullptr; + } + } + operator T *() const throw() { return p; } + T &operator*() const { return *p; } + T *operator->() const { return p; } + T **operator&() throw() { + assert(p == nullptr); + return &p; + } + bool operator!() const throw() { return (p == nullptr); } + bool operator<(T *pT) const throw() { return p < pT; } + bool operator!=(T *pT) const { return !operator==(pT); } + bool operator==(T *pT) const throw() { return p == pT; } + + // Release the interface and set to nullptr + void Release() throw() { + T *pTemp = p; + if (pTemp) { + p = nullptr; + pTemp->Release(); + } + } + + // Attach to an existing interface (does not AddRef) + void Attach(T *p2) throw() { + if (p) { + ULONG ref = p->Release(); + (void)(ref); + // Attaching to the same object only works if duplicate references are + // being coalesced. Otherwise re-attaching will cause the pointer to be + // released and may cause a crash on a subsequent dereference. + assert(ref != 0 || p2 != p); + } + p = p2; + } + + // Detach the interface (does not Release) + T *Detach() throw() { + T *pt = p; + p = nullptr; + return pt; + } + + HRESULT CopyTo(T **ppT) throw() { + assert(ppT != nullptr); + if (ppT == nullptr) + return E_POINTER; + *ppT = p; + if (p) + p->AddRef(); + return S_OK; + } + + template HRESULT QueryInterface(Q **pp) const throw() { + assert(pp != nullptr); + return p->QueryInterface(__uuidof(Q), (void **)pp); + } + + T *p; +}; + +template class CComPtr : public CComPtrBase { +public: + CComPtr() throw() {} + CComPtr(T *lp) throw() : CComPtrBase(lp) {} + CComPtr(const CComPtr &lp) throw() : CComPtrBase(lp.p) {} + T *operator=(T *lp) throw() { + if (*this != lp) { + CComPtr(lp).Swap(*this); + } + return *this; + } + + inline bool IsEqualObject(IUnknown *pOther) throw() { + if (this->p == nullptr && pOther == nullptr) + return true; // They are both NULL objects + + if (this->p == nullptr || pOther == nullptr) + return false; // One is NULL the other is not + + CComPtr punk1; + CComPtr punk2; + this->p->QueryInterface(__uuidof(IUnknown), (void **)&punk1); + pOther->QueryInterface(__uuidof(IUnknown), (void **)&punk2); + return punk1 == punk2; + } + + void ComPtrAssign(IUnknown **pp, IUnknown *lp, REFIID riid) { + IUnknown *pTemp = *pp; // takes ownership + if (lp == nullptr || FAILED(lp->QueryInterface(riid, (void **)pp))) + *pp = nullptr; + if (pTemp) + pTemp->Release(); + } + + template T *operator=(const CComPtr &lp) throw() { + if (!this->IsEqualObject(lp)) { + ComPtrAssign((IUnknown **)&this->p, lp, __uuidof(T)); + } + return *this; + } + + T *operator=(const CComPtr &lp) throw() { + if (*this != lp) { + CComPtr(lp).Swap(*this); + } + return *this; + } + + CComPtr(CComPtr &&lp) throw() : CComPtrBase() { lp.Swap(*this); } + + T *operator=(CComPtr &&lp) throw() { + if (*this != lp) { + CComPtr(static_cast(lp)).Swap(*this); + } + return *this; + } +}; + +template class CSimpleArray : public std::vector { +public: + bool Add(const T &t) { + this->push_back(t); + return true; + } + int GetSize() { return this->size(); } + T *GetData() { return this->data(); } + void RemoveAll() { this->clear(); } +}; + +template class CHeapPtrBase { +protected: + CHeapPtrBase() throw() : m_pData(NULL) {} + CHeapPtrBase(CHeapPtrBase &p) throw() { + m_pData = p.Detach(); // Transfer ownership + } + explicit CHeapPtrBase(T *pData) throw() : m_pData(pData) {} + +public: + ~CHeapPtrBase() throw() { Free(); } + +protected: + CHeapPtrBase &operator=(CHeapPtrBase &p) throw() { + if (m_pData != p.m_pData) + Attach(p.Detach()); // Transfer ownership + return *this; + } + +public: + operator T *() const throw() { return m_pData; } + T *operator->() const throw() { + assert(m_pData != NULL); + return m_pData; + } + + T **operator&() throw() { + assert(m_pData == NULL); + return &m_pData; + } + + // Allocate a buffer with the given number of bytes + bool AllocateBytes(size_t nBytes) throw() { + assert(m_pData == NULL); + m_pData = static_cast(Allocator::Allocate(nBytes * sizeof(char))); + if (m_pData == NULL) + return false; + + return true; + } + + // Attach to an existing pointer (takes ownership) + void Attach(T *pData) throw() { + Allocator::Free(m_pData); + m_pData = pData; + } + + // Detach the pointer (releases ownership) + T *Detach() throw() { + T *pTemp = m_pData; + m_pData = NULL; + return pTemp; + } + + // Free the memory pointed to, and set the pointer to NULL + void Free() throw() { + Allocator::Free(m_pData); + m_pData = NULL; + } + + // Reallocate the buffer to hold a given number of bytes + bool ReallocateBytes(size_t nBytes) throw() { + T *pNew; + pNew = + static_cast(Allocator::Reallocate(m_pData, nBytes * sizeof(char))); + if (pNew == NULL) + return false; + m_pData = pNew; + + return true; + } + +public: + T *m_pData; +}; + +template +class CHeapPtr : public CHeapPtrBase { +public: + CHeapPtr() throw() {} + CHeapPtr(CHeapPtr &p) throw() : CHeapPtrBase(p) {} + explicit CHeapPtr(T *p) throw() : CHeapPtrBase(p) {} + CHeapPtr &operator=(CHeapPtr &p) throw() { + CHeapPtrBase::operator=(p); + return *this; + } + + // Allocate a buffer with the given number of elements + bool Allocate(size_t nElements = 1) throw() { + size_t nBytes = nElements * sizeof(T); + return this->AllocateBytes(nBytes); + } + + // Reallocate the buffer to hold a given number of elements + bool Reallocate(size_t nElements) throw() { + size_t nBytes = nElements * sizeof(T); + return this->ReallocateBytes(nBytes); + } +}; + +#define CComHeapPtr CHeapPtr + +//===--------------------------- BSTR Allocation --------------------------===// + +void SysFreeString(BSTR bstrString); +// Allocate string with length prefix +BSTR SysAllocStringLen(const OLECHAR *strIn, UINT ui); + +//===--------------------- UTF-8 Related Types ----------------------------===// + +// Code Page +#define CP_ACP 0 +#define CP_UTF8 65001 // UTF-8 translation. + +// Convert Windows codepage value to locale string +const char *CPToLocale(uint32_t CodePage); + +// The t_nBufferLength parameter is part of the published interface, but not +// used here. +template class CW2AEX { +public: + CW2AEX(LPCWSTR psz, UINT nCodePage = CP_UTF8) { + const char *locale = CPToLocale(nCodePage); + if (locale == nullptr) { + // Current Implementation only supports CP_UTF8, and CP_ACP + assert(false && "CW2AEX implementation for Linux only handles " + "UTF8 and ACP code pages"); + return; + } + + if (!psz) { + m_psz = NULL; + return; + } + + locale = setlocale(LC_ALL, locale); + int len = (wcslen(psz) + 1) * 4; + m_psz = new char[len]; + std::wcstombs(m_psz, psz, len); + setlocale(LC_ALL, locale); + } + + ~CW2AEX() { delete[] m_psz; } + + operator LPSTR() const { return m_psz; } + + char *m_psz; +}; +typedef CW2AEX<> CW2A; + +// The t_nBufferLength parameter is part of the published interface, but not +// used here. +template class CA2WEX { +public: + CA2WEX(LPCSTR psz, UINT nCodePage = CP_UTF8) { + const char *locale = CPToLocale(nCodePage); + if (locale == nullptr) { + // Current Implementation only supports CP_UTF8, and CP_ACP + assert(false && "CA2WEX implementation for Linux only handles " + "UTF8 and ACP code pages"); + return; + } + + if (!psz) { + m_psz = NULL; + return; + } + + locale = setlocale(LC_ALL, locale); + int len = strlen(psz) + 1; + m_psz = new wchar_t[len]; + std::mbstowcs(m_psz, psz, len); + setlocale(LC_ALL, locale); + } + + ~CA2WEX() { delete[] m_psz; } + + operator LPWSTR() const { return m_psz; } + + wchar_t *m_psz; +}; + +typedef CA2WEX<> CA2W; + +//===--------- File IO Related Types ----------------===// + +class CHandle { +public: + CHandle(HANDLE h); + ~CHandle(); + operator HANDLE() const throw(); + +private: + HANDLE m_h; +}; + +#endif // __cplusplus + +#endif // _WIN32 + +#endif // LLVM_SUPPORT_WIN_ADAPTER_H diff --git a/WickedEngine/libdxcompiler.so b/WickedEngine/libdxcompiler.so new file mode 100755 index 000000000..c55f08161 Binary files /dev/null and b/WickedEngine/libdxcompiler.so differ diff --git a/WickedEngine/shaders/CMakeLists.txt b/WickedEngine/shaders/CMakeLists.txt deleted file mode 100644 index a8f5ec69d..000000000 --- a/WickedEngine/shaders/CMakeLists.txt +++ /dev/null @@ -1,404 +0,0 @@ -# Compile shaders - -set(SHADERS_CS - "hairparticle_simulateCS.hlsl" - "hairparticle_finishUpdateCS.hlsl" - "emittedparticle_simulateCS.hlsl" - "generateMIPChainCubeCS_float4.hlsl" - "generateMIPChainCubeCS_unorm4.hlsl" - "generateMIPChainCubeArrayCS_float4.hlsl" - "generateMIPChainCubeArrayCS_unorm4.hlsl" - "generateMIPChain3DCS_float4.hlsl" - "generateMIPChain3DCS_unorm4.hlsl" - "generateMIPChain2DCS_float4.hlsl" - "generateMIPChain2DCS_unorm4.hlsl" - "blur_gaussian_float4CS.hlsl" - "bloomseparateCS.hlsl" - "depthoffield_mainCS.hlsl" - "depthoffield_neighborhoodMaxCOCCS.hlsl" - "depthoffield_prepassCS.hlsl" - "depthoffield_upsampleCS.hlsl" - "depthoffield_tileMaxCOC_verticalCS.hlsl" - "depthoffield_tileMaxCOC_horizontalCS.hlsl" - "voxelRadianceSecondaryBounceCS.hlsl" - "voxelSceneCopyClearCS.hlsl" - "voxelClearOnlyNormalCS.hlsl" - "upsample_bilateral_float1CS.hlsl" - "upsample_bilateral_float4CS.hlsl" - "upsample_bilateral_unorm1CS.hlsl" - "upsample_bilateral_unorm4CS.hlsl" - "temporalaaCS.hlsl" - "tileFrustumsCS.hlsl" - "tonemapCS.hlsl" - "fsr_upscalingCS.hlsl" - "fsr_sharpenCS.hlsl" - "ssr_resolveCS.hlsl" - "ssr_temporalCS.hlsl" - "ssaoCS.hlsl" - "ssr_medianCS.hlsl" - "ssr_raytraceCS.hlsl" - "sharpenCS.hlsl" - "skinningCS.hlsl" - "resolveMSAADepthStencilCS.hlsl" - "paint_textureCS.hlsl" - "raytraceCS.hlsl" - "raytraceCS_rtapi.hlsl" - "oceanUpdateDisplacementMapCS.hlsl" - "oceanUpdateGradientFoldingCS.hlsl" - "oceanSimulatorCS.hlsl" - "msao_interleaveCS.hlsl" - "msao_preparedepthbuffers1CS.hlsl" - "msao_preparedepthbuffers2CS.hlsl" - "msao_blurupsampleCS.hlsl" - "msao_blurupsampleCS_blendout.hlsl" - "msao_blurupsampleCS_premin.hlsl" - "msao_blurupsampleCS_premin_blendout.hlsl" - "msaoCS.hlsl" - "motionblur_neighborhoodMaxVelocityCS.hlsl" - "motionblur_tileMaxVelocity_horizontalCS.hlsl" - "motionblur_tileMaxVelocity_verticalCS.hlsl" - "luminancePass2CS.hlsl" - "motionblur_kickjobsCS.hlsl" - "motionblurCS.hlsl" - "motionblurCS_cheap.hlsl" - "motionblurCS_earlyexit.hlsl" - "luminancePass1CS.hlsl" - "lightShaftsCS.hlsl" - "lightCullingCS_ADVANCED_DEBUG.hlsl" - "lightCullingCS_DEBUG.hlsl" - "lightCullingCS.hlsl" - "lightCullingCS_ADVANCED.hlsl" - "hbaoCS.hlsl" - "gpusortlib_sortInnerCS.hlsl" - "gpusortlib_sortStepCS.hlsl" - "gpusortlib_kickoffSortCS.hlsl" - "gpusortlib_sortCS.hlsl" - "fxaaCS.hlsl" - "filterEnvMapCS.hlsl" - "fft_512x512_c2c_CS.hlsl" - "fft_512x512_c2c_v2_CS.hlsl" - "emittedparticle_sphpartitionCS.hlsl" - "emittedparticle_sphpartitionoffsetsCS.hlsl" - "emittedparticle_sphpartitionoffsetsresetCS.hlsl" - "emittedparticle_simulateCS_SORTING.hlsl" - "emittedparticle_simulateCS_SORTING_DEPTHCOLLISIONS.hlsl" - "emittedparticle_sphdensityCS.hlsl" - "emittedparticle_sphforceCS.hlsl" - "emittedparticle_kickoffUpdateCS.hlsl" - "emittedparticle_simulateCS_DEPTHCOLLISIONS.hlsl" - "emittedparticle_emitCS.hlsl" - "emittedparticle_emitCS_FROMMESH.hlsl" - "emittedparticle_emitCS_volume.hlsl" - "emittedparticle_finishUpdateCS.hlsl" - "downsample4xCS.hlsl" - "depthoffield_prepassCS_earlyexit.hlsl" - "depthoffield_mainCS_cheap.hlsl" - "depthoffield_mainCS_earlyexit.hlsl" - "depthoffield_postfilterCS.hlsl" - "depthoffield_kickjobsCS.hlsl" - "copytexture2D_float4_borderexpandCS.hlsl" - "copytexture2D_unorm4_borderexpandCS.hlsl" - "copytexture2D_unorm4CS.hlsl" - "copytexture2D_float4CS.hlsl" - "chromatic_aberrationCS.hlsl" - "bvh_hierarchyCS.hlsl" - "bvh_primitivesCS.hlsl" - "bvh_propagateaabbCS.hlsl" - "blur_gaussian_wide_unorm1CS.hlsl" - "blur_gaussian_wide_unorm4CS.hlsl" - "blur_gaussian_unorm1CS.hlsl" - "blur_gaussian_unorm4CS.hlsl" - "blur_gaussian_wide_float1CS.hlsl" - "blur_gaussian_wide_float3CS.hlsl" - "blur_gaussian_wide_float4CS.hlsl" - "blur_bilateral_wide_unorm4CS.hlsl" - "blur_gaussian_float1CS.hlsl" - "blur_gaussian_float3CS.hlsl" - "blur_bilateral_unorm4CS.hlsl" - "blur_bilateral_wide_float1CS.hlsl" - "blur_bilateral_wide_float3CS.hlsl" - "blur_bilateral_wide_float4CS.hlsl" - "blur_bilateral_wide_unorm1CS.hlsl" - "blur_bilateral_float1CS.hlsl" - "blur_bilateral_float3CS.hlsl" - "blur_bilateral_float4CS.hlsl" - "blur_bilateral_unorm1CS.hlsl" - "voxelSceneCopyClearCS_TemporalSmoothing.hlsl" - "normalsfromdepthCS.hlsl" - "volumetricCloud_shapenoiseCS.hlsl" - "volumetricCloud_detailnoiseCS.hlsl" - "volumetricCloud_curlnoiseCS.hlsl" - "volumetricCloud_weathermapCS.hlsl" - "volumetricCloud_renderCS.hlsl" - "volumetricCloud_reprojectCS.hlsl" - "volumetricCloud_temporalCS.hlsl" - "shadingRateClassificationCS.hlsl" - "shadingRateClassificationCS_DEBUG.hlsl" - "skyAtmosphere_transmittanceLutCS.hlsl" - "skyAtmosphere_skyViewLutCS.hlsl" - "skyAtmosphere_multiScatteredLuminanceLutCS.hlsl" - "skyAtmosphere_skyLuminanceLutCS.hlsl" - "upsample_bilateral_uint4CS.hlsl" - "screenspaceshadowCS.hlsl" - "rtshadowCS.hlsl" - "rtshadow_denoise_tileclassificationCS.hlsl" - "rtshadow_denoise_filterCS.hlsl" - "rtshadow_denoise_temporalCS.hlsl" - "rtaoCS.hlsl" - "rtao_denoise_tileclassificationCS.hlsl" - "rtao_denoise_filterCS.hlsl" - "visibility_resolveCS.hlsl" - "visibility_resolveCS_MSAA.hlsl" - "surfel_coverageCS.hlsl" - "surfel_indirectprepareCS.hlsl" - "surfel_updateCS.hlsl" - "surfel_gridresetCS.hlsl" - "surfel_gridoffsetsCS.hlsl" - "surfel_binningCS.hlsl" - "surfel_raytraceCS_rtapi.hlsl" - "surfel_raytraceCS.hlsl" -) - -set(SHADERS_PS - "emittedparticlePS_soft.hlsl" - "screenPS.hlsl" - "imagePS.hlsl" - "emittedparticlePS_soft_lighting.hlsl" - "oceanSurfacePS.hlsl" - "hairparticlePS.hlsl" - "impostorPS.hlsl" - "volumetricLight_SpotPS.hlsl" - "volumetricLight_PointPS.hlsl" - "volumetricLight_DirectionalPS.hlsl" - "voxelPS.hlsl" - "vertexcolorPS.hlsl" - "upsample_bilateralPS.hlsl" - "sunPS.hlsl" - "skyPS_dynamic.hlsl" - "skyPS_static.hlsl" - "shadowPS_transparent.hlsl" - "shadowPS_water.hlsl" - "shadowPS_alphatest.hlsl" - "renderlightmapPS.hlsl" - "renderlightmapPS_rtapi.hlsl" - "raytrace_debugbvhPS.hlsl" - "outlinePS.hlsl" - "oceanSurfaceSimplePS.hlsl" - "objectPS_transparent_pom.hlsl" - "objectPS_water.hlsl" - "objectPS_voxelizer.hlsl" - "objectPS_voxelizer_terrain.hlsl" - "objectPS_transparent.hlsl" - "objectPS_transparent_planarreflection.hlsl" - "objectPS_planarreflection.hlsl" - "objectPS_pom.hlsl" - "objectPS_terrain.hlsl" - "objectPS.hlsl" - "objectPS_hologram.hlsl" - "objectPS_paintradius.hlsl" - "objectPS_simple.hlsl" - "objectPS_debug.hlsl" - "objectPS_prepass.hlsl" - "objectPS_prepass_alphatest.hlsl" - "objectPS_anisotropic.hlsl" - "objectPS_transparent_anisotropic.hlsl" - "objectPS_cloth.hlsl" - "objectPS_transparent_cloth.hlsl" - "objectPS_clearcoat.hlsl" - "objectPS_transparent_clearcoat.hlsl" - "objectPS_cloth_clearcoat.hlsl" - "objectPS_transparent_cloth_clearcoat.hlsl" - "objectPS_cartoon.hlsl" - "objectPS_transparent_cartoon.hlsl" - "objectPS_unlit.hlsl" - "objectPS_transparent_unlit.hlsl" - "lightVisualizerPS.hlsl" - "lensFlarePS.hlsl" - "impostorPS_wire.hlsl" - "impostorPS_simple.hlsl" - "impostorPS_prepass.hlsl" - "hairparticlePS_simple.hlsl" - "hairparticlePS_prepass.hlsl" - "forceFieldVisualizerPS.hlsl" - "fontPS.hlsl" - "envMap_skyPS_static.hlsl" - "envMap_skyPS_dynamic.hlsl" - "envMapPS.hlsl" - "envMapPS_terrain.hlsl" - "emittedparticlePS_soft_distortion.hlsl" - "downsampleDepthBuffer4xPS.hlsl" - "emittedparticlePS_simple.hlsl" - "cubeMapPS.hlsl" - "circlePS.hlsl" - "captureImpostorPS_normal.hlsl" - "captureImpostorPS_surface.hlsl" - "captureImpostorPS_albedo.hlsl" -) - -set(SHADERS_VS - "hairparticleVS.hlsl" - "emittedparticleVS.hlsl" - "imageVS.hlsl" - "fontVS.hlsl" - "voxelVS.hlsl" - "vertexcolorVS.hlsl" - "volumetriclight_directionalVS.hlsl" - "volumetriclight_pointVS.hlsl" - "volumetriclight_spotVS.hlsl" - "vSpotLightVS.hlsl" - "vPointLightVS.hlsl" - "sphereVS.hlsl" - "skyVS.hlsl" - "shadowVS_transparent.hlsl" - "shadowVS.hlsl" - "shadowVS_alphatest.hlsl" - "screenVS.hlsl" - "renderlightmapVS.hlsl" - "raytrace_screenVS.hlsl" - "oceanSurfaceVS.hlsl" - "objectVS_simple.hlsl" - "objectVS_voxelizer.hlsl" - "objectVS_common.hlsl" - "objectVS_common_tessellation.hlsl" - "objectVS_prepass.hlsl" - "objectVS_prepass_alphatest.hlsl" - "objectVS_prepass_tessellation.hlsl" - "objectVS_prepass_alphatest_tessellation.hlsl" - "objectVS_simple_tessellation.hlsl" - "objectVS_debug.hlsl" - "lensFlareVS.hlsl" - "impostorVS.hlsl" - "forceFieldPointVisualizerVS.hlsl" - "forceFieldPlaneVisualizerVS.hlsl" - "envMap_skyVS.hlsl" - "envMapVS.hlsl" - "envMap_skyVS_emulation.hlsl" - "envMapVS_emulation.hlsl" - "cubeShadowVS.hlsl" - "cubeShadowVS_alphatest.hlsl" - "cubeShadowVS_emulation.hlsl" - "cubeShadowVS_alphatest_emulation.hlsl" - "cubeShadowVS_transparent.hlsl" - "cubeShadowVS_transparent_emulation.hlsl" - "cubeVS.hlsl" -) - -set(SHADERS_GS - "envMap_skyGS_emulation.hlsl" - "envMapGS_emulation.hlsl" - "cubeShadowGS_emulation.hlsl" - "cubeShadowGS_alphatest_emulation.hlsl" - "cubeShadowGS_transparent_emulation.hlsl" - "voxelGS.hlsl" - "objectGS_voxelizer.hlsl" -) - -set(SHADERS_HS - "objectHS.hlsl" - "objectHS_prepass.hlsl" - "objectHS_prepass_alphatest.hlsl" - "objectHS_simple.hlsl" -) - -set(SHADERS_DS - "objectDS.hlsl" - "objectDS_prepass.hlsl" - "objectDS_prepass_alphatest.hlsl" - "objectDS_simple.hlsl" -) - -set(SHADERS_LIB - "rtreflectionLIB.hlsl" -) - - -SET(SPIRV_BINARY_FILES) -SET(DXC_BINARY_FILES) - -#dxc (DirectX Shader Compiler) is installed as part of the Vulkan SDK -set(SPIRV_OUTPUT_DIR spirv) - -function(Generate_Shaders_SPIRV SHADERS_SRC_LIST SHADER_TYPE) - foreach (Shader IN LISTS ${SHADERS_SRC_LIST}) - get_filename_component(FILE_NAME ${Shader} NAME_WLE) - - set(SPIRV_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${SPIRV_OUTPUT_DIR}/${FILE_NAME}.cso") - set(SPIRV_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/${Shader}") - - # Only do this for shaders that are missing or updated (very slow re-config otherwise) - file(TIMESTAMP "${SPIRV_SOURCE}" NEWTIMESTAMP) - - if((NOT "${NEWTIMESTAMP}" STREQUAL "${${Shader}-LASTMOD}") OR (NOT EXISTS "${SPIRV_OUTPUT}")) - - set(${Shader}-LASTMOD ${NEWTIMESTAMP} CACHE INTERNAL "") - - message(STATUS "CALCULATING DEPENDENCIES FOR SHADER ${SHADER_TYPE} ${FILE_NAME}") - set(VK_VERSION "vulkan1.2") - - set(COMMAND_PARAMS ${DXC_TARGET} - "${SPIRV_SOURCE}" - -T "${SHADER_TYPE}_6_5" - -I "${CMAKE_CURRENT_SOURCE_DIR}/" - -D SPIRV - #-all-resources-bound - #-pack-optimized - -res-may-alias - -no-legacy-cbuf-layout - -spirv - -fspv-target-env=${VK_VERSION} - -fvk-use-dx-layout - -fvk-use-dx-position-w - -flegacy-macro-expansion - -Fo ${SPIRV_OUTPUT} - -fvk-t-shift 1000 0 - -fvk-u-shift 2000 0 - -fvk-s-shift 3000 0 - #-fspv-extension=KHR - ) - - # Determine include dependencies (recursively) - # - # This works by compiling the shader with the option -Vi, - # which seems to print all inclusion operations done during compilation. - # The process is quite slow, it would be nice to have a dedicated option - # in dxc to do this properly, like the -MM option in gcc/clang. - execute_process(COMMAND ${COMMAND_PARAMS} -Vi - ERROR_VARIABLE INCLUDE_DEPENDENCIES - OUTPUT_VARIABLE CMD_OUT - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - if(INCLUDE_DEPENDENCIES) - string(REPLACE "\n" ";" INCLUDE_DEPENDENCIES ${INCLUDE_DEPENDENCIES}) # transform lines in cmake list - list(FILTER INCLUDE_DEPENDENCIES INCLUDE REGEX "Opening file") # remove non dependencies lines - list(LENGTH INCLUDE_DEPENDENCIES INCLUDE_DEPENDENCIES_LENGTH) - if(${INCLUDE_DEPENDENCIES_LENGTH} GREATER 0) - #filter out [inplace] filename from program output - list(TRANSFORM INCLUDE_DEPENDENCIES - REPLACE "Opening file \\[(.+)\\], stack top.*" - "\\1") - endif() - endif() - - add_custom_command( - OUTPUT ${SPIRV_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/${SPIRV_OUTPUT_DIR}/" - COMMAND ${COMMAND_PARAMS} - DEPENDS ${SPIRV_SOURCE} ${INCLUDE_DEPENDENCIES} - ) - endif() - list(APPEND SPIRV_BINARY_FILES ${SPIRV_OUTPUT}) - endforeach() - set(SPIRV_BINARY_FILES ${SPIRV_BINARY_FILES} PARENT_SCOPE) -endfunction() - -Generate_Shaders_SPIRV(SHADERS_VS vs) -Generate_Shaders_SPIRV(SHADERS_HS hs) -Generate_Shaders_SPIRV(SHADERS_DS ds) -Generate_Shaders_SPIRV(SHADERS_GS gs) -Generate_Shaders_SPIRV(SHADERS_PS ps) -Generate_Shaders_SPIRV(SHADERS_CS cs) -Generate_Shaders_SPIRV(SHADERS_LIB lib) - -add_custom_target(Shaders_SPIRV DEPENDS ${SPIRV_BINARY_FILES}) -set_property(TARGET "Shaders_SPIRV" PROPERTY FOLDER "Shaders") - diff --git a/WickedEngine/wiJobSystem.cpp b/WickedEngine/wiJobSystem.cpp index e71890e82..e7cb2ea86 100644 --- a/WickedEngine/wiJobSystem.cpp +++ b/WickedEngine/wiJobSystem.cpp @@ -21,17 +21,34 @@ namespace wiJobSystem uint32_t groupJobEnd; uint32_t sharedmemory_size; }; + struct WorkerState + { + std::atomic_bool alive{ true }; + }; - uint32_t numThreads = 0; - wiContainers::ThreadSafeRingBuffer jobQueue; - std::condition_variable wakeCondition; - std::mutex wakeMutex; + // This structure is responsible to stop worker thread loops. + // Once this is destroyed, worker threads will be woken up and end their loops. + // This is to workaround a problem on Linux, where threads still running their loops don't let the main thread to exit + struct InternalState + { + uint32_t numCores = 0; + uint32_t numThreads = 0; + std::shared_ptr worker_state = std::make_shared(); // kept alive by both threads and internal_state + std::condition_variable wakeCondition; + std::mutex wakeMutex; + wiContainers::ThreadSafeRingBuffer jobQueue; + ~InternalState() + { + worker_state->alive.store(false); + wakeCondition.notify_all(); // wakes up sleeping worker threads + } + } static internal_state; // This function executes the next item from the job queue. Returns true if successful, false if there was no job available inline bool work() { Job job; - if (jobQueue.pop_front(job)) + if (internal_state.jobQueue.pop_front(job)) { wiJobArgs args; args.groupID = job.groupID; @@ -64,22 +81,23 @@ namespace wiJobSystem wiTimer timer; // Retrieve the number of hardware threads in this system: - auto numCores = std::thread::hardware_concurrency(); + internal_state.numCores = std::thread::hardware_concurrency(); // Calculate the actual number of worker threads we want (-1 main thread): - numThreads = std::max(1u, numCores - 1); + internal_state.numThreads = std::max(1u, internal_state.numCores - 1); - for (uint32_t threadID = 0; threadID < numThreads; ++threadID) + for (uint32_t threadID = 0; threadID < internal_state.numThreads; ++threadID) { std::thread worker([] { - while (true) + std::shared_ptr worker_state = internal_state.worker_state; // this is a copy of shared_ptr, so it will remain alive for the thread's lifetime + while (worker_state->alive.load()) { if (!work()) { // no job, put thread to sleep - std::unique_lock lock(wakeMutex); - wakeCondition.wait(lock); + std::unique_lock lock(internal_state.wakeMutex); + internal_state.wakeCondition.wait(lock); } } @@ -107,12 +125,12 @@ namespace wiJobSystem worker.detach(); } - wiBackLog::post("wiJobSystem Initialized with [" + std::to_string(numCores) + " cores] [" + std::to_string(numThreads) + " threads] (" + std::to_string((int)std::round(timer.elapsed())) + " ms)"); + wiBackLog::post("wiJobSystem Initialized with [" + std::to_string(internal_state.numCores) + " cores] [" + std::to_string(internal_state.numThreads) + " threads] (" + std::to_string((int)std::round(timer.elapsed())) + " ms)"); } uint32_t GetThreadCount() { - return numThreads; + return internal_state.numThreads; } void Execute(context& ctx, const std::function& task) @@ -129,10 +147,10 @@ namespace wiJobSystem job.sharedmemory_size = 0; // Try to push a new job until it is pushed successfully: - while (!jobQueue.push_back(job)) { wakeCondition.notify_all(); work(); } + while (!internal_state.jobQueue.push_back(job)) { internal_state.wakeCondition.notify_all(); work(); } // Wake any one thread that might be sleeping: - wakeCondition.notify_one(); + internal_state.wakeCondition.notify_one(); } void Dispatch(context& ctx, uint32_t jobCount, uint32_t groupSize, const std::function& task, size_t sharedmemory_size) @@ -160,11 +178,11 @@ namespace wiJobSystem job.groupJobEnd = std::min(job.groupJobOffset + groupSize, jobCount); // Try to push a new job until it is pushed successfully: - while (!jobQueue.push_back(job)) { wakeCondition.notify_all(); work(); } + while (!internal_state.jobQueue.push_back(job)) { internal_state.wakeCondition.notify_all(); work(); } } // Wake any threads that might be sleeping: - wakeCondition.notify_all(); + internal_state.wakeCondition.notify_all(); } uint32_t DispatchGroupCount(uint32_t jobCount, uint32_t groupSize) @@ -182,7 +200,7 @@ namespace wiJobSystem void Wait(const context& ctx) { // Wake any threads that might be sleeping: - wakeCondition.notify_all(); + internal_state.wakeCondition.notify_all(); // Waiting will also put the current thread to good use by working on an other job if it can: while (IsBusy(ctx)) { work(); } diff --git a/WickedEngine/wiPlatform.h b/WickedEngine/wiPlatform.h index da6cd5a84..0f17d6abf 100644 --- a/WickedEngine/wiPlatform.h +++ b/WickedEngine/wiPlatform.h @@ -32,7 +32,7 @@ #define PLATFORM_LINUX #define wiLoadLibrary(name) dlopen(name, RTLD_LAZY) #define wiGetProcAddress(handle,name) dlsym(handle, name) -#define HMODULE (void*) +typedef void* HMODULE; #endif // _WIN32 diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 4ee0acf07..a38d7d7f4 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -735,7 +735,7 @@ PipelineState PSO_debug[DEBUGRENDERING_COUNT]; #if __has_include("wiShaderDump.h") // In this case, wiShaderDump.h contains precompiled shader binary data -#include "wiShaderdump.h" +#include "wiShaderDump.h" #define SHADERDUMP_ENABLED size_t GetShaderDumpCount() { diff --git a/WickedEngine/wiShaderCompiler.cpp b/WickedEngine/wiShaderCompiler.cpp index 10d30f257..64538dbfb 100644 --- a/WickedEngine/wiShaderCompiler.cpp +++ b/WickedEngine/wiShaderCompiler.cpp @@ -17,8 +17,9 @@ #endif // _WIN32 #ifdef PLATFORM_LINUX -// TODO: dxcompiler for linux -//#define SHADERCOMPILER_ENABLED_DXCOMPILER +#define SHADERCOMPILER_ENABLED +#define SHADERCOMPILER_ENABLED_DXCOMPILER +#define __RPC_FAR #endif // PLATFORM_LINUX #ifdef SHADERCOMPILER_ENABLED_DXCOMPILER @@ -579,12 +580,18 @@ namespace wiShaderCompiler void Initialize() { #ifdef SHADERCOMPILER_ENABLED_DXCOMPILER - if (dxcCompiler != nullptr) // Already initialized? + if (dxcCompiler != nullptr) { - return; + return; // already initialized } - HMODULE dxcompiler = wiLoadLibrary("dxcompiler.dll"); +#ifdef _WIN32 +#define LIBDXCOMPILER "dxcompiler.dll" + HMODULE dxcompiler = wiLoadLibrary(LIBDXCOMPILER); +#elif defined(PLATFORM_LINUX) +#define LIBDXCOMPILER "libdxcompiler.so" + HMODULE dxcompiler = wiLoadLibrary("./" LIBDXCOMPILER); +#endif if(dxcompiler != nullptr) { DxcCreateInstance = (DxcCreateInstanceProc)wiGetProcAddress(dxcompiler, "DxcCreateInstance"); @@ -596,12 +603,21 @@ namespace wiShaderCompiler assert(SUCCEEDED(hr)); hr = dxcUtils->CreateDefaultIncludeHandler(&dxcIncludeHandler); assert(SUCCEEDED(hr)); - wiBackLog::post("wiShaderCompiler: loaded dxcompiler.dll"); + wiBackLog::post("wiShaderCompiler: loaded " LIBDXCOMPILER); } } + else + { + wiBackLog::post("wiShaderCompiler: could not load library " LIBDXCOMPILER); + } #endif // SHADERCOMPILER_ENABLED_DXCOMPILER #ifdef SHADERCOMPILER_ENABLED_D3DCOMPILER + if (D3DCompile != nullptr) + { + return; // already initialized + } + HMODULE d3dcompiler = wiLoadLibrary("d3dcompiler_47.dll"); if(d3dcompiler != nullptr) {