Add wrapper around spirv-cross

This commit is contained in:
David Chavez 2024-12-18 14:25:24 +01:00
parent 7bcd1585ff
commit a7f8b5ee9d
6 changed files with 115 additions and 5 deletions

2
.gitmodules vendored
View File

@ -48,7 +48,7 @@
url = https://github.com/btzy/nativefiledialog-extended
[submodule "src/contrib/spirv-cross"]
path = src/contrib/spirv-cross
url = https://github.com/rt64/spriv-cross-bin.git
url = https://github.com/KhronosGroup/SPIRV-Cross.git
[submodule "src/contrib/ddspp"]
path = src/contrib/ddspp
url = https://github.com/redorav/ddspp.git

View File

@ -122,8 +122,8 @@ function(build_shader_msl_impl TARGETOBJ FILENAME TARGET_NAME OUTNAME)
COMMAND ${DXC} ${DXC_SPV_OPTS} ${ARGN} ${FILENAME} /Fo ${OUTNAME}.spv
DEPENDS ${FILENAME})
add_custom_command(OUTPUT ${OUTNAME}.metal
COMMAND ${SPIRVCROSS} ${OUTNAME}.spv --msl --output ${OUTNAME}.metal --msl-version 20100 --flip-vert-y --msl-argument-buffers --msl-decoration-binding --msl-texture-buffer-native
DEPENDS ${OUTNAME}.spv)
COMMAND spirv_cross_msl ${OUTNAME}.spv ${OUTNAME}.metal
DEPENDS ${OUTNAME}.spv spirv_cross_msl)
add_custom_command(OUTPUT ${OUTNAME}.ir
COMMAND xcrun -sdk macosx metal -o ${OUTNAME}.ir -c ${OUTNAME}.metal $<$<CONFIG:Debug>:-frecord-sources>
DEPENDS ${OUTNAME}.metal)
@ -429,6 +429,8 @@ add_subdirectory(src/tools/texture_packer)
# Add any Apple-specific source files and libraries
if (APPLE)
add_subdirectory(src/tools/spirv_cross_msl)
target_sources(rt64 PRIVATE
"${PROJECT_SOURCE_DIR}/src/metal/rt64_metal.cpp"
"${PROJECT_SOURCE_DIR}/src/common/rt64_apple.mm"

View File

@ -1251,7 +1251,7 @@ namespace RT64 {
using TestSetupFunc = std::function<std::unique_ptr<TestBase>()>;
static std::vector<TestSetupFunc> g_Tests;
static std::unique_ptr<TestBase> g_CurrentTest;
static uint32_t g_CurrentTestIndex = 1;
static uint32_t g_CurrentTestIndex = 2;
void RegisterTests() {
g_Tests.push_back([]() { return std::make_unique<ClearTest>(); });

@ -1 +1 @@
Subproject commit 3158d6dd29174984f1b2f2da4fe215b42bc89e04
Subproject commit 6173e24b31f09a0c3217103a130e74c4ddec14a6

View File

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.20)
project(spirv_cross_msl)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
add_executable(spirv_cross_msl "spirv_cross_msl.cpp")
target_include_directories(spirv_cross_msl PRIVATE "../../contrib/spirv-cross")
add_subdirectory(../../contrib/spirv-cross ${CMAKE_BINARY_DIR}/spirv-cross)
target_link_libraries(spirv_cross_msl spirv-cross-core spirv-cross-msl)

View File

@ -0,0 +1,94 @@
#include "spirv_msl.hpp"
#include "spirv_parser.hpp"
#include <fstream>
#include <iostream>
#include <vector>
static std::vector<uint32_t> read_spirv_file_stdin() {
#ifdef _WIN32
setmode(fileno(stdin), O_BINARY);
#endif
std::vector<uint32_t> buffer;
uint32_t tmp[256];
size_t ret;
while ((ret = fread(tmp, sizeof(uint32_t), 256, stdin)))
buffer.insert(buffer.end(), tmp, tmp + ret);
return buffer;
}
static std::vector<uint32_t> read_spirv_file(const char *path) {
if (path[0] == '-' && path[1] == '\0')
return read_spirv_file_stdin();
FILE *file = fopen(path, "rb");
if (!file)
{
fprintf(stderr, "Failed to open SPIR-V file: %s\n", path);
return {};
}
fseek(file, 0, SEEK_END);
long len = ftell(file) / sizeof(uint32_t);
rewind(file);
std::vector<uint32_t> spirv(len);
if (fread(spirv.data(), sizeof(uint32_t), len, file) != size_t(len))
spirv.clear();
fclose(file);
return spirv;
}
static bool write_string_to_file(const char *path, const char *string) {
FILE *file = fopen(path, "w");
if (!file)
{
fprintf(stderr, "Failed to write file: %s\n", path);
return false;
}
fprintf(file, "%s", string);
fclose(file);
return true;
}
int main(int argc, char* argv[]) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <input.spv> <output.metal>\n";
return 1;
}
try {
// Load SPIR-V
auto spirv_file = read_spirv_file(argv[1]);
spirv_cross::Parser spirv_parser(std::move(spirv_file));
spirv_parser.parse();
// Initialize MSL compiler
spirv_cross::CompilerMSL msl(std::move(spirv_parser.get_parsed_ir()));
// Configure MSL options
spirv_cross::CompilerMSL::Options msl_options;
msl_options.msl_version = spirv_cross::CompilerMSL::Options::make_msl_version(2, 1);
msl_options.argument_buffers = true;
msl_options.texture_buffer_native = true;
msl.set_msl_options(msl_options);
// Configure common options
spirv_cross::CompilerGLSL::Options common_options;
common_options.vertex.flip_vert_y = true;
msl.set_common_options(common_options);
// Generate MSL source
std::string source = msl.compile();
write_string_to_file(argv[2], source.c_str());
return 0;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << "\n";
return 1;
}
}