Merge pull request #2076 from billhollings/ios-tier2-writable-images

MSL: Add support for writable images in iOS Tier2 argument buffers.
This commit is contained in:
Hans-Kristian Arntzen 2023-01-09 11:52:29 +01:00 committed by GitHub
commit cded61dde3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 15 deletions

View File

@ -332,7 +332,7 @@ if (SPIRV_CROSS_STATIC)
endif() endif()
set(spirv-cross-abi-major 0) set(spirv-cross-abi-major 0)
set(spirv-cross-abi-minor 53) set(spirv-cross-abi-minor 54)
set(spirv-cross-abi-patch 0) set(spirv-cross-abi-patch 0)
if (SPIRV_CROSS_SHARED) if (SPIRV_CROSS_SHARED)

View File

@ -645,6 +645,7 @@ struct CLIArguments
bool msl_pad_fragment_output = false; bool msl_pad_fragment_output = false;
bool msl_domain_lower_left = false; bool msl_domain_lower_left = false;
bool msl_argument_buffers = false; bool msl_argument_buffers = false;
uint32_t msl_argument_buffers_tier = 0; // Tier 1
bool msl_texture_buffer_native = false; bool msl_texture_buffer_native = false;
bool msl_framebuffer_fetch = false; bool msl_framebuffer_fetch = false;
bool msl_invariant_float_math = false; bool msl_invariant_float_math = false;
@ -856,8 +857,11 @@ static void print_help_msl()
"\t[--msl-pad-fragment-output]:\n\t\tAlways emit color outputs as 4-component variables.\n" "\t[--msl-pad-fragment-output]:\n\t\tAlways emit color outputs as 4-component variables.\n"
"\t\tIn Metal, the fragment shader must emit at least as many components as the render target format.\n" "\t\tIn Metal, the fragment shader must emit at least as many components as the render target format.\n"
"\t[--msl-domain-lower-left]:\n\t\tUse a lower-left tessellation domain.\n" "\t[--msl-domain-lower-left]:\n\t\tUse a lower-left tessellation domain.\n"
"\t[--msl-argument-buffers]:\n\t\tEmit Indirect Argument buffers instead of plain bindings.\n" "\t[--msl-argument-buffers]:\n\t\tEmit Metal argument buffers instead of discrete resource bindings.\n"
"\t\tRequires MSL 2.0 to be enabled.\n" "\t\tRequires MSL 2.0 to be enabled.\n"
"\t[--msl-argument-buffers-tier]:\n\t\tWhen using Metal argument buffers, indicate the Metal argument buffer tier level supported by the Metal platform.\n"
"\t\tUses same values as Metal MTLArgumentBuffersTier enumeration (0 = Tier1, 1 = Tier2).\n"
"\t\tSetting this value also enables msl-argument-buffers.\n"
"\t[--msl-texture-buffer-native]:\n\t\tEnable native support for texel buffers. Otherwise, it is emulated as a normal texture.\n" "\t[--msl-texture-buffer-native]:\n\t\tEnable native support for texel buffers. Otherwise, it is emulated as a normal texture.\n"
"\t[--msl-framebuffer-fetch]:\n\t\tImplement subpass inputs with frame buffer fetch.\n" "\t[--msl-framebuffer-fetch]:\n\t\tImplement subpass inputs with frame buffer fetch.\n"
"\t\tEmits [[color(N)]] inputs in fragment stage.\n" "\t\tEmits [[color(N)]] inputs in fragment stage.\n"
@ -1190,6 +1194,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
msl_opts.pad_fragment_output_components = args.msl_pad_fragment_output; msl_opts.pad_fragment_output_components = args.msl_pad_fragment_output;
msl_opts.tess_domain_origin_lower_left = args.msl_domain_lower_left; msl_opts.tess_domain_origin_lower_left = args.msl_domain_lower_left;
msl_opts.argument_buffers = args.msl_argument_buffers; msl_opts.argument_buffers = args.msl_argument_buffers;
msl_opts.argument_buffers_tier = static_cast<CompilerMSL::Options::ArgumentBuffersTier>(args.msl_argument_buffers_tier);
msl_opts.texture_buffer_native = args.msl_texture_buffer_native; msl_opts.texture_buffer_native = args.msl_texture_buffer_native;
msl_opts.multiview = args.msl_multiview; msl_opts.multiview = args.msl_multiview;
msl_opts.multiview_layered_rendering = args.msl_multiview_layered_rendering; msl_opts.multiview_layered_rendering = args.msl_multiview_layered_rendering;
@ -1621,6 +1626,10 @@ static int main_inner(int argc, char *argv[])
cbs.add("--msl-pad-fragment-output", [&args](CLIParser &) { args.msl_pad_fragment_output = true; }); cbs.add("--msl-pad-fragment-output", [&args](CLIParser &) { args.msl_pad_fragment_output = true; });
cbs.add("--msl-domain-lower-left", [&args](CLIParser &) { args.msl_domain_lower_left = true; }); cbs.add("--msl-domain-lower-left", [&args](CLIParser &) { args.msl_domain_lower_left = true; });
cbs.add("--msl-argument-buffers", [&args](CLIParser &) { args.msl_argument_buffers = true; }); cbs.add("--msl-argument-buffers", [&args](CLIParser &) { args.msl_argument_buffers = true; });
cbs.add("--msl-argument-buffer-tier", [&args](CLIParser &parser) {
args.msl_argument_buffers_tier = parser.next_uint();
args.msl_argument_buffers = true;
});
cbs.add("--msl-discrete-descriptor-set", cbs.add("--msl-discrete-descriptor-set",
[&args](CLIParser &parser) { args.msl_discrete_descriptor_sets.push_back(parser.next_uint()); }); [&args](CLIParser &parser) { args.msl_discrete_descriptor_sets.push_back(parser.next_uint()); });
cbs.add("--msl-device-argument-buffer", cbs.add("--msl-device-argument-buffer",

View File

@ -734,6 +734,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
case SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES: case SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES:
options->msl.check_discarded_frag_stores = value != 0; options->msl.check_discarded_frag_stores = value != 0;
break; break;
case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER:
options->msl.argument_buffers_tier = static_cast<CompilerMSL::Options::ArgumentBuffersTier>(value);
break;
#endif #endif
default: default:

View File

@ -40,7 +40,7 @@ extern "C" {
/* Bumped if ABI or API breaks backwards compatibility. */ /* Bumped if ABI or API breaks backwards compatibility. */
#define SPVC_C_API_VERSION_MAJOR 0 #define SPVC_C_API_VERSION_MAJOR 0
/* Bumped if APIs or enumerations are added in a backwards compatible way. */ /* Bumped if APIs or enumerations are added in a backwards compatible way. */
#define SPVC_C_API_VERSION_MINOR 53 #define SPVC_C_API_VERSION_MINOR 54
/* Bumped if internal implementation details change. */ /* Bumped if internal implementation details change. */
#define SPVC_C_API_VERSION_PATCH 0 #define SPVC_C_API_VERSION_PATCH 0
@ -723,6 +723,8 @@ typedef enum spvc_compiler_option
SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND = 83 | SPVC_COMPILER_OPTION_GLSL_BIT, SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND = 83 | SPVC_COMPILER_OPTION_GLSL_BIT,
SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER = 84 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
} spvc_compiler_option; } spvc_compiler_option;

View File

@ -11608,11 +11608,14 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_
} }
} }
// Very specifically, image load-store in argument buffers are disallowed on MSL on iOS. // iOS Tier 1 argument buffers do not support writable images.
if (msl_options.is_ios() && physical_type.basetype == SPIRType::Image && physical_type.image.sampled == 2) if (physical_type.basetype == SPIRType::Image &&
physical_type.image.sampled == 2 &&
msl_options.is_ios() &&
msl_options.argument_buffers_tier <= Options::ArgumentBuffersTier::Tier1 &&
!has_decoration(orig_id, DecorationNonWritable))
{ {
if (!has_decoration(orig_id, DecorationNonWritable)) SPIRV_CROSS_THROW("Writable images are not allowed on Tier1 argument buffers on iOS.");
SPIRV_CROSS_THROW("Writable images are not allowed in argument buffers on iOS.");
} }
// Array information is baked into these types. // Array information is baked into these types.
@ -16953,13 +16956,14 @@ bool CompilerMSL::descriptor_set_is_argument_buffer(uint32_t desc_set) const
bool CompilerMSL::is_supported_argument_buffer_type(const SPIRType &type) const bool CompilerMSL::is_supported_argument_buffer_type(const SPIRType &type) const
{ {
// Very specifically, image load-store in argument buffers are disallowed on MSL on iOS. // iOS Tier 1 argument buffers do not support writable images.
// But we won't know when the argument buffer is encoded whether this image will have // When the argument buffer is encoded, we don't know whether this image will have a
// a NonWritable decoration. So just use discrete arguments for all storage images // NonWritable decoration, so just use discrete arguments for all storage images on iOS.
// on iOS. bool is_supported_type = !(type.basetype == SPIRType::Image &&
bool is_storage_image = type.basetype == SPIRType::Image && type.image.sampled == 2; type.image.sampled == 2 &&
bool is_supported_type = !msl_options.is_ios() || !is_storage_image; msl_options.is_ios() &&
return !type_is_msl_framebuffer_fetch(type) && is_supported_type; msl_options.argument_buffers_tier <= Options::ArgumentBuffersTier::Tier1);
return is_supported_type && !type_is_msl_framebuffer_fetch(type);
} }
void CompilerMSL::analyze_argument_buffers() void CompilerMSL::analyze_argument_buffers()

