From 6a6465e12ea1d44e0d39edef5215208c1ce6b87e Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Sun, 13 Jul 2025 17:15:44 +0200 Subject: [PATCH] get rid of full dxvk --- CMakeLists.txt | 4 +-- cmake/FetchDXBC.cmake | 33 ++++++++++++++++++++++ cmake/FetchDXVK.cmake | 60 --------------------------------------- src/extract/trans.cpp | 65 ++++++++++++++++++++++++++++++++++--------- 4 files changed, 87 insertions(+), 75 deletions(-) create mode 100644 cmake/FetchDXBC.cmake delete mode 100644 cmake/FetchDXVK.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ef8c74a..f057af5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ endif() # subprojects -include(cmake/FetchDXVK.cmake) +include(cmake/FetchDXBC.cmake) include(cmake/FetchPeParse.cmake) add_subdirectory(lsfg-vk-common) @@ -41,7 +41,7 @@ target_include_directories(lsfg-vk PRIVATE include) target_link_libraries(lsfg-vk PRIVATE lsfg-vk-common lsfg-vk-v3.1 lsfg-vk-v3.1p - peparse dxvk vulkan) + peparse dxvk_dxbc vulkan) if(CMAKE_BUILD_TYPE STREQUAL "Release") set_target_properties(lsfg-vk PROPERTIES diff --git a/cmake/FetchDXBC.cmake b/cmake/FetchDXBC.cmake new file mode 100644 index 0000000..3311a26 --- /dev/null +++ b/cmake/FetchDXBC.cmake @@ -0,0 +1,33 @@ +include(ExternalProject) + +ExternalProject_Add(dxbc_git + GIT_REPOSITORY "https://github.com/PancakeTAS/dxbc" + GIT_TAG "d77124f" + UPDATE_DISCONNECTED true + USES_TERMINAL_CONFIGURE true + USES_TERMINAL_BUILD true + BUILD_IN_SOURCE true + CONFIGURE_COMMAND + cmake -S . -B build -G Ninja + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_C_COMPILER=clang + -DCMAKE_CXX_COMPILER=clang++ + -DCMAKE_C_FLAGS=-fPIC + -DCMAKE_CXX_FLAGS=-fPIC + BUILD_COMMAND + ninja -C build + INSTALL_COMMAND "" +) + +ExternalProject_Get_Property(dxbc_git SOURCE_DIR) + +add_library(dxvk_dxbc INTERFACE) +add_dependencies(dxvk_dxbc dxbc_git) + +target_link_directories(dxvk_dxbc + INTERFACE ${SOURCE_DIR}/build) +target_include_directories(dxvk_dxbc SYSTEM + INTERFACE ${SOURCE_DIR}/include/dxbc + INTERFACE ${SOURCE_DIR}/include/spirv ${SOURCE_DIR}/include/util ${SOURCE_DIR}/include/dxvk) +target_link_libraries(dxvk_dxbc + INTERFACE dxbc) diff --git a/cmake/FetchDXVK.cmake b/cmake/FetchDXVK.cmake deleted file mode 100644 index f84de82..0000000 --- a/cmake/FetchDXVK.cmake +++ /dev/null @@ -1,60 +0,0 @@ -include(ExternalProject) - -if(CMAKE_BUILD_TYPE STREQUAL "Release") - set(BUILD_TYPE "release") - set(STRIP_FLAG "--strip") -else() - set(BUILD_TYPE "debug") - set(STRIP_FLAG "") -endif() - -ExternalProject_Add(dxvk_git - GIT_REPOSITORY "https://github.com/doitsujin/dxvk" - GIT_TAG "v2.6.2" - UPDATE_DISCONNECTED true - USES_TERMINAL_CONFIGURE true - USES_TERMINAL_BUILD true - BUILD_IN_SOURCE true - CONFIGURE_COMMAND - sed -i s/private://g - src/dxvk/dxvk_shader.h && - CC=clang CXX=clang++ CFLAGS=-w CXXFLAGS=-w - meson setup - --buildtype ${BUILD_TYPE} - --prefix /build-native - ${STRIP_FLAG} - -Dbuild_id=false - -Denable_d3d8=false - -Denable_d3d9=false - -Denable_d3d10=false - --force-fallback-for=libdisplay-info - --wipe - build - BUILD_COMMAND - ninja -C build install && - mv build/src/dxvk/libdxvk.a build/src/dxvk/libldxvk.a && - cd build/src/dxgi/libdxvk_dxgi.so.0.20602.p && - bash -c "ar rcs -o ../libdxgi.a *.o" && - cd ../../d3d11/libdxvk_d3d11.so.0.20602.p && - bash -c "ar rcs -o ../libd3d11.a *.o .*.o" - INSTALL_COMMAND "" -) - -ExternalProject_Get_Property(dxvk_git SOURCE_DIR) - -add_library(dxvk INTERFACE) -add_dependencies(dxvk dxvk_git) - -target_link_directories(dxvk - INTERFACE ${SOURCE_DIR}/build/src/dxvk - INTERFACE ${SOURCE_DIR}/build/src/dxbc - INTERFACE ${SOURCE_DIR}/build/src/dxgi - INTERFACE ${SOURCE_DIR}/build/src/d3d11 - INTERFACE ${SOURCE_DIR}/build/src/spirv - INTERFACE ${SOURCE_DIR}/build/src/util) -target_include_directories(dxvk SYSTEM - INTERFACE ${SOURCE_DIR}/build-native/include/dxvk - INTERFACE ${SOURCE_DIR}/src - INTERFACE ${SOURCE_DIR}/include/spirv/include) -target_link_libraries(dxvk INTERFACE - -Wl,--start-group dxgi d3d11 util ldxvk dxbc spirv -Wl,--end-group) diff --git a/src/extract/trans.cpp b/src/extract/trans.cpp index f9860f9..d458fea 100644 --- a/src/extract/trans.cpp +++ b/src/extract/trans.cpp @@ -1,8 +1,10 @@ #include "extract/trans.hpp" -#include -#include -#include +#include + +#include +#include +#include #include #include @@ -11,23 +13,60 @@ using namespace Extract; +struct BindingOffsets { + uint32_t bindingIndex{}; + uint32_t bindingOffset{}; + uint32_t setIndex{}; + uint32_t setOffset{}; +}; + std::vector Extract::translateShader(std::vector bytecode) { // compile the shader dxvk::DxbcReader reader(reinterpret_cast(bytecode.data()), bytecode.size()); dxvk::DxbcModule module(reader); const dxvk::DxbcModuleInfo info{}; - auto shader = module.compile(info, "CS"); + auto code = module.compile(info, "CS"); - // extract spir-v from d3d11 shader - auto code = shader->getRawCode(); + // find all bindings + std::vector bindingOffsets; + std::vector varIds; + for (auto ins : code) { + if (ins.opCode() == spv::OpDecorate) { + if (ins.arg(2) == spv::DecorationBinding) { + const uint32_t varId = ins.arg(1); + bindingOffsets.resize(std::max(bindingOffsets.size(), size_t(varId + 1))); + bindingOffsets[varId].bindingIndex = ins.arg(3); + bindingOffsets[varId].bindingOffset = ins.offset() + 3; + varIds.push_back(varId); + } - // patch binding offsets -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" - for (size_t i = 0; i < shader->m_bindingOffsets.size(); i++) - code.data()[shader->m_bindingOffsets.at(i).bindingOffset] // NOLINT - = static_cast(i); -#pragma clang diagnostic pop + if (ins.arg(2) == spv::DecorationDescriptorSet) { + const uint32_t varId = ins.arg(1); + bindingOffsets.resize(std::max(bindingOffsets.size(), size_t(varId + 1))); + bindingOffsets[varId].setIndex = ins.arg(3); + bindingOffsets[varId].setOffset = ins.offset() + 3; + } + } + + if (ins.opCode() == spv::OpFunction) + break; + } + + std::vector validBindings; + for (const auto varId : varIds) { + auto info = bindingOffsets[varId]; + + if (info.bindingOffset) + validBindings.push_back(info); + } + + // patch binding offset + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" + for (size_t i = 0; i < validBindings.size(); i++) + code.data()[validBindings.at(i).bindingOffset] // NOLINT + = static_cast(i); + #pragma clang diagnostic pop // return the new bytecode std::vector spirvBytecode(code.size());