mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-15 00:11:06 +00:00
Support array of images and samplers in MSL.
This commit is contained in:
parent
81eb72a9a0
commit
5827dd54ea
@ -2292,7 +2292,11 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
|
||||
// Manufacture automatic sampler arg for SampledImage texture
|
||||
auto &arg_type = get<SPIRType>(arg.type);
|
||||
if (arg_type.basetype == SPIRType::SampledImage && arg_type.image.dim != DimBuffer)
|
||||
decl += ", thread const sampler& " + to_sampler_expression(arg.id);
|
||||
{
|
||||
//const char *reference = arg_type.array.empty() ? "& " : " ";
|
||||
const char *reference = " ";
|
||||
decl += join(", thread const ", sampler_type(arg_type), reference, to_sampler_expression(arg.id));
|
||||
}
|
||||
|
||||
if (&arg != &func.arguments.back())
|
||||
decl += ", ";
|
||||
@ -2594,14 +2598,9 @@ string CompilerMSL::to_func_call_arg(uint32_t id)
|
||||
string arg_str = CompilerGLSL::to_func_call_arg(id);
|
||||
|
||||
// Manufacture automatic sampler arg if the arg is a SampledImage texture.
|
||||
Variant &id_v = ids[id];
|
||||
if (id_v.get_type() == TypeVariable)
|
||||
{
|
||||
auto &var = id_v.get<SPIRVariable>();
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer)
|
||||
arg_str += ", " + to_sampler_expression(id);
|
||||
}
|
||||
auto &type = expression_type(id);
|
||||
if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer)
|
||||
arg_str += ", " + to_sampler_expression(id);
|
||||
|
||||
return arg_str;
|
||||
}
|
||||
@ -2611,8 +2610,18 @@ string CompilerMSL::to_func_call_arg(uint32_t id)
|
||||
// by appending a suffix to the expression constructed from the ID.
|
||||
string CompilerMSL::to_sampler_expression(uint32_t id)
|
||||
{
|
||||
auto expr = to_expression(id);
|
||||
auto index = expr.find_first_of('[');
|
||||
uint32_t samp_id = meta[id].sampler;
|
||||
return samp_id ? to_expression(samp_id) : to_expression(id) + sampler_name_suffix;
|
||||
|
||||
if (index == string::npos)
|
||||
return samp_id ? to_expression(samp_id) : expr + sampler_name_suffix;
|
||||
else
|
||||
{
|
||||
auto image_expr = expr.substr(0, index);
|
||||
auto array_expr = expr.substr(index);
|
||||
return samp_id ? to_expression(samp_id) : (image_expr + sampler_name_suffix + array_expr);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks whether the ID is a row_major matrix that requires conversion before use
|
||||
@ -3110,7 +3119,7 @@ string CompilerMSL::entry_point_args(bool append_comma)
|
||||
case SPIRType::Sampler:
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args += "sampler " + r.name;
|
||||
ep_args += type_to_glsl(type) + " " + r.name;
|
||||
ep_args += " [[sampler(" + convert_to_string(r.index) + ")]]";
|
||||
break;
|
||||
case SPIRType::Image:
|
||||
@ -3215,6 +3224,15 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
|
||||
auto &type = expression_type(arg.id);
|
||||
bool constref = !arg.alias_global_variable && (!type.pointer || arg.write_count == 0);
|
||||
|
||||
bool type_is_image =
|
||||
type.basetype == SPIRType::Image ||
|
||||
type.basetype == SPIRType::SampledImage ||
|
||||
type.basetype == SPIRType::Sampler;
|
||||
|
||||
// Arrays of images/samplers in MSL are always const.
|
||||
if (!type.array.empty() && type_is_image)
|
||||
constref = true;
|
||||
|
||||
// TODO: Check if this arg is an uniform pointer
|
||||
bool pointer = type.storage == StorageClassUniformConstant;
|
||||
|
||||
@ -3227,7 +3245,8 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
|
||||
else
|
||||
decl += type_to_glsl(type, arg.id);
|
||||
|
||||
if (is_array(type))
|
||||
// Arrays of images and samplers are special cased.
|
||||
if (is_array(type) && !type_is_image)
|
||||
{
|
||||
decl += " (&";
|
||||
decl += to_expression(var.self);
|
||||
@ -3383,7 +3402,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
||||
return image_type_glsl(type, id);
|
||||
|
||||
case SPIRType::Sampler:
|
||||
return "sampler";
|
||||
return sampler_type(type);
|
||||
|
||||
case SPIRType::Void:
|
||||
return "void";
|
||||
@ -3435,9 +3454,44 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
||||
return type_name;
|
||||
}
|
||||
|
||||
std::string CompilerMSL::sampler_type(const SPIRType &type)
|
||||
{
|
||||
if (!type.array.empty())
|
||||
{
|
||||
// Arrays of samplers in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||
auto *parent = &type;
|
||||
while (parent->pointer)
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
|
||||
uint32_t array_size = type.array_size_literal.back() ?
|
||||
type.array.back() : get<SPIRConstant>(type.array.back()).scalar();
|
||||
|
||||
if (array_size == 0)
|
||||
SPIRV_CROSS_THROW("Unsized array of samplers is not supported in MSL.");
|
||||
return join("array<", sampler_type(*parent), ", ", array_size, ">");
|
||||
}
|
||||
else
|
||||
return "sampler";
|
||||
}
|
||||
|
||||
// Returns an MSL string describing the SPIR-V image type
|
||||
string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
{
|
||||
if (!type.array.empty())
|
||||
{
|
||||
// Arrays of images in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||
auto *parent = &type;
|
||||
while (parent->pointer)
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
parent = &get<SPIRType>(parent->parent_type);
|
||||
|
||||
uint32_t array_size = type.array_size_literal.back() ? type.array.back() : get<SPIRConstant>(type.array.back()).scalar();
|
||||
if (array_size == 0)
|
||||
SPIRV_CROSS_THROW("Unsized array of images is not supported in MSL.");
|
||||
return join("array<", image_type_glsl(*parent, id), ", ", array_size, ">");
|
||||
}
|
||||
|
||||
string img_type_name;
|
||||
|
||||
// Bypass pointers because we need the real image struct
|
||||
|
@ -202,6 +202,7 @@ protected:
|
||||
const std::string &qualifier = "", uint32_t base_offset = 0) 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 sampler_type(const SPIRType &type);
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) 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;
|
||||
|
Loading…
Reference in New Issue
Block a user