Merge pull request #190 from brenwill/master
Emit type declarations tuned for specified SPIR-V objects + MSL builtin enhancements.
This commit is contained in:
commit
3ab1700073
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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
|
||||
|
@ -18,8 +18,6 @@ struct main0_out
|
||||
{
|
||||
float4 VertexOut_color [[user(locn0)]];
|
||||
float4 gl_Position [[position]];
|
||||
float gl_PointSize;
|
||||
float gl_ClipDistance[1] /* [[clip_distance]] built-in not yet supported under Metal. */;
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant Transform& block [[buffer(0)]])
|
||||
|
@ -20,7 +20,6 @@ struct main0_out
|
||||
float4 color [[user(locn0)]];
|
||||
float4 gl_Position [[position]];
|
||||
float gl_PointSize [[point_size]];
|
||||
float gl_ClipDistance[1] /* [[clip_distance]] built-in not yet supported under Metal. */;
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant params& _19 [[buffer(0)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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)]])
|
||||
|
@ -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]])
|
||||
|
@ -296,10 +296,9 @@ struct SPIRType : IVariant
|
||||
bool depth;
|
||||
bool arrayed;
|
||||
bool ms;
|
||||
bool is_read = false; // TODO: temp hack to be replaced with var-based type output
|
||||
bool is_written = false; // TODO: temp hack to be replaced with var-based type output
|
||||
uint32_t sampled;
|
||||
spv::ImageFormat format;
|
||||
spv::AccessQualifier access;
|
||||
} image;
|
||||
|
||||
// Structs can be declared multiple times if they are used as part of interface blocks.
|
||||
|
@ -1468,6 +1468,11 @@ void Compiler::parse(const Instruction &instruction)
|
||||
type.image.ms = ops[5] != 0;
|
||||
type.image.sampled = ops[6];
|
||||
type.image.format = static_cast<ImageFormat>(ops[7]);
|
||||
type.image.access = (length >= 9) ? static_cast<AccessQualifier>(ops[8]) : AccessQualifierMax;
|
||||
|
||||
if (type.image.sampled == 0)
|
||||
SPIRV_CROSS_THROW("OpTypeImage Sampled parameter must not be zero.");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3409,6 +3414,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);
|
||||
|
@ -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,
|
||||
|
@ -2893,9 +2893,6 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
|
||||
auto &type = expression_type(img);
|
||||
auto &imgtype = get<SPIRType>(type.self);
|
||||
|
||||
// Mark that this shader reads from this image
|
||||
imgtype.image.is_read = true;
|
||||
|
||||
uint32_t coord_components = 0;
|
||||
switch (imgtype.image.dim)
|
||||
{
|
||||
@ -6107,7 +6104,7 @@ string CompilerGLSL::type_to_array_glsl(const SPIRType &type)
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerGLSL::image_type_glsl(const SPIRType &type)
|
||||
string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t /* id */)
|
||||
{
|
||||
auto &imagetype = get<SPIRType>(type.image.type);
|
||||
string res;
|
||||
@ -6202,7 +6199,10 @@ string CompilerGLSL::type_to_glsl_constructor(const SPIRType &type)
|
||||
return e;
|
||||
}
|
||||
|
||||
string CompilerGLSL::type_to_glsl(const SPIRType &type)
|
||||
// The optional id parameter indicates the object whose type we are trying
|
||||
// to find the description for. It is optional. Most type descriptions do not
|
||||
// depend on a specific object's use of that type.
|
||||
string CompilerGLSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
||||
{
|
||||
// Ignore the pointer type since GLSL doesn't have pointers.
|
||||
|
||||
@ -6217,7 +6217,7 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type)
|
||||
|
||||
case SPIRType::Image:
|
||||
case SPIRType::SampledImage:
|
||||
return image_type_glsl(type);
|
||||
return image_type_glsl(type, id);
|
||||
|
||||
case SPIRType::Sampler:
|
||||
// This is a hacky workaround. The sampler type in SPIR-V doesn't actually signal this distinction,
|
||||
|
@ -171,11 +171,11 @@ protected:
|
||||
virtual void emit_header();
|
||||
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
|
||||
virtual void emit_texture_op(const Instruction &i);
|
||||
virtual std::string type_to_glsl(const SPIRType &type);
|
||||
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
|
||||
virtual std::string builtin_to_glsl(spv::BuiltIn builtin);
|
||||
virtual void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||
const std::string &qualifier = "");
|
||||
virtual std::string image_type_glsl(const SPIRType &type);
|
||||
virtual std::string image_type_glsl(const SPIRType &type, uint32_t id = 0);
|
||||
virtual std::string constant_expression(const SPIRConstant &c);
|
||||
std::string constant_op_expression(const SPIRConstantOp &cop);
|
||||
virtual std::string constant_expression_vector(const SPIRConstant &c, uint32_t vector);
|
||||
|
@ -154,7 +154,10 @@ string CompilerHLSL::image_type_hlsl(const SPIRType &type)
|
||||
return image_type_hlsl_modern(type);
|
||||
}
|
||||
|
||||
string CompilerHLSL::type_to_glsl(const SPIRType &type)
|
||||
// The optional id parameter indicates the object whose type we are trying
|
||||
// to find the description for. It is optional. Most type descriptions do not
|
||||
// depend on a specific object's use of that type.
|
||||
string CompilerHLSL::type_to_glsl(const SPIRType &type, uint32_t /* id */)
|
||||
{
|
||||
// Ignore the pointer type since GLSL doesn't have pointers.
|
||||
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
std::string compile() override;
|
||||
|
||||
private:
|
||||
std::string type_to_glsl(const SPIRType &type) override;
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string image_type_hlsl(const SPIRType &type);
|
||||
std::string image_type_hlsl_modern(const SPIRType &type);
|
||||
std::string image_type_hlsl_legacy(const SPIRType &type);
|
||||
|
158
spirv_msl.cpp
158
spirv_msl.cpp
@ -85,6 +85,7 @@ string CompilerMSL::compile()
|
||||
struct_member_padding.clear();
|
||||
|
||||
update_active_builtins();
|
||||
fixup_image_load_store_access();
|
||||
|
||||
// Preprocess OpCodes to extract the need to output additional header content
|
||||
preprocess_op_codes();
|
||||
@ -406,12 +407,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 +437,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 +453,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 +482,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;
|
||||
@ -1176,10 +1179,18 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
|
||||
// Images
|
||||
|
||||
// Reads == fetches in Metal
|
||||
// Reads == Fetches in Metal
|
||||
case OpImageRead:
|
||||
{
|
||||
// Mark that this shader reads from this image
|
||||
uint32_t img_id = ops[2];
|
||||
auto *p_var = maybe_get_backing_variable(img_id);
|
||||
if (p_var)
|
||||
unset_decoration(p_var->self, DecorationNonReadable);
|
||||
|
||||
emit_texture_op(instruction);
|
||||
break;
|
||||
}
|
||||
|
||||
case OpImageWrite:
|
||||
{
|
||||
@ -1195,26 +1206,13 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
|
||||
// Ensure this image has been marked as being written to and force a
|
||||
// recommpile so that the image type output will include write access
|
||||
if (!img_type.image.is_written)
|
||||
auto *p_var = maybe_get_backing_variable(img_id);
|
||||
if (p_var && has_decoration(p_var->self, DecorationNonWritable))
|
||||
{
|
||||
img_type.image.is_written = true;
|
||||
unset_decoration(p_var->self, DecorationNonWritable);
|
||||
force_recompile = true;
|
||||
}
|
||||
|
||||
// We added Nonwritable speculatively to the OpImage variable due to glslangValidator
|
||||
// not adding the proper qualifiers.
|
||||
// If it turns out we need to write to the image after all, remove the qualifier and recompile.
|
||||
auto *var = maybe_get_backing_variable(img_id);
|
||||
if (var)
|
||||
{
|
||||
auto &flags = meta.at(var->self).decoration.decoration_flags;
|
||||
if (flags & (1ull << DecorationNonWritable))
|
||||
{
|
||||
flags &= ~(1ull << DecorationNonWritable);
|
||||
force_recompile = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool forward = false;
|
||||
uint32_t bias = 0;
|
||||
uint32_t lod = 0;
|
||||
@ -1242,7 +1240,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
to_function_args(img_id, img_type, true, false, false, coord_id, 0, 0, 0, 0, lod, 0, 0, 0, 0, 0, &forward),
|
||||
");"));
|
||||
|
||||
if (var && variable_storage_is_aliased(*var))
|
||||
if (p_var && variable_storage_is_aliased(*p_var))
|
||||
flush_all_aliased_variables();
|
||||
|
||||
break;
|
||||
@ -1916,7 +1914,7 @@ void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_
|
||||
string pack_pfx = member_is_packed_type(type, index) ? "packed_" : "";
|
||||
|
||||
statement(pack_pfx, type_to_glsl(membertype), " ", qualifier, to_member_name(type, index),
|
||||
type_to_array_glsl(membertype), member_attribute_qualifier(type, index), ";");
|
||||
member_attribute_qualifier(type, index), type_to_array_glsl(membertype), ";");
|
||||
}
|
||||
|
||||
// Return a MSL qualifier for the specified function attribute member
|
||||
@ -1924,6 +1922,9 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
|
||||
{
|
||||
auto &execution = get_entry_point();
|
||||
|
||||
uint32_t mbr_type_id = type.member_types[index];
|
||||
auto &mbr_type = get<SPIRType>(mbr_type_id);
|
||||
|
||||
BuiltIn builtin;
|
||||
bool is_builtin = is_member_builtin(type, index, &builtin);
|
||||
|
||||
@ -1956,21 +1957,17 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
|
||||
{
|
||||
switch (builtin)
|
||||
{
|
||||
case BuiltInClipDistance:
|
||||
return " /* [[clip_distance]] built-in not yet supported under Metal. */";
|
||||
|
||||
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:
|
||||
return string(" [[") + builtin_qualifier(builtin) + "]]";
|
||||
case BuiltInClipDistance:
|
||||
return string(" [[") + builtin_qualifier(builtin) + "]]" + (mbr_type.array.empty() ? "" : " ");
|
||||
|
||||
default:
|
||||
return "";
|
||||
@ -2201,6 +2198,8 @@ string CompilerMSL::entry_point_args(bool append_comma)
|
||||
auto &var = id.get<SPIRVariable>();
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
|
||||
uint32_t var_id = var.self;
|
||||
|
||||
if ((var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant ||
|
||||
var.storage == StorageClassPushConstant) &&
|
||||
!is_hidden_variable(var))
|
||||
@ -2214,31 +2213,31 @@ string CompilerMSL::entry_point_args(bool append_comma)
|
||||
break;
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args += get_argument_address_space(var) + " " + type_to_glsl(type) + "& " + to_name(var.self);
|
||||
ep_args += get_argument_address_space(var) + " " + type_to_glsl(type) + "& " + to_name(var_id);
|
||||
ep_args += " [[buffer(" + convert_to_string(get_metal_resource_index(var, type.basetype)) + ")]]";
|
||||
break;
|
||||
}
|
||||
case SPIRType::Sampler:
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args += type_to_glsl(type) + " " + to_name(var.self);
|
||||
ep_args += type_to_glsl(type) + " " + to_name(var_id);
|
||||
ep_args += " [[sampler(" + convert_to_string(get_metal_resource_index(var, type.basetype)) + ")]]";
|
||||
break;
|
||||
case SPIRType::Image:
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args += type_to_glsl(type) + " " + to_name(var.self);
|
||||
ep_args += type_to_glsl(type, var_id) + " " + to_name(var_id);
|
||||
ep_args += " [[texture(" + convert_to_string(get_metal_resource_index(var, type.basetype)) + ")]]";
|
||||
break;
|
||||
case SPIRType::SampledImage:
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args += type_to_glsl(type) + " " + to_name(var.self);
|
||||
ep_args += type_to_glsl(type, var_id) + " " + to_name(var_id);
|
||||
ep_args +=
|
||||
" [[texture(" + convert_to_string(get_metal_resource_index(var, SPIRType::Image)) + ")]]";
|
||||
if (type.image.dim != DimBuffer)
|
||||
{
|
||||
ep_args += ", sampler " + to_sampler_expression(var.self);
|
||||
ep_args += ", sampler " + to_sampler_expression(var_id);
|
||||
ep_args +=
|
||||
" [[sampler(" + convert_to_string(get_metal_resource_index(var, SPIRType::Sampler)) + ")]]";
|
||||
}
|
||||
@ -2251,8 +2250,8 @@ string CompilerMSL::entry_point_args(bool append_comma)
|
||||
{
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
BuiltIn bi_type = meta[var.self].decoration.builtin_type;
|
||||
ep_args += builtin_type_decl(bi_type) + " " + to_expression(var.self);
|
||||
BuiltIn bi_type = meta[var_id].decoration.builtin_type;
|
||||
ep_args += builtin_type_decl(bi_type) + " " + to_expression(var_id);
|
||||
ep_args += " [[" + builtin_qualifier(bi_type) + "]]";
|
||||
}
|
||||
}
|
||||
@ -2377,8 +2376,10 @@ string CompilerMSL::ensure_valid_name(string name, string pfx)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an MSL string describing the SPIR-V type
|
||||
string CompilerMSL::type_to_glsl(const SPIRType &type)
|
||||
// The optional id parameter indicates the object whose type we are trying
|
||||
// to find the description for. It is optional. Most type descriptions do not
|
||||
// depend on a specific object's use of that type.
|
||||
string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
||||
{
|
||||
// Ignore the pointer type since GLSL doesn't have pointers.
|
||||
|
||||
@ -2392,7 +2393,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type)
|
||||
|
||||
case SPIRType::Image:
|
||||
case SPIRType::SampledImage:
|
||||
return image_type_glsl(type);
|
||||
return image_type_glsl(type, id);
|
||||
|
||||
case SPIRType::Sampler:
|
||||
return "sampler";
|
||||
@ -2445,7 +2446,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type)
|
||||
}
|
||||
|
||||
// Returns an MSL string describing the SPIR-V image type
|
||||
string CompilerMSL::image_type_glsl(const SPIRType &type)
|
||||
string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
{
|
||||
string img_type_name;
|
||||
|
||||
@ -2456,10 +2457,10 @@ string CompilerMSL::image_type_glsl(const SPIRType &type)
|
||||
{
|
||||
switch (img_type.dim)
|
||||
{
|
||||
case spv::Dim2D:
|
||||
case Dim2D:
|
||||
img_type_name += (img_type.ms ? "depth2d_ms" : (img_type.arrayed ? "depth2d_array" : "depth2d"));
|
||||
break;
|
||||
case spv::DimCube:
|
||||
case DimCube:
|
||||
img_type_name += (img_type.arrayed ? "depthcube_array" : "depthcube");
|
||||
break;
|
||||
default:
|
||||
@ -2471,17 +2472,17 @@ string CompilerMSL::image_type_glsl(const SPIRType &type)
|
||||
{
|
||||
switch (img_type.dim)
|
||||
{
|
||||
case spv::Dim1D:
|
||||
case Dim1D:
|
||||
img_type_name += (img_type.arrayed ? "texture1d_array" : "texture1d");
|
||||
break;
|
||||
case spv::DimBuffer:
|
||||
case spv::Dim2D:
|
||||
case DimBuffer:
|
||||
case Dim2D:
|
||||
img_type_name += (img_type.ms ? "texture2d_ms" : (img_type.arrayed ? "texture2d_array" : "texture2d"));
|
||||
break;
|
||||
case spv::Dim3D:
|
||||
case Dim3D:
|
||||
img_type_name += "texture3d";
|
||||
break;
|
||||
case spv::DimCube:
|
||||
case DimCube:
|
||||
img_type_name += (img_type.arrayed ? "texturecube_array" : "texturecube");
|
||||
break;
|
||||
default:
|
||||
@ -2491,18 +2492,43 @@ string CompilerMSL::image_type_glsl(const SPIRType &type)
|
||||
}
|
||||
|
||||
// Append the pixel type
|
||||
auto &img_pix_type = get<SPIRType>(img_type.type);
|
||||
img_type_name += "<";
|
||||
img_type_name += type_to_glsl(img_pix_type);
|
||||
img_type_name += type_to_glsl(get<SPIRType>(img_type.type));
|
||||
|
||||
if (img_type.is_written)
|
||||
// For unsampled images, append the sample/read/write access qualifier.
|
||||
// For kernel images, the access qualifier my be supplied directly by SPIR-V.
|
||||
// Otherwise it may be set based on whether the image is read from or written to within the shader.
|
||||
if (type.basetype == SPIRType::Image && type.image.sampled == 2)
|
||||
{
|
||||
img_type_name += ", access::";
|
||||
switch (img_type.access)
|
||||
{
|
||||
case AccessQualifierReadOnly:
|
||||
img_type_name += ", access::read";
|
||||
break;
|
||||
|
||||
if (img_type.is_read)
|
||||
img_type_name += "read_";
|
||||
case AccessQualifierWriteOnly:
|
||||
img_type_name += ", access::write";
|
||||
break;
|
||||
|
||||
img_type_name += "write";
|
||||
case AccessQualifierReadWrite:
|
||||
img_type_name += ", access::read_write";
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
auto *p_var = maybe_get_backing_variable(id);
|
||||
if (p_var && !has_decoration(p_var->self, DecorationNonWritable))
|
||||
{
|
||||
img_type_name += ", access::";
|
||||
|
||||
if (!has_decoration(p_var->self, DecorationNonReadable))
|
||||
img_type_name += "read_";
|
||||
|
||||
img_type_name += "write";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img_type_name += ">";
|
||||
|
@ -149,8 +149,8 @@ protected:
|
||||
void emit_fixup() override;
|
||||
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
|
||||
const std::string &qualifier = "") override;
|
||||
std::string type_to_glsl(const SPIRType &type) override;
|
||||
std::string image_type_glsl(const SPIRType &type) override;
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin) override;
|
||||
std::string constant_expression(const SPIRConstant &c) override;
|
||||
size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const override;
|
||||
@ -165,6 +165,7 @@ protected:
|
||||
uint32_t comp, uint32_t sample, bool *p_forward) override;
|
||||
std::string unpack_expression_type(std::string expr_str, const SPIRType &type) override;
|
||||
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;
|
||||
bool skip_argument(uint32_t id) const override;
|
||||
|
||||
void preprocess_op_codes();
|
||||
void emit_custom_functions();
|
||||
@ -217,7 +218,6 @@ protected:
|
||||
bool op1_is_pointer = false, uint32_t op2 = 0);
|
||||
const char *get_memory_order(uint32_t spv_mem_sem);
|
||||
void add_pragma_line(const std::string &line);
|
||||
bool skip_argument(uint32_t id) const override;
|
||||
|
||||
Options options;
|
||||
std::unordered_map<std::string, std::string> func_name_overrides;
|
||||
|
Loading…
Reference in New Issue
Block a user