summaryrefslogtreecommitdiff
path: root/spirv_msl.hpp
diff options
context:
space:
mode:
authorChip Davis <chip@holochip.com>2022-08-13 16:55:34 -0700
committerChip Davis <chip@holochip.com>2022-09-09 17:06:34 -0700
commit064eaebe728f7c541face5ce865680b720fb4ff8 (patch)
treef6ab0af7405cd54108d329c558a3ff1abe857805 /spirv_msl.hpp
parent210a80013067672b52847ec7aa70ff78b2f4d77e (diff)
downloadSPIRV-Cross-064eaebe728f7c541face5ce865680b720fb4ff8.tar.gz
SPIRV-Cross-064eaebe728f7c541face5ce865680b720fb4ff8.tar.bz2
SPIRV-Cross-064eaebe728f7c541face5ce865680b720fb4ff8.zip
MSL: Add a mechanism to fix up shader outputs.
This is analogous to the existing support for fixing up shader inputs. It is intended to be used with tessellation to add implicit builtins that are read from a later stage, despite not being written in an earlier stage. (Believe it or not, this is in fact legal in Vulkan.) Helps fix 8 CTS tests under `dEQP-VK.pipeline.*.no_position`. (Eight other tests work solely by accident without this change.)
Diffstat (limited to 'spirv_msl.hpp')
-rw-r--r--spirv_msl.hpp67
1 files changed, 47 insertions, 20 deletions
diff --git a/spirv_msl.hpp b/spirv_msl.hpp
index c15159cf..4b9d88da 100644
--- a/spirv_msl.hpp
+++ b/spirv_msl.hpp
@@ -34,34 +34,39 @@
namespace SPIRV_CROSS_NAMESPACE
{
-// Indicates the format of a shader input. Currently limited to specifying
+// Indicates the format of a shader interface variable. Currently limited to specifying
// if the input is an 8-bit unsigned integer, 16-bit unsigned integer, or
// some other format.
-enum MSLShaderInputFormat
+enum MSLShaderVariableFormat
{
- MSL_SHADER_INPUT_FORMAT_OTHER = 0,
- MSL_SHADER_INPUT_FORMAT_UINT8 = 1,
- MSL_SHADER_INPUT_FORMAT_UINT16 = 2,
- MSL_SHADER_INPUT_FORMAT_ANY16 = 3,
- MSL_SHADER_INPUT_FORMAT_ANY32 = 4,
+ MSL_SHADER_VARIABLE_FORMAT_OTHER = 0,
+ MSL_SHADER_VARIABLE_FORMAT_UINT8 = 1,
+ MSL_SHADER_VARIABLE_FORMAT_UINT16 = 2,
+ MSL_SHADER_VARIABLE_FORMAT_ANY16 = 3,
+ MSL_SHADER_VARIABLE_FORMAT_ANY32 = 4,
// Deprecated aliases.
- MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_INPUT_FORMAT_OTHER,
- MSL_VERTEX_FORMAT_UINT8 = MSL_SHADER_INPUT_FORMAT_UINT8,
- MSL_VERTEX_FORMAT_UINT16 = MSL_SHADER_INPUT_FORMAT_UINT16,
-
- MSL_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff
+ MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_VARIABLE_FORMAT_OTHER,
+ MSL_VERTEX_FORMAT_UINT8 = MSL_SHADER_VARIABLE_FORMAT_UINT8,
+ MSL_VERTEX_FORMAT_UINT16 = MSL_SHADER_VARIABLE_FORMAT_UINT16,
+ MSL_SHADER_INPUT_FORMAT_OTHER = MSL_SHADER_VARIABLE_FORMAT_OTHER,
+ MSL_SHADER_INPUT_FORMAT_UINT8 = MSL_SHADER_VARIABLE_FORMAT_UINT8,
+ MSL_SHADER_INPUT_FORMAT_UINT16 = MSL_SHADER_VARIABLE_FORMAT_UINT16,
+ MSL_SHADER_INPUT_FORMAT_ANY16 = MSL_SHADER_VARIABLE_FORMAT_ANY16,
+ MSL_SHADER_INPUT_FORMAT_ANY32 = MSL_SHADER_VARIABLE_FORMAT_ANY32,
+
+ MSL_SHADER_VARIABLE_FORMAT_INT_MAX = 0x7fffffff
};
-// Defines MSL characteristics of an input variable at a particular location.
+// Defines MSL characteristics of a shader interface variable at a particular location.
// After compilation, it is possible to query whether or not this location was used.
// If vecsize is nonzero, it must be greater than or equal to the vecsize declared in the shader,
// or behavior is undefined.
-struct MSLShaderInput
+struct MSLShaderInterfaceVariable
{
uint32_t location = 0;
uint32_t component = 0;
- MSLShaderInputFormat format = MSL_SHADER_INPUT_FORMAT_OTHER;
+ MSLShaderVariableFormat format = MSL_SHADER_VARIABLE_FORMAT_OTHER;
spv::BuiltIn builtin = spv::BuiltInMax;
uint32_t vecsize = 0;
};
@@ -539,10 +544,15 @@ public:
explicit CompilerMSL(const ParsedIR &ir);
explicit CompilerMSL(ParsedIR &&ir);
- // input is a shader input description used to fix up shader input variables.
+ // input is a shader interface variable description used to fix up shader input variables.
// If shader inputs are provided, is_msl_shader_input_used() will return true after
- // calling ::compile() if the location was used by the MSL code.
- void add_msl_shader_input(const MSLShaderInput &input);
+ // calling ::compile() if the location were used by the MSL code.
+ void add_msl_shader_input(const MSLShaderInterfaceVariable &input);
+
+ // output is a shader interface variable description used to fix up shader output variables.
+ // If shader outputs are provided, is_msl_shader_output_used() will return true after
+ // calling ::compile() if the location were used by the MSL code.
+ void add_msl_shader_output(const MSLShaderInterfaceVariable &output);
// resource is a resource binding to indicate the MSL buffer,
// texture or sampler index to use for a particular SPIR-V description set
@@ -577,6 +587,9 @@ public:
// Query after compilation is done. This allows you to check if an input location was used by the shader.
bool is_msl_shader_input_used(uint32_t location);
+ // Query after compilation is done. This allows you to check if an output location were used by the shader.
+ bool is_msl_shader_output_used(uint32_t location);
+
// If not using add_msl_shader_input, it's possible
// that certain builtin attributes need to be automatically assigned locations.
// This is typical for tessellation builtin inputs such as tess levels, gl_Position, etc.
@@ -584,6 +597,13 @@ public:
// add_msl_shader_input or the builtin is not used, otherwise returns N in [[attribute(N)]].
uint32_t get_automatic_builtin_input_location(spv::BuiltIn builtin) const;
+ // If not using add_msl_shader_output, it's possible
+ // that certain builtin attributes need to be automatically assigned locations.
+ // This is typical for tessellation builtin outputs such as tess levels, gl_Position, etc.
+ // This returns k_unknown_location if the location were explicitly assigned with
+ // add_msl_shader_output or the builtin were not used, otherwise returns N in [[attribute(N)]].
+ uint32_t get_automatic_builtin_output_location(spv::BuiltIn builtin) const;
+
// NOTE: Only resources which are remapped using add_msl_resource_binding will be reported here.
// Constexpr samplers are always assumed to be emitted.
// No specific MSLResourceBinding remapping is required for constexpr samplers as long as they are remapped
@@ -894,6 +914,8 @@ protected:
uint32_t get_member_location(uint32_t type_id, uint32_t index, uint32_t *comp = nullptr) const;
uint32_t get_or_allocate_builtin_input_member_location(spv::BuiltIn builtin,
uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
+ uint32_t get_or_allocate_builtin_output_member_location(spv::BuiltIn builtin,
+ uint32_t type_id, uint32_t index, uint32_t *comp = nullptr);
uint32_t get_physical_tess_level_array_size(spv::BuiltIn builtin) const;
@@ -1004,12 +1026,17 @@ protected:
Options msl_options;
std::set<SPVFuncImpl> spv_function_implementations;
// Must be ordered to ensure declarations are in a specific order.
- std::map<LocationComponentPair, MSLShaderInput> inputs_by_location;
- std::unordered_map<uint32_t, MSLShaderInput> inputs_by_builtin;
+ std::map<LocationComponentPair, MSLShaderInterfaceVariable> inputs_by_location;
+ std::unordered_map<uint32_t, MSLShaderInterfaceVariable> inputs_by_builtin;
+ std::map<LocationComponentPair, MSLShaderInterfaceVariable> outputs_by_location;
+ std::unordered_map<uint32_t, MSLShaderInterfaceVariable> outputs_by_builtin;
std::unordered_set<uint32_t> location_inputs_in_use;
std::unordered_set<uint32_t> location_inputs_in_use_fallback;
+ std::unordered_set<uint32_t> location_outputs_in_use;
+ std::unordered_set<uint32_t> location_outputs_in_use_fallback;
std::unordered_map<uint32_t, uint32_t> fragment_output_components;
std::unordered_map<uint32_t, uint32_t> builtin_to_automatic_input_location;
+ std::unordered_map<uint32_t, uint32_t> builtin_to_automatic_output_location;
std::set<std::string> pragma_lines;
std::set<std::string> typedef_lines;
SmallVector<uint32_t> vars_needing_early_declaration;