CompilerMSL support larger texel buffers by using 2D Metal textures.

Add CompilerMSL::Options::texture_width_max.
Emit and use spvTexelBufferCoord() function to convert 1D
texel buffer coordinates to 2D Metal texture coordinates.
This commit is contained in:
Bill Hollings 2018-06-26 17:30:21 -04:00
parent 314f39a7c4
commit 4c5142b9d3
5 changed files with 63 additions and 16 deletions

View File

@ -1,3 +1,5 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib> #include <metal_stdlib>
#include <simd/simd.h> #include <simd/simd.h>
@ -8,10 +10,16 @@ struct main0_out
float4 gl_Position [[position]]; float4 gl_Position [[position]];
}; };
// Returns 2D texture coords corresponding to 1D texel buffer coords
uint2 spvTexelBufferCoord(uint tc)
{
return uint2(tc % 4096, tc / 4096);
}
vertex main0_out main0(texture2d<float> uSamp [[texture(4)]], texture2d<float> uSampo [[texture(5)]]) vertex main0_out main0(texture2d<float> uSamp [[texture(4)]], texture2d<float> uSampo [[texture(5)]])
{ {
main0_out out = {}; main0_out out = {};
out.gl_Position = uSamp.read(uint2(10, 0)) + uSampo.read(uint2(100, 0)); out.gl_Position = uSamp.read(spvTexelBufferCoord(10)) + uSampo.read(spvTexelBufferCoord(100));
return out; return out;
} }

View File

