Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HLSL: Support depth comparison texture sampling in SM 2/3. #1520

Merged
merged 2 commits into from
Nov 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions reference/opt/shaders-hlsl/frag/tex-sampling.sm30.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
uniform sampler1D tex1d;
uniform sampler2D tex2d;
uniform sampler3D tex3d;
uniform samplerCUBE texCube;
uniform sampler1D tex1dShadow;
uniform sampler2D tex2dShadow;

static float texCoord1d;
static float2 texCoord2d;
static float3 texCoord3d;
static float4 FragColor;
static float4 texCoord4d;

struct SPIRV_Cross_Input
{
float texCoord1d : TEXCOORD0;
float2 texCoord2d : TEXCOORD1;
float3 texCoord3d : TEXCOORD2;
float4 texCoord4d : TEXCOORD3;
};

struct SPIRV_Cross_Output
{
float4 FragColor : COLOR0;
};

void frag_main()
{
float2 _34 = float2(texCoord1d, 2.0f);
float3 _73 = float3(texCoord2d, 2.0f);
float4 _112 = float4(texCoord3d, 2.0f);
float4 _139 = ((((((((((((((((tex1D(tex1d, texCoord1d) + tex1Dlod(tex1d, float4(texCoord1d, 0.0, 0.0, 2.0f))) + tex1Dgrad(tex1d, texCoord1d, 1.0f, 2.0f)) + tex1Dproj(tex1d, float4(_34.x, 0.0, 0.0, _34.y))) + tex1Dbias(tex1d, float4(texCoord1d, 0.0, 0.0, 1.0f))) + tex2D(tex2d, texCoord2d)) + tex2Dlod(tex2d, float4(texCoord2d, 0.0, 2.0f))) + tex2Dgrad(tex2d, texCoord2d, float2(1.0f, 2.0f), float2(3.0f, 4.0f))) + tex2Dproj(tex2d, float4(_73.xy, 0.0, _73.z))) + tex2Dbias(tex2d, float4(texCoord2d, 0.0, 1.0f))) + tex3D(tex3d, texCoord3d)) + tex3Dlod(tex3d, float4(texCoord3d, 2.0f))) + tex3Dgrad(tex3d, texCoord3d, float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f))) + tex3Dproj(tex3d, float4(_112.xyz, _112.w))) + tex3Dbias(tex3d, float4(texCoord3d, 1.0f))) + texCUBE(texCube, texCoord3d)) + texCUBElod(texCube, float4(texCoord3d, 2.0f))) + texCUBEbias(texCube, float4(texCoord3d, 1.0f));
float3 _147 = float3(texCoord1d, 0.0f, 0.0f);
float4 _171 = float4(texCoord1d, 0.0f, 0.0f, 2.0f);
_171.y = 2.0f;
float3 _194 = float3(texCoord2d, 0.0f);
float4 _219 = float4(texCoord2d, 0.0f, 2.0f);
_219.z = 2.0f;
float4 _264 = _139;
_264.w = (((((((_139.w + tex1Dproj(tex1dShadow, float4(_147.x, 0.0, 0.0f, 1.0)).x) + tex1Dlod(tex1dShadow, float4(_147.x, 0.0, 0.0f, 2.0f)).x) + tex1Dproj(tex1dShadow, float4(_171.x, 0.0, 0.0f, _171.y)).x) + tex1Dbias(tex1dShadow, float4(_147.x, 0.0, 0.0f, 1.0f)).x) + tex2Dproj(tex2dShadow, float4(_194.xy, 0.0f, 1.0)).x) + tex2Dlod(tex2dShadow, float4(_194.xy, 0.0f, 2.0f)).x) + tex2Dproj(tex2dShadow, float4(_219.xy, 0.0f, _219.z)).x) + tex2Dbias(tex2dShadow, float4(_194.xy, 0.0f, 1.0f)).x;
FragColor = _264;
}

SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
texCoord1d = stage_input.texCoord1d;
texCoord2d = stage_input.texCoord2d;
texCoord3d = stage_input.texCoord3d;
texCoord4d = stage_input.texCoord4d;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = float4(FragColor);
return stage_output;
}
83 changes: 83 additions & 0 deletions reference/shaders-hlsl/frag/tex-sampling.sm30.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
uniform sampler1D tex1d;
uniform sampler2D tex2d;
uniform sampler3D tex3d;
uniform samplerCUBE texCube;
uniform sampler1D tex1dShadow;
uniform sampler2D tex2dShadow;

