diff --git a/.gitignore b/.gitignore index 5a841fa7..e7f2d08e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,6 @@ tags TAGS bazel-* build/ -zig-cache/ -zig-out/ Test/localResults/ External/googletest External/spirv-tools @@ -25,3 +23,8 @@ tools/ # Random OS stuff .DS_Store ._* + +# Zig +.zig-cache/ +zig-cache/ +zig-out/ \ No newline at end of file diff --git a/StandAlone/minimal-test.cpp b/StandAlone/minimal-test.cpp new file mode 100644 index 00000000..83f366b9 --- /dev/null +++ b/StandAlone/minimal-test.cpp @@ -0,0 +1,133 @@ +#include "glslang/Include/glslang_c_interface.h" +#include "glslang/Public/resource_limits_c.h" +#include + + +int main(void) +{ + glslang_initialize_process(); + + glslang_stage_t stage = GLSLANG_STAGE_FRAGMENT; + + const char* fileName = u8"ExampleShader.hlsl"; + + const char* shaderSource = u8R"( +struct VertexInput +{ + float2 Position : POSITION; + float4 Color : COLOR0; +}; + +struct VertexOutput +{ + float4 Position : SV_POSITION; + float4 Color : COLOR0; +}; + + +VertexOutput vertex(VertexInput input) +{ + VertexOutput output; + output.Position = float4(input.Position, 0, 1); + output.Color = input.Color; + return output; +} + +#define DO_SOMETHING(x) x * 10 + 4 - 8 + sqrt(x) / abs(x) + + +float4 pixel(VertexOutput input) : SV_Target +{ + float value = DO_SOMETHING(input.Color.r); + + float value2 = DO_SOMETHING(value); + + float value3 = DO_SOMETHING(value2); + + input.Color *= 10; + + input.Color /= 43.55; + + input.Color.g = value2; + input.Color.b = value; + input.Color.a = value3; + + return input.Color; +} + )"; + + const glslang_input_t input = { + .language = GLSLANG_SOURCE_HLSL, + .stage = stage, + .client = GLSLANG_CLIENT_VULKAN, + .client_version = GLSLANG_TARGET_VULKAN_1_2, + .target_language = GLSLANG_TARGET_SPV, + .target_language_version = GLSLANG_TARGET_SPV_1_5, + .code = shaderSource, + .entrypoint = "main", + .source_entrypoint = "pixel", + .default_version = 100, + .default_profile = GLSLANG_NO_PROFILE, + .force_default_version_and_profile = false, + .forward_compatible = false, + .messages = GLSLANG_MSG_DEFAULT_BIT, + .resource = glslang_default_resource(), + }; + + glslang_shader_t* shader = glslang_shader_create(&input); + + if (!glslang_shader_preprocess(shader, &input)) { + printf("HLSL preprocessing failed %s\n", fileName); + printf("%s\n", glslang_shader_get_info_log(shader)); + printf("%s\n", glslang_shader_get_info_debug_log(shader)); + printf("%s\n", input.code); + glslang_shader_delete(shader); + return 1; + } + + if (!glslang_shader_parse(shader, &input)) { + printf("HLSL parsing failed %s\n", fileName); + printf("%s\n", glslang_shader_get_info_log(shader)); + printf("%s\n", glslang_shader_get_info_debug_log(shader)); + printf("%s\n", glslang_shader_get_preprocessed_code(shader)); + glslang_shader_delete(shader); + glslang_finalize_process(); + return 1; + } + + glslang_program_t* program = glslang_program_create(); + glslang_program_add_shader(program, shader); + + if (!glslang_program_link(program, GLSLANG_MSG_SPV_RULES_BIT | GLSLANG_MSG_VULKAN_RULES_BIT)) { + printf("HLSL linking failed %s\n", fileName); + printf("%s\n", glslang_program_get_info_log(program)); + printf("%s\n", glslang_program_get_info_debug_log(program)); + glslang_program_delete(program); + glslang_shader_delete(shader); + glslang_finalize_process(); + return 1; + } + + glslang_program_SPIRV_generate(program, stage); + + size_t size = glslang_program_SPIRV_get_size(program); + uint32_t* words = static_cast(malloc(size * sizeof(uint32_t))); + glslang_program_SPIRV_get(program, words); + + const char* spirv_messages = glslang_program_SPIRV_get_messages(program); + if (spirv_messages) + printf("(%s) %s\b", fileName, spirv_messages); + + glslang_program_delete(program); + glslang_shader_delete(shader); + + char* disassembled = glslang_SPIRV_disassemble(words, size); + + std::cout << "Generated " << size << " SPIR-V words" << std::endl; + std::cout << disassembled << std::endl; + + free(disassembled); + free(words); + + glslang_finalize_process(); +} \ No newline at end of file diff --git a/build.zig b/build.zig index ed530975..cd330923 100644 --- a/build.zig +++ b/build.zig @@ -13,7 +13,8 @@ pub fn build(b: *Build) !void { const enable_opt = !(b.option(bool, "no_opt", "Skip building spirv-tools optimization.") orelse false); const shared_tools = b.option(bool, "shared_tools", "Build and link spirv-tools as a shared library.") orelse false; const standalone_glslang = b.option(bool, "standalone", "Build glslang.exe standalone command-line compiler.") orelse false; - const standalone_spvremap = b.option(bool, "standalone-remap", "Build spirv-remap.exe standalone command-line remapper.") orelse false; + const standalone_spvremap = b.option(bool, "standalone_remap", "Build spirv-remap.exe standalone command-line remapper.") orelse false; + const minimal_test_exe = b.option(bool, "minimal_test", "Build a minimal test for linking") orelse false; if (shared and (standalone_glslang or standalone_spvremap)) { log.err("Cannot build standalone sources with shared glslang. Recompile without `-Dshared` or `-Dstandalone/-Dstandalone-remap`", .{}); @@ -162,7 +163,7 @@ pub fn build(b: *Build) !void { } - addIncludes(glslang_lib); + addIncludes(b, glslang_lib); glslang_lib.linkLibCpp(); @@ -185,7 +186,7 @@ pub fn build(b: *Build) !void { .flags = &.{ "-std=c++17" }, }); - addIncludes(glslang_exe); + addIncludes(b, glslang_exe); b.installArtifact(glslang_exe); glslang_exe.linkLibrary(glslang_lib); @@ -227,7 +228,7 @@ pub fn build(b: *Build) !void { .flags = &.{ "-std=c++17" }, }); - addIncludes(spirv_remap); + addIncludes(b, spirv_remap); b.installArtifact(spirv_remap); spirv_remap.linkLibrary(glslang_lib); @@ -236,16 +237,45 @@ pub fn build(b: *Build) !void { spirv_remap.want_lto = false; } } + + + if (minimal_test_exe) { + const min_test = b.addExecutable(.{ + .name = "minimal-test", + .optimize = optimize, + .target = target, + }); + + if (shared) { + min_test.defineCMacro("GLSLANG_IS_SHARED_LIBRARY", ""); + } + + const min_test_step = b.step("minimal-test", "Build and install minimal-test.exe"); + min_test_step.dependOn(&b.addInstallArtifact(min_test, .{}).step); + min_test.addCSourceFile(.{ + .file = b.path("StandAlone/minimal-test.cpp"), + .flags = &.{ "-std=c++17" }, + }); + + addIncludes(b, min_test); + + b.installArtifact(min_test); + min_test.linkLibrary(glslang_lib); + + if (target.result.os.tag == .windows) { + min_test.want_lto = false; + } + } } -fn addIncludes(step: *std.Build.Step.Compile) void { - step.addIncludePath(.{ .path = sdkPath("/" ++ output_path) }); - step.addIncludePath(.{ .path = sdkPath("/") }); - step.addIncludePath(.{ .path = sdkPath("/External/spirv-tools/include") }); +fn addIncludes(b: *Build, step: *std.Build.Step.Compile) void { + step.addIncludePath(b.path(output_path)); + step.addIncludePath(b.path("")); + step.addIncludePath(b.path("External/spirv-tools/include")); } fn ensureCommandExists(allocator: std.mem.Allocator, name: []const u8, exist_check: []const u8) bool { - const result = std.ChildProcess.run(.{ + const result = std.process.Child.run(.{ .allocator = allocator, .argv = &[_][]const u8{ name, exist_check }, .cwd = ".", @@ -273,7 +303,7 @@ fn exec(allocator: std.mem.Allocator, argv: []const []const u8, cwd: []const u8) } log.info("{s}", .{buf.items}); - var child = std.ChildProcess.init(argv, allocator); + var child = std.process.Child.init(argv, allocator); child.cwd = cwd; _ = try child.spawnAndWait(); }