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()
set(spirv-cross-abi-major 0)
set(spirv-cross-abi-minor 53)
set(spirv-cross-abi-minor 54)
set(spirv-cross-abi-patch 0)
if (SPIRV_CROSS_SHARED)

View File

@ -645,6 +645,7 @@ struct CLIArguments
bool msl_pad_fragment_output = false;
bool msl_domain_lower_left = false;
bool msl_argument_buffers = false;
uint32_t msl_argument_buffers_tier = 0; // Tier 1
bool msl_texture_buffer_native = false;
bool msl_framebuffer_fetch = 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\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-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[--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-framebuffer-fetch]:\n\t\tImplement subpass inputs with frame buffer fetch.\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.tess_domain_origin_lower_left = args.msl_domain_lower_left;
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.multiview = args.msl_multiview;
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-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-buffer-tier", [&args](CLIParser &parser) {
args.msl_argument_buffers_tier = parser.next_uint();
args.msl_argument_buffers = true;
});
cbs.add("--msl-discrete-descriptor-set",
[&args](CLIParser &parser) { args.msl_discrete_descriptor_sets.push_back(parser.next_uint()); });
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:
options->msl.check_discarded_frag_stores = value != 0;
break;
case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER:
options->msl.argument_buffers_tier = static_cast<CompilerMSL::Options::ArgumentBuffersTier>(value);
break;
#endif
default:

View File

@ -40,7 +40,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 53
#define SPVC_C_API_VERSION_MINOR 54
/* Bumped if internal implementation details change. */
#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_MSL_ARGUMENT_BUFFERS_TIER = 84 | SPVC_COMPILER_OPTION_MSL_BIT,
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
} 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.
if (msl_options.is_ios() && physical_type.basetype == SPIRType::Image && physical_type.image.sampled == 2)
// iOS Tier 1 argument buffers do not support writable images.
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 in argument buffers on iOS.");
SPIRV_CROSS_THROW("Writable images are not allowed on Tier1 argument buffers on iOS.");
}
// 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
{
// Very specifically, image load-store in argument buffers are disallowed on MSL on iOS.
// But we won't know when the argument buffer is encoded whether this image will have
// a NonWritable decoration. So just use discrete arguments for all storage images
// on iOS.
bool is_storage_image = type.basetype == SPIRType::Image && type.image.sampled == 2;
bool is_supported_type = !msl_options.is_ios() || !is_storage_image;
return !type_is_msl_framebuffer_fetch(type) && is_supported_type;
// iOS Tier 1 argument buffers do not support writable images.
// When the argument buffer is encoded, we don't know whether this image will have a
// NonWritable decoration, so just use discrete arguments for all storage images on iOS.
bool is_supported_type = !(type.basetype == SPIRType::Image &&
type.image.sampled == 2 &&
msl_options.is_ios() &&
msl_options.argument_buffers_tier <= Options::ArgumentBuffersTier::Tier1);
return is_supported_type && !type_is_msl_framebuffer_fetch(type);
}
void CompilerMSL::analyze_argument_buffers()

View File

@ -339,10 +339,25 @@ public:
bool dispatch_base = 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.
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.
bool enable_base_index_zero = false;