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:
parent
c6051bbbfa
commit
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
|
#version 450
|
||||||
|
|
||||||
in float v0;
|
layout(location = 0) in float v0;
|
||||||
in float v1;
|
layout(location = 1) in float v1;
|
||||||
out float FragColor;
|
layout(location = 0) out float FragColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
113
shaders/asm/frag/hlsl-sample-cmp-level-zero.asm.frag
Normal file
113
shaders/asm/frag/hlsl-sample-cmp-level-zero.asm.frag
Normal file
@ -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 %b "b"
|
||||||
OpName %v1 "v1"
|
OpName %v1 "v1"
|
||||||
OpName %FragColor "FragColor"
|
OpName %FragColor "FragColor"
|
||||||
|
OpDecorate %v0 Location 0
|
||||||
|
OpDecorate %v1 Location 1
|
||||||
|
OpDecorate %FragColor Location 0
|
||||||
%2 = OpTypeVoid
|
%2 = OpTypeVoid
|
||||||
%3 = OpTypeFunction %2
|
%3 = OpTypeFunction %2
|
||||||
%float = OpTypeFloat 32
|
%float = OpTypeFloat 32
|
||||||
|
@ -2973,6 +2973,19 @@ string CompilerGLSL::to_function_name(uint32_t, const SPIRType &imgtype, bool is
|
|||||||
{
|
{
|
||||||
string fname;
|
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)
|
if (is_fetch)
|
||||||
fname += "texelFetch";
|
fname += "texelFetch";
|
||||||
else
|
else
|
||||||
@ -2985,9 +2998,9 @@ string CompilerGLSL::to_function_name(uint32_t, const SPIRType &imgtype, bool is
|
|||||||
fname += "Offsets";
|
fname += "Offsets";
|
||||||
if (is_proj)
|
if (is_proj)
|
||||||
fname += "Proj";
|
fname += "Proj";
|
||||||
if (has_grad)
|
if (has_grad || workaround_lod_array_shadow_as_grad)
|
||||||
fname += "Grad";
|
fname += "Grad";
|
||||||
if (!!lod)
|
if (!!lod && !workaround_lod_array_shadow_as_grad)
|
||||||
fname += "Lod";
|
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.
|
// 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 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 lod, uint32_t coffset, uint32_t offset, uint32_t bias, uint32_t comp,
|
||||||
uint32_t sample, bool *p_forward)
|
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.
|
// Only enclose the UV expression if needed.
|
||||||
auto coord_expr = (*swizzle_expr == '\0') ? to_expression(coord) : (to_enclosed_expression(coord) + swizzle_expr);
|
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)
|
if (dref)
|
||||||
{
|
{
|
||||||
@ -3075,6 +3099,14 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &, bool, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lod)
|
if (lod)
|
||||||
|
{
|
||||||
|
if (workaround_lod_array_shadow_as_grad)
|
||||||
|
{
|
||||||
|
// 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))
|
if (check_explicit_lod_allowed(lod))
|
||||||
{
|
{
|
||||||
@ -3083,6 +3115,7 @@ string CompilerGLSL::to_function_args(uint32_t img, const SPIRType &, bool, bool
|
|||||||
farg_str += to_expression(lod);
|
farg_str += to_expression(lod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (coffset)
|
if (coffset)
|
||||||
{
|
{
|
||||||
|
@ -161,7 +161,7 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
|
|||||||
|
|
||||||
if vulkan or spirv:
|
if vulkan or spirv:
|
||||||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--vulkan-semantics', '--output', vulkan_glsl_path, spirv_path] + extra_args)
|
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)
|
return (spirv_path, glsl_path, vulkan_glsl_path if vulkan else None)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user