Updated spirv-cross.
This commit is contained in:
parent
765b7b02eb
commit
248d56709e
13
3rdparty/spirv-cross/main.cpp
vendored
13
3rdparty/spirv-cross/main.cpp
vendored
@ -549,6 +549,7 @@ struct CLIArguments
|
||||
bool msl_invariant_float_math = false;
|
||||
bool msl_emulate_cube_array = false;
|
||||
bool msl_multiview = false;
|
||||
bool msl_multiview_layered_rendering = true;
|
||||
bool msl_view_index_from_device_index = false;
|
||||
bool msl_dispatch_base = false;
|
||||
bool msl_decoration_binding = false;
|
||||
@ -561,6 +562,7 @@ struct CLIArguments
|
||||
bool msl_multi_patch_workgroup = false;
|
||||
bool msl_vertex_for_tessellation = false;
|
||||
uint32_t msl_additional_fixed_sample_mask = 0xffffffff;
|
||||
bool msl_arrayed_subpass_input = false;
|
||||
bool glsl_emit_push_constant_as_ubo = false;
|
||||
bool glsl_emit_ubo_as_plain_uniforms = false;
|
||||
bool glsl_force_flattened_io_blocks = false;
|
||||
@ -732,6 +734,8 @@ static void print_help_msl()
|
||||
"\t[--msl-device-argument-buffer <descriptor set index>]:\n\t\tUse device address space to hold indirect argument buffers instead of constant.\n"
|
||||
"\t\tComes up when trying to support argument buffers which are larger than 64 KiB.\n"
|
||||
"\t[--msl-multiview]:\n\t\tEnable SPV_KHR_multiview emulation.\n"
|
||||
"\t[--msl-multiview-no-layered-rendering]:\n\t\tDon't set [[render_target_array_index]] in multiview shaders.\n"
|
||||
"\t\tUseful for devices which don't support layered rendering. Only effective when --msl-multiview is enabled.\n"
|
||||
"\t[--msl-view-index-from-device-index]:\n\t\tTreat the view index as the device index instead.\n"
|
||||
"\t\tFor multi-GPU rendering.\n"
|
||||
"\t[--msl-dispatch-base]:\n\t\tAdd support for vkCmdDispatchBase() or similar APIs.\n"
|
||||
@ -762,7 +766,9 @@ static void print_help_msl()
|
||||
"\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");
|
||||
"\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"
|
||||
"\t[--msl-arrayed-subpass-input]:\n\t\tAssume that images of dimension SubpassData have multiple layers. Layered input attachments are accessed relative to BuiltInLayer.\n"
|
||||
"\t\tThis option has no effect if multiview is also enabled.\n");
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
@ -987,6 +993,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
||||
msl_opts.argument_buffers = args.msl_argument_buffers;
|
||||
msl_opts.texture_buffer_native = args.msl_texture_buffer_native;
|
||||
msl_opts.multiview = args.msl_multiview;
|
||||
msl_opts.multiview_layered_rendering = args.msl_multiview_layered_rendering;
|
||||
msl_opts.view_index_from_device_index = args.msl_view_index_from_device_index;
|
||||
msl_opts.dispatch_base = args.msl_dispatch_base;
|
||||
msl_opts.enable_decoration_binding = args.msl_decoration_binding;
|
||||
@ -999,6 +1006,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
||||
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_opts.arrayed_subpass_input = args.msl_arrayed_subpass_input;
|
||||
msl_comp->set_msl_options(msl_opts);
|
||||
for (auto &v : args.msl_discrete_descriptor_sets)
|
||||
msl_comp->add_discrete_descriptor_set(v);
|
||||
@ -1366,6 +1374,8 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--msl-invariant-float-math", [&args](CLIParser &) { args.msl_invariant_float_math = true; });
|
||||
cbs.add("--msl-emulate-cube-array", [&args](CLIParser &) { args.msl_emulate_cube_array = true; });
|
||||
cbs.add("--msl-multiview", [&args](CLIParser &) { args.msl_multiview = true; });
|
||||
cbs.add("--msl-multiview-no-layered-rendering",
|
||||
[&args](CLIParser &) { args.msl_multiview_layered_rendering = false; });
|
||||
cbs.add("--msl-view-index-from-device-index",
|
||||
[&args](CLIParser &) { args.msl_view_index_from_device_index = true; });
|
||||
cbs.add("--msl-dispatch-base", [&args](CLIParser &) { args.msl_dispatch_base = true; });
|
||||
@ -1416,6 +1426,7 @@ static int main_inner(int argc, char *argv[])
|
||||
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("--msl-arrayed-subpass-input", [&args](CLIParser &) { args.msl_arrayed_subpass_input = true; });
|
||||
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();
|
||||
|
8
3rdparty/spirv-cross/spirv_cross_c.cpp
vendored
8
3rdparty/spirv-cross/spirv_cross_c.cpp
vendored
@ -658,6 +658,14 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE:
|
||||
options->msl.vertex_index_type = static_cast<CompilerMSL::Options::IndexType>(value);
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_MULTIVIEW_LAYERED_RENDERING:
|
||||
options->msl.multiview_layered_rendering = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_ARRAYED_SUBPASS_INPUT:
|
||||
options->msl.arrayed_subpass_input = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
5
3rdparty/spirv-cross/spirv_cross_c.h
vendored
5
3rdparty/spirv-cross/spirv_cross_c.h
vendored
@ -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 37
|
||||
#define SPVC_C_API_VERSION_MINOR 39
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
@ -636,6 +636,9 @@ typedef enum spvc_compiler_option
|
||||
|
||||
SPVC_COMPILER_OPTION_GLSL_FORCE_FLATTENED_IO_BLOCKS = 66 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_MULTIVIEW_LAYERED_RENDERING = 67 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
SPVC_COMPILER_OPTION_MSL_ARRAYED_SUBPASS_INPUT = 68 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
|
15
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
15
3rdparty/spirv-cross/spirv_glsl.cpp
vendored
@ -2881,11 +2881,16 @@ void CompilerGLSL::declare_undefined_values()
|
||||
{
|
||||
bool emitted = false;
|
||||
ir.for_each_typed_id<SPIRUndef>([&](uint32_t, const SPIRUndef &undef) {
|
||||
auto &type = this->get<SPIRType>(undef.basetype);
|
||||
// OpUndef can be void for some reason ...
|
||||
if (type.basetype == SPIRType::Void)
|
||||
return;
|
||||
|
||||
string initializer;
|
||||
if (options.force_zero_initialized_variables && type_can_zero_initialize(this->get<SPIRType>(undef.basetype)))
|
||||
if (options.force_zero_initialized_variables && type_can_zero_initialize(type))
|
||||
initializer = join(" = ", to_zero_initialized_expression(undef.basetype));
|
||||
|
||||
statement(variable_decl(this->get<SPIRType>(undef.basetype), to_name(undef.self), undef.self), initializer,
|
||||
statement(variable_decl(type, to_name(undef.self), undef.self), initializer,
|
||||
";");
|
||||
emitted = true;
|
||||
});
|
||||
@ -9280,7 +9285,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
statement(declare_temporary(result_type, id), to_expression(vec), ";");
|
||||
set<SPIRExpression>(id, to_name(id), result_type, true);
|
||||
auto chain = access_chain_internal(id, &index, 1, 0, nullptr);
|
||||
statement(chain, " = ", to_expression(comp), ";");
|
||||
statement(chain, " = ", to_unpacked_expression(comp), ";");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -9382,7 +9387,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
statement(declare_temporary(result_type, id), to_expression(composite), ";");
|
||||
set<SPIRExpression>(id, to_name(id), result_type, true);
|
||||
auto chain = access_chain_internal(id, elems, length, ACCESS_CHAIN_INDEX_IS_LITERAL_BIT, nullptr);
|
||||
statement(chain, " = ", to_expression(obj), ";");
|
||||
statement(chain, " = ", to_unpacked_expression(obj), ";");
|
||||
|
||||
break;
|
||||
}
|
||||
@ -9395,7 +9400,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
||||
{
|
||||
flush_variable_declaration(lhs);
|
||||
flush_variable_declaration(rhs);
|
||||
statement(to_expression(lhs), " = ", to_expression(rhs), ";");
|
||||
statement(to_expression(lhs), " = ", to_unpacked_expression(rhs), ";");
|
||||
register_write(lhs);
|
||||
}
|
||||
break;
|
||||
|
9
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
9
3rdparty/spirv-cross/spirv_hlsl.cpp
vendored
@ -1220,11 +1220,16 @@ void CompilerHLSL::declare_undefined_values()
|
||||
{
|
||||
bool emitted = false;
|
||||
ir.for_each_typed_id<SPIRUndef>([&](uint32_t, const SPIRUndef &undef) {
|
||||
auto &type = this->get<SPIRType>(undef.basetype);
|
||||
// OpUndef can be void for some reason ...
|
||||
if (type.basetype == SPIRType::Void)
|
||||
return;
|
||||
|
||||
string initializer;
|
||||
if (options.force_zero_initialized_variables && type_can_zero_initialize(this->get<SPIRType>(undef.basetype)))
|
||||
if (options.force_zero_initialized_variables && type_can_zero_initialize(type))
|
||||
initializer = join(" = ", to_zero_initialized_expression(undef.basetype));
|
||||
|
||||
statement("static ", variable_decl(this->get<SPIRType>(undef.basetype), to_name(undef.self), undef.self),
|
||||
statement("static ", variable_decl(type, to_name(undef.self), undef.self),
|
||||
initializer, ";");
|
||||
emitted = true;
|
||||
});
|
||||
|
211
3rdparty/spirv-cross/spirv_msl.cpp
vendored
211
3rdparty/spirv-cross/spirv_msl.cpp
vendored
@ -146,6 +146,7 @@ void CompilerMSL::build_implicit_builtins()
|
||||
bool need_subgroup_ge_mask = !msl_options.is_ios() && (active_input_builtins.get(BuiltInSubgroupGeMask) ||
|
||||
active_input_builtins.get(BuiltInSubgroupGtMask));
|
||||
bool need_multiview = get_execution_model() == ExecutionModelVertex && !msl_options.view_index_from_device_index &&
|
||||
msl_options.multiview_layered_rendering &&
|
||||
(msl_options.multiview || active_input_builtins.get(BuiltInViewIndex));
|
||||
bool need_dispatch_base =
|
||||
msl_options.dispatch_base && get_execution_model() == ExecutionModelGLCompute &&
|
||||
@ -172,6 +173,7 @@ void CompilerMSL::build_implicit_builtins()
|
||||
bool has_subgroup_invocation_id = false;
|
||||
bool has_subgroup_size = false;
|
||||
bool has_view_idx = false;
|
||||
bool has_layer = false;
|
||||
uint32_t workgroup_id_type = 0;
|
||||
|
||||
// FIXME: Investigate the fact that there are no checks for the entry point interface variables.
|
||||
@ -195,12 +197,32 @@ void CompilerMSL::build_implicit_builtins()
|
||||
if (var.storage != StorageClassInput)
|
||||
return;
|
||||
|
||||
if (need_subpass_input && (!msl_options.is_ios() || !msl_options.ios_use_framebuffer_fetch_subpasses) &&
|
||||
builtin == BuiltInFragCoord)
|
||||
if (need_subpass_input && (!msl_options.is_ios() || !msl_options.ios_use_framebuffer_fetch_subpasses))
|
||||
{
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInFragCoord, var.self);
|
||||
builtin_frag_coord_id = var.self;
|
||||
has_frag_coord = true;
|
||||
switch (builtin)
|
||||
{
|
||||
case BuiltInFragCoord:
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInFragCoord, var.self);
|
||||
builtin_frag_coord_id = var.self;
|
||||
has_frag_coord = true;
|
||||
break;
|
||||
case BuiltInLayer:
|
||||
if (!msl_options.arrayed_subpass_input || msl_options.multiview)
|
||||
break;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInLayer, var.self);
|
||||
builtin_layer_id = var.self;
|
||||
has_layer = true;
|
||||
break;
|
||||
case BuiltInViewIndex:
|
||||
if (!msl_options.multiview)
|
||||
break;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInViewIndex, var.self);
|
||||
builtin_view_idx_id = var.self;
|
||||
has_view_idx = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_sample_pos && builtin == BuiltInSampleId)
|
||||
@ -282,6 +304,12 @@ void CompilerMSL::build_implicit_builtins()
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInInstanceIndex, var.self);
|
||||
has_instance_idx = true;
|
||||
break;
|
||||
case BuiltInBaseInstance:
|
||||
// If a non-zero base instance is used, we need to adjust for it when calculating the view index.
|
||||
builtin_base_instance_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInBaseInstance, var.self);
|
||||
has_base_instance = true;
|
||||
break;
|
||||
case BuiltInViewIndex:
|
||||
builtin_view_idx_id = var.self;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInViewIndex, var.self);
|
||||
@ -301,33 +329,79 @@ void CompilerMSL::build_implicit_builtins()
|
||||
});
|
||||
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
if (!has_frag_coord && (!msl_options.is_ios() || !msl_options.ios_use_framebuffer_fetch_subpasses) &&
|
||||
need_subpass_input)
|
||||
if ((!has_frag_coord || (msl_options.multiview && !has_view_idx) ||
|
||||
(msl_options.arrayed_subpass_input && !msl_options.multiview && !has_layer)) &&
|
||||
(!msl_options.is_ios() || !msl_options.ios_use_framebuffer_fetch_subpasses) && need_subpass_input)
|
||||
{
|
||||
uint32_t offset = ir.increase_bound_by(3);
|
||||
uint32_t type_id = offset;
|
||||
uint32_t type_ptr_id = offset + 1;
|
||||
uint32_t var_id = offset + 2;
|
||||
if (!has_frag_coord)
|
||||
{
|
||||
uint32_t offset = ir.increase_bound_by(3);
|
||||
uint32_t type_id = offset;
|
||||
uint32_t type_ptr_id = offset + 1;
|
||||
uint32_t var_id = offset + 2;
|
||||
|
||||
// Create gl_FragCoord.
|
||||
SPIRType vec4_type;
|
||||
vec4_type.basetype = SPIRType::Float;
|
||||
vec4_type.width = 32;
|
||||
vec4_type.vecsize = 4;
|
||||
set<SPIRType>(type_id, vec4_type);
|
||||
// Create gl_FragCoord.
|
||||
SPIRType vec4_type;
|
||||
vec4_type.basetype = SPIRType::Float;
|
||||
vec4_type.width = 32;
|
||||
vec4_type.vecsize = 4;
|
||||
set<SPIRType>(type_id, vec4_type);
|
||||
|
||||
SPIRType vec4_type_ptr;
|
||||
vec4_type_ptr = vec4_type;
|
||||
vec4_type_ptr.pointer = true;
|
||||
vec4_type_ptr.parent_type = type_id;
|
||||
vec4_type_ptr.storage = StorageClassInput;
|
||||
auto &ptr_type = set<SPIRType>(type_ptr_id, vec4_type_ptr);
|
||||
ptr_type.self = type_id;
|
||||
SPIRType vec4_type_ptr;
|
||||
vec4_type_ptr = vec4_type;
|
||||
vec4_type_ptr.pointer = true;
|
||||
vec4_type_ptr.parent_type = type_id;
|
||||
vec4_type_ptr.storage = StorageClassInput;
|
||||
auto &ptr_type = set<SPIRType>(type_ptr_id, vec4_type_ptr);
|
||||
ptr_type.self = type_id;
|
||||
|
||||
set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
|
||||
set_decoration(var_id, DecorationBuiltIn, BuiltInFragCoord);
|
||||
builtin_frag_coord_id = var_id;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInFragCoord, var_id);
|
||||
set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
|
||||
set_decoration(var_id, DecorationBuiltIn, BuiltInFragCoord);
|
||||
builtin_frag_coord_id = var_id;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInFragCoord, var_id);
|
||||
}
|
||||
|
||||
if (!has_layer && msl_options.arrayed_subpass_input && !msl_options.multiview)
|
||||
{
|
||||
uint32_t offset = ir.increase_bound_by(2);
|
||||
uint32_t type_ptr_id = offset;
|
||||
uint32_t var_id = offset + 1;
|
||||
|
||||
// Create gl_Layer.
|
||||
SPIRType uint_type_ptr;
|
||||
uint_type_ptr = get_uint_type();
|
||||
uint_type_ptr.pointer = true;
|
||||
uint_type_ptr.parent_type = get_uint_type_id();
|
||||
uint_type_ptr.storage = StorageClassInput;
|
||||
auto &ptr_type = set<SPIRType>(type_ptr_id, uint_type_ptr);
|
||||
ptr_type.self = get_uint_type_id();
|
||||
|
||||
set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
|
||||
set_decoration(var_id, DecorationBuiltIn, BuiltInLayer);
|
||||
builtin_layer_id = var_id;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInLayer, var_id);
|
||||
}
|
||||
|
||||
if (!has_view_idx && msl_options.multiview)
|
||||
{
|
||||
uint32_t offset = ir.increase_bound_by(2);
|
||||
uint32_t type_ptr_id = offset;
|
||||
uint32_t var_id = offset + 1;
|
||||
|
||||
// Create gl_ViewIndex.
|
||||
SPIRType uint_type_ptr;
|
||||
uint_type_ptr = get_uint_type();
|
||||
uint_type_ptr.pointer = true;
|
||||
uint_type_ptr.parent_type = get_uint_type_id();
|
||||
uint_type_ptr.storage = StorageClassInput;
|
||||
auto &ptr_type = set<SPIRType>(type_ptr_id, uint_type_ptr);
|
||||
ptr_type.self = get_uint_type_id();
|
||||
|
||||
set<SPIRVariable>(var_id, type_ptr_id, StorageClassInput);
|
||||
set_decoration(var_id, DecorationBuiltIn, BuiltInViewIndex);
|
||||
builtin_view_idx_id = var_id;
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInViewIndex, var_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_sample_id && need_sample_pos)
|
||||
@ -352,7 +426,7 @@ void CompilerMSL::build_implicit_builtins()
|
||||
}
|
||||
|
||||
if ((need_vertex_params && (!has_vertex_idx || !has_base_vertex || !has_instance_idx || !has_base_instance)) ||
|
||||
(need_multiview && (!has_instance_idx || !has_view_idx)))
|
||||
(need_multiview && (!has_instance_idx || !has_base_instance || !has_view_idx)))
|
||||
{
|
||||
uint32_t type_ptr_id = ir.increase_bound_by(1);
|
||||
|
||||
@ -397,7 +471,7 @@ void CompilerMSL::build_implicit_builtins()
|
||||
mark_implicit_builtin(StorageClassInput, BuiltInInstanceIndex, var_id);
|
||||
}
|
||||
|
||||
if (need_vertex_params && !has_base_instance)
|
||||
if (!has_base_instance) // Needed by both multiview and tessellation
|
||||
{
|
||||
uint32_t var_id = ir.increase_bound_by(1);
|
||||
|
||||
@ -1303,6 +1377,18 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std::
|
||||
// Implicitly reads gl_FragCoord.
|
||||
assert(builtin_frag_coord_id != 0);
|
||||
added_arg_ids.insert(builtin_frag_coord_id);
|
||||
if (msl_options.multiview)
|
||||
{
|
||||
// Implicitly reads gl_ViewIndex.
|
||||
assert(builtin_view_idx_id != 0);
|
||||
added_arg_ids.insert(builtin_view_idx_id);
|
||||
}
|
||||
else if (msl_options.arrayed_subpass_input)
|
||||
{
|
||||
// Implicitly reads gl_Layer.
|
||||
assert(builtin_layer_id != 0);
|
||||
added_arg_ids.insert(builtin_layer_id);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@ -3904,7 +3990,7 @@ void CompilerMSL::emit_custom_templates()
|
||||
// otherwise they will cause problems when linked together in a single Metallib.
|
||||
void CompilerMSL::emit_custom_functions()
|
||||
{
|
||||
for (uint32_t i = SPVFuncImplArrayCopyMultidimMax; i >= 2; i--)
|
||||
for (uint32_t i = kArrayCopyMultidimMax; i >= 2; i--)
|
||||
if (spv_function_implementations.count(static_cast<SPVFuncImpl>(SPVFuncImplArrayCopyMultidimBase + i)))
|
||||
spv_function_implementations.insert(static_cast<SPVFuncImpl>(SPVFuncImplArrayCopyMultidimBase + i - 1));
|
||||
|
||||
@ -5339,6 +5425,10 @@ void CompilerMSL::declare_undefined_values()
|
||||
bool emitted = false;
|
||||
ir.for_each_typed_id<SPIRUndef>([&](uint32_t, SPIRUndef &undef) {
|
||||
auto &type = this->get<SPIRType>(undef.basetype);
|
||||
// OpUndef can be void for some reason ...
|
||||
if (type.basetype == SPIRType::Void)
|
||||
return;
|
||||
|
||||
statement("constant ", variable_decl(type, to_name(undef.self), undef.self), " = {};");
|
||||
emitted = true;
|
||||
});
|
||||
@ -7198,7 +7288,7 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t rhs_id, StorageCla
|
||||
// if this is the only use of array copies in our shader.
|
||||
if (type.array.size() > 1)
|
||||
{
|
||||
if (type.array.size() > SPVFuncImplArrayCopyMultidimMax)
|
||||
if (type.array.size() > kArrayCopyMultidimMax)
|
||||
SPIRV_CROSS_THROW("Cannot support this many dimensions for arrays of arrays.");
|
||||
auto func = static_cast<SPVFuncImpl>(SPVFuncImplArrayCopyMultidimBase + type.array.size());
|
||||
add_spv_func_and_recompile(func);
|
||||
@ -8100,10 +8190,8 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
case DimSubpassData:
|
||||
// If we're using Metal's native frame-buffer fetch API for subpass inputs,
|
||||
// this path will not be hit.
|
||||
if (imgtype.image.ms)
|
||||
tex_coords = "uint2(gl_FragCoord.xy)";
|
||||
else
|
||||
tex_coords = join("uint2(gl_FragCoord.xy), 0");
|
||||
tex_coords = "uint2(gl_FragCoord.xy)";
|
||||
alt_coord_component = 2;
|
||||
break;
|
||||
|
||||
case Dim2D:
|
||||
@ -8220,12 +8308,30 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
{
|
||||
// Special case for cube arrays, face and layer are packed in one dimension.
|
||||
if (imgtype.image.dim == DimCube && args.base.is_fetch)
|
||||
{
|
||||
farg_str += ", uint(" + to_extract_component_expression(args.coord, 2) + ") / 6u";
|
||||
}
|
||||
else
|
||||
{
|
||||
farg_str +=
|
||||
", uint(" +
|
||||
round_fp_tex_coords(to_extract_component_expression(args.coord, alt_coord_component), coord_is_fp) +
|
||||
")";
|
||||
if (imgtype.image.dim == DimSubpassData)
|
||||
{
|
||||
if (msl_options.multiview)
|
||||
farg_str += " + gl_ViewIndex";
|
||||
else if (msl_options.arrayed_subpass_input)
|
||||
farg_str += " + gl_Layer";
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (imgtype.image.dim == DimSubpassData)
|
||||
{
|
||||
if (msl_options.multiview)
|
||||
farg_str += ", gl_ViewIndex";
|
||||
else if (msl_options.arrayed_subpass_input)
|
||||
farg_str += ", gl_Layer";
|
||||
}
|
||||
}
|
||||
|
||||
@ -9236,7 +9342,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
|
||||
switch (builtin)
|
||||
{
|
||||
case BuiltInViewIndex:
|
||||
if (!msl_options.multiview)
|
||||
if (!msl_options.multiview || !msl_options.multiview_layered_rendering)
|
||||
break;
|
||||
/* fallthrough */
|
||||
case BuiltInFrontFacing:
|
||||
@ -9654,7 +9760,8 @@ bool CompilerMSL::is_direct_input_builtin(BuiltIn bi_type)
|
||||
case BuiltInBaryCoordNoPerspNV:
|
||||
return false;
|
||||
case BuiltInViewIndex:
|
||||
return get_execution_model() == ExecutionModelFragment && msl_options.multiview;
|
||||
return get_execution_model() == ExecutionModelFragment && msl_options.multiview &&
|
||||
msl_options.multiview_layered_rendering;
|
||||
// Any stage function in
|
||||
case BuiltInDeviceIndex:
|
||||
case BuiltInSubgroupEqMask:
|
||||
@ -10424,6 +10531,15 @@ void CompilerMSL::fix_up_shader_inputs_outputs()
|
||||
// Since every physical device is rendering a different view,
|
||||
// there's no need for layered rendering here.
|
||||
}
|
||||
else if (!msl_options.multiview_layered_rendering)
|
||||
{
|
||||
// In this case, the views are rendered one at a time. The view index, then,
|
||||
// is just the first part of the "view mask".
|
||||
entry_func.fixup_hooks_in.push_back([=]() {
|
||||
statement("const ", builtin_type_decl(bi_type), " ", to_expression(var_id), " = ",
|
||||
to_expression(view_mask_buffer_id), "[0];");
|
||||
});
|
||||
}
|
||||
else if (get_execution_model() == ExecutionModelFragment)
|
||||
{
|
||||
// Because we adjusted the view index in the vertex shader, we have to
|
||||
@ -10438,10 +10554,13 @@ void CompilerMSL::fix_up_shader_inputs_outputs()
|
||||
// the view index in the instance index.
|
||||
entry_func.fixup_hooks_in.push_back([=]() {
|
||||
statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = ",
|
||||
to_expression(view_mask_buffer_id), "[0] + ", to_expression(builtin_instance_idx_id),
|
||||
" % ", to_expression(view_mask_buffer_id), "[1];");
|
||||
statement(to_expression(builtin_instance_idx_id), " /= ", to_expression(view_mask_buffer_id),
|
||||
"[1];");
|
||||
to_expression(view_mask_buffer_id), "[0] + (", to_expression(builtin_instance_idx_id),
|
||||
" - ", to_expression(builtin_base_instance_id), ") % ",
|
||||
to_expression(view_mask_buffer_id), "[1];");
|
||||
statement(to_expression(builtin_instance_idx_id), " = (",
|
||||
to_expression(builtin_instance_idx_id), " - ",
|
||||
to_expression(builtin_base_instance_id), ") / ", to_expression(view_mask_buffer_id),
|
||||
"[1] + ", to_expression(builtin_base_instance_id), ";");
|
||||
});
|
||||
// In addition to setting the variable itself, we also need to
|
||||
// set the render_target_array_index with it on output. We have to
|
||||
@ -11556,6 +11675,9 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
case Dim1D:
|
||||
case Dim2D:
|
||||
case DimSubpassData:
|
||||
{
|
||||
bool subpass_array =
|
||||
img_type.dim == DimSubpassData && (msl_options.multiview || msl_options.arrayed_subpass_input);
|
||||
if (img_type.dim == Dim1D && !msl_options.texture_1D_as_2D)
|
||||
{
|
||||
// Use a native Metal 1D texture
|
||||
@ -11570,7 +11692,7 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
img_type_4.vecsize = 4;
|
||||
return type_to_glsl(img_type_4);
|
||||
}
|
||||
if (img_type.ms && img_type.arrayed)
|
||||
if (img_type.ms && (img_type.arrayed || subpass_array))
|
||||
{
|
||||
if (!msl_options.supports_msl_version(2, 1))
|
||||
SPIRV_CROSS_THROW("Multisampled array textures are supported from 2.1.");
|
||||
@ -11578,11 +11700,12 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
}
|
||||
else if (img_type.ms)
|
||||
img_type_name += "texture2d_ms";
|
||||
else if (img_type.arrayed)
|
||||
else if (img_type.arrayed || subpass_array)
|
||||
img_type_name += "texture2d_array";
|
||||
else
|
||||
img_type_name += "texture2d";
|
||||
break;
|
||||
}
|
||||
case Dim3D:
|
||||
img_type_name += "texture3d";
|
||||
break;
|
||||
|
12
3rdparty/spirv-cross/spirv_msl.hpp
vendored
12
3rdparty/spirv-cross/spirv_msl.hpp
vendored
@ -249,6 +249,9 @@ static const uint32_t kArgumentBufferBinding = ~(3u);
|
||||
|
||||
static const uint32_t kMaxArgumentBuffers = 8;
|
||||
|
||||
// The arbitrary maximum for the nesting of array of array copies.
|
||||
static const uint32_t kArrayCopyMultidimMax = 6;
|
||||
|
||||
// Decompiles SPIR-V to Metal Shading Language
|
||||
class CompilerMSL : public CompilerGLSL
|
||||
{
|
||||
@ -290,6 +293,7 @@ public:
|
||||
bool swizzle_texture_samples = false;
|
||||
bool tess_domain_origin_lower_left = false;
|
||||
bool multiview = false;
|
||||
bool multiview_layered_rendering = true;
|
||||
bool view_index_from_device_index = false;
|
||||
bool dispatch_base = false;
|
||||
bool texture_1D_as_2D = false;
|
||||
@ -347,6 +351,12 @@ public:
|
||||
// to index the output buffer.
|
||||
bool vertex_for_tessellation = false;
|
||||
|
||||
// Assume that SubpassData images have multiple layers. Layered input attachments
|
||||
// are addressed relative to the Layer output from the vertex pipeline. This option
|
||||
// has no effect with multiview, since all input attachments are assumed to be layered
|
||||
// and will be addressed using the current ViewIndex.
|
||||
bool arrayed_subpass_input = false;
|
||||
|
||||
enum class IndexType
|
||||
{
|
||||
None = 0,
|
||||
@ -614,8 +624,6 @@ protected:
|
||||
SPVFuncImplConvertYCbCrBT601,
|
||||
SPVFuncImplConvertYCbCrBT2020,
|
||||
SPVFuncImplDynamicImageSampler,
|
||||
|
||||
SPVFuncImplArrayCopyMultidimMax = 6
|
||||
};
|
||||
|
||||
// If the underlying resource has been used for comparison then duplicate loads of that resource must be too
|
||||
|
2
3rdparty/spirv-cross/spirv_reflect.cpp
vendored
2
3rdparty/spirv-cross/spirv_reflect.cpp
vendored
@ -647,7 +647,7 @@ void CompilerReflection::emit_specialization_constants()
|
||||
return;
|
||||
|
||||
json_stream->emit_json_key_array("specialization_constants");
|
||||
for (const auto spec_const : specialization_constants)
|
||||
for (const auto &spec_const : specialization_constants)
|
||||
{
|
||||
auto &c = get<SPIRConstant>(spec_const.id);
|
||||
auto type = get<SPIRType>(c.constant_type);
|
||||
|
Loading…
Reference in New Issue
Block a user