Skip to content

Commit

Permalink
CompilerMSL support larger texel buffers by using 2D Metal textures.
Browse files Browse the repository at this point in the history
Add CompilerMSL::Options::texture_width_max.
Emit and use spvTexelBufferCoord() function to convert 1D
texel buffer coordinates to 2D Metal texture coordinates.
  • Loading branch information
billhollings committed Jun 26, 2018
1 parent 314f39a commit 4c5142b
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 16 deletions.
10 changes: 9 additions & 1 deletion reference/opt/shaders-msl/vert/texture_buffer.vert
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"

#include <metal_stdlib>
#include <simd/simd.h>

Expand All @@ -8,10 +10,16 @@ struct main0_out
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)]])
{
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;
}

20 changes: 13 additions & 7 deletions reference/shaders-msl-no-opt/vert/functions_nested.vert
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ struct main0_out
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)
{
int attribute_flags = v_227.input_attributes[location].w;
Expand Down Expand Up @@ -76,10 +82,10 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
{
int _131 = first_byte;
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;
first_byte = _138 + 1;
tmp.y = input_stream.read(uint2(_138, 0)).x;
tmp.y = input_stream.read(spvTexelBufferCoord(_138)).x;
uint4 param = tmp;
int param_1 = desc.swap_bytes;
result[n] = float(get_bits(param, param_1));
Expand All @@ -89,16 +95,16 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
{
int _156 = first_byte;
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;
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;
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;
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;
int param_3 = desc.swap_bytes;
result[n] = as_type<float>(get_bits(param_2, param_3));
Expand All @@ -108,7 +114,7 @@ float4 fetch_attr(thread const attr_desc& desc, thread const int& vertex_id, thr
{
int _195 = first_byte;
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;
break;
}
Expand Down
10 changes: 9 additions & 1 deletion reference/shaders-msl/vert/texture_buffer.vert
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma clang diagnostic ignored "-Wmissing-prototypes"

#include <metal_stdlib>
#include <simd/simd.h>

Expand All @@ -8,10 +10,16 @@ struct main0_out
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)]])
{
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;
}

37 changes: 30 additions & 7 deletions spirv_msl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,18 @@ void CompilerMSL::emit_custom_functions()
statement("");
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:
statement("// Returns the determinant of a 2x2 matrix.");
statement("inline float spvDet2x2(float a1, float a2, float b1, float b2)");
Expand Down Expand Up @@ -2454,8 +2466,9 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
if (coord_type.vecsize > 1)
tex_coords += ".x";

// Metal texel buffer textures are 2D
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";

Expand Down Expand Up @@ -4053,8 +4066,8 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
auto &return_type = compiler.get<SPIRType>(args[0]);
if (!return_type.array.empty())
return SPVFuncImplArrayCopy;
else
return SPVFuncImplNone;

break;
}

case OpStore:
Expand All @@ -4072,14 +4085,24 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
else
{
// Or ... an expression.
if (result_types[id_rhs] != 0)
type = &compiler.get<SPIRType>(result_types[id_rhs]);
uint32_t tid = result_types[id_rhs];
if (tid)
type = &compiler.get<SPIRType>(tid);
}

if (type && compiler.is_array(*type))
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;
}

Expand Down
2 changes: 2 additions & 0 deletions spirv_msl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ class CompilerMSL : public CompilerGLSL

Platform platform = macOS;
uint32_t msl_version = make_msl_version(1, 2);
uint32_t texture_width_max = 4096;
bool enable_point_size_builtin = true;
bool resolve_specialized_array_lengths = true;

Expand Down Expand Up @@ -215,6 +216,7 @@ class CompilerMSL : public CompilerGLSL
SPVFuncImplFindSMsb,
SPVFuncImplFindUMsb,
SPVFuncImplArrayCopy,
SPVFuncImplTexelBufferCoords,
SPVFuncImplInverse4x4,
SPVFuncImplInverse3x3,
SPVFuncImplInverse2x2,
Expand Down

0 comments on commit 4c5142b

Please sign in to comment.