Implement workaround for textureLod on 2D array shadow.
This does not exist in GLSL, but it exists in HLSL if LOD == 0.0.
This commit is contained in:
Родитель
c6051bbbfa
Коммит
ad2b7c05e7
|
@ -0,0 +1,27 @@
|
|||
#version 450
|
||||
|
||||
uniform sampler2DArrayShadow SPIRV_Cross_CombinedShadowMapShadowSamplerPCF;
|
||||
|
||||
layout(location = 0) in vec2 texCoords;
|
||||
layout(location = 1) in float cascadeIndex;
|
||||
layout(location = 2) in float fragDepth;
|
||||
layout(location = 0) out vec4 _entryPointOutput;
|
||||
|
||||
vec4 _main(vec2 texCoords_1, float cascadeIndex_1, float fragDepth_1)
|
||||
{
|
||||
vec4 _60 = vec4(vec3(texCoords_1, cascadeIndex_1), fragDepth_1);
|
||||
float c = textureGrad(SPIRV_Cross_CombinedShadowMapShadowSamplerPCF, vec4(_60.xyz, _60.w), vec2(0.0), vec2(0.0));
|
||||
return vec4(c, c, c, c);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 texCoords_1 = texCoords;
|
||||
float cascadeIndex_1 = cascadeIndex;
|
||||
float fragDepth_1 = fragDepth;
|
||||
vec2 param = texCoords_1;
|
||||
float param_1 = cascadeIndex_1;
|
||||
float param_2 = fragDepth_1;
|
||||
_entryPointOutput = _main(param, param_1, param_2);
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#version 450
|
||||
|
||||
in float v0;
|
||||
in float v1;
|
||||
out float FragColor;
|
||||
layout(location = 0) in float v0;
|
||||
layout(location = 1) in float v1;
|
||||
layout(location = 0) out float FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 1
|
||||
; Bound: 70
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main" %texCoords_1 %cascadeIndex_1 %fragDepth_1 %_entryPointOutput
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
OpName %_main_vf2_f1_f1_ "@main(vf2;f1;f1;"
|
||||
OpName %texCoords "texCoords"
|
||||
OpName %cascadeIndex "cascadeIndex"
|
||||
OpName %fragDepth "fragDepth"
|
||||
OpName %c "c"
|
||||
OpName %ShadowMap "ShadowMap"
|
||||
OpName %ShadowSamplerPCF "ShadowSamplerPCF"
|
||||
OpName %texCoords_0 "texCoords"
|
||||
OpName %texCoords_1 "texCoords"
|
||||
OpName %cascadeIndex_0 "cascadeIndex"
|
||||
OpName %cascadeIndex_1 "cascadeIndex"
|
||||
OpName %fragDepth_0 "fragDepth"
|
||||
OpName %fragDepth_1 "fragDepth"
|
||||
OpName %_entryPointOutput "@entryPointOutput"
|
||||
OpName %param "param"
|
||||
OpName %param_0 "param"
|
||||
OpName %param_1 "param"
|
||||
OpDecorate %ShadowMap DescriptorSet 0
|
||||
OpDecorate %ShadowSamplerPCF DescriptorSet 0
|
||||
OpDecorate %texCoords_1 Location 0
|
||||
OpDecorate %cascadeIndex_1 Location 1
|
||||
OpDecorate %fragDepth_1 Location 2
|
||||
OpDecorate %_entryPointOutput Location 0
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%v4float = OpTypeVector %float 4
|
||||
%11 = OpTypeFunction %v4float %_ptr_Function_v2float %_ptr_Function_float %_ptr_Function_float
|
||||
%18 = OpTypeImage %float 2D 0 1 0 1 Unknown
|
||||
%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
|
||||
%ShadowMap = OpVariable %_ptr_UniformConstant_18 UniformConstant
|
||||
%22 = OpTypeSampler
|
||||
%_ptr_UniformConstant_22 = OpTypePointer UniformConstant %22
|
||||
%ShadowSamplerPCF = OpVariable %_ptr_UniformConstant_22 UniformConstant
|
||||
%26 = OpTypeImage %float 2D 1 1 0 1 Unknown
|
||||
%27 = OpTypeSampledImage %26
|
||||
%v3float = OpTypeVector %float 3
|
||||
%float_0 = OpConstant %float 0
|
||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
||||
%texCoords_1 = OpVariable %_ptr_Input_v2float Input
|
||||
%_ptr_Input_float = OpTypePointer Input %float
|
||||
%cascadeIndex_1 = OpVariable %_ptr_Input_float Input
|
||||
%fragDepth_1 = OpVariable %_ptr_Input_float Input
|
||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
||||
%_entryPointOutput = OpVariable %_ptr_Output_v4float Output
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%texCoords_0 = OpVariable %_ptr_Function_v2float Function
|
||||
%cascadeIndex_0 = OpVariable %_ptr_Function_float Function
|
||||
%fragDepth_0 = OpVariable %_ptr_Function_float Function
|
||||
%param = OpVariable %_ptr_Function_v2float Function
|
||||
%param_0 = OpVariable %_ptr_Function_float Function
|
||||
%param_1 = OpVariable %_ptr_Function_float Function
|
||||
%53 = OpLoad %v2float %texCoords_1
|
||||
OpStore %texCoords_0 %53
|
||||
%57 = OpLoad %float %cascadeIndex_1
|
||||
OpStore %cascadeIndex_0 %57
|
||||
%60 = OpLoad %float %fragDepth_1
|
||||
OpStore %fragDepth_0 %60
|
||||
%64 = OpLoad %v2float %texCoords_0
|
||||
OpStore %param %64
|
||||
%66 = OpLoad %float %cascadeIndex_0
|
||||
OpStore %param_0 %66
|
||||
%68 = OpLoad %float %fragDepth_0
|
||||
OpStore %param_1 %68
|
||||
%69 = OpFunctionCall %v4float %_main_vf2_f1_f1_ %param %param_0 %param_1
|
||||
OpStore %_entryPointOutput %69
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%_main_vf2_f1_f1_ = OpFunction %v4float None %11
|
||||
%texCoords = OpFunctionParameter %_ptr_Function_v2float
|
||||
%cascadeIndex = OpFunctionParameter %_ptr_Function_float
|
||||
%fragDepth = OpFunctionParameter %_ptr_Function_float
|
||||
%16 = OpLabel
|
||||
%c = OpVariable %_ptr_Function_float Function
|
||||
%21 = OpLoad %18 %ShadowMap
|
||||
%25 = OpLoad %22 %ShadowSamplerPCF
|
||||
%28 = OpSampledImage %27 %21 %25
|
||||
%29 = OpLoad %v2float %texCoords
|
||||
%30 = OpLoad %float %cascadeIndex
|
||||
%32 = OpCompositeExtract %float %29 0
|
||||
%33 = OpCompositeExtract %float %29 1
|
||||
%34 = OpCompositeConstruct %v3float %32 %33 %30
|
||||
%35 = OpLoad %float %fragDepth
|
||||
%36 = OpCompositeExtract %float %34 0
|
||||
%37 = OpCompositeExtract %float %34 1
|
||||
%38 = OpCompositeExtract %float %34 2
|
||||
%39 = OpCompositeConstruct %v4float %36 %37 %38 %35
|
||||
%41 = OpCompositeExtract %float %39 3
|
||||
%42 = OpImageSampleDrefExplicitLod %float %28 %39 %41 Lod %float_0
|
||||
OpStore %c %42
|
||||
%43 = OpLoad %float %c
|
||||
%44 = OpLoad %float %c
|
||||
%45 = OpLoad %float %c
|
||||
%46 = OpLoad %float %c
|
||||
%47 = OpCompositeConstruct %v4float %43 %44 %45 %46
|
||||
OpReturnValue %47
|
||||
OpFunctionEnd
|
|
@ -15,6 +15,9 @@
|
|||
OpName %b "b"
|
||||
OpName %v1 "v1"
|
||||
OpName %FragColor "FragColor"
|
||||
OpDecorate %v0 Location 0
|
||||
OpDecorate %v1 Location 1
|
||||
OpDecorate %FragColor Location 0
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%float = OpTypeFloat 32
|
||||
|
|
|
@ -2973,6 +2973,19 @@ string CompilerGLSL::to_function_name(uint32_t, const SPIRType &imgtype, bool is
|
|||
{
|
||||
string fname;
|
||||
|
||||
// textureLod on sampler2DArrayShadow does not exist in GLSL for some reason.
|
||||
// To emulate this, we will have to use textureGrad with a constant gradient of 0.
|
||||
// The workaround will assert that the LOD is in fact constant 0, or we cannot emit correct code.
|
||||
// This happens for HLSL SampleCmpLevelZero on Texture2DArray.
|
||||
bool workaround_lod_array_shadow_as_grad = false;
|
||||
if (imgtype.image.arrayed && imgtype.image.dim == Dim2D && imgtype.image.depth && lod)
|
||||
{
|
||||
auto *constant_lod = maybe_get<SPIRConstant>(lod);
|
||||
if (!constant_lod || constant_lod->scalar_f32() != 0.0f)
|
||||
SPIRV_CROSS_THROW("textureLod on sampler2DArraySahdow is not constant 0.0. This cannot be expressed in GLSL.");
|
||||
workaround_lod_array_shadow_as_grad = true;
|
||||
}
|
||||
|
||||
if (is_fetch)
|
||||
fname += "texelFetch";
|
||||
else
|
||||
|
@ -2985,9 +2998,9 @@ string CompilerGLSL::to_function_name(uint32_t, const SPIRType &imgtype, bool is
|
|||
fname += "Offsets";
|
||||
if (is_proj)
|
||||
fname += "Proj";
|
||||
if (has_grad)
|
||||
if (has_grad || workaround_lod_array_shadow_as_grad)
|
||||
fname += "Grad";
|
||||
if (!!lod)
|
||||
if (!!lod && !workaround_lod_array_shadow_as_grad)
|
||||
fname += "Lod";
|
||||
}
|
||||
|
||||
|
@ -2998,7 +3011,7 @@ string CompilerGLSL::to_function_name(uint32_t, const SPIRType &imgtype, bool is
|
|||
}
|
||||
|
||||
// Returns the function args for a texture sampling function for the specified image and sampling characteristics.
|
||||
string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &, bool, bool, bool, uint32_t coord,
|
||||
string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool, bool, bool, 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)
|
||||
|
@ -3030,7 +3043,18 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &, bool, bool
|
|||
// Only enclose the UV expression if needed.
|
||||
auto coord_expr = (*swizzle_expr == '\0') ? to_expression(coord) : (to_enclosed_expression(coord) + swizzle_expr);
|
||||
|
||||
// TODO: implement rest ... A bit intensive.
|
||||
// textureLod on sampler2DArrayShadow does not exist in GLSL for some reason.
|
||||
// To emulate this, we will have to use textureGrad with a constant gradient of 0.
|
||||
// The workaround will assert that the LOD is in fact constant 0, or we cannot emit correct code.
|
||||
// This happens for HLSL SampleCmpLevelZero on Texture2DArray.
|
||||
bool workaround_lod_array_shadow_as_grad = false;
|
||||
if (imgtype.image.arrayed && imgtype.image.dim == Dim2D && imgtype.image.depth && lod)
|
||||
{
|
||||
auto *constant_lod = maybe_get<SPIRConstant>(lod);
|
||||
if (!constant_lod || constant_lod->scalar_f32() != 0.0f)
|
||||
SPIRV_CROSS_THROW("textureLod on sampler2DArraySahdow is not constant 0.0. This cannot be expressed in GLSL.");
|
||||
workaround_lod_array_shadow_as_grad = true;
|
||||
}
|
||||
|
||||
if (dref)
|
||||
{
|
||||
|
@ -3076,11 +3100,20 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &, bool, bool
|
|||
|
||||
if (lod)
|
||||
{
|
||||
if (check_explicit_lod_allowed(lod))
|
||||
if (workaround_lod_array_shadow_as_grad)
|
||||
{
|
||||
forward = forward && should_forward(lod);
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(lod);
|
||||
// Implement textureGrad() instead. LOD == 0.0 is implemented as gradient of 0.0.
|
||||
// Implementing this as plain texture() is not safe on some implementations.
|
||||
farg_str += ", vec2(0.0), vec2(0.0)";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (check_explicit_lod_allowed(lod))
|
||||
{
|
||||
forward = forward && should_forward(lod);
|
||||
farg_str += ", ";
|
||||
farg_str += to_expression(lod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
|
|||
|
||||
if vulkan or spirv:
|
||||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--vulkan-semantics', '--output', vulkan_glsl_path, spirv_path] + extra_args)
|
||||
validate_shader(vulkan_glsl_path, vulkan)
|
||||
validate_shader(vulkan_glsl_path, True)
|
||||
|
||||
return (spirv_path, glsl_path, vulkan_glsl_path if vulkan else None)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче