ES31: Support translating textureGather into HLSL - Part I
This patch is the first one in the series of supporting GLSL texture
function textureGather/textureGatherOffset on D3D11.
According to ESSL 3.1 SPEC (Chapter 8.9.3, Page 130), the definition
of textureGather on sampler2D is:
gvec4 textureGather (gsampler2D sampler, vec2 P[, int comp])
The parameter "comp" is optional, and if it is specified, the value
of "comp" must be a constant integer expression with a value of 0, 1,
2, or 3, identifying the x, y, z, or w postswizzled component of the
four-component vector lookup result for each texel, respectively. If
comp is not specified, it is treated as 0.
According to the definition above, textureGather is equivalent to
Texture2D.Gather[Red|Green|Blue|Alpha] in HLSL, where we can use a
switch-case expression to choose the right HLSL texture function.
The features listed here will be implemented in the following patches:
1. Support textureGatherOffset
2. Support textureGather[Offset] on isamplers and usamplers
3. Support textureGather[Offset] on textures when swizzle is on
4. Support textureGather[Offset] on shadow samplers
BUG=angleproject:2826
TEST=dEQP-GLES31.functional.texture.gather.basic.2d.rgba8.*
dEQP-GLES31.functional.texture.gather.basic.cube.rgba8.*
(without texture_swizzle)
dEQP-GLES31.functional.texture.gather.basic.2d_array.rgba8.*
(without texture_swizzle)
Change-Id: Iff2ed4f8b65dad613cb0bafdfd19f8f0528e832c
Reviewed-on: https://chromium-review.googlesource.com/1232980
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/TextureFunctionHLSL.cpp b/src/compiler/translator/TextureFunctionHLSL.cpp
index 1666004..685c904 100644
--- a/src/compiler/translator/TextureFunctionHLSL.cpp
+++ b/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -381,6 +381,8 @@
break;
case TextureFunctionHLSL::TextureFunction::GRAD:
break;
+ case TextureFunctionHLSL::TextureFunction::GATHER:
+ break;
default:
UNREACHABLE();
}
@@ -416,6 +418,10 @@
{
out << ", float bias";
}
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER)
+ {
+ out << ", int comp = 0";
+ }
}
void GetTextureReference(TInfoSinkBase &out,
@@ -812,6 +818,61 @@
}
}
+void OutputTextureGatherFunctionBody(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ShShaderOutput outputType,
+ const ImmutableString &textureReference,
+ const ImmutableString &samplerReference,
+ const ImmutableString &texCoordX,
+ const ImmutableString &texCoordY,
+ const ImmutableString &texCoordZ)
+{
+ const int hlslCoords = GetHLSLCoordCount(textureFunction, outputType);
+ ImmutableString samplerCoordTypeString(
+ GetSamplerCoordinateTypeString(textureFunction, hlslCoords));
+ ImmutableStringBuilder samplerCoordBuilder(
+ samplerCoordTypeString.length() + strlen("(") + texCoordX.length() + strlen(", ") +
+ texCoordY.length() + strlen(", ") + texCoordZ.length() + strlen(")"));
+
+ samplerCoordBuilder << samplerCoordTypeString << "(" << texCoordX << ", " << texCoordY;
+ if (hlslCoords >= 3)
+ {
+ if (textureFunction.coords < 3)
+ {
+ samplerCoordBuilder << ", 0";
+ }
+ else
+ {
+ samplerCoordBuilder << ", " << texCoordZ;
+ }
+ }
+ samplerCoordBuilder << ")";
+
+ ImmutableString samplerCoordString(samplerCoordBuilder);
+
+ out << " switch(comp)\n"
+ " {\n"
+ " case 0:\n"
+ " return "
+ << textureReference << ".GatherRed(" << samplerReference << ", " << samplerCoordString
+ << ");\n"
+ " case 1:\n"
+ " return "
+ << textureReference << ".GatherGreen(" << samplerReference << ", " << samplerCoordString
+ << ");\n"
+ " case 2:\n"
+ " return "
+ << textureReference << ".GatherBlue(" << samplerReference << ", " << samplerCoordString
+ << ");\n"
+ " case 3:\n"
+ " return "
+ << textureReference << ".GatherAlpha(" << samplerReference << ", " << samplerCoordString
+ << ");\n"
+ " default:\n"
+ " return float4(0.0, 0.0, 0.0, 1.0);\n"
+ " }\n";
+}
+
void OutputTextureSampleFunctionReturnStatement(
TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction,
@@ -1078,6 +1139,9 @@
case GRAD:
name << "Grad";
break;
+ case GATHER:
+ name << "Gather";
+ break;
default:
UNREACHABLE();
}
@@ -1252,6 +1316,10 @@
textureFunction.proj = true;
textureFunction.offset = true;
}
+ else if (name == "textureGather")
+ {
+ textureFunction.method = TextureFunction::GATHER;
+ }
else
UNREACHABLE();
@@ -1321,13 +1389,21 @@
ImmutableString texCoordX("t.x");
ImmutableString texCoordY("t.y");
ImmutableString texCoordZ("t.z");
- ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ);
- OutputIntegerTextureSampleFunctionComputations(out, textureFunction, outputType,
- textureReference, &texCoordX, &texCoordY,
- &texCoordZ);
- OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType,
- textureReference, samplerReference,
- texCoordX, texCoordY, texCoordZ);
+ if (textureFunction.method == TextureFunction::GATHER)
+ {
+ OutputTextureGatherFunctionBody(out, textureFunction, outputType, textureReference,
+ samplerReference, texCoordX, texCoordY, texCoordZ);
+ }
+ else
+ {
+ ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ);
+ OutputIntegerTextureSampleFunctionComputations(out, textureFunction, outputType,
+ textureReference, &texCoordX,
+ &texCoordY, &texCoordZ);
+ OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType,
+ textureReference, samplerReference,
+ texCoordX, texCoordY, texCoordZ);
+ }
}
out << "}\n"