@ -36,6 +36,12 @@ struct main0_out
float4 gl_Position [[position]]; float4 gl_Position [[position]];
}; };
// Returns 2D texture coords corresponding to 1D texel buffer coords
uint2 spvTexelBufferCoord(uint tc)
{
return uint2(tc % 4096, tc / 4096);
}
attr_desc fetch_desc(thread const int& location, constant VertexBuffer& v_227) attr_desc fetch_desc(thread const int& location, constant VertexBuffer& v_227)
{ {
int attribute_flags = v_227.input_attributes[location].w; int attribute_flags = v_227.input_attributes[location].w;
@ -76,10 +82,10 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
{ {
int _131 = first_byte; int _131 = first_byte;
first_byte = _131 + 1; first_byte = _131 + 1;
tmp.x = input_stream.read(uint2(_131, 0)).x; tmp.x = input_stream.read(spvTexelBufferCoord(_131)).x;
int _138 = first_byte; int _138 = first_byte;
first_byte = _138 + 1; first_byte = _138 + 1;
tmp.y = input_stream.read(uint2(_138, 0)).x; tmp.y = input_stream.read(spvTexelBufferCoord(_138)).x;
uint4 param = tmp; uint4 param = tmp;
int param_1 = desc.swap_bytes; int param_1 = desc.swap_bytes;
result[n] = float(get_bits(param, param_1)); result[n] = float(get_bits(param, param_1));
@ -89,16 +95,16 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
{ {
int _156 = first_byte; int _156 = first_byte;
first_byte = _156 + 1; first_byte = _156 + 1;
tmp.x = input_stream.read(uint2(_156, 0)).x; tmp.x = input_stream.read(spvTexelBufferCoord(_156)).x;
int _163 = first_byte; int _163 = first_byte;
first_byte = _163 + 1; first_byte = _163 + 1;
tmp.y = input_stream.read(uint2(_163, 0)).x; tmp.y = input_stream.read(spvTexelBufferCoord(_163)).x;
int _170 = first_byte; int _170 = first_byte;
first_byte = _170 + 1; first_byte = _170 + 1;
tmp.z = input_stream.read(uint2(_170, 0)).x; tmp.z = input_stream.read(spvTexelBufferCoord(_170)).x;
int _177 = first_byte; int _177 = first_byte;
first_byte = _177 + 1; first_byte = _177 + 1;
tmp.w = input_stream.read(uint2(_177, 0)).x; tmp.w = input_stream.read(spvTexelBufferCoord(_177)).x;
uint4 param_2 = tmp; uint4 param_2 = tmp;
int param_3 = desc.swap_bytes; int param_3 = desc.swap_bytes;
result[n] = as_type<float>(get_bits(param_2, param_3)); result[n] = as_type<float>(get_bits(param_2, param_3));
@ -108,7 +114,7 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
{ {
int _195 = first_byte; int _195 = first_byte;
first_byte = _195 + 1; first_byte = _195 + 1;
result[n] = float(input_stream.read(uint2(_195, 0)).x); result[n] = float(input_stream.read(spvTexelBufferCoord(_195)).x);
reverse_order = desc.swap_bytes != 0; reverse_order = desc.swap_bytes != 0;
break; break;
} }

View File

@ -1,3 +1,5 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#include <metal_stdlib> #include <metal_stdlib>
#include <simd/simd.h> #include <simd/simd.h>
@ -8,10 +10,16 @@ struct main0_out
float4 gl_Position [[position]]; float4 gl_Position [[position]];
}; };
// Returns 2D texture coords corresponding to 1D texel buffer coords
uint2 spvTexelBufferCoord(uint tc)
{
return uint2(tc % 4096, tc / 4096);
}
vertex main0_out main0(texture2d<float> uSamp [[texture(4)]], texture2d<float> uSampo [[texture(5)]]) vertex main0_out main0(texture2d<float> uSamp [[texture(4)]], texture2d<float> uSampo [[texture(5)]])
{ {
main0_out out = {}; main0_out out = {};
out.gl_Position = uSamp.read(uint2(10, 0)) + uSampo.read(uint2(100, 0)); out.gl_Position = uSamp.read(spvTexelBufferCoord(10)) + uSampo.read(spvTexelBufferCoord(100));
return out; return out;
} }

View File

@ -1173,6 +1173,18 @@ void CompilerMSL::emit_custom_functions()
statement(""); statement("");
break; break;
case SPVFuncImplTexelBufferCoords:
{
string max_width_str = convert_to_string(msl_options.texture_width_max);
statement("// Returns 2D texture coords corresponding to 1D texel buffer coords");
statement("uint2 spvTexelBufferCoord(uint tc)");
begin_scope();
statement(join("return uint2(tc % ", max_width_str, ", tc / ", max_width_str, ");"));
end_scope();
statement("");
break;
}
case SPVFuncImplInverse4x4: case SPVFuncImplInverse4x4:
statement("// Returns the determinant of a 2x2 matrix."); statement("// Returns the determinant of a 2x2 matrix.");
statement("inline float spvDet2x2(float a1, float a2, float b1, float b2)"); statement("inline float spvDet2x2(float a1, float a2, float b1, float b2)");
@ -2454,8 +2466,9 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
if (coord_type.vecsize > 1) if (coord_type.vecsize > 1)
tex_coords += ".x"; tex_coords += ".x";
// Metal texel buffer textures are 2D
if (is_fetch) if (is_fetch)
tex_coords = "uint2(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ", 0)"; // Metal textures are 2D tex_coords = "spvTexelBufferCoord(" + round_fp_tex_coords(tex_coords, coord_is_fp) + ")";
alt_coord = ".y"; alt_coord = ".y";
@ -4053,8 +4066,8 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
auto &return_type = compiler.get<SPIRType>(args[0]); auto &return_type = compiler.get<SPIRType>(args[0]);
if (!return_type.array.empty()) if (!return_type.array.empty())
return SPVFuncImplArrayCopy; return SPVFuncImplArrayCopy;
else
return SPVFuncImplNone; break;
} }
case OpStore: case OpStore:
@ -4072,14 +4085,24 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
else else
{ {
// Or ... an expression. // Or ... an expression.
if (result_types[id_rhs] != 0) uint32_t tid = result_types[id_rhs];
type = &compiler.get<SPIRType>(result_types[id_rhs]); if (tid)
type = &compiler.get<SPIRType>(tid);
} }
if (type && compiler.is_array(*type)) if (type && compiler.is_array(*type))
return SPVFuncImplArrayCopy; return SPVFuncImplArrayCopy;
else
return SPVFuncImplNone; break;
}
case OpImageFetch:
{
// Retrieve the image type, and if it's a Buffer, emit a texel coordinate function
uint32_t tid = result_types[args[2]];
if (tid && compiler.get<SPIRType>(tid).image.dim == DimBuffer)
return SPVFuncImplTexelBufferCoords;
break; break;
} }

View File

@ -152,6 +152,7 @@ public:
Platform platform = macOS; Platform platform = macOS;
uint32_t msl_version = make_msl_version(1, 2); uint32_t msl_version = make_msl_version(1, 2);
uint32_t texture_width_max = 4096;
bool enable_point_size_builtin = true; bool enable_point_size_builtin = true;
bool resolve_specialized_array_lengths = true; bool resolve_specialized_array_lengths = true;
@ -215,6 +216,7 @@ public:
SPVFuncImplFindSMsb, SPVFuncImplFindSMsb,
SPVFuncImplFindUMsb, SPVFuncImplFindUMsb,
SPVFuncImplArrayCopy, SPVFuncImplArrayCopy,
SPVFuncImplTexelBufferCoords,
SPVFuncImplInverse4x4, SPVFuncImplInverse4x4,
SPVFuncImplInverse3x3, SPVFuncImplInverse3x3,
SPVFuncImplInverse2x2, SPVFuncImplInverse2x2,