diff --git a/CMakeLists.txt b/CMakeLists.txt index eb6ec8f..5ee7c9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required (VERSION 3.21) -set(EFXC2_VERSION 0.0.13.259) +set(EFXC2_VERSION 0.0.13.261) project (efxc2 VERSION ${EFXC2_VERSION} DESCRIPTION "Enhanced fxc2" HOMEPAGE_URL "https://github.com/JPeterMugaas/efxc2" @@ -34,8 +34,59 @@ list(APPEND CMAKE_MODULE_PATH "${EFXC2_FMT_PATH}/lib/cmake") list(APPEND CMAKE_INCLUDE_PATH "${EFXC2_FMT_PATH}/include") list(APPEND CMAKE_LIBRARY_PATH "${EFXC2_FMT_PATH}/lib") -message(STATUS "Check for C++20 formatting library") +message(STATUS "Check for C++20 std::bit_cast support") +file(WRITE + ${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp + "#include \r\n" + "#include \r\n" + "#include \r\n" + "\r\n" + "int main()\r\n" + "{\r\n" + "int number = -1;\r\n" + "std::cout << std::to_string(std::bit_cast(number));\r\n" + "return 0;\r\n" + "}\r\n") +try_compile(BIT_CAST_SUPPORTED + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp + OUTPUT_VARIABLE OUTPUT) +if (BIT_CAST_SUPPORTED) + message(STATUS "Check for C++20 std::bit_cast support - yes") +else() + message(STATUS "Check for C++20 std::bit_cast support - no") +endif() + + +message(STATUS "Check for C++20 std::ranges support") +file(WRITE + ${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp + "#include \r\n" + "#include \r\n" + "#include \r\n" + "#include \r\n" + "\r\n" + "int main()\r\n" + "{\r\n" + "std::vector numbers = { 1, 2, 3, 4, 5, 6 };\r\n" + "\r\n" + "auto print = [](const int& n) { std::cout << n << ' '; };\r\n" + "\r\n" + "std::ranges::for_each (numbers.begin(), numbers.end(), print);\r\n" + "return 0;\r\n" + "}\r\n") +try_compile(RANGES_SUPPORTED + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp + OUTPUT_VARIABLE OUTPUT) +if (RANGES_SUPPORTED) + message(STATUS "Check for C++20 std::ranges support - yes") +else() + message(STATUS "Check for C++20 std::ranges support - no") +endif() + set(USE_FMT_LIBRARY OFF) +message(STATUS "Check for C++20 formatting library") file(WRITE ${CMAKE_BINARY_DIR}/CMakeTmp/testCCompiler.cpp "#include \r\n" diff --git a/efxc2Compiler.cpp b/efxc2Compiler.cpp index 02180d4..0a03a83 100644 --- a/efxc2Compiler.cpp +++ b/efxc2Compiler.cpp @@ -26,7 +26,7 @@ void efxc2Compiler::SetupDefines(efxc2Utils::M_COMPILER_DEFINES _defines, std::v _def.Name = a.Name.c_str(); (void)defines.insert(defines.end(), _def); }; - (void)std::ranges::for_each(_defines->begin(), _defines->end(), insert_def); + (void)M_FOR_EACH(_defines->begin(), _defines->end(), insert_def); _def.Definition = nullptr; _def.Name = nullptr; @@ -35,7 +35,7 @@ void efxc2Compiler::SetupDefines(efxc2Utils::M_COMPILER_DEFINES _defines, std::v void efxc2Compiler::print_defines(std::vector const& defines) { std::cout << "\t"; - (void)std::ranges::for_each(defines, print_D3D_SHADER_MACRO); + (void)M_FOR_EACH(defines, print_D3D_SHADER_MACRO); std::cout << ",\n"; } @@ -106,7 +106,7 @@ void efxc2Compiler::Compiler::Preprocess() { std::cerr << "Preprocess error"; console.std_out_pink(); if (errors) { - auto* error = std::bit_cast(errors->GetBufferPointer()); + auto* error = M_BIT_CAST(errors->GetBufferPointer()); std::cout << M_FORMAT("Got an error while preprocessing:\n{}\n", error); (void)errors->Release(); std::cout << M_FORMAT("Error Code: {:#08x}", hr); @@ -210,7 +210,7 @@ void efxc2Compiler::Compiler::Compile() { console.std_out_pink(); std::cerr << "Compile error"; if (errors) { - auto* error = std::bit_cast(errors->GetBufferPointer()); + auto* error = M_BIT_CAST(errors->GetBufferPointer()); std::cout << M_FORMAT("Got an error while compiling:\n{}\n", error); (void)errors->Release(); std::cout << M_FORMAT("Error Code: {:#08x}", hr); @@ -227,7 +227,7 @@ void efxc2Compiler::Compiler::Compile() { } void efxc2Compiler::Compiler::Disassemble() { - auto const* compiledString = std::bit_cast(compilerOutput->GetBufferPointer()); + auto const* compiledString = M_BIT_CAST(compilerOutput->GetBufferPointer()); size_t compiledLen = compilerOutput->GetBufferSize(); auto disassembly_flags = params.get_disassembly_flags(); HRESULT hr = 0; @@ -288,7 +288,7 @@ void efxc2Compiler::Compiler::StripShader() { #pragma warning( push ) #pragma warning( disable : 6387) #endif - auto const* compiledString = std::bit_cast(compilerOutput->GetBufferPointer()); + auto const* compiledString = M_BIT_CAST(compilerOutput->GetBufferPointer()); size_t compiledLen = compilerOutput->GetBufferSize(); HRESULT hr = 0; auto ptr = api.get_ptr_D3DStripShader(); @@ -309,7 +309,7 @@ size_t efxc2Compiler::Compiler::WriteAssemblyCode(std::ofstream& f) { size_t outputLen = 0; if (disassemblyCodeBlob != nullptr) { - outputString = std::bit_cast(disassemblyCodeBlob->GetBufferPointer()); + outputString = M_BIT_CAST(disassemblyCodeBlob->GetBufferPointer()); outputLen = disassemblyCodeBlob->GetBufferSize(); (void)f.write(outputString, outputLen); } @@ -341,11 +341,11 @@ size_t efxc2Compiler::Compiler::WriteObjectFile(std::ofstream& f) { char const* outputString; size_t outputLen = 0; if (strippedBlob == nullptr) { - outputString = std::bit_cast(compilerOutput->GetBufferPointer()); + outputString = M_BIT_CAST(compilerOutput->GetBufferPointer()); outputLen = compilerOutput->GetBufferSize(); } else { - outputString = std::bit_cast(strippedBlob->GetBufferPointer()); + outputString = M_BIT_CAST(strippedBlob->GetBufferPointer()); outputLen = strippedBlob->GetBufferSize(); } (void)f.write(outputString, outputLen); @@ -353,7 +353,7 @@ size_t efxc2Compiler::Compiler::WriteObjectFile(std::ofstream& f) { } size_t efxc2Compiler::Compiler::WritePreprocessFile(std::ofstream& f) { - const char* outputString = std::bit_cast(pPreprocessOutput->GetBufferPointer()); + const char* outputString = M_BIT_CAST(pPreprocessOutput->GetBufferPointer()); size_t outputLen = pPreprocessOutput->GetBufferSize(); (void)f.write(outputString, outputLen); return outputLen; @@ -367,7 +367,7 @@ std::string efxc2Compiler::Compiler::GetPDBFileName() { */ - auto const* compiledString = std::bit_cast(compilerOutput->GetBufferPointer()); + auto const* compiledString = M_BIT_CAST(compilerOutput->GetBufferPointer()); size_t compiledLen = compilerOutput->GetBufferSize(); HRESULT hr = 0; /*Get filename*/ @@ -394,7 +394,7 @@ std::string efxc2Compiler::Compiler::GetPDBFileName() { efxc2Utils::print_hresult_error(hr); throw efxc2Exception::Win32HLSLFailure(); } - char* pName = std::bit_cast(pPDBName->GetBufferPointer()); + char* pName = M_BIT_CAST(pPDBName->GetBufferPointer()); /* Skip over reserved feild - uint_16 and length field uint_16*/ for (int i = 0; i <= 3; i++) { ++pName; @@ -406,7 +406,7 @@ std::string efxc2Compiler::Compiler::GetPDBFileName() { } void efxc2Compiler::Compiler::EmbedPrivateData() { - auto const* compiledString = std::bit_cast(compilerOutput->GetBufferPointer()); + auto const* compiledString = M_BIT_CAST(compilerOutput->GetBufferPointer()); size_t compiledLen = compilerOutput->GetBufferSize(); auto private_data = params.get_PrivateData(); size_t private_data_size = private_data->size(); @@ -459,7 +459,7 @@ void efxc2Compiler::Compiler::SetPDBFileName(_In_ const std::string_view _fileNa pNameBlobContent.resize(nameBlobPartSize + sizeof(ShaderDebugName)); // Ensure bytes after name are indeed zeroes: (void)std::ranges::fill(pNameBlobContent, 0); - auto* header = std::bit_cast(&pNameBlobContent[0]); + auto* header = M_BIT_CAST(&pNameBlobContent[0]); header->Flags = 0; // declared length does not include the null terminator: @@ -470,7 +470,7 @@ void efxc2Compiler::Compiler::SetPDBFileName(_In_ const std::string_view _fileNa pNameBlobContent[sizeof(ShaderDebugName) + i] = _fileName[i]; } - auto const* compiledString = std::bit_cast(compilerOutput->GetBufferPointer()); + auto const* compiledString = M_BIT_CAST(compilerOutput->GetBufferPointer()); size_t compiledLen = compilerOutput->GetBufferSize(); if (params.get_verbose() && params.get_debug()) { @@ -508,7 +508,7 @@ size_t efxc2Compiler::Compiler::WritePDBFile(std::ofstream& f) { ID3DBlob* PDBData = nullptr; char const* compiledString = nullptr; size_t compiledLen = 0; - compiledString = std::bit_cast(compilerOutput->GetBufferPointer()); + compiledString = M_BIT_CAST(compilerOutput->GetBufferPointer()); compiledLen = compilerOutput->GetBufferSize(); if (params.get_verbose() && params.get_debug()) { std::cout << "Calling D3DGetBlobPart(\n"; @@ -532,7 +532,7 @@ size_t efxc2Compiler::Compiler::WritePDBFile(std::ofstream& f) { efxc2Utils::print_hresult_error(hr); throw efxc2Exception::Win32HLSLFailure(); } - auto outputString = std::bit_cast(PDBData->GetBufferPointer()); + auto outputString = M_BIT_CAST(PDBData->GetBufferPointer()); size_t outputLen = PDBData->GetBufferSize(); (void)f.write(outputString, outputLen); return compiledLen; diff --git a/efxc2CompilerAPIContainer.cpp b/efxc2CompilerAPIContainer.cpp index 9a4e084..7ebaef4 100644 --- a/efxc2CompilerAPIContainer.cpp +++ b/efxc2CompilerAPIContainer.cpp @@ -26,7 +26,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { #pragma warning( push ) #pragma warning( disable : 6387) #endif - ptr_D3DCompile2 = std::bit_cast(GetProcAddress(h, FCN_D3DCompile2)); + ptr_D3DCompile2 = M_BIT_CAST(GetProcAddress(h, FCN_D3DCompile2)); #ifdef _MSC_VER #pragma warning( pop ) #endif @@ -37,7 +37,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { efxc2Utils::print_windows_error(); throw efxc2Exception::Win32APIFailure(); } - ptr_D3DStripShader = std::bit_cast(GetProcAddress(h, FCN_D3DStripShader)); + ptr_D3DStripShader = M_BIT_CAST(GetProcAddress(h, FCN_D3DStripShader)); if (ptr_D3DStripShader == nullptr) { console.PinkOutput(); std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DStripShader); @@ -45,7 +45,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { efxc2Utils::print_windows_error(); throw efxc2Exception::Win32APIFailure(); } - ptr_D3DGetBlobPart = std::bit_cast(GetProcAddress(h, FCN_D3DGetBlobPart)); + ptr_D3DGetBlobPart = M_BIT_CAST(GetProcAddress(h, FCN_D3DGetBlobPart)); if (ptr_D3DGetBlobPart == nullptr) { console.PinkOutput(); std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DGetBlobPart); @@ -53,7 +53,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { efxc2Utils::print_windows_error(); throw efxc2Exception::Win32APIFailure(); } - ptr_D3DSetBlobPart = std::bit_cast(GetProcAddress(h, FCN_D3DSetBlobPart)); + ptr_D3DSetBlobPart = M_BIT_CAST(GetProcAddress(h, FCN_D3DSetBlobPart)); if (ptr_D3DSetBlobPart == nullptr) { console.PinkOutput(); std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DSetBlobPart); @@ -61,7 +61,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { efxc2Utils::print_windows_error(); throw efxc2Exception::Win32APIFailure(); } - ptr_D3DDisassemble = std::bit_cast(GetProcAddress(h, FCN_D3DDisassemble)); + ptr_D3DDisassemble = M_BIT_CAST(GetProcAddress(h, FCN_D3DDisassemble)); if (ptr_D3DDisassemble == nullptr) { console.PinkOutput(); std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DDisassemble); @@ -69,7 +69,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { efxc2Utils::print_windows_error(); throw efxc2Exception::Win32APIFailure(); } - ptr_D3DLoadModule = std::bit_cast(GetProcAddress(h, FCN_D3DLoadModule)); + ptr_D3DLoadModule = M_BIT_CAST(GetProcAddress(h, FCN_D3DLoadModule)); if (ptr_D3DLoadModule == nullptr) { console.PinkOutput(); std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DLoadModule); @@ -77,7 +77,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { efxc2Utils::print_windows_error(); throw efxc2Exception::Win32APIFailure(); } - ptr_D3DCreateLinker = std::bit_cast(GetProcAddress(h, FCN_D3DCreateLinker)); + ptr_D3DCreateLinker = M_BIT_CAST(GetProcAddress(h, FCN_D3DCreateLinker)); if (ptr_D3DCreateLinker == nullptr) { console.PinkOutput(); std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DCreateLinker); @@ -85,7 +85,7 @@ efxc2CompilerAPIContainer::CompilerAPIContainer::CompilerAPIContainer() { efxc2Utils::print_windows_error(); throw efxc2Exception::Win32APIFailure(); } - ptr_D3DCreateFunctionLinkingGraph = std::bit_cast(GetProcAddress(h, FCN_D3DCreateFunctionLinkingGraph)); + ptr_D3DCreateFunctionLinkingGraph = M_BIT_CAST(GetProcAddress(h, FCN_D3DCreateFunctionLinkingGraph)); if (ptr_D3DCreateFunctionLinkingGraph == nullptr) { console.PinkOutput(); std::cerr << M_FORMAT(ERR_LOAD_FCN, FCN_D3DCreateFunctionLinkingGraph); diff --git a/efxc2CompilerIncludes.cpp b/efxc2CompilerIncludes.cpp index 96a367c..2edaddc 100644 --- a/efxc2CompilerIncludes.cpp +++ b/efxc2CompilerIncludes.cpp @@ -152,7 +152,7 @@ namespace efxc2CompilerIncludes { std::cout << "\tpData: nullptr\n"; } } - auto buf = std::bit_cast(pData); + auto buf = M_BIT_CAST(pData); delete[] buf; //-V2511 return S_OK; } diff --git a/efxc2Utils.cpp b/efxc2Utils.cpp index a335d52..44def39 100644 --- a/efxc2Utils.cpp +++ b/efxc2Utils.cpp @@ -97,7 +97,7 @@ void efxc2Utils::print_hresult_error(const HRESULT hr) { console.std_out_pink(); LPSTR messageBuffer = nullptr; size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), std::bit_cast(&messageBuffer), 0, nullptr); + nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), M_BIT_CAST(&messageBuffer), 0, nullptr); #ifdef _MSC_VER #pragma warning(push) #pragma warning(suppress : 6387) @@ -129,7 +129,7 @@ void efxc2Utils::print_windows_error() { nullptr, dLastError, 0, - std::bit_cast(&strErrorMessage), + M_BIT_CAST(&strErrorMessage), 0, nullptr); @@ -157,7 +157,7 @@ void efxc2Utils::WriteByteArrayConst(_In_ std::ofstream& f, ID3DBlob* data, _In_ const int outputHex) { size_t len = data->GetBufferSize(); f << M_FORMAT("const BYTE {}[] =\n{{\n", variableName); - auto p = std::bit_cast(data->GetBufferPointer()); + auto p = M_BIT_CAST(data->GetBufferPointer()); for (size_t i = 0; i < len; i++) { if (outputHex) { f << M_FORMAT(" 0x{:02x}", *p); @@ -388,7 +388,7 @@ std::wstring efxc2Utils::utf8_to_wstring(std::string const& str) } auto _wstr = std::make_unique>(); _wstr->resize((nchars + 1) * sizeof(wchar_t)); - auto* wstr = std::bit_cast(_wstr->data()); + auto* wstr = M_BIT_CAST(_wstr->data()); wstr[nchars] = L'\0'; //-V3539 //-V2563 if (terminate_function == false) { err = _mbstowcs_s_l(&nchars, wstr, nchars, str.c_str(), str.length() + 1, locale); diff --git a/efxc2Utils.h b/efxc2Utils.h index d442601..26d1986 100644 --- a/efxc2Utils.h +++ b/efxc2Utils.h @@ -18,6 +18,28 @@ namespace efxc2Utils { using M_BUFFER = std::shared_ptr>; +#ifndef RANGES_SUPPORTED +#define M_FOR_EACH std::for_each +#else +#define M_FOR_EACH std::ranges::for_each +#endif + +#ifndef BIT_CAST_SUPPORTED + template + T2 cpp11_bit_cast(T1 t1) { + static_assert(sizeof(T1) == sizeof(T2), "Types must match sizes"); + static_assert(std::is_pod::value, "Requires POD input"); + static_assert(std::is_pod::value, "Requires POD output"); + + T2 t2; + std::memcpy(std::addressof(t2), std::addressof(t1), sizeof(T1)); + return t2; + } +#define M_BIT_CAST bit_cast +#else +#define M_BIT_CAST std::bit_cast +#endif + #ifdef _WIN32 using M_CMD_PARAMS = std::vector; using M_STRING = std::wstring;