MSL: Support MinLod operand.

This commit is contained in:
Hans-Kristian Arntzen 2019-06-11 11:10:16 +02:00
parent 05ea055096
commit f171d82590
8 changed files with 122 additions and 10 deletions

View 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
{
float2 vUV [[user(locn0)]];
};
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, in.vUV, min_lod_clamp(4.0));
return out;
}

View 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
{
float2 vUV [[user(locn0)]];
};
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, in.vUV, min_lod_clamp(4.0));
return out;
}

View File

@ -0,0 +1,42 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 21
; Schema: 0
OpCapability Shader
OpCapability MinLod
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %FragColor %vUV
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpName %main "main"
OpName %FragColor "FragColor"
OpName %uSampler "uSampler"
OpName %vUV "vUV"
OpDecorate %FragColor Location 0
OpDecorate %uSampler DescriptorSet 0
OpDecorate %uSampler Binding 0
OpDecorate %vUV Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%FragColor = OpVariable %_ptr_Output_v4float Output
%10 = OpTypeImage %float 2D 0 0 0 1 Unknown
%11 = OpTypeSampledImage %10
%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
%uSampler = OpVariable %_ptr_UniformConstant_11 UniformConstant
%v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
%vUV = OpVariable %_ptr_Input_v2float Input
%float_4 = OpConstant %float 4
%main = OpFunction %void None %3
%5 = OpLabel
%14 = OpLoad %11 %uSampler
%18 = OpLoad %v2float %vUV
%20 = OpImageSampleImplicitLod %v4float %14 %18 MinLod %float_4
OpStore %FragColor %20
OpReturn
OpFunctionEnd

View File

@ -4700,6 +4700,7 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
uint32_t offset = 0;
uint32_t coffsets = 0;
uint32_t sample = 0;
uint32_t minlod = 0;
uint32_t flags = 0;
if (length)
@ -4725,14 +4726,15 @@ void CompilerGLSL::emit_texture_op(const Instruction &i)
test(offset, ImageOperandsOffsetMask);
test(coffsets, ImageOperandsConstOffsetsMask);
test(sample, ImageOperandsSampleMask);
test(minlod, ImageOperandsMinLodMask);
string expr;
bool forward = false;
expr += to_function_name(img, imgtype, !!fetch, !!gather, !!proj, !!coffsets, (!!coffset || !!offset),
(!!grad_x || !!grad_y), !!dref, lod);
(!!grad_x || !!grad_y), !!dref, lod, minlod);
expr += "(";
expr += to_function_args(img, imgtype, fetch, gather, proj, coord, coord_components, dref, grad_x, grad_y, lod,
coffset, offset, bias, comp, sample, &forward);
coffset, offset, bias, comp, sample, minlod, &forward);
expr += ")";
// texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here.
@ -4797,8 +4799,11 @@ bool CompilerGLSL::expression_is_constant_null(uint32_t id) const
// For some subclasses, the function is a method on the specified image.
string CompilerGLSL::to_function_name(uint32_t tex, const SPIRType &imgtype, bool is_fetch, bool is_gather,
bool is_proj, bool has_array_offsets, bool has_offset, bool has_grad, bool,
uint32_t lod)
uint32_t lod, uint32_t minlod)
{
if (minlod != 0)
SPIRV_CROSS_THROW("Sparse texturing not yet supported.");
string fname;
// textureLod on sampler2DArrayShadow and samplerCubeShadow does not exist in GLSL for some reason.
@ -4877,7 +4882,7 @@ std::string CompilerGLSL::convert_separate_image_to_expression(uint32_t id)
string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
bool is_proj, uint32_t coord, uint32_t coord_components, uint32_t dref,
uint32_t grad_x, uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset,
uint32_t bias, uint32_t comp, uint32_t sample, bool *p_forward)
uint32_t bias, uint32_t comp, uint32_t sample, uint32_t /*minlod*/, bool *p_forward)
{
string farg_str;
if (is_fetch)

View File

@ -257,11 +257,12 @@ protected:
virtual std::string to_func_call_arg(uint32_t id);
virtual std::string to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
bool is_proj, bool has_array_offsets, bool has_offset, bool has_grad,
bool has_dref, uint32_t lod);
bool has_dref, uint32_t lod, uint32_t minlod);
virtual std::string to_function_args(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather,
bool is_proj, uint32_t coord, uint32_t coord_components, uint32_t dref,
uint32_t grad_x, uint32_t grad_y, uint32_t lod, uint32_t coffset,
uint32_t offset, uint32_t bias, uint32_t comp, uint32_t sample,
uint32_t minlod,
bool *p_forward);
virtual void emit_buffer_block(const SPIRVariable &type);
virtual void emit_push_constant_block(const SPIRVariable &var);

