Adding BuiltInSampleMask in HLSL

This commit is contained in:
Tomek Ponitka 2020-07-23 19:09:43 +02:00
parent 3dcc23a5b3
commit ba58f78395
11 changed files with 232 additions and 2 deletions

View File

@ -0,0 +1,30 @@
static int gl_SampleMaskIn;
static int gl_SampleMask;
static float4 FragColor;
struct SPIRV_Cross_Input
{
uint gl_SampleMaskIn : SV_Coverage;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
uint gl_SampleMask : SV_Coverage;
};
void frag_main()
{
FragColor = 1.0f.xxxx;
gl_SampleMask = gl_SampleMaskIn;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_SampleMaskIn = stage_input.gl_SampleMaskIn;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_SampleMask = gl_SampleMask;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,32 @@
static int gl_SampleID;
static int gl_SampleMaskIn;
static float4 FragColor;
struct SPIRV_Cross_Input
{
uint gl_SampleID : SV_SampleIndex;
uint gl_SampleMaskIn : SV_Coverage;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
if ((gl_SampleMaskIn & (1 << gl_SampleID)) != 0)
{
FragColor = 1.0f.xxxx;
}
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_SampleID = stage_input.gl_SampleID;
gl_SampleMaskIn = stage_input.gl_SampleMaskIn;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,23 @@
static int gl_SampleMask;
static float4 FragColor;
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
uint gl_SampleMask : SV_Coverage;
};
void frag_main()
{
FragColor = 1.0f.xxxx;
gl_SampleMask = 0;
}
SPIRV_Cross_Output main()
{
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_SampleMask = gl_SampleMask;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,30 @@
static int gl_SampleMaskIn;
static int gl_SampleMask;
static float4 FragColor;
struct SPIRV_Cross_Input
{
uint gl_SampleMaskIn : SV_Coverage;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
uint gl_SampleMask : SV_Coverage;
};
void frag_main()
{
FragColor = 1.0f.xxxx;
gl_SampleMask = gl_SampleMaskIn;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_SampleMaskIn = stage_input.gl_SampleMaskIn;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_SampleMask = gl_SampleMask;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,32 @@
static int gl_SampleID;
static int gl_SampleMaskIn;
static float4 FragColor;
struct SPIRV_Cross_Input
{
uint gl_SampleID : SV_SampleIndex;
uint gl_SampleMaskIn : SV_Coverage;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
if ((gl_SampleMaskIn & (1 << gl_SampleID)) != 0)
{
FragColor = 1.0f.xxxx;
}
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
gl_SampleID = stage_input.gl_SampleID;
gl_SampleMaskIn = stage_input.gl_SampleMaskIn;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,23 @@
static int gl_SampleMask;
static float4 FragColor;
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
uint gl_SampleMask : SV_Coverage;
};
void frag_main()
{
FragColor = 1.0f.xxxx;
gl_SampleMask = 0;
}
SPIRV_Cross_Output main()
{
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.gl_SampleMask = gl_SampleMask;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,9 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(1.0);
gl_SampleMask[0] = gl_SampleMaskIn[0];
}

View File

@ -0,0 +1,11 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
if ((gl_SampleMaskIn[0] & (1 << gl_SampleID)) != 0)
{
FragColor = vec4(1.0);
}
}

View File

@ -0,0 +1,9 @@
#version 450
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = vec4(1.0);
gl_SampleMask[0] = 0;
}

View File

@ -568,6 +568,13 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
semantic = legacy ? "POSITION" : "SV_Position";
break;
case BuiltInSampleMask:
if (hlsl_options.shader_model < 41 || execution.model != ExecutionModelFragment)
SPIRV_CROSS_THROW("Sample Mask output is only supported in PS 4.1 or higher.");
type = "uint";
semantic = "SV_Coverage";
break;
case BuiltInFragDepth:
type = "float";
if (legacy)
@ -673,6 +680,13 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
semantic = "SV_SampleIndex";
break;
case BuiltInSampleMask:
if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelFragment)
SPIRV_CROSS_THROW("Sample Mask input is only supported in PS 5.0 or higher.");
type = "uint";
semantic = "SV_Coverage";
break;
case BuiltInGlobalInvocationId:
type = "uint3";
semantic = "SV_DispatchThreadID";
@ -1064,13 +1078,15 @@ void CompilerHLSL::emit_builtin_variables()
type = "float";
break;
case BuiltInSampleMask:
type = "int";
break;
default:
SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin)));
}
StorageClass storage = active_input_builtins.get(i) ? StorageClassInput : StorageClassOutput;
// FIXME: SampleMask can be both in and out with sample builtin,
// need to distinguish that when we add support for that.
if (type)
{
@ -1079,6 +1095,13 @@ void CompilerHLSL::emit_builtin_variables()
else
statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
}
// SampleMask can be both in and out with sample builtin, in this case we have already
// declared the input variable and we need to add the output one now.
if (builtin == BuiltInSampleMask && storage == StorageClassInput && this->active_output_builtins.get(i))
{
statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), ";");
}
});
if (need_base_vertex_info)
@ -5700,3 +5723,8 @@ void CompilerHLSL::set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint3
SetBindingPair pair = { desc_set, binding };
force_uav_buffer_bindings.insert(pair);
}
bool CompilerHLSL::builtin_translates_to_nonarray(spv::BuiltIn builtin) const
{
return (builtin == BuiltInSampleMask);
}

View File

@ -352,6 +352,9 @@ private:
void remap_hlsl_resource_binding(HLSLBindingFlagBits type, uint32_t &desc_set, uint32_t &binding);
std::unordered_set<SetBindingPair, InternalHasher> force_uav_buffer_bindings;
// Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL.
bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override;
};
} // namespace SPIRV_CROSS_NAMESPACE