Merge pull request #2350 from etang-cw/QueryLod

Fix MSL for OpImageQueryLod on a vector larger than needed
This commit is contained in:
Hans-Kristian Arntzen 2024-07-15 12:02:06 +02:00 committed by GitHub
commit c1bf9099b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 180 additions and 2 deletions

View File

@ -0,0 +1,37 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 LOD [[color(0)]];
};
struct main0_in
{
float4 Coord [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> Texture0 [[texture(0)]], texture2d_array<float> Texture1 [[texture(1)]], texture3d<float> Texture2 [[texture(2)]], texturecube<float> Texture3 [[texture(3)]], texturecube_array<float> Texture4 [[texture(4)]], sampler Texture0Smplr [[sampler(0)]], sampler Texture1Smplr [[sampler(1)]], sampler Texture2Smplr [[sampler(2)]], sampler Texture3Smplr [[sampler(3)]], sampler Texture4Smplr [[sampler(4)]])
{
main0_out out = {};
float2 _44;
_44.x = Texture0.calculate_clamped_lod(Texture0Smplr, in.Coord.xy);
_44.y = Texture0.calculate_unclamped_lod(Texture0Smplr, in.Coord.xy);
float2 _45;
_45.x = Texture1.calculate_clamped_lod(Texture1Smplr, in.Coord.xy);
_45.y = Texture1.calculate_unclamped_lod(Texture1Smplr, in.Coord.xy);
float2 _46;
_46.x = Texture2.calculate_clamped_lod(Texture2Smplr, in.Coord.xyz);
_46.y = Texture2.calculate_unclamped_lod(Texture2Smplr, in.Coord.xyz);
float2 _47;
_47.x = Texture3.calculate_clamped_lod(Texture3Smplr, in.Coord.xyz);
_47.y = Texture3.calculate_unclamped_lod(Texture3Smplr, in.Coord.xyz);
float2 _48;
_48.x = Texture4.calculate_clamped_lod(Texture4Smplr, in.Coord.xyz);
_48.y = Texture4.calculate_unclamped_lod(Texture4Smplr, in.Coord.xyz);
out.LOD = ((_44 + _45) + (_46 + _47)) + _48;
return out;
}

View File

@ -0,0 +1,37 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float2 LOD [[color(0)]];
};
struct main0_in
{
float4 Coord [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> Texture0 [[texture(0)]], texture2d_array<float> Texture1 [[texture(1)]], texture3d<float> Texture2 [[texture(2)]], texturecube<float> Texture3 [[texture(3)]], texturecube_array<float> Texture4 [[texture(4)]], sampler Texture0Smplr [[sampler(0)]], sampler Texture1Smplr [[sampler(1)]], sampler Texture2Smplr [[sampler(2)]], sampler Texture3Smplr [[sampler(3)]], sampler Texture4Smplr [[sampler(4)]])
{
main0_out out = {};
float2 _44;
_44.x = Texture0.calculate_clamped_lod(Texture0Smplr, in.Coord.xy);
_44.y = Texture0.calculate_unclamped_lod(Texture0Smplr, in.Coord.xy);
float2 _45;
_45.x = Texture1.calculate_clamped_lod(Texture1Smplr, in.Coord.xy);
_45.y = Texture1.calculate_unclamped_lod(Texture1Smplr, in.Coord.xy);
float2 _46;
_46.x = Texture2.calculate_clamped_lod(Texture2Smplr, in.Coord.xyz);
_46.y = Texture2.calculate_unclamped_lod(Texture2Smplr, in.Coord.xyz);
float2 _47;
_47.x = Texture3.calculate_clamped_lod(Texture3Smplr, in.Coord.xyz);
_47.y = Texture3.calculate_unclamped_lod(Texture3Smplr, in.Coord.xyz);
float2 _48;
_48.x = Texture4.calculate_clamped_lod(Texture4Smplr, in.Coord.xyz);
_48.y = Texture4.calculate_unclamped_lod(Texture4Smplr, in.Coord.xyz);
out.LOD = ((_44 + _45) + (_46 + _47)) + _48;
return out;
}

View File

@ -0,0 +1,82 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 6
; Bound: 19
; Schema: 0
OpCapability Shader
OpCapability ImageQuery
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %LOD %Coord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpName %main "main"
OpName %LOD "LOD"
OpName %Coord "Coord"
OpName %Texture0 "Texture0"
OpName %Texture1 "Texture1"
OpName %Texture2 "Texture2"
OpName %Texture3 "Texture3"
OpName %Texture4 "Texture4"
OpDecorate %LOD Location 0
OpDecorate %Coord Location 0
OpDecorate %Texture0 DescriptorSet 0
OpDecorate %Texture0 Binding 0
OpDecorate %Texture1 DescriptorSet 0
OpDecorate %Texture1 Binding 1
OpDecorate %Texture2 DescriptorSet 0
OpDecorate %Texture2 Binding 2
OpDecorate %Texture3 DescriptorSet 0
OpDecorate %Texture3 Binding 3
OpDecorate %Texture4 DescriptorSet 0
OpDecorate %Texture4 Binding 4
%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
%float = OpTypeFloat 32
%v2float = OpTypeVector %float 2
%v4float = OpTypeVector %float 4
%_ptr_Output_v2float = OpTypePointer Output %v2float
%_ptr_Input_v4float = OpTypePointer Input %v4float
%LOD = OpVariable %_ptr_Output_v2float Output
%Coord = OpVariable %_ptr_Input_v4float Input
%tex2d = OpTypeImage %float 2D 0 0 0 1 Unknown
%tex2darr = OpTypeImage %float 2D 0 1 0 1 Unknown
%tex3d = OpTypeImage %float 3D 0 0 0 1 Unknown
%texcube = OpTypeImage %float Cube 0 0 0 1 Unknown
%texcubearr = OpTypeImage %float Cube 0 1 0 1 Unknown
%samp2d = OpTypeSampledImage %tex2d
%samp2darr = OpTypeSampledImage %tex2darr
%samp3d = OpTypeSampledImage %tex3d
%sampcube = OpTypeSampledImage %texcube
%sampcubearr = OpTypeSampledImage %texcubearr
%pucs2d = OpTypePointer UniformConstant %samp2d
%pucs2darr = OpTypePointer UniformConstant %samp2darr
%pucs3d = OpTypePointer UniformConstant %samp3d
%pucscube = OpTypePointer UniformConstant %sampcube
%pucscubearr = OpTypePointer UniformConstant %sampcubearr
%Texture0 = OpVariable %pucs2d UniformConstant
%Texture1 = OpVariable %pucs2darr UniformConstant
%Texture2 = OpVariable %pucs3d UniformConstant
%Texture3 = OpVariable %pucscube UniformConstant
%Texture4 = OpVariable %pucscubearr UniformConstant
%main = OpFunction %void None %3
%5 = OpLabel
%coord = OpLoad %v4float %Coord
%t0 = OpLoad %samp2d %Texture0
%t1 = OpLoad %samp2darr %Texture1
%t2 = OpLoad %samp3d %Texture2
%t3 = OpLoad %sampcube %Texture3
%t4 = OpLoad %sampcubearr %Texture4
%l0 = OpImageQueryLod %v2float %t0 %coord
%l1 = OpImageQueryLod %v2float %t1 %coord
%l2 = OpImageQueryLod %v2float %t2 %coord
%l3 = OpImageQueryLod %v2float %t3 %coord
%l4 = OpImageQueryLod %v2float %t4 %coord
%10 = OpFAdd %v2float %l0 %l1
%11 = OpFAdd %v2float %l2 %l3
%12 = OpFAdd %v2float %10 %11
%13 = OpFAdd %v2float %12 %l4
OpStore %LOD %13
OpReturn
OpFunctionEnd

View File

@ -9258,18 +9258,40 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
uint32_t coord_id = ops[3];
emit_uninitialized_temporary_expression(result_type, id);
std::string coord_expr = to_expression(coord_id);
auto sampler_expr = to_sampler_expression(image_id);
auto *combined = maybe_get<SPIRCombinedImageSampler>(image_id);
auto image_expr = combined ? to_expression(combined->image) : to_expression(image_id);
const SPIRType &image_type = expression_type(image_id);
const SPIRType &coord_type = expression_type(coord_id);
switch (image_type.image.dim)
{
case Dim1D:
if (!msl_options.texture_1D_as_2D)
SPIRV_CROSS_THROW("ImageQueryLod is not supported on 1D textures.");
[[fallthrough]];
case Dim2D:
if (coord_type.vecsize > 2)
coord_expr = enclose_expression(coord_expr) + ".xy";
break;
case DimCube:
case Dim3D:
if (coord_type.vecsize > 3)
coord_expr = enclose_expression(coord_expr) + ".xyz";
break;
default:
SPIRV_CROSS_THROW("Bad image type given to OpImageQueryLod");
}
// TODO: It is unclear if calculcate_clamped_lod also conditionally rounds
// the reported LOD based on the sampler. NEAREST miplevel should
// round the LOD, but LINEAR miplevel should not round.
// Let's hope this does not become an issue ...
statement(to_expression(id), ".x = ", image_expr, ".calculate_clamped_lod(", sampler_expr, ", ",
to_expression(coord_id), ");");
coord_expr, ");");
statement(to_expression(id), ".y = ", image_expr, ".calculate_unclamped_lod(", sampler_expr, ", ",
to_expression(coord_id), ");");
coord_expr, ");");
register_control_dependent_expression(id);
break;
}