View File

@ -2536,6 +2536,7 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
uint32_t offset = 0;
uint32_t coffsets = 0;
uint32_t sample = 0;
uint32_t minlod = 0;
uint32_t flags = 0;
if (length)
@ -2562,10 +2563,14 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
test(offset, ImageOperandsOffsetMask);
test(coffsets, ImageOperandsConstOffsetsMask);
test(sample, ImageOperandsSampleMask);
test(minlod, ImageOperandsMinLodMask);
string expr;
string texop;
if (minlod != 0)
SPIRV_CROSS_THROW("MinLod texture operand not supported in HLSL.");
if (op == OpImageFetch)
{
if (hlsl_options.shader_model < 40)

View File

@ -3849,7 +3849,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
statement(join(
to_expression(img_id), ".write(", remap_swizzle(store_type, texel_type.vecsize, to_expression(texel_id)),
", ",
to_function_args(img_id, img_type, true, false, false, coord_id, 0, 0, 0, 0, lod, 0, 0, 0, 0, 0, &forward),
to_function_args(img_id, img_type, true, false, false, coord_id, 0, 0, 0, 0, lod, 0, 0, 0, 0, 0, 0, &forward),
");"));
if (p_var && variable_storage_is_aliased(*p_var))
@ -4661,7 +4661,7 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
// Returns the texture sampling function string for the specified image and sampling characteristics.
string CompilerMSL::to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool, bool,
bool has_offset, bool, bool has_dref, uint32_t)
bool has_offset, bool, bool has_dref, uint32_t, uint32_t)
{
// Special-case gather. We have to alter the component being looked up
// in the swizzle case.
@ -4721,7 +4721,7 @@ string CompilerMSL::to_function_name(uint32_t img, const SPIRType &imgtype, bool
string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
uint32_t coord, uint32_t, uint32_t dref, uint32_t grad_x, uint32_t grad_y,
uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias, uint32_t comp,
uint32_t sample, bool *p_forward)
uint32_t sample, uint32_t minlod, bool *p_forward)
{
string farg_str;
if (!is_fetch)
@ -4978,6 +4978,20 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
farg_str += ", gradient" + grad_opt + "(" + to_expression(grad_x) + ", " + to_expression(grad_y) + ")";
}
if (minlod)
{
if (msl_options.is_macos())
{
if (!msl_options.supports_msl_version(2, 2))
SPIRV_CROSS_THROW("min_lod_clamp() is only supported in MSL 2.2+ and up on macOS.");
}
else if (msl_options.is_ios())
SPIRV_CROSS_THROW("min_lod_clamp() is not supported on iOS.");
forward = forward && should_forward(minlod);
farg_str += ", min_lod_clamp(" + to_expression(minlod) + ")";
}
// Add offsets
string offset_expr;
if (coffset && !is_fetch)
@ -5026,6 +5040,7 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
if (sample)
{
forward = forward && should_forward(sample);
farg_str += ", ";
farg_str += to_expression(sample);
}

View File

@ -398,11 +398,11 @@ protected:
std::string to_name(uint32_t id, bool allow_alias = true) const override;
std::string to_function_name(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
bool has_array_offsets, bool has_offset, bool has_grad, bool has_dref,
uint32_t lod) override;
uint32_t lod, uint32_t minlod) override;
std::string to_function_args(uint32_t img, const SPIRType &imgtype, bool is_fetch, bool is_gather, bool is_proj,
uint32_t coord, uint32_t coord_components, uint32_t dref, uint32_t grad_x,
uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias,
uint32_t comp, uint32_t sample, bool *p_forward) override;
uint32_t comp, uint32_t sample, uint32_t minlod, bool *p_forward) override;
std::string to_initializer_expression(const SPIRVariable &var) override;
std::string unpack_expression_type(std::string expr_str, const SPIRType &type, uint32_t packed_type_id) override;
std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override;