View File

@ -339,10 +339,25 @@ public:
bool dispatch_base = false; bool dispatch_base = false;
bool texture_1D_as_2D = false; bool texture_1D_as_2D = false;
// Enable use of MSL 2.0 indirect argument buffers. // Enable use of Metal argument buffers.
// MSL 2.0 must also be enabled. // MSL 2.0 must also be enabled.
bool argument_buffers = false; bool argument_buffers = false;
// Defines Metal argument buffer tier levels.
// Uses same values as Metal MTLArgumentBuffersTier enumeration.
enum class ArgumentBuffersTier
{
Tier1 = 0,
Tier2 = 1,
};
// When using Metal argument buffers, indicates the Metal argument buffer tier level supported by the Metal platform.
// Ignored when Options::argument_buffers is disabled.
// - Tier1 supports writable images on macOS, but not on iOS.
// - Tier2 supports writable images on macOS and iOS, and higher resource count limits.
// Tier capabilities based on recommendations from Apple engineering.
ArgumentBuffersTier argument_buffers_tier = ArgumentBuffersTier::Tier1;
// Ensures vertex and instance indices start at zero. This reflects the behavior of HLSL with SV_VertexID and SV_InstanceID. // Ensures vertex and instance indices start at zero. This reflects the behavior of HLSL with SV_VertexID and SV_InstanceID.
bool enable_base_index_zero = false; bool enable_base_index_zero = false;