mirror of
https://github.com/KhronosGroup/SPIRV-Cross.git
synced 2024-11-16 00:40:08 +00:00
Merge pull request #952 from KhronosGroup/fix-950
MSL: Add native texture buffer support.
This commit is contained in:
commit
43bbeacae2
@ -267,7 +267,7 @@ endif()
|
||||
|
||||
if (SPIRV_CROSS_SHARED)
|
||||
set(spirv-cross-abi-major 0)
|
||||
set(spirv-cross-abi-minor 5)
|
||||
set(spirv-cross-abi-minor 6)
|
||||
set(spirv-cross-abi-patch 0)
|
||||
set(SPIRV_CROSS_VERSION ${spirv-cross-abi-major}.${spirv-cross-abi-minor}.${spirv-cross-abi-patch})
|
||||
set(SPIRV_CROSS_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
|
4
main.cpp
4
main.cpp
@ -509,6 +509,7 @@ struct CLIArguments
|
||||
bool msl_pad_fragment_output = false;
|
||||
bool msl_domain_lower_left = false;
|
||||
bool msl_argument_buffers = false;
|
||||
bool msl_texture_buffer_native = false;
|
||||
bool glsl_emit_push_constant_as_ubo = false;
|
||||
SmallVector<uint32_t> msl_discrete_descriptor_sets;
|
||||
SmallVector<PLSArg> pls_in;
|
||||
@ -570,6 +571,7 @@ static void print_help()
|
||||
"\t[--msl-pad-fragment-output]\n"
|
||||
"\t[--msl-domain-lower-left]\n"
|
||||
"\t[--msl-argument-buffers]\n"
|
||||
"\t[--msl-texture-buffer-native]\n"
|
||||
"\t[--msl-discrete-descriptor-set <index>]\n"
|
||||
"\t[--hlsl]\n"
|
||||
"\t[--reflect]\n"
|
||||
@ -727,6 +729,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.texture_buffer_native = args.msl_texture_buffer_native;
|
||||
msl_comp->set_msl_options(msl_opts);
|
||||
for (auto &v : args.msl_discrete_descriptor_sets)
|
||||
msl_comp->add_discrete_descriptor_set(v);
|
||||
@ -1038,6 +1041,7 @@ static int main_inner(int argc, char *argv[])
|
||||
cbs.add("--msl-argument-buffers", [&args](CLIParser &) { 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-texture-buffer-native", [&args](CLIParser &) { args.msl_texture_buffer_native = 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();
|
||||
|
@ -16,10 +16,11 @@ uint2 spvTexelBufferCoord(uint tc)
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
fragment main0_out main0(texture2d<float> buf [[texture(0)]])
|
||||
fragment main0_out main0(texture2d<float> buf [[texture(0)]], texture2d<float, access::write> bufOut [[texture(1)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = buf.read(spvTexelBufferCoord(0));
|
||||
bufOut.write(out.FragColor, spvTexelBufferCoord(int(gl_FragCoord.x)));
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(texture_buffer<float> buf [[texture(0)]], texture_buffer<float, access::write> bufOut [[texture(1)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = buf.read(uint(0));
|
||||
bufOut.write(out.FragColor, uint(int(gl_FragCoord.x)));
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(texture_buffer<float> uSamp [[texture(4)]], texture_buffer<float> uSampo [[texture(5)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = uSamp.read(uint(10)) + uSampo.read(uint(100));
|
||||
return out;
|
||||
}
|
||||
|
@ -16,10 +16,11 @@ uint2 spvTexelBufferCoord(uint tc)
|
||||
return uint2(tc % 4096, tc / 4096);
|
||||
}
|
||||
|
||||
fragment main0_out main0(texture2d<float> buf [[texture(0)]])
|
||||
fragment main0_out main0(texture2d<float> buf [[texture(0)]], texture2d<float, access::write> bufOut [[texture(1)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = buf.read(spvTexelBufferCoord(0));
|
||||
bufOut.write(out.FragColor, spvTexelBufferCoord(int(gl_FragCoord.x)));
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(texture_buffer<float> buf [[texture(0)]], texture_buffer<float, access::write> bufOut [[texture(1)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = buf.read(uint(0));
|
||||
bufOut.write(out.FragColor, uint(int(gl_FragCoord.x)));
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(texture_buffer<float> uSamp [[texture(4)]], texture_buffer<float> uSampo [[texture(5)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = uSamp.read(uint(10)) + uSampo.read(uint(100));
|
||||
return out;
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
#version 450
|
||||
|
||||
layout(rgba8, binding = 0) uniform readonly imageBuffer buf;
|
||||
layout(rgba8, binding = 1) uniform writeonly imageBuffer bufOut;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = imageLoad(buf, 0);
|
||||
imageStore(bufOut, int(gl_FragCoord.x), FragColor);
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
layout(rgba8, binding = 0) uniform readonly imageBuffer buf;
|
||||
layout(rgba8, binding = 1) uniform writeonly imageBuffer bufOut;
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = imageLoad(buf, 0);
|
||||
imageStore(bufOut, int(gl_FragCoord.x), FragColor);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
#version 310 es
|
||||
#extension GL_OES_texture_buffer : require
|
||||
|
||||
layout(binding = 4) uniform highp samplerBuffer uSamp;
|
||||
layout(rgba32f, binding = 5) uniform readonly highp imageBuffer uSampo;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = texelFetch(uSamp, 10) + imageLoad(uSampo, 100);
|
||||
}
|
@ -526,6 +526,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
|
||||
case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS:
|
||||
options->msl.argument_buffers = value != 0;
|
||||
break;
|
||||
|
||||
case SPVC_COMPILER_OPTION_MSL_TEXTURE_BUFFER_NATIVE:
|
||||
options->msl.texture_buffer_native = value != 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
@ -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 5
|
||||
#define SPVC_C_API_VERSION_MINOR 6
|
||||
/* Bumped if internal implementation details change. */
|
||||
#define SPVC_C_API_VERSION_PATCH 0
|
||||
|
||||
@ -424,6 +424,8 @@ typedef enum spvc_compiler_option
|
||||
|
||||
SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER = 33 | SPVC_COMPILER_OPTION_GLSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_MSL_TEXTURE_BUFFER_NATIVE = 34 | SPVC_COMPILER_OPTION_MSL_BIT,
|
||||
|
||||
SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
|
||||
} spvc_compiler_option;
|
||||
|
||||
|
@ -3729,6 +3729,9 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
case OpImageTexelPointer:
|
||||
SPIRV_CROSS_THROW("MSL does not support atomic operations on images or texel buffers.");
|
||||
|
||||
// Casting
|
||||
case OpQuantizeToF16:
|
||||
{
|
||||
@ -4483,9 +4486,16 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
||||
if (coord_type.vecsize > 1)
|
||||
tex_coords = enclose_expression(tex_coords) + ".x";
|
||||
|
||||
// Metal texel buffer textures are 2D, so convert 1D coord to 2D.
|
||||
if (is_fetch)
|
||||
tex_coords = "spvTexelBufferCoord(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")";
|
||||
if (msl_options.texture_buffer_native)
|
||||
{
|
||||
tex_coords = "uint(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Metal texel buffer textures are 2D, so convert 1D coord to 2D.
|
||||
if (is_fetch)
|
||||
tex_coords = "spvTexelBufferCoord(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")";
|
||||
}
|
||||
|
||||
alt_coord_component = 1;
|
||||
break;
|
||||
@ -5613,14 +5623,14 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args)
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args +=
|
||||
join("constant uint* spvIndirectParams [[buffer(", msl_options.indirect_params_buffer_index, ")]]");
|
||||
join("constant uint* spvIndirectParams [[buffer(", msl_options.indirect_params_buffer_index, ")]]");
|
||||
}
|
||||
else if (stage_out_var_id)
|
||||
{
|
||||
if (!ep_args.empty())
|
||||
ep_args += ", ";
|
||||
ep_args +=
|
||||
join("device uint* spvIndirectParams [[buffer(", msl_options.indirect_params_buffer_index, ")]]");
|
||||
join("device uint* spvIndirectParams [[buffer(", msl_options.indirect_params_buffer_index, ")]]");
|
||||
}
|
||||
|
||||
// Tessellation control shaders get three additional parameters:
|
||||
@ -6643,6 +6653,18 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
img_type_name += (img_type.arrayed ? "texture1d_array" : "texture1d");
|
||||
break;
|
||||
case DimBuffer:
|
||||
if (img_type.ms || img_type.arrayed)
|
||||
SPIRV_CROSS_THROW("Cannot use texel buffers with multisampling or array layers.");
|
||||
|
||||
if (msl_options.texture_buffer_native)
|
||||
{
|
||||
if (!msl_options.supports_msl_version(2, 1))
|
||||
SPIRV_CROSS_THROW("Native texture_buffer type is only supported in MSL 2.1.");
|
||||
img_type_name = "texture_buffer";
|
||||
}
|
||||
else
|
||||
img_type_name += "texture2d";
|
||||
break;
|
||||
case Dim2D:
|
||||
case DimSubpassData:
|
||||
if (img_type.ms && img_type.arrayed)
|
||||
@ -7328,7 +7350,7 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
|
||||
{
|
||||
// Retrieve the image type, and if it's a Buffer, emit a texel coordinate function
|
||||
uint32_t tid = result_types[args[opcode == OpImageWrite ? 0 : 2]];
|
||||
if (tid && compiler.get<SPIRType>(tid).image.dim == DimBuffer)
|
||||
if (tid && compiler.get<SPIRType>(tid).image.dim == DimBuffer && !compiler.msl_options.texture_buffer_native)
|
||||
return SPVFuncImplTexelBufferCoords;
|
||||
|
||||
if (opcode == OpImageFetch && compiler.msl_options.swizzle_texture_samples)
|
||||
|
@ -194,6 +194,9 @@ public:
|
||||
// Add support to explicit pad out components.
|
||||
bool pad_fragment_output_components = false;
|
||||
|
||||
// Requires MSL 2.1, use the native support for texel buffers.
|
||||
bool texture_buffer_native = false;
|
||||
|
||||
bool is_ios()
|
||||
{
|
||||
return platform == iOS;
|
||||
|
@ -172,6 +172,8 @@ def cross_compile_msl(shader, spirv, opt, iterations, paths):
|
||||
msl_args.append('--msl-domain-lower-left')
|
||||
if '.argument.' in shader:
|
||||
msl_args.append('--msl-argument-buffers')
|
||||
if '.texture-buffer-native.' in shader:
|
||||
msl_args.append('--msl-texture-buffer-native')
|
||||
if '.discrete.' in shader:
|
||||
# Arbitrary for testing purposes.
|
||||
msl_args.append('--msl-discrete-descriptor-set')
|
||||
|
Loading…
Reference in New Issue
Block a user