Support textureQueryLod in HLSL.

This commit is contained in:
Hans-Kristian Arntzen 2017-12-01 13:28:51 +01:00
parent a02b008ce0
commit aeeb0e3dd0
4 changed files with 100 additions and 5 deletions

View File

@ -0,0 +1,30 @@
Texture2D<float4> uSampler : register(t0);
SamplerState _uSampler_sampler : register(s0);
static float4 FragColor;
static float2 vTexCoord;
struct SPIRV_Cross_Input
{
float2 vTexCoord : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
float _19_tmp = uSampler.CalculateLevelOfDetail(_uSampler_sampler, vTexCoord);
FragColor = float2(_19_tmp, _19_tmp).xyxy;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vTexCoord = stage_input.vTexCoord;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,30 @@
Texture2D<float4> uSampler : register(t0);
SamplerState _uSampler_sampler : register(s0);
static float4 FragColor;
static float2 vTexCoord;
struct SPIRV_Cross_Input
{
float2 vTexCoord : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
float _19_tmp = uSampler.CalculateLevelOfDetail(_uSampler_sampler, vTexCoord);
FragColor = float2(_19_tmp, _19_tmp).xyxy;
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vTexCoord = stage_input.vTexCoord;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,10 @@
#version 450
layout(location = 0) in vec2 vTexCoord;
layout(binding = 0) uniform sampler2D uSampler;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = textureQueryLod(uSampler, vTexCoord).xyxy;
}

View File

@ -1880,6 +1880,11 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
proj = true;
break;
case OpImageQueryLod:
opt = &ops[4];
length -= 4;
break;
default:
opt = &ops[4];
length -= 4;
@ -1961,6 +1966,11 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
texop += img_expr;
texop += ".Load";
}
else if (op == OpImageQueryLod)
{
texop += img_expr;
texop += ".CalculateLevelOfDetail";
}
else
{
auto &imgformat = get<SPIRType>(imgtype.image.type);
@ -2144,11 +2154,8 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
if (imgtype.image.dim != DimBuffer)
coord_expr = join("int", coordtype.vecsize + 1, "(", coord_expr, ", ", to_expression(lod), ")");
}
if (op != OpImageFetch)
{
else
expr += ", ";
}
expr += coord_expr;
if (dref)
@ -2203,7 +2210,21 @@ void CompilerHLSL::emit_texture_op(const Instruction &i)
expr += ")";
emit_op(result_type, id, expr, forward, false);
if (op == OpImageQueryLod)
{
// This is rather awkward.
// textureQueryLod returns two values, the "accessed level",
// as well as the actual LOD lambda.
// As far as I can tell, there is no way to get the .x component
// according to GLSL spec, and it depends on the sampler itself.
// Just assume X == Y, so we will need to splat the result to a float2.
statement("float _", id, "_tmp = ", expr, ";");
emit_op(result_type, id, join("float2(_", id, "_tmp, _", id, "_tmp)"), true, true);
}
else
{
emit_op(result_type, id, expr, forward, false);
}
}
string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
@ -3236,6 +3257,10 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
break;
}
case OpImageQueryLod:
emit_texture_op(instruction);
break;
case OpImageQuerySizeLod:
{
auto result_type = ops[0];