static float texCoord1d;
static float2 texCoord2d;
static float3 texCoord3d;
static float4 FragColor;
static float4 texCoord4d;

struct SPIRV_Cross_Input
{
float texCoord1d : TEXCOORD0;
float2 texCoord2d : TEXCOORD1;
float3 texCoord3d : TEXCOORD2;
float4 texCoord4d : TEXCOORD3;
};

struct SPIRV_Cross_Output
{
float4 FragColor : COLOR0;
};

void frag_main()
{
float4 texcolor = tex1D(tex1d, texCoord1d);
texcolor += tex1Dlod(tex1d, float4(texCoord1d, 0.0, 0.0, 2.0f));
texcolor += tex1Dgrad(tex1d, texCoord1d, 1.0f, 2.0f);
float2 _34 = float2(texCoord1d, 2.0f);
texcolor += tex1Dproj(tex1d, float4(_34.x, 0.0, 0.0, _34.y));
texcolor += tex1Dbias(tex1d, float4(texCoord1d, 0.0, 0.0, 1.0f));
texcolor += tex2D(tex2d, texCoord2d);
texcolor += tex2Dlod(tex2d, float4(texCoord2d, 0.0, 2.0f));
texcolor += tex2Dgrad(tex2d, texCoord2d, float2(1.0f, 2.0f), float2(3.0f, 4.0f));
float3 _73 = float3(texCoord2d, 2.0f);
texcolor += tex2Dproj(tex2d, float4(_73.xy, 0.0, _73.z));
texcolor += tex2Dbias(tex2d, float4(texCoord2d, 0.0, 1.0f));
texcolor += tex3D(tex3d, texCoord3d);
texcolor += tex3Dlod(tex3d, float4(texCoord3d, 2.0f));
texcolor += tex3Dgrad(tex3d, texCoord3d, float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
float4 _112 = float4(texCoord3d, 2.0f);
texcolor += tex3Dproj(tex3d, float4(_112.xyz, _112.w));
texcolor += tex3Dbias(tex3d, float4(texCoord3d, 1.0f));
texcolor += texCUBE(texCube, texCoord3d);
texcolor += texCUBElod(texCube, float4(texCoord3d, 2.0f));
texcolor += texCUBEbias(texCube, float4(texCoord3d, 1.0f));
float3 _147 = float3(texCoord1d, 0.0f, 0.0f);
texcolor.w += tex1Dproj(tex1dShadow, float4(_147.x, 0.0, _147.z, 1.0)).x;
float3 _159 = float3(texCoord1d, 0.0f, 0.0f);
texcolor.w += tex1Dlod(tex1dShadow, float4(_159.x, 0.0, _159.z, 2.0f)).x;
float4 _168 = float4(texCoord1d, 0.0f, 0.0f, 2.0f);
float4 _171 = _168;
_171.y = _168.w;
texcolor.w += tex1Dproj(tex1dShadow, float4(_171.x, 0.0, _168.z, _171.y)).x;
float3 _179 = float3(texCoord1d, 0.0f, 0.0f);
texcolor.w += tex1Dbias(tex1dShadow, float4(_179.x, 0.0, _179.z, 1.0f)).x;
float3 _194 = float3(texCoord2d, 0.0f);
texcolor.w += tex2Dproj(tex2dShadow, float4(_194.xy, _194.z, 1.0)).x;
float3 _205 = float3(texCoord2d, 0.0f);
texcolor.w += tex2Dlod(tex2dShadow, float4(_205.xy, _205.z, 2.0f)).x;
float4 _216 = float4(texCoord2d, 0.0f, 2.0f);
float4 _219 = _216;
_219.z = _216.w;
texcolor.w += tex2Dproj(tex2dShadow, float4(_219.xy, _216.z, _219.z)).x;
float3 _229 = float3(texCoord2d, 0.0f);
texcolor.w += tex2Dbias(tex2dShadow, float4(_229.xy, _229.z, 1.0f)).x;
FragColor = texcolor;
}

SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
texCoord1d = stage_input.texCoord1d;
texCoord2d = stage_input.texCoord2d;
texCoord3d = stage_input.texCoord3d;
texCoord4d = stage_input.texCoord4d;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = float4(FragColor);
return stage_output;
}
69 changes: 40 additions & 29 deletions spirv_hlsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ string CompilerHLSL::image_type_hlsl_modern(const SPIRType &type, uint32_t id)
">");
}

