Updated spirv-cross.

This commit is contained in:
Бранимир Караџић 2020-07-26 17:02:41 -07:00
parent fd71b4060d
commit 9e5e34f018
6 changed files with 901 additions and 218 deletions

View File

@ -558,6 +558,9 @@ struct CLIArguments
bool msl_enable_frag_stencil_ref_builtin = true;
uint32_t msl_enable_frag_output_mask = 0xffffffff;
bool msl_enable_clip_distance_user_varying = true;
bool msl_multi_patch_workgroup = false;
bool msl_vertex_for_tessellation = false;
uint32_t msl_additional_fixed_sample_mask = 0xffffffff;
bool glsl_emit_push_constant_as_ubo = false;
bool glsl_emit_ubo_as_plain_uniforms = false;
SmallVector<pair<uint32_t, uint32_t>> glsl_ext_framebuffer_fetch;
@ -747,9 +750,17 @@ static void print_help_msl()
"\t[--msl-enable-frag-output-mask <mask>]:\n\t\tOnly selectively enable fragment outputs. Useful if pipeline does not enable fragment output for certain locations, as pipeline creation might otherwise fail.\n"
"\t[--msl-no-clip-distance-user-varying]:\n\t\tDo not emit user varyings to emulate gl_ClipDistance in fragment shaders.\n"
"\t[--msl-shader-input <index> <format> <size>]:\n\t\tSpecify the format of the shader input at <index>.\n"
"\t\t<format> can be 'u16', 'u8', or 'other', to indicate a 16-bit unsigned integer, 8-bit unsigned integer, "
"\t\t<format> can be 'any32', 'any16', 'u16', 'u8', or 'other', to indicate a 32-bit opaque value, 16-bit opaque value, 16-bit unsigned integer, 8-bit unsigned integer, "
"or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader.\n"
"\t\tUseful if shader stage interfaces don't match up, as pipeline creation might otherwise fail.\n");
"\t\tUseful if shader stage interfaces don't match up, as pipeline creation might otherwise fail.\n"
"\t[--msl-multi-patch-workgroup]:\n\t\tUse the new style of tessellation control processing, where multiple patches are processed per workgroup.\n"
"\t\tThis should increase throughput by ensuring all the GPU's SIMD lanes are occupied, but it is not compatible with the old style.\n"
"\t\tIn addition, this style also passes input variables in buffers directly instead of using vertex attribute processing.\n"
"\t\tIn a future version of SPIRV-Cross, this will become the default.\n"
"\t[--msl-vertex-for-tessellation]:\n\t\tWhen handling a vertex shader, marks it as one that will be used with a new-style tessellation control shader.\n"
"\t\tThe vertex shader is output to MSL as a compute kernel which outputs vertices to the buffer in the order they are received, rather than in index order as with --msl-capture-output normally.\n"
"\t[--msl-additional-fixed-sample-mask <mask>]:\n"
"\t\tSet an additional fixed sample mask. If the shader outputs a sample mask, then the final sample mask will be a bitwise AND of the two.\n");
// clang-format on
}
@ -983,6 +994,9 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
msl_opts.enable_frag_stencil_ref_builtin = args.msl_enable_frag_stencil_ref_builtin;
msl_opts.enable_frag_output_mask = args.msl_enable_frag_output_mask;
msl_opts.enable_clip_distance_user_varying = args.msl_enable_clip_distance_user_varying;
msl_opts.multi_patch_workgroup = args.msl_multi_patch_workgroup;
msl_opts.vertex_for_tessellation = args.msl_vertex_for_tessellation;
msl_opts.additional_fixed_sample_mask = args.msl_additional_fixed_sample_mask;
msl_comp->set_msl_options(msl_opts);
for (auto &v : args.msl_discrete_descriptor_sets)
msl_comp->add_discrete_descriptor_set(v);
@ -1381,15 +1395,23 @@ static int main_inner(int argc, char *argv[])
// Make sure next_uint() is called in-order.
input.location = parser.next_uint();
const char *format = parser.next_value_string("other");
if (strcmp(format, "u16") == 0)
input.format = MSL_VERTEX_FORMAT_UINT16;
if (strcmp(format, "any32") == 0)
input.format = MSL_SHADER_INPUT_FORMAT_ANY32;
else if (strcmp(format, "any16") == 0)
input.format = MSL_SHADER_INPUT_FORMAT_ANY16;
else if (strcmp(format, "u16") == 0)
input.format = MSL_SHADER_INPUT_FORMAT_UINT16;
else if (strcmp(format, "u8") == 0)
input.format = MSL_VERTEX_FORMAT_UINT8;
input.format = MSL_SHADER_INPUT_FORMAT_UINT8;
else
input.format = MSL_VERTEX_FORMAT_OTHER;
input.format = MSL_SHADER_INPUT_FORMAT_OTHER;
input.vecsize = parser.next_uint();
args.msl_shader_inputs.push_back(input);
});
cbs.add("--msl-multi-patch-workgroup", [&args](CLIParser &) { args.msl_multi_patch_workgroup = true; });
cbs.add("--msl-vertex-for-tessellation", [&args](CLIParser &) { args.msl_vertex_for_tessellation = true; });
cbs.add("--msl-additional-fixed-sample-mask",
[&args](CLIParser &parser) { args.msl_additional_fixed_sample_mask = parser.next_hex_uint(); });
cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); });
cbs.add("--rename-entry-point", [&args](CLIParser &parser) {
auto old_name = parser.next_string();

View File

@ -1589,8 +1589,10 @@ enum ExtendedDecorations
// Marks a buffer block for using explicit offsets (GLSL/HLSL).
SPIRVCrossDecorationExplicitOffset,
// Apply to a variable in the Input storage class; marks it as holding the base group passed to vkCmdDispatchBase().
// In MSL, this is used to adjust the WorkgroupId and GlobalInvocationId variables.
// Apply to a variable in the Input storage class; marks it as holding the base group passed to vkCmdDispatchBase(),
// or the base vertex and instance indices passed to vkCmdDrawIndexed().
// In MSL, this is used to adjust the WorkgroupId and GlobalInvocationId variables in compute shaders,
// and to hold the BaseVertex and BaseInstance variables in vertex shaders.
SPIRVCrossDecorationBuiltInDispatchBase,
// Apply to a variable that is a function parameter; marks it as being a "dynamic"
@ -1599,6 +1601,20 @@ enum ExtendedDecorations
// Y'CbCr conversion.
SPIRVCrossDecorationDynamicImageSampler,
// Apply to a variable in the Input storage class; marks it as holding the size of the stage
// input grid.
// In MSL, this is used to hold the vertex and instance counts in a tessellation pipeline
// vertex shader.
SPIRVCrossDecorationBuiltInStageInputSize,
// Apply to any access chain of a tessellation I/O variable; stores the type of the sub-object
// that was chained to, as recorded in the input variable itself. This is used in case the pointer
// is itself used as the base of an access chain, to calculate the original type of the sub-object
// chained to, in case a swizzle needs to be applied. This should not happen normally with valid
// SPIR-V, but the MSL backend can change the type of input variables, necessitating the
// addition of swizzles to keep the generated code compiling.
SPIRVCrossDecorationTessIOOriginalInputTypeID,
SPIRVCrossDecorationCount
};

View File

@ -635,6 +635,26 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
case SPVC_COMPILER_OPTION_MSL_ENABLE_CLIP_DISTANCE_USER_VARYING:
options->msl.enable_clip_distance_user_varying = value != 0;
break;
case SPVC_COMPILER_OPTION_MSL_MULTI_PATCH_WORKGROUP:
options->msl.multi_patch_workgroup = value != 0;
break;
case SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_BUFFER_INDEX:
options->msl.shader_input_buffer_index = value;
break;
case SPVC_COMPILER_OPTION_MSL_SHADER_INDEX_BUFFER_INDEX:
options->msl.shader_index_buffer_index = value;
break;
case SPVC_COMPILER_OPTION_MSL_VERTEX_FOR_TESSELLATION:
options->msl.vertex_for_tessellation = value != 0;
break;
case SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE:
options->msl.vertex_index_type = static_cast<CompilerMSL::Options::IndexType>(value);
break;
#endif
default:

View File

@ -33,7 +33,7 @@ extern "C" {
/* Bumped if ABI or API breaks backwards compatibility. */
#define SPVC_C_API_VERSION_MAJOR 0
/* Bumped if APIs or enumerations are added in a backwards compatible way. */
#define SPVC_C_API_VERSION_MINOR 35
#define SPVC_C_API_VERSION_MINOR 36
/* Bumped if internal implementation details change. */
#define SPVC_C_API_VERSION_PATCH 0
@ -258,12 +258,23 @@ typedef enum spvc_msl_platform
SPVC_MSL_PLATFORM_MAX_INT = 0x7fffffff
} spvc_msl_platform;
/* Maps to C++ API. */
typedef enum spvc_msl_index_type
{
SPVC_MSL_INDEX_TYPE_NONE = 0,
SPVC_MSL_INDEX_TYPE_UINT16 = 1,
SPVC_MSL_INDEX_TYPE_UINT32 = 2,
SPVC_MSL_INDEX_TYPE_MAX_INT = 0x7fffffff
} spvc_msl_index_type;
/* Maps to C++ API. */
typedef enum spvc_msl_shader_input_format
{
SPVC_MSL_SHADER_INPUT_FORMAT_OTHER = 0,
SPVC_MSL_SHADER_INPUT_FORMAT_UINT8 = 1,
SPVC_MSL_SHADER_INPUT_FORMAT_UINT16 = 2,
SPVC_MSL_SHADER_INPUT_FORMAT_ANY16 = 3,
SPVC_MSL_SHADER_INPUT_FORMAT_ANY32 = 4,
/* Deprecated names. */
SPVC_MSL_VERTEX_FORMAT_OTHER = SPVC_MSL_SHADER_INPUT_FORMAT_OTHER,
@ -617,6 +628,12 @@ typedef enum spvc_compiler_option
SPVC_COMPILER_OPTION_HLSL_ENABLE_16BIT_TYPES = 60 | SPVC_COMPILER_OPTION_HLSL_BIT,
SPVC_COMPILER_OPTION_MSL_MULTI_PATCH_WORKGROUP = 61 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_BUFFER_INDEX = 62 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_MSL_SHADER_INDEX_BUFFER_INDEX = 63 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_MSL_VERTEX_FOR_TESSELLATION = 64 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE = 65 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
} spvc_compiler_option;

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,8 @@ enum MSLShaderInputFormat
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,
// Deprecated aliases.
MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_INPUT_FORMAT_OTHER,
@ -271,9 +273,15 @@ public:
uint32_t buffer_size_buffer_index = 25;
uint32_t view_mask_buffer_index = 24;
uint32_t dynamic_offsets_buffer_index = 23;
uint32_t shader_input_buffer_index = 22;
uint32_t shader_index_buffer_index = 21;
uint32_t shader_input_wg_index = 0;
uint32_t device_index = 0;
uint32_t enable_frag_output_mask = 0xffffffff;
// Metal doesn't allow setting a fixed sample mask directly in the pipeline.
// We can evade this restriction by ANDing the internal sample_mask output
// of the shader with the additional fixed sample mask.
uint32_t additional_fixed_sample_mask = 0xffffffff;
bool enable_point_size_builtin = true;
bool enable_frag_depth_builtin = true;
bool enable_frag_stencil_ref_builtin = true;
@ -329,6 +337,31 @@ public:
// can be read in subsequent stages.
bool enable_clip_distance_user_varying = true;
// In a tessellation control shader, assume that more than one patch can be processed in a
// single workgroup. This requires changes to the way the InvocationId and PrimitiveId
// builtins are processed, but should result in more efficient usage of the GPU.
bool multi_patch_workgroup = false;
// If set, a vertex shader will be compiled as part of a tessellation pipeline.
// It will be translated as a compute kernel, so it can use the global invocation ID
// to index the output buffer.
bool vertex_for_tessellation = false;
enum class IndexType
{
None = 0,
UInt16 = 1,
UInt32 = 2
};
// The type of index in the index buffer, if present. For a compute shader, Metal
// requires specifying the indexing at pipeline creation, rather than at draw time
// as with graphics pipelines. This means we must create three different pipelines,
// for no indexing, 16-bit indices, and 32-bit indices. Each requires different
// handling for the gl_VertexIndex builtin. We may as well, then, create three
// different shaders for these three scenarios.
IndexType vertex_index_type = IndexType::None;
bool is_ios() const
{
return platform == iOS;
@ -431,7 +464,7 @@ public:
// input is a shader input 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 &attr);
void add_msl_shader_input(const MSLShaderInput &input);
// resource is a resource binding to indicate the MSL buffer,
// texture or sampler index to use for a particular SPIR-V description set
@ -692,7 +725,7 @@ protected:
void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id);
void mark_location_as_used_by_shader(uint32_t location, spv::StorageClass storage);
void mark_location_as_used_by_shader(uint32_t location, const SPIRType &type, spv::StorageClass storage);
uint32_t ensure_correct_builtin_type(uint32_t type_id, spv::BuiltIn builtin);
uint32_t ensure_correct_input_type(uint32_t type_id, uint32_t location, uint32_t num_components = 0);
@ -716,6 +749,7 @@ protected:
std::string to_sampler_expression(uint32_t id);
std::string to_swizzle_expression(uint32_t id);
std::string to_buffer_size_expression(uint32_t id);
bool is_direct_input_builtin(spv::BuiltIn builtin);
std::string builtin_qualifier(spv::BuiltIn builtin);
std::string builtin_type_decl(spv::BuiltIn builtin, uint32_t id = 0);
std::string built_in_func_arg(spv::BuiltIn builtin, bool prefix_comma);
@ -738,7 +772,13 @@ protected:
uint32_t get_declared_struct_member_matrix_stride_msl(const SPIRType &struct_type, uint32_t index) const;
uint32_t get_declared_struct_member_alignment_msl(const SPIRType &struct_type, uint32_t index) const;
uint32_t get_declared_input_size_msl(const SPIRType &struct_type, uint32_t index) const;
uint32_t get_declared_input_array_stride_msl(const SPIRType &struct_type, uint32_t index) const;
uint32_t get_declared_input_matrix_stride_msl(const SPIRType &struct_type, uint32_t index) const;
uint32_t get_declared_input_alignment_msl(const SPIRType &struct_type, uint32_t index) const;
const SPIRType &get_physical_member_type(const SPIRType &struct_type, uint32_t index) const;
SPIRType get_presumed_input_type(const SPIRType &struct_type, uint32_t index) const;
uint32_t get_declared_struct_size_msl(const SPIRType &struct_type, bool ignore_alignment = false,
bool ignore_padding = false) const;
@ -757,6 +797,8 @@ protected:
SPIRType &get_patch_stage_in_struct_type();
SPIRType &get_patch_stage_out_struct_type();
std::string get_tess_factor_struct_name();
SPIRType &get_uint_type();
uint32_t get_uint_type_id();
void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, uint32_t mem_order_1,
uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0,
bool op1_is_pointer = false, bool op1_is_literal = false, uint32_t op2 = 0);
@ -771,6 +813,7 @@ protected:
void emit_entry_point_declarations() override;
uint32_t builtin_frag_coord_id = 0;
uint32_t builtin_sample_id_id = 0;
uint32_t builtin_sample_mask_id = 0;
uint32_t builtin_vertex_idx_id = 0;
uint32_t builtin_base_vertex_id = 0;
uint32_t builtin_instance_idx_id = 0;
@ -782,10 +825,14 @@ protected:
uint32_t builtin_subgroup_invocation_id_id = 0;
uint32_t builtin_subgroup_size_id = 0;
uint32_t builtin_dispatch_base_id = 0;
uint32_t builtin_stage_input_size_id = 0;
uint32_t swizzle_buffer_id = 0;
uint32_t buffer_size_buffer_id = 0;
uint32_t view_mask_buffer_id = 0;
uint32_t dynamic_offsets_buffer_id = 0;
uint32_t uint_type_id = 0;
bool does_shader_write_sample_mask = false;
void bitcast_to_builtin_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override;
void bitcast_from_builtin_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override;
@ -807,7 +854,8 @@ protected:
Options msl_options;
std::set<SPVFuncImpl> spv_function_implementations;
std::unordered_map<uint32_t, MSLShaderInput> inputs_by_location;
// Must be ordered to ensure declarations are in a specific order.
std::map<uint32_t, MSLShaderInput> inputs_by_location;
std::unordered_map<uint32_t, MSLShaderInput> inputs_by_builtin;
std::unordered_set<uint32_t> inputs_in_use;
std::unordered_map<uint32_t, uint32_t> fragment_output_components;
@ -862,9 +910,11 @@ protected:
std::string buffer_size_name_suffix = "BufferSize";
std::string plane_name_suffix = "Plane";
std::string input_wg_var_name = "gl_in";
std::string input_buffer_var_name = "spvIn";
std::string output_buffer_var_name = "spvOut";
std::string patch_output_buffer_var_name = "spvPatchOut";
std::string tess_factor_buffer_var_name = "spvTessLevel";
std::string index_buffer_var_name = "spvIndices";
spv::Op previous_instruction_opcode = spv::OpNop;
// Must be ordered since declaration is in a specific order.