Merge pull request #1516 from billhollings/VK_EXT_descriptor_indexing
MSL: Support run-time sized image and sampler arrays
This commit is contained in:
commit
244839d350
@ -10024,12 +10024,22 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
bool pointer = get<SPIRType>(result_type).pointer;
|
||||
|
||||
auto *chain = maybe_get<SPIRAccessChain>(rhs);
|
||||
auto *imgsamp = maybe_get<SPIRCombinedImageSampler>(rhs);
|
||||
if (chain)
|
||||
{
|
||||
// Cannot lower to a SPIRExpression, just copy the object.
|
||||
auto &e = set<SPIRAccessChain>(id, *chain);
|
||||
e.self = id;
|
||||
}
|
||||
else if (imgsamp)
|
||||
{
|
||||
// Cannot lower to a SPIRExpression, just copy the object.
|
||||
// GLSL does not currently use this type and will never get here, but MSL does.
|
||||
// Handled here instead of CompilerMSL for better integration and general handling,
|
||||
// and in case GLSL or other subclasses require it in the future.
|
||||
auto &e = set<SPIRCombinedImageSampler>(id, *imgsamp);
|
||||
e.self = id;
|
||||
}
|
||||
else if (expression_is_lvalue(rhs) && !pointer)
|
||||
{
|
||||
// Need a copy.
|
||||
|
@ -103,6 +103,16 @@ bool CompilerMSL::is_msl_resource_binding_used(ExecutionModel model, uint32_t de
|
||||
return itr != end(resource_bindings) && itr->second.second;
|
||||
}
|
||||
|
||||
// Returns the size of the array of resources used by the variable with the specified id.
|
||||
// The returned value is retrieved from the resource binding added using add_msl_resource_binding().
|
||||
uint32_t CompilerMSL::get_resource_array_size(uint32_t id) const
|
||||
{
|
||||
StageSetBinding tuple = { get_entry_point().model, get_decoration(id, DecorationDescriptorSet),
|
||||
get_decoration(id, DecorationBinding) };
|
||||
auto itr = resource_bindings.find(tuple);
|
||||
return itr != end(resource_bindings) ? itr->second.first.count : 0;
|
||||
}
|
||||
|
||||
uint32_t CompilerMSL::get_automatic_msl_resource_binding(uint32_t id) const
|
||||
{
|
||||
return get_extended_decoration(id, SPIRVCrossDecorationResourceIndexPrimary);
|
||||
@ -8136,7 +8146,7 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
|
||||
|
||||
// Manufacture automatic sampler arg for SampledImage texture
|
||||
if (arg_type.image.dim != DimBuffer)
|
||||
decl += join(", thread const ", sampler_type(arg_type), " ", to_sampler_expression(arg.id));
|
||||
decl += join(", thread const ", sampler_type(arg_type, arg.id), " ", to_sampler_expression(arg.id));
|
||||
}
|
||||
|
||||
// Manufacture automatic swizzle arg.
|
||||
@ -10449,7 +10459,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args)
|
||||
case SPIRType::Sampler:
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args += sampler_type(type) + " " + r.name;
|
||||
ep_args += sampler_type(type, var_id) + " " + r.name;
|
||||
ep_args += " [[sampler(" + convert_to_string(r.index) + ")]]";
|
||||
break;
|
||||
case SPIRType::Image:
|
||||
@ -11709,7 +11719,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
|
||||
return image_type_glsl(type, id);
|
||||
|
||||
case SPIRType::Sampler:
|
||||
return sampler_type(type);
|
||||
return sampler_type(type, id);
|
||||
|
||||
case SPIRType::Void:
|
||||
return "void";
|
||||
@ -11840,8 +11850,15 @@ std::string CompilerMSL::variable_decl(const SPIRType &type, const std::string &
|
||||
return CompilerGLSL::variable_decl(type, name, id);
|
||||
}
|
||||
|
||||
std::string CompilerMSL::sampler_type(const SPIRType &type)
|
||||
std::string CompilerMSL::sampler_type(const SPIRType &type, uint32_t id)
|
||||
{
|
||||
auto *var = maybe_get<SPIRVariable>(id);
|
||||
if (var && var->basevariable)
|
||||
{
|
||||
// Check against the base variable, and not a fake ID which might have been generated for this variable.
|
||||
id = var->basevariable;
|
||||
}
|
||||
|
||||
if (!type.array.empty())
|
||||
{
|
||||
if (!msl_options.supports_msl_version(2))
|
||||
@ -11851,12 +11868,16 @@ std::string CompilerMSL::sampler_type(const SPIRType &type)
|
||||
SPIRV_CROSS_THROW("Arrays of arrays of samplers are not supported in MSL.");
|
||||
|
||||
// Arrays of samplers in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||
// If we have a runtime array, it could be a variable-count descriptor set binding.
|
||||
uint32_t array_size = to_array_size_literal(type);
|
||||
if (array_size == 0)
|
||||
array_size = get_resource_array_size(id);
|
||||
|
||||
if (array_size == 0)
|
||||
SPIRV_CROSS_THROW("Unsized array of samplers is not supported in MSL.");
|
||||
|
||||
auto &parent = get<SPIRType>(get_pointee_type(type).parent_type);
|
||||
return join("array<", sampler_type(parent), ", ", array_size, ">");
|
||||
return join("array<", sampler_type(parent, id), ", ", array_size, ">");
|
||||
}
|
||||
else
|
||||
return "sampler";
|
||||
@ -11893,7 +11914,11 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
SPIRV_CROSS_THROW("Arrays of arrays of textures are not supported in MSL.");
|
||||
|
||||
// Arrays of images in MSL must be declared with a special array<T, N> syntax ala C++11 std::array.
|
||||
// If we have a runtime array, it could be a variable-count descriptor set binding.
|
||||
uint32_t array_size = to_array_size_literal(type);
|
||||
if (array_size == 0)
|
||||
array_size = get_resource_array_size(id);
|
||||
|
||||
if (array_size == 0)
|
||||
SPIRV_CROSS_THROW("Unsized array of images is not supported in MSL.");
|
||||
|
||||
|
@ -60,7 +60,11 @@ struct MSLShaderInput
|
||||
|
||||
// Matches the binding index of a MSL resource for a binding within a descriptor set.
|
||||
// Taken together, the stage, desc_set and binding combine to form a reference to a resource
|
||||
// descriptor used in a particular shading stage.
|
||||
// descriptor used in a particular shading stage. The count field indicates the number of
|
||||
// resources consumed by this binding, if the binding represents an array of resources.
|
||||
// If the resource array is a run-time-sized array, which are legal in GLSL or SPIR-V, this value
|
||||
// will be used to declare the array size in MSL, which does not support run-time-sized arrays.
|
||||
// For resources that are not held in a run-time-sized array, the count field does not need to be populated.
|
||||
// If using MSL 2.0 argument buffers, the descriptor set is not marked as a discrete descriptor set,
|
||||
// and (for iOS only) the resource is not a storage image (sampled != 2), the binding reference we
|
||||
// remap to will become an [[id(N)]] attribute within the "descriptor set" argument buffer structure.
|
||||
@ -71,6 +75,7 @@ struct MSLResourceBinding
|
||||
spv::ExecutionModel stage = spv::ExecutionModelMax;
|
||||
uint32_t desc_set = 0;
|
||||
uint32_t binding = 0;
|
||||
uint32_t count = 0;
|
||||
uint32_t msl_buffer = 0;
|
||||
uint32_t msl_texture = 0;
|
||||
uint32_t msl_sampler = 0;
|
||||
@ -672,7 +677,7 @@ protected:
|
||||
std::string variable_decl(const SPIRType &type, const std::string &name, 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 sampler_type(const SPIRType &type, uint32_t id);
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
||||
std::string to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_t id) override;
|
||||
std::string to_name(uint32_t id, bool allow_alias = true) const override;
|
||||
@ -756,6 +761,7 @@ protected:
|
||||
void emit_specialization_constants_and_structs();
|
||||
void emit_interface_block(uint32_t ib_var_id);
|
||||
bool maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs);
|
||||
uint32_t get_resource_array_size(uint32_t id) const;
|
||||
|
||||
void fix_up_shader_inputs_outputs();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user