MSL: Handle Offset and Grad operands for 1D-as-2D textures.
This commit is contained in:
parent
0db1569e97
commit
5845e009ea
7
main.cpp
7
main.cpp
@ -565,6 +565,7 @@ struct CLIArguments
|
||||
bool msl_arrayed_subpass_input = false;
|
||||
uint32_t msl_r32ui_linear_texture_alignment = 4;
|
||||
uint32_t msl_r32ui_alignment_constant_id = 65535;
|
||||
bool msl_texture_1d_as_2d = false;
|
||||
bool glsl_emit_push_constant_as_ubo = false;
|
||||
bool glsl_emit_ubo_as_plain_uniforms = false;
|
||||
bool glsl_force_flattened_io_blocks = false;
|
||||
@ -774,7 +775,9 @@ static void print_help_msl()
|
||||
"\t[--msl-r32ui-linear-texture-align <alignment>]:\n\t\tThe required alignment of linear textures of format MTLPixelFormatR32Uint.\n"
|
||||
"\t\tThis is used to align the row stride for atomic accesses to such images.\n"
|
||||
"\t[--msl-r32ui-linear-texture-align-constant-id <id>]:\n\t\tThe function constant ID to use for the linear texture alignment.\n"
|
||||
"\t\tOn MSL 1.2 or later, you can override the alignment by setting this function constant.\n");
|
||||
"\t\tOn MSL 1.2 or later, you can override the alignment by setting this function constant.\n"
|
||||
"\t[--msl-texture-1d-as-2d]:\n\t\tEmit Image variables of dimension Dim1D as texture2d.\n"
|
||||
"\t\tIn Metal, 1D textures do not support all features that 2D textures do. Use this option if your code relies on these features.\n");
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
@ -1015,6 +1018,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
||||
msl_opts.arrayed_subpass_input = args.msl_arrayed_subpass_input;
|
||||
msl_opts.r32ui_linear_texture_alignment = args.msl_r32ui_linear_texture_alignment;
|
||||
msl_opts.r32ui_alignment_constant_id = args.msl_r32ui_alignment_constant_id;
|
||||
msl_opts.texture_1D_as_2D = args.msl_texture_1d_as_2d;
|
||||
msl_comp->set_msl_options(msl_opts);
|
||||
for (auto &v : args.msl_discrete_descriptor_sets)
|
||||
msl_comp->add_discrete_descriptor_set(v);
|
||||
@ -1439,6 +1443,7 @@ static int main_inner(int argc, char *argv[])
|
||||
[&args](CLIParser &parser) { args.msl_r32ui_linear_texture_alignment = parser.next_uint(); });
|
||||
cbs.add("--msl-r32ui-linear-texture-align-constant-id",
|
||||
[&args](CLIParser &parser) { args.msl_r32ui_alignment_constant_id = parser.next_uint(); });
|
||||
cbs.add("--msl-texture-1d-as-2d", [&args](CLIParser &) { args.msl_texture_1d_as_2d = 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();
|
||||
|
26
reference/opt/shaders-msl/frag/bitcasting.1d-as-2d.frag
Normal file
26
reference/opt/shaders-msl/frag/bitcasting.1d-as-2d.frag
Normal file
@ -0,0 +1,26 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor0 [[color(0)]];
|
||||
float4 FragColor1 [[color(1)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float4 VertGeom [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> TextureBase [[texture(0)]], texture2d<float> TextureDetail [[texture(1)]], sampler TextureBaseSmplr [[sampler(0)]], sampler TextureDetailSmplr [[sampler(1)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 _22 = TextureBase.sample(TextureBaseSmplr, float2(in.VertGeom.x, 0.5));
|
||||
float4 _30 = TextureDetail.sample(TextureDetailSmplr, float2(in.VertGeom.x, 0.5), int2(3, 0));
|
||||
out.FragColor0 = as_type<float4>(as_type<int4>(_22)) * as_type<float4>(as_type<int4>(_30));
|
||||
out.FragColor1 = as_type<float4>(as_type<uint4>(_22)) * as_type<float4>(as_type<uint4>(_30));
|
||||
return out;
|
||||
}
|
||||
|
22
reference/opt/shaders-msl/frag/sampler-1d-lod.1d-as-2d.frag
Normal file
22
reference/opt/shaders-msl/frag/sampler-1d-lod.1d-as-2d.frag
Normal file
@ -0,0 +1,22 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float vTex [[user(locn0), flat]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSampler [[texture(0)]], sampler uSamplerSmplr [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor += ((uSampler.sample(uSamplerSmplr, float2(in.vTex, 0.5), bias(2.0)) + uSampler.sample(uSamplerSmplr, float2(in.vTex, 0.5), level(3.0))) + uSampler.sample(uSamplerSmplr, float2(in.vTex, 0.5), gradient2d(5.0, 8.0)));
|
||||
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(texture2d<float> uTexture [[texture(0)]], texture2d<float> uTexture2 [[texture(1)]], sampler uTextureSmplr [[sampler(0)]], sampler uTexture2Smplr [[sampler(1)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = uTexture.read(uint2(int2(gl_FragCoord.xy)) + uint2(int2(1)), 0);
|
||||
out.FragColor += uTexture2.read(uint2(uint(int(gl_FragCoord.x)), 0) + uint2(uint(-1), 0), 0);
|
||||
return out;
|
||||
}
|
||||
|
30
reference/shaders-msl/frag/bitcasting.1d-as-2d.frag
Normal file
30
reference/shaders-msl/frag/bitcasting.1d-as-2d.frag
Normal file
@ -0,0 +1,30 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor0 [[color(0)]];
|
||||
float4 FragColor1 [[color(1)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float4 VertGeom [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> TextureBase [[texture(0)]], texture2d<float> TextureDetail [[texture(1)]], sampler TextureBaseSmplr [[sampler(0)]], sampler TextureDetailSmplr [[sampler(1)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 texSample0 = TextureBase.sample(TextureBaseSmplr, float2(in.VertGeom.x, 0.5));
|
||||
float4 texSample1 = TextureDetail.sample(TextureDetailSmplr, float2(in.VertGeom.x, 0.5), int2(3, 0));
|
||||
int4 iResult0 = as_type<int4>(texSample0);
|
||||
int4 iResult1 = as_type<int4>(texSample1);
|
||||
out.FragColor0 = as_type<float4>(iResult0) * as_type<float4>(iResult1);
|
||||
uint4 uResult0 = as_type<uint4>(texSample0);
|
||||
uint4 uResult1 = as_type<uint4>(texSample1);
|
||||
out.FragColor1 = as_type<float4>(uResult0) * as_type<float4>(uResult1);
|
||||
return out;
|
||||
}
|
||||
|
22
reference/shaders-msl/frag/sampler-1d-lod.1d-as-2d.frag
Normal file
22
reference/shaders-msl/frag/sampler-1d-lod.1d-as-2d.frag
Normal file
@ -0,0 +1,22 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float vTex [[user(locn0), flat]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> uSampler [[texture(0)]], sampler uSamplerSmplr [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor += ((uSampler.sample(uSamplerSmplr, float2(in.vTex, 0.5), bias(2.0)) + uSampler.sample(uSamplerSmplr, float2(in.vTex, 0.5), level(3.0))) + uSampler.sample(uSamplerSmplr, float2(in.vTex, 0.5), gradient2d(5.0, 8.0)));
|
||||
return out;
|
||||
}
|
||||
|
18
reference/shaders-msl/frag/texel-fetch-offset.1d-as-2d.frag
Normal file
18
reference/shaders-msl/frag/texel-fetch-offset.1d-as-2d.frag
Normal 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(texture2d<float> uTexture [[texture(0)]], texture2d<float> uTexture2 [[texture(1)]], sampler uTextureSmplr [[sampler(0)]], sampler uTexture2Smplr [[sampler(1)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = uTexture.read(uint2(int2(gl_FragCoord.xy)) + uint2(int2(1)), 0);
|
||||
out.FragColor += uTexture2.read(uint2(uint(int(gl_FragCoord.x)), 0) + uint2(uint(-1), 0), 0);
|
||||
return out;
|
||||
}
|
||||
|
23
shaders-msl/frag/bitcasting.1d-as-2d.frag
Normal file
23
shaders-msl/frag/bitcasting.1d-as-2d.frag
Normal file
@ -0,0 +1,23 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform sampler1D TextureBase;
|
||||
layout(binding = 1) uniform sampler1D TextureDetail;
|
||||
|
||||
layout(location = 0) in vec4 VertGeom;
|
||||
|
||||
layout(location = 0) out vec4 FragColor0;
|
||||
layout(location = 1) out vec4 FragColor1;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texSample0 = texture(TextureBase, VertGeom.x);
|
||||
vec4 texSample1 = textureOffset(TextureDetail, VertGeom.x, 3);
|
||||
|
||||
ivec4 iResult0 = floatBitsToInt(texSample0);
|
||||
ivec4 iResult1 = floatBitsToInt(texSample1);
|
||||
FragColor0 = (intBitsToFloat(iResult0) * intBitsToFloat(iResult1));
|
||||
|
||||
uvec4 uResult0 = floatBitsToUint(texSample0);
|
||||
uvec4 uResult1 = floatBitsToUint(texSample1);
|
||||
FragColor1 = (uintBitsToFloat(uResult0) * uintBitsToFloat(uResult1));
|
||||
}
|
12
shaders-msl/frag/sampler-1d-lod.1d-as-2d.frag
Normal file
12
shaders-msl/frag/sampler-1d-lod.1d-as-2d.frag
Normal file
@ -0,0 +1,12 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(location = 0) flat in float vTex;
|
||||
layout(binding = 0) uniform sampler1D uSampler;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor += texture(uSampler, vTex, 2.0) +
|
||||
textureLod(uSampler, vTex, 3.0) +
|
||||
textureGrad(uSampler, vTex, 5.0, 8.0);
|
||||
}
|
10
shaders-msl/frag/texel-fetch-offset.1d-as-2d.frag
Normal file
10
shaders-msl/frag/texel-fetch-offset.1d-as-2d.frag
Normal file
@ -0,0 +1,10 @@
|
||||
#version 450
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(binding = 0) uniform sampler2D uTexture;
|
||||
layout(binding = 1) uniform sampler1D uTexture2;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texelFetchOffset(uTexture, ivec2(gl_FragCoord.xy), 0, ivec2(1, 1));
|
||||
FragColor += texelFetchOffset(uTexture2, int(gl_FragCoord.x), 0, int(-1));
|
||||
}
|
@ -8265,25 +8265,26 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
break;
|
||||
}
|
||||
|
||||
if (args.base.is_fetch && args.offset)
|
||||
if (args.base.is_fetch && (args.offset || args.coffset))
|
||||
{
|
||||
uint32_t offset_expr = args.offset ? args.offset : args.coffset;
|
||||
// Fetch offsets must be applied directly to the coordinate.
|
||||
forward = forward && should_forward(args.offset);
|
||||
auto &type = expression_type(args.offset);
|
||||
if (type.basetype != SPIRType::UInt)
|
||||
tex_coords += " + " + bitcast_expression(SPIRType::UInt, args.offset);
|
||||
forward = forward && should_forward(offset_expr);
|
||||
auto &type = expression_type(offset_expr);
|
||||
if (imgtype.image.dim == Dim1D && msl_options.texture_1D_as_2D)
|
||||
{
|
||||
if (type.basetype != SPIRType::UInt)
|
||||
tex_coords += join(" + uint2(", bitcast_expression(SPIRType::UInt, offset_expr), ", 0)");
|
||||
else
|
||||
tex_coords += join(" + uint2(", to_enclosed_expression(offset_expr), ", 0)");
|
||||
}
|
||||
else
|
||||
tex_coords += " + " + to_enclosed_expression(args.offset);
|
||||
}
|
||||
else if (args.base.is_fetch && args.coffset)
|
||||
{
|
||||
// Fetch offsets must be applied directly to the coordinate.
|
||||
forward = forward && should_forward(args.coffset);
|
||||
auto &type = expression_type(args.coffset);
|
||||
if (type.basetype != SPIRType::UInt)
|
||||
tex_coords += " + " + bitcast_expression(SPIRType::UInt, args.coffset);
|
||||
else
|
||||
tex_coords += " + " + to_enclosed_expression(args.coffset);
|
||||
{
|
||||
if (type.basetype != SPIRType::UInt)
|
||||
tex_coords += " + " + bitcast_expression(SPIRType::UInt, offset_expr);
|
||||
else
|
||||
tex_coords += " + " + to_enclosed_expression(offset_expr);
|
||||
}
|
||||
}
|
||||
|
||||
// If projection, use alt coord as divisor
|
||||
@ -8454,6 +8455,7 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
string grad_opt;
|
||||
switch (imgtype.image.dim)
|
||||
{
|
||||
case Dim1D:
|
||||
case Dim2D:
|
||||
grad_opt = "2d";
|
||||
break;
|
||||
@ -8489,30 +8491,42 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool
|
||||
|
||||
// Add offsets
|
||||
string offset_expr;
|
||||
const SPIRType *offset_type = nullptr;
|
||||
if (args.coffset && !args.base.is_fetch)
|
||||
{
|
||||
forward = forward && should_forward(args.coffset);
|
||||
offset_expr = to_expression(args.coffset);
|
||||
offset_type = &expression_type(args.coffset);
|
||||
}
|
||||
else if (args.offset && !args.base.is_fetch)
|
||||
{
|
||||
forward = forward && should_forward(args.offset);
|
||||
offset_expr = to_expression(args.offset);
|
||||
offset_type = &expression_type(args.offset);
|
||||
}
|
||||
|
||||
if (!offset_expr.empty())
|
||||
{
|
||||
switch (imgtype.image.dim)
|
||||
{
|
||||
case Dim1D:
|
||||
if (!msl_options.texture_1D_as_2D)
|
||||
break;
|
||||
if (offset_type->vecsize > 1)
|
||||
offset_expr = enclose_expression(offset_expr) + ".x";
|
||||
|
||||
farg_str += join(", int2(", offset_expr, ", 0)");
|
||||
break;
|
||||
|
||||
case Dim2D:
|
||||
if (coord_type.vecsize > 2)
|
||||
if (offset_type->vecsize > 2)
|
||||
offset_expr = enclose_expression(offset_expr) + ".xy";
|
||||
|
||||
farg_str += ", " + offset_expr;
|
||||
break;
|
||||
|
||||
case Dim3D:
|
||||
if (coord_type.vecsize > 3)
|
||||
if (offset_type->vecsize > 3)
|
||||
offset_expr = enclose_expression(offset_expr) + ".xyz";
|
||||
|
||||
farg_str += ", " + offset_expr;
|
||||
|
@ -306,6 +306,8 @@ def cross_compile_msl(shader, spirv, opt, iterations, paths):
|
||||
msl_args.append('0x00000022')
|
||||
if '.arrayed-subpass.' in shader:
|
||||
msl_args.append('--msl-arrayed-subpass-input')
|
||||
if '.1d-as-2d.' in shader:
|
||||
msl_args.append('--msl-texture-1d-as-2d')
|
||||
|
||||
subprocess.check_call(msl_args)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user