Implement textureGrad.
BUG=angle:564
Change-Id: I95dcd95a274f6d560250c197be0d6e64a5b23516
Reviewed-on: https://chromium-review.googlesource.com/187081
Tested-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index 69a1faf..3979a79 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -511,6 +511,14 @@
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, float3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, float3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, float2, float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4, float3, float3);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2, float2);
+ symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4, float2, float2);
+
//
// Depth range in window coordinates
//
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 03ff3fc..860e29a 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -61,6 +61,7 @@
case LOD0: name += "Lod0"; break;
case SIZE: name += "Size"; break;
case FETCH: name += "Fetch"; break;
+ case GRAD: name += "Grad"; break;
default: UNREACHABLE();
}
@@ -1022,6 +1023,33 @@
}
}
+ if (textureFunction->method == TextureFunction::GRAD)
+ {
+ switch(textureFunction->sampler)
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ out << ", float2 ddx, float2 ddy";
+ break;
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeShadow:
+ out << ", float3 ddx, float3 ddy";
+ break;
+ default: UNREACHABLE();
+ }
+ }
+
switch(textureFunction->method)
{
case TextureFunction::IMPLICIT: break;
@@ -1030,6 +1058,7 @@
case TextureFunction::LOD0: break;
case TextureFunction::SIZE: break;
case TextureFunction::FETCH: out << ", int mip"; break;
+ case TextureFunction::GRAD: break;
default: UNREACHABLE();
}
@@ -1146,6 +1175,11 @@
out << " lod += bias;\n";
}
}
+ else if (textureFunction->method == TextureFunction::GRAD)
+ {
+ out << " x.GetDimensions(0, width, height, layers, levels);\n"
+ " float lod = log2(max(length(ddx), length(ddy)));\n";
+ }
out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
}
@@ -1180,6 +1214,11 @@
{
out << " x.GetDimensions(0, width, height, levels);\n";
}
+ else if (textureFunction->method == TextureFunction::GRAD)
+ {
+ out << " x.GetDimensions(0, width, height, levels);\n"
+ " float lod = log2(max(length(ddx), length(ddy)));\n";
+ }
out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
}
@@ -1211,6 +1250,11 @@
out << " lod += bias;\n";
}
}
+ else if (textureFunction->method == TextureFunction::GRAD)
+ {
+ out << " x.GetDimensions(0, width, height, depth, levels);\n"
+ " float lod = log2(max(length(ddx), length(ddy)));\n";
+ }
out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
}
@@ -1243,8 +1287,23 @@
}
else if (mOutputType == SH_HLSL11_OUTPUT)
{
- if (IsIntegerSampler(textureFunction->sampler) ||
- textureFunction->method == TextureFunction::FETCH)
+ if (textureFunction->method == TextureFunction::GRAD)
+ {
+ if (IsIntegerSampler(textureFunction->sampler))
+ {
+ out << "x.Load(";
+ }
+ else if (IsShadowSampler(textureFunction->sampler))
+ {
+ out << "x.SampleCmpLevelZero(s, ";
+ }
+ else
+ {
+ out << "x.SampleGrad(s, ";
+ }
+ }
+ else if (IsIntegerSampler(textureFunction->sampler) ||
+ textureFunction->method == TextureFunction::FETCH)
{
out << "x.Load(";
}
@@ -1359,8 +1418,29 @@
out << ", " + addressz + ("t.z" + proj) + close;
}
- if (IsIntegerSampler(textureFunction->sampler) ||
- textureFunction->method == TextureFunction::FETCH)
+ if (textureFunction->method == TextureFunction::GRAD)
+ {
+ if (IsIntegerSampler(textureFunction->sampler))
+ {
+ out << ", mip)";
+ }
+ else if (IsShadowSampler(textureFunction->sampler))
+ {
+ // Compare value
+ switch(textureFunction->coords)
+ {
+ case 3: out << "), t.z"; break;
+ case 4: out << "), t.w"; break;
+ default: UNREACHABLE();
+ }
+ }
+ else
+ {
+ out << "), ddx, ddy";
+ }
+ }
+ else if (IsIntegerSampler(textureFunction->sampler) ||
+ textureFunction->method == TextureFunction::FETCH)
{
out << ", mip)";
}
@@ -2400,6 +2480,10 @@
textureFunction.method = TextureFunction::FETCH;
textureFunction.offset = true;
}
+ else if (name == "textureGrad")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ }
else UNREACHABLE();
if (textureFunction.method == TextureFunction::IMPLICIT) // Could require lod 0 or have a bias argument
diff --git a/src/compiler/translator/OutputHLSL.h b/src/compiler/translator/OutputHLSL.h
index e8d24f8..79e5572 100644
--- a/src/compiler/translator/OutputHLSL.h
+++ b/src/compiler/translator/OutputHLSL.h
@@ -105,7 +105,8 @@
LOD,
LOD0,
SIZE, // textureSize()
- FETCH
+ FETCH,
+ GRAD
};
TBasicType sampler;