string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type, uint32_t id)
string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type, uint32_t /*id*/)
{
auto &imagetype = get<SPIRType>(type.image.type);
string res;
Expand Down Expand Up @@ -373,8 +373,6 @@ string CompilerHLSL::image_type_hlsl_legacy(const SPIRType &type, uint32_t id)
res += "MS";
if (type.image.arrayed)
res += "Array";
if (image_is_comparison(type, id))
res += "Shadow";

return res;
}
Expand Down Expand Up @@ -2933,14 +2931,15 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)
SPIRV_CROSS_THROW("textureGather is not supported in HLSL shader model 2/3.");
if (offset || coffset)
SPIRV_CROSS_THROW("textureOffset is not supported in HLSL shader model 2/3.");
if (proj)
texop += "proj";

if (grad_x || grad_y)
texop += "grad";
if (lod)
else if (lod)
texop += "lod";
if (bias)
else if (bias)
texop += "bias";
else if (proj || dref)
texop += "proj";
}
}

Expand Down Expand Up @@ -2994,35 +2993,47 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)

if (hlsl_options.shader_model < 40)
{
string coord_filler;
uint32_t modifier_count = 0;
if (dref)
{
if (imgtype.image.dim != spv::Dim1D && imgtype.image.dim != spv::Dim2D)
SPIRV_CROSS_THROW("Depth comparison is only supported for 1D and 2D textures in HLSL shader model 2/3.");

if (lod)
if (grad_x || grad_y)
SPIRV_CROSS_THROW("Depth comparison is not supported for grad sampling in HLSL shader model 2/3.");

for (uint32_t size = coord_components; size < 2; ++size)
coord_expr += ", 0.0";

forward = forward && should_forward(dref);
coord_expr += ", " + to_expression(dref);
}
else if (lod || bias || proj)
{
for (uint32_t size = coord_components; size < 3; ++size)
coord_filler += ", 0.0";
coord_expr = "float4(" + coord_expr + coord_filler + ", " + to_expression(lod) + ")";
modifier_count++;
coord_expr += ", 0.0";
}

if (bias)
if (lod)
{
for (uint32_t size = coord_components; size < 3; ++size)
coord_filler += ", 0.0";
coord_expr = "float4(" + coord_expr + coord_filler + ", " + to_expression(bias) + ")";
modifier_count++;
coord_expr = "float4(" + coord_expr + ", " + to_expression(lod) + ")";
}

if (proj)
else if (bias)
{
for (uint32_t size = coord_components; size < 3; ++size)
coord_filler += ", 0.0";
coord_expr = "float4(" + coord_expr + coord_filler + ", " +
coord_expr = "float4(" + coord_expr + ", " + to_expression(bias) + ")";
}
else if (proj)
{
coord_expr = "float4(" + coord_expr + ", " +
to_extract_component_expression(coord, coord_components) + ")";
modifier_count++;
}
else if (dref)
{
// A "normal" sample gets fed into tex2Dproj as well, because the
// regular tex2D accepts only two coordinates.
coord_expr = "float4(" + coord_expr + ", 1.0)";
}

if (modifier_count > 1)
if (!!lod + !!bias + !!proj > 1)
SPIRV_CROSS_THROW("Legacy HLSL can only use one of lod/bias/proj modifiers.");
}

Expand All @@ -3036,11 +3047,8 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)
expr += ", ";
expr += coord_expr;

if (dref)
if (dref && hlsl_options.shader_model >= 40)
{
if (hlsl_options.shader_model < 40)
SPIRV_CROSS_THROW("Legacy HLSL does not support comparison sampling.");

forward = forward && should_forward(dref);
expr += ", ";

Expand Down Expand Up @@ -3095,6 +3103,9 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)

expr += ")";

if (dref && hlsl_options.shader_model < 40)
expr += ".x";

if (op == OpImageQueryLod)
{
// This is rather awkward.
Expand Down