Merge pull request #952 from KhronosGroup/fix-950

MSL: Add native texture buffer support.
This commit is contained in:
Hans-Kristian Arntzen 2019-04-23 15:43:29 +02:00 committed by GitHub
commit 43bbeacae2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 143 additions and 10 deletions

View File

@ -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)

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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:

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 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;

View File

@ -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)

View File

@ -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;

View File

@ -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')