CompilerMSL elide unused builtins from entry function input and output structs.

Add Compiler::has_active_builtin() function.
Update test reference shaders that included unused builtins.
This commit is contained in:
Bill Hollings 2017-05-24 09:31:38 -04:00
parent d77de7ab80
commit 192bdc9516
19 changed files with 38 additions and 35 deletions

View File

@ -18,7 +18,6 @@ struct main0_out
{
float3 vNormal [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]])

View File

@ -16,7 +16,6 @@ struct main0_in
struct main0_out
{
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _20 [[buffer(0)]])

View File

@ -20,7 +20,6 @@ struct main0_out
{
float2 vRot [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant PushMe& registers [[buffer(0)]])

View File

@ -26,7 +26,6 @@ struct main0_out
{
float4 vColor [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _18 [[buffer(0)]])

View File

@ -30,7 +30,6 @@ struct main0_out
float4 oB [[user(locn4)]];
float4 oA [[user(locn5)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(constant UBO& _22 [[buffer(0)]])

View File

@ -18,7 +18,6 @@ struct main0_in
struct main0_out
{
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant Buffer& _13 [[buffer(0)]])

View File

@ -18,7 +18,6 @@ struct main0_out
{
float3 vNormal [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]])

View File

@ -26,7 +26,6 @@ struct main0_out
{
float4 vColor [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _21 [[buffer(0)]])

View File

@ -26,7 +26,6 @@ struct main0_out
{
float4 vColor [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _21 [[buffer(0)]])

View File

@ -27,7 +27,6 @@ struct main0_out
int2 vMSB [[user(locn3)]];
int2 vLSB [[user(locn4)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
// Implementation of the GLSL radians() function

View File

@ -18,8 +18,6 @@ struct main0_out
{
float4 VertexOut_color [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
float gl_ClipDistance [[clip_distance]] [1];
};
vertex main0_out main0(main0_in in [[stage_in]], constant Transform& block [[buffer(0)]])

View File

@ -20,7 +20,6 @@ struct main0_out
float4 color [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize [[point_size]];
float gl_ClipDistance [[clip_distance]] [1];
};
vertex main0_out main0(main0_in in [[stage_in]], constant params& _19 [[buffer(0)]])

View File

@ -6,7 +6,6 @@ using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(texture2d<float> uSamp [[texture(0)]], texture2d<float> uSampo [[texture(1)]])

View File

@ -24,7 +24,6 @@ struct main0_out
float3 vNormal [[user(locn1)]];
float3 vColor [[user(locn2)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _18 [[buffer(0)]])

View File

@ -18,7 +18,6 @@ struct main0_out
{
float3 vNormal [[user(locn0)]];
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(main0_in in [[stage_in]], constant UBO& _16 [[buffer(0)]])

View File

@ -6,7 +6,6 @@ using namespace metal;
struct main0_out
{
float4 gl_Position [[position]];
float gl_PointSize;
};
vertex main0_out main0(uint gl_VertexIndex [[vertex_id]], uint gl_InstanceIndex [[instance_id]])

View File

@ -3409,6 +3409,25 @@ void Compiler::update_active_builtins()
traverse_all_reachable_opcodes(get<SPIRFunction>(entry_point), handler);
}
// Returns whether this shader uses a builtin of the storage class
bool Compiler::has_active_builtin(BuiltIn builtin, StorageClass storage)
{
uint64_t flags;
switch (storage)
{
case StorageClassInput:
flags = active_input_builtins;
break;
case StorageClassOutput:
flags = active_output_builtins;
break;
default:
return false;
}
return flags & (1ull << builtin);
}
void Compiler::analyze_sampler_comparison_states()
{
CombinedImageSamplerUsageHandler handler(*this);

View File

@ -640,6 +640,7 @@ protected:
uint64_t active_output_builtins = 0;
// Traverses all reachable opcodes and sets active_builtins to a bitmask of all builtin variables which are accessed in the shader.
void update_active_builtins();
bool has_active_builtin(spv::BuiltIn builtin, spv::StorageClass storage);
void analyze_parameter_preservation(
SPIRFunction &entry, const CFG &cfg,

View File

@ -406,12 +406,14 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
uint32_t mbr_idx = 0;
for (auto &mbr_type_id : type.member_types)
{
BuiltIn builtin;
bool is_builtin = is_member_builtin(type, mbr_idx, &builtin);
auto &mbr_type = get<SPIRType>(mbr_type_id);
if (is_matrix(mbr_type))
{
exclude_member_from_stage_in(type, mbr_idx);
}
else
else if (!is_builtin || has_active_builtin(builtin, storage))
{
// Add a reference to the member to the interface struct.
uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size());
@ -434,8 +436,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
}
// Mark the member as builtin if needed
BuiltIn builtin;
if (is_member_builtin(type, mbr_idx, &builtin))
if (is_builtin)
{
set_member_decoration(ib_type_id, ib_mbr_idx, DecorationBuiltIn, builtin);
if (builtin == BuiltInPosition)
@ -451,11 +452,13 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
type.basetype == SPIRType::Float || type.basetype == SPIRType::Double ||
type.basetype == SPIRType::Boolean)
{
bool is_builtin = is_builtin_variable(*p_var);
BuiltIn builtin = BuiltIn(get_decoration(p_var->self, DecorationBuiltIn));
if (is_matrix(type))
{
exclude_from_stage_in(*p_var);
}
else
else if (!is_builtin || has_active_builtin(builtin, storage))
{
// Add a reference to the variable type to the interface struct.
uint32_t ib_mbr_idx = uint32_t(ib_type.member_types.size());
@ -478,9 +481,8 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
}
// Mark the member as builtin if needed
if (is_builtin_variable(*p_var))
if (is_builtin)
{
uint32_t builtin = get_decoration(p_var->self, DecorationBuiltIn);
set_member_decoration(ib_type_id, ib_mbr_idx, DecorationBuiltIn, builtin);
if (builtin == BuiltInPosition)
qual_pos_var_name = qual_var_name;
@ -1959,14 +1961,12 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
{
switch (builtin)
{
case BuiltInPointSize: // Must output only if really rendering points
// SPIR-V might declare PointSize as a builtin even though it's not really used.
// In some cases PointSize builtin may be written without Point topology.
// This is not an issue on GL/Vulkan, but it is on Metal, so we also have some way to forcefully disable
// this builtin.
return (active_output_builtins & (1ull << BuiltInPointSize)) && options.enable_point_size_builtin ?
(string(" [[") + builtin_qualifier(builtin) + "]]") :
"";
case BuiltInPointSize:
// Only mark the PointSize builtin if really rendering points.
// Some shaders may include a PointSize builtin even when used to render
// non-point topologies, and Metal will reject this builtin when compiling
// the shader into a render pipeline that uses a non-point topology.
return options.enable_point_size_builtin ? (string(" [[") + builtin_qualifier(builtin) + "]]") : "";
case BuiltInPosition:
case BuiltInLayer: