Further updates for pull request #1162; also added two test cases for spvCubemapTo2DArrayFace function and added '--msl-framebuffer-fetch'/ '--msl-emulate-cube-array' compiler options.
This commit is contained in:
parent
c3d6022956
commit
f3a6d28a1d
10
main.cpp
10
main.cpp
@ -514,6 +514,8 @@ struct CLIArguments
|
||||
bool msl_domain_lower_left = false;
|
||||
bool msl_argument_buffers = false;
|
||||
bool msl_texture_buffer_native = false;
|
||||
bool msl_framebuffer_fetch = false;
|
||||
bool msl_emulate_cube_array = false;
|
||||
bool msl_multiview = false;
|
||||
bool msl_view_index_from_device_index = false;
|
||||
bool msl_dispatch_base = false;
|
||||
@ -597,6 +599,8 @@ static void print_help()
|
||||
"\t[--msl-domain-lower-left]\n"
|
||||
"\t[--msl-argument-buffers]\n"
|
||||
"\t[--msl-texture-buffer-native]\n"
|
||||
"\t[--msl-framebuffer-fetch]\n"
|
||||
"\t[--msl-emulate-cube-array]\n"
|
||||
"\t[--msl-discrete-descriptor-set <index>]\n"
|
||||
"\t[--msl-multiview]\n"
|
||||
"\t[--msl-view-index-from-device-index]\n"
|
||||
@ -755,7 +759,11 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
|
||||
msl_opts.capture_output_to_buffer = args.msl_capture_output_to_buffer;
|
||||
msl_opts.swizzle_texture_samples = args.msl_swizzle_texture_samples;
|
||||
if (args.msl_ios)
|
||||
{
|
||||
msl_opts.platform = CompilerMSL::Options::iOS;
|
||||
msl_opts.ios_use_framebuffer_fetch_subpasses = args.msl_framebuffer_fetch;
|
||||
msl_opts.emulate_cube_array = args.msl_emulate_cube_array;
|
||||
}
|
||||
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;
|
||||
@ -1087,6 +1095,8 @@ static int main_inner(int argc, char *argv[])
|
||||
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("--msl-framebuffer-fetch", [&args](CLIParser &) { args.msl_framebuffer_fetch = true; });
|
||||
cbs.add("--msl-emulate-cube-array", [&args](CLIParser &) { args.msl_emulate_cube_array = true; });
|
||||
cbs.add("--msl-multiview", [&args](CLIParser &) { args.msl_multiview = true; });
|
||||
cbs.add("--msl-view-index-from-device-index",
|
||||
[&args](CLIParser &) { args.msl_view_index_from_device_index = true; });
|
||||
|
@ -238,10 +238,10 @@ struct main0_out
|
||||
float4 out_var_SV_Target0 [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(constant type_View& View [[buffer(0)]], constant type_Globals& _Globals [[buffer(1)]], texture2d<float> _gl_LastFragData [[texture(0)]], texture2d<float> ShadowDepthTexture [[texture(1)]], sampler ShadowDepthTextureSampler [[sampler(0)]], float4 gl_FragCoord [[position]])
|
||||
fragment main0_out main0(constant type_View& View [[buffer(0)]], constant type_Globals& _Globals [[buffer(1)]], float4 _gl_LastFragData [[color(0)]], texture2d<float> ShadowDepthTexture [[texture(1)]], sampler ShadowDepthTextureSampler [[sampler(0)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 _67 = _gl_LastFragData.read(uint2(gl_FragCoord.xy), 0);
|
||||
float4 _67 = _gl_LastFragData;
|
||||
float _68 = _67.w;
|
||||
float4 _82 = _Globals.ScreenToShadowMatrix * float4((((gl_FragCoord.xy * View.View_BufferSizeAndInvSize.zw) - View.View_ScreenPositionScaleBias.wz) / View.View_ScreenPositionScaleBias.xy) * float2(_68), _68, 1.0);
|
||||
float _118 = fast::clamp(((fast::clamp((ShadowDepthTexture.sample(ShadowDepthTextureSampler, (((_82.xyz / float3(_82.w)).xy * _Globals.ShadowTileOffsetAndSize.zw).xy + _Globals.ShadowTileOffsetAndSize.xy).xy, level(0.0)).xxx * float3(_Globals.SoftTransitionScale.z)) - float3((fast::min(_82.z, 0.999989986419677734375) * _Globals.SoftTransitionScale.z) - 1.0), float3(0.0), float3(1.0)).x - 0.5) * _Globals.ShadowSharpen) + 0.5, 0.0, 1.0);
|
22
reference/opt/shaders-msl/frag/texture-cube-array.frag
Normal file
22
reference/opt/shaders-msl/frag/texture-cube-array.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
|
||||
{
|
||||
float4 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texturecube<float> cubeSampler [[texture(0)]], texturecube_array<float> cubeArraySampler [[texture(1)]], texture2d_array<float> texArraySampler [[texture(2)]], sampler cubeSamplerSmplr [[sampler(0)]], sampler cubeArraySamplerSmplr [[sampler(1)]], sampler texArraySamplerSmplr [[sampler(2)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = (cubeSampler.sample(cubeSamplerSmplr, in.vUV.xyz) + cubeArraySampler.sample(cubeArraySamplerSmplr, in.vUV.xyz, uint(round(in.vUV.w)))) + texArraySampler.sample(texArraySamplerSmplr, in.vUV.xyz.xy, uint(round(in.vUV.xyz.z)));
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float4 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float3 spvCubemapTo2DArrayFace(float3 P)
|
||||
{
|
||||
float3 Coords = abs(P.xyz);
|
||||
float CubeFace = 0;
|
||||
float ProjectionAxis = 0;
|
||||
float u = 0;
|
||||
float v = 0;
|
||||
if (Coords.x >= Coords.y && Coords.x >= Coords.z)
|
||||
{
|
||||
CubeFace = P.x >= 0 ? 0 : 1;
|
||||
ProjectionAxis = Coords.x;
|
||||
u = P.x >= 0 ? -P.z : P.z;
|
||||
v = -P.y;
|
||||
}
|
||||
else if (Coords.y >= Coords.x && Coords.y >= Coords.z)
|
||||
{
|
||||
CubeFace = P.y >= 0 ? 2 : 3;
|
||||
ProjectionAxis = Coords.y;
|
||||
u = P.x;
|
||||
v = P.y >= 0 ? P.z : -P.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
CubeFace = P.z >= 0 ? 4 : 5;
|
||||
ProjectionAxis = Coords.z;
|
||||
u = P.z >= 0 ? P.x : -P.x;
|
||||
v = -P.y;
|
||||
}
|
||||
u = 0.5 * (u/ProjectionAxis + 1);
|
||||
v = 0.5 * (v/ProjectionAxis + 1);
|
||||
return float3(u, v, CubeFace);
|
||||
}
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texturecube<float> cubeSampler [[texture(0)]], texture2d_array<float> cubeArraySampler [[texture(1)]], texture2d_array<float> texArraySampler [[texture(2)]], sampler cubeSamplerSmplr [[sampler(0)]], sampler cubeArraySamplerSmplr [[sampler(1)]], sampler texArraySamplerSmplr [[sampler(2)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = (cubeSampler.sample(cubeSamplerSmplr, in.vUV.xyz) + cubeArraySampler.sample(cubeArraySamplerSmplr, spvCubemapTo2DArrayFace(in.vUV.xyz).xy, uint(spvCubemapTo2DArrayFace(in.vUV.xyz).z) + (uint(round(in.vUV.w)) * 6u))) + texArraySampler.sample(texArraySamplerSmplr, in.vUV.xyz.xy, uint(round(in.vUV.xyz.z)));
|
||||
return out;
|
||||
}
|
||||
|
@ -238,10 +238,10 @@ struct main0_out
|
||||
float4 out_var_SV_Target0 [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(constant type_View& View [[buffer(0)]], constant type_Globals& _Globals [[buffer(1)]], texture2d<float> _gl_LastFragData [[texture(0)]], texture2d<float> ShadowDepthTexture [[texture(1)]], sampler ShadowDepthTextureSampler [[sampler(0)]], float4 gl_FragCoord [[position]])
|
||||
fragment main0_out main0(constant type_View& View [[buffer(0)]], constant type_Globals& _Globals [[buffer(1)]], float4 _gl_LastFragData [[color(0)]], texture2d<float> ShadowDepthTexture [[texture(1)]], sampler ShadowDepthTextureSampler [[sampler(0)]], float4 gl_FragCoord [[position]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 _67 = _gl_LastFragData.read(uint2(gl_FragCoord.xy), 0);
|
||||
float4 _67 = _gl_LastFragData;
|
||||
float _68 = _67.w;
|
||||
float4 _82 = _Globals.ScreenToShadowMatrix * float4((((gl_FragCoord.xy * View.View_BufferSizeAndInvSize.zw) - View.View_ScreenPositionScaleBias.wz) / View.View_ScreenPositionScaleBias.xy) * float2(_68), _68, 1.0);
|
||||
float _118 = fast::clamp(((fast::clamp((ShadowDepthTexture.sample(ShadowDepthTextureSampler, (((_82.xyz / float3(_82.w)).xy * _Globals.ShadowTileOffsetAndSize.zw).xy + _Globals.ShadowTileOffsetAndSize.xy).xy, level(0.0)).xxx * float3(_Globals.SoftTransitionScale.z)) - float3((fast::min(_82.z, 0.999989986419677734375) * _Globals.SoftTransitionScale.z) - 1.0), float3(0.0), float3(1.0)).x - 0.5) * _Globals.ShadowSharpen) + 0.5, 0.0, 1.0);
|
25
reference/shaders-msl/frag/texture-cube-array.frag
Normal file
25
reference/shaders-msl/frag/texture-cube-array.frag
Normal file
@ -0,0 +1,25 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float4 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texturecube<float> cubeSampler [[texture(0)]], texturecube_array<float> cubeArraySampler [[texture(1)]], texture2d_array<float> texArraySampler [[texture(2)]], sampler cubeSamplerSmplr [[sampler(0)]], sampler cubeArraySamplerSmplr [[sampler(1)]], sampler texArraySamplerSmplr [[sampler(2)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 a = cubeSampler.sample(cubeSamplerSmplr, in.vUV.xyz);
|
||||
float4 b = cubeArraySampler.sample(cubeArraySamplerSmplr, in.vUV.xyz, uint(round(in.vUV.w)));
|
||||
float4 c = texArraySampler.sample(texArraySamplerSmplr, in.vUV.xyz.xy, uint(round(in.vUV.xyz.z)));
|
||||
out.FragColor = (a + b) + c;
|
||||
return out;
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float4 vUV [[user(locn0)]];
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float3 spvCubemapTo2DArrayFace(float3 P)
|
||||
{
|
||||
float3 Coords = abs(P.xyz);
|
||||
float CubeFace = 0;
|
||||
float ProjectionAxis = 0;
|
||||
float u = 0;
|
||||
float v = 0;
|
||||
if (Coords.x >= Coords.y && Coords.x >= Coords.z)
|
||||
{
|
||||
CubeFace = P.x >= 0 ? 0 : 1;
|
||||
ProjectionAxis = Coords.x;
|
||||
u = P.x >= 0 ? -P.z : P.z;
|
||||
v = -P.y;
|
||||
}
|
||||
else if (Coords.y >= Coords.x && Coords.y >= Coords.z)
|
||||
{
|
||||
CubeFace = P.y >= 0 ? 2 : 3;
|
||||
ProjectionAxis = Coords.y;
|
||||
u = P.x;
|
||||
v = P.y >= 0 ? P.z : -P.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
CubeFace = P.z >= 0 ? 4 : 5;
|
||||
ProjectionAxis = Coords.z;
|
||||
u = P.z >= 0 ? P.x : -P.x;
|
||||
v = -P.y;
|
||||
}
|
||||
u = 0.5 * (u/ProjectionAxis + 1);
|
||||
v = 0.5 * (v/ProjectionAxis + 1);
|
||||
return float3(u, v, CubeFace);
|
||||
}
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texturecube<float> cubeSampler [[texture(0)]], texture2d_array<float> cubeArraySampler [[texture(1)]], texture2d_array<float> texArraySampler [[texture(2)]], sampler cubeSamplerSmplr [[sampler(0)]], sampler cubeArraySamplerSmplr [[sampler(1)]], sampler texArraySamplerSmplr [[sampler(2)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float4 a = cubeSampler.sample(cubeSamplerSmplr, in.vUV.xyz);
|
||||
float4 b = cubeArraySampler.sample(cubeArraySamplerSmplr, spvCubemapTo2DArrayFace(in.vUV.xyz).xy, uint(spvCubemapTo2DArrayFace(in.vUV.xyz).z) + (uint(round(in.vUV.w)) * 6u));
|
||||
float4 c = texArraySampler.sample(texArraySamplerSmplr, in.vUV.xyz.xy, uint(round(in.vUV.xyz.z)));
|
||||
out.FragColor = (a + b) + c;
|
||||
return out;
|
||||
}
|
||||
|
16
shaders-msl/frag/texture-cube-array.frag
Normal file
16
shaders-msl/frag/texture-cube-array.frag
Normal file
@ -0,0 +1,16 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform samplerCube cubeSampler;
|
||||
layout(set = 0, binding = 1) uniform samplerCubeArray cubeArraySampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2DArray texArraySampler;
|
||||
|
||||
layout(location = 0) in vec4 vUV;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 a = texture(cubeSampler, vUV.xyz);
|
||||
vec4 b = texture(cubeArraySampler, vUV);
|
||||
vec4 c = texture(texArraySampler, vUV.xyz);
|
||||
FragColor = a + b + c;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#version 450
|
||||
|
||||
layout(set = 0, binding = 0) uniform samplerCube cubeSampler;
|
||||
layout(set = 0, binding = 1) uniform samplerCubeArray cubeArraySampler;
|
||||
layout(set = 0, binding = 2) uniform sampler2DArray texArraySampler;
|
||||
|
||||
layout(location = 0) in vec4 vUV;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 a = texture(cubeSampler, vUV.xyz);
|
||||
vec4 b = texture(cubeArraySampler, vUV);
|
||||
vec4 c = texture(texArraySampler, vUV.xyz);
|
||||
FragColor = a + b + c;
|
||||
}
|
@ -487,9 +487,6 @@ public:
|
||||
// The most common use here is to check if a buffer is readonly or writeonly.
|
||||
Bitset get_buffer_block_flags(VariableID id) const;
|
||||
|
||||
// Returns true if the target language supports combined texture-samplers. Returns fasle by default.
|
||||
virtual bool supports_combined_samplers() const;
|
||||
|
||||
protected:
|
||||
const uint32_t *stream(const Instruction &instr) const
|
||||
{
|
||||
@ -615,6 +612,9 @@ protected:
|
||||
void register_read(uint32_t expr, uint32_t chain, bool forwarded);
|
||||
void register_write(uint32_t chain);
|
||||
|
||||
// Returns true if the target language supports combined texture-samplers. Returns fasle by default.
|
||||
virtual bool supports_combined_samplers() const;
|
||||
|
||||
inline bool is_continue(uint32_t next) const
|
||||
{
|
||||
return (ir.block_meta[next] & ParsedIR::BLOCK_META_CONTINUE_BIT) != 0;
|
||||
|
@ -3437,6 +3437,11 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c)
|
||||
|
||||
return res;
|
||||
}
|
||||
else if (type.basetype == SPIRType::Struct && type.member_types.size() == 0)
|
||||
{
|
||||
// Metal tessellation likes empty structs which are then constant expressions.
|
||||
return "{ }";
|
||||
}
|
||||
else if (c.columns() == 1)
|
||||
{
|
||||
return constant_expression_vector(c, 0);
|
||||
@ -4023,18 +4028,6 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
}
|
||||
break;
|
||||
|
||||
// Metal tessellation likes empty structs which are then constant expressions.
|
||||
case SPIRType::Struct:
|
||||
if (type.member_types.size() == 0)
|
||||
{
|
||||
res += "{ }";
|
||||
}
|
||||
else
|
||||
{
|
||||
SPIRV_CROSS_THROW("Invalid constant struct initialisation missing member initializers.");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SPIRV_CROSS_THROW("Invalid constant expression basetype.");
|
||||
}
|
||||
|
@ -4782,7 +4782,7 @@ void CompilerMSL::declare_undefined_values()
|
||||
bool emitted = false;
|
||||
ir.for_each_typed_id<SPIRUndef>([&](uint32_t, SPIRUndef &undef) {
|
||||
auto &type = this->get<SPIRType>(undef.basetype);
|
||||
statement("constant ", CompilerGLSL::variable_decl(type, to_name(undef.self), undef.self), " = {};");
|
||||
statement("constant ", variable_decl(type, to_name(undef.self), undef.self), " = {};");
|
||||
emitted = true;
|
||||
});
|
||||
|
||||
@ -4805,7 +4805,7 @@ void CompilerMSL::declare_constant_arrays()
|
||||
if (!type.array.empty() && (is_scalar(type) || is_vector(type)))
|
||||
{
|
||||
auto name = to_name(c.self);
|
||||
statement("constant ", CompilerGLSL::variable_decl(type, name), " = ", constant_expression(c), ";");
|
||||
statement("constant ", variable_decl(type, name), " = ", constant_expression(c), ";");
|
||||
emitted = true;
|
||||
}
|
||||
});
|
||||
@ -4829,7 +4829,7 @@ void CompilerMSL::declare_complex_constant_arrays()
|
||||
if (!type.array.empty() && !(is_scalar(type) || is_vector(type)))
|
||||
{
|
||||
auto name = to_name(c.self);
|
||||
statement("", CompilerGLSL::variable_decl(type, name), " = ", constant_expression(c), ";");
|
||||
statement("", variable_decl(type, name), " = ", constant_expression(c), ";");
|
||||
emitted = true;
|
||||
}
|
||||
});
|
||||
@ -4940,7 +4940,7 @@ void CompilerMSL::emit_specialization_constants_and_structs()
|
||||
auto &c = id.get<SPIRConstantOp>();
|
||||
auto &type = get<SPIRType>(c.basetype);
|
||||
auto name = to_name(c.self);
|
||||
statement("constant ", CompilerGLSL::variable_decl(type, name), " = ", constant_op_expression(c), ";");
|
||||
statement("constant ", variable_decl(type, name), " = ", constant_op_expression(c), ";");
|
||||
emitted = true;
|
||||
}
|
||||
else if (id.get_type() == TypeType)
|
||||
@ -5066,7 +5066,7 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l
|
||||
if (is_matrix(*type) || is_array(*type) || type->basetype == SPIRType::Struct)
|
||||
{
|
||||
std::string temp_name = join(to_name(var->self), "_", ops[1]);
|
||||
statement(CompilerGLSL::variable_decl(*type, temp_name, var->self), ";");
|
||||
statement(variable_decl(*type, temp_name, var->self), ";");
|
||||
// Set up the initializer for this temporary variable.
|
||||
indices.push_back(const_mbr_id);
|
||||
if (type->basetype == SPIRType::Struct)
|
||||
@ -6123,43 +6123,32 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
||||
|
||||
void CompilerMSL::emit_texture_op(const Instruction &i)
|
||||
{
|
||||
auto *ops = stream(i);
|
||||
auto op = static_cast<Op>(i.op);
|
||||
|
||||
SmallVector<uint32_t> inherited_expressions;
|
||||
|
||||
uint32_t result_type_id = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
uint32_t img = ops[2];
|
||||
|
||||
auto &type = expression_type(img);
|
||||
auto &imgtype = get<SPIRType>(type.self);
|
||||
|
||||
bool forward = false;
|
||||
string expr = to_texture_op(i, &forward, inherited_expressions);
|
||||
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
if (imgtype.image.dim == DimSubpassData && msl_options.is_ios() && msl_options.ios_use_framebuffer_fetch_subpasses)
|
||||
if (msl_options.is_ios() && msl_options.ios_use_framebuffer_fetch_subpasses)
|
||||
{
|
||||
expr = to_expression(img);
|
||||
auto *ops = stream(i);
|
||||
|
||||
uint32_t result_type_id = ops[0];
|
||||
uint32_t id = ops[1];
|
||||
uint32_t img = ops[2];
|
||||
|
||||
auto &type = expression_type(img);
|
||||
auto &imgtype = get<SPIRType>(type.self);
|
||||
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
if (imgtype.image.dim == DimSubpassData)
|
||||
{
|
||||
SmallVector<uint32_t> inherited_expressions;
|
||||
bool forward = false;
|
||||
to_texture_op(i, &forward, inherited_expressions);
|
||||
|
||||
string expr = to_expression(img);
|
||||
emit_op(result_type_id, id, expr, forward);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
emit_op(result_type_id, id, expr, forward);
|
||||
for (auto &inherit : inherited_expressions)
|
||||
inherit_expression_dependencies(id, inherit);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case OpImageSampleDrefImplicitLod:
|
||||
case OpImageSampleImplicitLod:
|
||||
case OpImageSampleProjImplicitLod:
|
||||
case OpImageSampleProjDrefImplicitLod:
|
||||
register_control_dependent_expression(id);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Fallback to default implementation
|
||||
CompilerGLSL::emit_texture_op(i);
|
||||
}
|
||||
|
||||
void CompilerMSL::emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem)
|
||||
@ -7261,7 +7250,7 @@ string CompilerMSL::to_function_args(VariableID img, const SPIRType &imgtype, bo
|
||||
if (!farg_str.empty())
|
||||
farg_str += ", ";
|
||||
|
||||
if (imgtype.image.arrayed && msl_options.emulate_cube_array)
|
||||
if (imgtype.image.dim == DimCube && imgtype.image.arrayed && msl_options.emulate_cube_array)
|
||||
{
|
||||
farg_str += "spvCubemapTo2DArrayFace(" + tex_coords + ").xy";
|
||||
|
||||
@ -7269,7 +7258,7 @@ string CompilerMSL::to_function_args(VariableID img, const SPIRType &imgtype, bo
|
||||
farg_str += ", uint(" + to_extract_component_expression(coord, 2) + ")";
|
||||
else
|
||||
farg_str += ", uint(spvCubemapTo2DArrayFace(" + tex_coords + ").z) + (uint(" +
|
||||
to_extract_component_expression(coord, 2) + ") * 6u)";
|
||||
round_fp_tex_coords(to_extract_component_expression(coord, alt_coord_component), coord_is_fp) + ") * 6u)";
|
||||
|
||||
add_spv_func_and_recompile(SPVFuncImplCubemapTo2DArrayFace);
|
||||
}
|
||||
@ -10275,6 +10264,12 @@ std::string CompilerMSL::variable_decl(const SPIRVariable &variable)
|
||||
return expr;
|
||||
}
|
||||
|
||||
// GCC workaround of lambdas calling protected funcs
|
||||
std::string CompilerMSL::variable_decl(const SPIRType &type, const std::string &name, uint32_t id)
|
||||
{
|
||||
return CompilerGLSL::variable_decl(type, name, id);
|
||||
}
|
||||
|
||||
std::string CompilerMSL::sampler_type(const SPIRType &type)
|
||||
{
|
||||
if (!type.array.empty())
|
||||
@ -10395,11 +10390,14 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
||||
else
|
||||
img_type_name += "texture2d";
|
||||
break;
|
||||
case Dim2D:
|
||||
case DimSubpassData:
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
if (msl_options.is_ios() && msl_options.ios_use_framebuffer_fetch_subpasses)
|
||||
if (img_type.dim == DimSubpassData && msl_options.is_ios() &&
|
||||
msl_options.ios_use_framebuffer_fetch_subpasses)
|
||||
{
|
||||
return type_to_glsl(get<SPIRType>(img_type.type));
|
||||
case Dim2D:
|
||||
}
|
||||
if (img_type.ms && img_type.arrayed)
|
||||
{
|
||||
if (!msl_options.supports_msl_version(2, 1))
|
||||
|
@ -291,7 +291,7 @@ public:
|
||||
bool ios_support_base_vertex_instance = false;
|
||||
|
||||
// Use Metal's native frame-buffer fetch API for subpass inputs.
|
||||
bool ios_use_framebuffer_fetch_subpasses = true;
|
||||
bool ios_use_framebuffer_fetch_subpasses = false;
|
||||
|
||||
// Storage buffer robustness - clamps access to SSBOs to the size of the buffer
|
||||
bool enforce_storge_buffer_bounds = false;
|
||||
@ -576,9 +576,16 @@ protected:
|
||||
const std::string &qualifier = "", uint32_t base_offset = 0) override;
|
||||
void emit_struct_padding_target(const SPIRType &type) override;
|
||||
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string type_to_array_glsl(
|
||||
const SPIRType &type) override; // Allow Metal to use the array<T> template to make arrays a value type
|
||||
std::string variable_decl(const SPIRVariable &variable) override; // Threadgroup arrays can't have a wrapper type
|
||||
|
||||
// Allow Metal to use the array<T> template to make arrays a value type
|
||||
std::string type_to_array_glsl(const SPIRType &type) override;
|
||||
|
||||
// Threadgroup arrays can't have a wrapper type
|
||||
std::string variable_decl(const SPIRVariable &variable) override;
|
||||
|
||||
// GCC workaround of lambdas calling protected functions (for older GCC versions)
|
||||
std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0) override;
|
||||
|
||||
std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override;
|
||||
std::string sampler_type(const SPIRType &type);
|
||||
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
|
||||
|
@ -195,6 +195,10 @@ def cross_compile_msl(shader, spirv, opt, iterations, paths):
|
||||
msl_args.append('--msl-argument-buffers')
|
||||
if '.texture-buffer-native.' in shader:
|
||||
msl_args.append('--msl-texture-buffer-native')
|
||||
if '.framebuffer-fetch.' in shader:
|
||||
msl_args.append('--msl-framebuffer-fetch')
|
||||
if '.emulate-cube-array.' in shader:
|
||||
msl_args.append('--msl-emulate-cube-array')
|
||||
if '.discrete.' in shader:
|
||||
# Arbitrary for testing purposes.
|
||||
msl_args.append('--msl-discrete-descriptor-set')
|
||||
|
Loading…
Reference in New Issue
Block a user