diff --git a/main.cpp b/main.cpp index ae156d99..a8021417 100644 --- a/main.cpp +++ b/main.cpp @@ -435,6 +435,7 @@ struct CLIArguments bool msl = false; bool msl_pack_ubos = true; bool hlsl = false; + bool hlsl_compat = false; bool vulkan_semantics = false; bool remove_unused = false; bool cfg_analysis = true; @@ -447,7 +448,7 @@ static void print_help() "[--vulkan-semantics] [--flatten-ubo] [--fixup-clipspace] [--iterations iter] " "[--cpp] [--cpp-interface-name ] " "[--msl] [--msl-no-pack-ubos] " - "[--hlsl] [--shader-model] " + "[--hlsl] [--shader-model] [--hlsl-enable-compat] " "[--pls-in format input-name] [--pls-out format output-name] [--remap source_name target_name " "components] [--extension ext] [--entry name] [--remove-unused-variables] " "[--remap-variable-type ]\n"); @@ -571,6 +572,7 @@ int main(int argc, char *argv[]) cbs.add("--msl", [&args](CLIParser &) { args.msl = true; }); cbs.add("--msl-no-pack-ubos", [&args](CLIParser &) { args.msl_pack_ubos = false; }); cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; }); + cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; }); cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; }); cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); }); cbs.add("--entry", [&args](CLIParser &parser) { args.entry = parser.next_string(); }); @@ -698,6 +700,12 @@ int main(int argc, char *argv[]) hlsl_opts.shader_model = args.shader_model; } + + if (args.hlsl_compat) + { + // Enable all compat options. + hlsl_opts.point_size_compat = true; + } hlsl->set_options(hlsl_opts); } diff --git a/reference/shaders-hlsl/vert/point-size-compat.vert b/reference/shaders-hlsl/vert/point-size-compat.vert new file mode 100644 index 00000000..3aad537d --- /dev/null +++ b/reference/shaders-hlsl/vert/point-size-compat.vert @@ -0,0 +1,20 @@ +static float4 gl_Position; +static float gl_PointSize; +struct SPIRV_Cross_Output +{ + float4 gl_Position : SV_Position; +}; + +void vert_main() +{ + gl_Position = float4(1.0f, 1.0f, 1.0f, 1.0f); + gl_PointSize = 10.0f; +} + +SPIRV_Cross_Output main() +{ + vert_main(); + SPIRV_Cross_Output stage_output; + stage_output.gl_Position = gl_Position; + return stage_output; +} diff --git a/shaders-hlsl/vert/point-size-compat.vert b/shaders-hlsl/vert/point-size-compat.vert new file mode 100644 index 00000000..64eff363 --- /dev/null +++ b/shaders-hlsl/vert/point-size-compat.vert @@ -0,0 +1,8 @@ +#version 310 es + +void main() +{ + gl_Position = vec4(1.0); + gl_PointSize = 10.0; +} + diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp index 75e60313..7920e81a 100644 --- a/spirv_hlsl.cpp +++ b/spirv_hlsl.cpp @@ -270,6 +270,15 @@ void CompilerHLSL::emit_builtin_outputs_in_struct() semantic = legacy ? "DEPTH" : "SV_Depth"; break; + case BuiltInPointSize: + // If point_size_compat is enabled, just ignore PointSize. + // PointSize does not exist in HLSL, but some code bases might want to be able to use these shaders, + // even if it means working around the missing feature. + if (options.point_size_compat) + break; + else + SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); + default: SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); break; @@ -499,6 +508,16 @@ void CompilerHLSL::emit_builtin_variables() type = "int"; break; + case BuiltInPointSize: + if (options.point_size_compat) + { + // Just emit the global variable, it will be ignored. + type = "float"; + break; + } + else + SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin))); + default: SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin))); break; @@ -1035,6 +1054,10 @@ void CompilerHLSL::emit_hlsl_entry_point() if (!(active_output_builtins & (1ull << i))) continue; + // PointSize doesn't exist in HLSL. + if (i == BuiltInPointSize) + continue; + auto builtin = builtin_to_glsl(static_cast(i)); statement("stage_output.", builtin, " = ", builtin, ";"); } diff --git a/spirv_hlsl.hpp b/spirv_hlsl.hpp index 4a42ed64..3618c017 100644 --- a/spirv_hlsl.hpp +++ b/spirv_hlsl.hpp @@ -31,6 +31,9 @@ public: uint32_t shader_model = 30; // TODO: map ps_4_0_level_9_0,... somehow bool fixup_clipspace = false; bool flip_vert_y = false; + + // Allows the PointSize builtin, and ignores it, as PointSize is not supported in HLSL. + bool point_size_compat = true; }; CompilerHLSL(std::vector spirv_) diff --git a/test_shaders.py b/test_shaders.py index e28ddfad..4788691d 100755 --- a/test_shaders.py +++ b/test_shaders.py @@ -107,7 +107,7 @@ def cross_compile_hlsl(shader): os.close(hlsl_f) subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader]) spirv_cross_path = './spirv-cross' - subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', hlsl_path, spirv_path, '--hlsl', '--shader-model', '50']) + subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', hlsl_path, spirv_path, '--hlsl-enable-compat', '--hlsl', '--shader-model', '50']) subprocess.check_call(['spirv-val', spirv_path]) validate_shader_hlsl(hlsl_path)