Add compatibility option for PointSize in HLSL.

If we opt-in to it, PointSize can be ignored to avoid more annoying
workarounds.
This commit is contained in:
Hans-Kristian Arntzen 2017-05-04 10:10:30 +02:00
parent 9e85815394
commit 17d88ca928
6 changed files with 64 additions and 2 deletions

View File

@ -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 <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 <variable_name> <new_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);
}

View File

@ -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;
}

View File

@ -0,0 +1,8 @@
#version 310 es
void main()
{
gl_Position = vec4(1.0);
gl_PointSize = 10.0;
}

View File

@ -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<BuiltIn>(i));
statement("stage_output.", builtin, " = ", builtin, ";");
}

View File

@ -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<uint32_t> spirv_)

View File

@ -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)