Manually compute the mipmap size for the textureSize builtin.
There were two issues with the current implementation:
* The GetDimensions function already takes into account the base level of the
SRV.
* The GetDimensions function returns doesn't return valid sizes for levels
that don't exist in the SRV. Instead, manually do the lod offset.
BUG=angleproject:931
BUG=angleproject:1316
TEST=dEQP-GLES3.functional.shaders.texture_functions.texturesize.sampler2d_fixed_vertex
Change-Id: I63259b563a42b93b73949e0ef7ac412099a42f13
Reviewed-on: https://chromium-review.googlesource.com/376099
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/TextureFunctionHLSL.cpp b/src/compiler/translator/TextureFunctionHLSL.cpp
index f0b48d0..6580f25 100644
--- a/src/compiler/translator/TextureFunctionHLSL.cpp
+++ b/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -473,22 +473,40 @@
void OutputTextureSizeFunctionBody(TInfoSinkBase &out,
const TextureFunctionHLSL::TextureFunction &textureFunction,
- const TString &textureReference)
+ const TString &textureReference,
+ bool getDimensionsIgnoresBaseLevel)
{
- out << "int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
+ if (getDimensionsIgnoresBaseLevel)
+ {
+ out << "int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
+ }
+ else
+ {
+ out << "int baseLevel = 0;\n";
+ }
+
if (IsSampler3D(textureFunction.sampler) || IsSamplerArray(textureFunction.sampler) ||
(IsIntegerSampler(textureFunction.sampler) && IsSamplerCube(textureFunction.sampler)))
{
// "depth" stores either the number of layers in an array texture or 3D depth
out << " uint width; uint height; uint depth; uint numberOfLevels;\n"
<< " " << textureReference
- << ".GetDimensions(baseLevel + lod, width, height, depth, numberOfLevels);\n";
+ << ".GetDimensions(baseLevel, width, height, depth, numberOfLevels);\n"
+ << " width = max(width >> lod, 1);\n"
+ << " height = max(height >> lod, 1);\n";
+
+ if (!IsSamplerArray(textureFunction.sampler))
+ {
+ out << " depth = max(depth >> lod, 1);\n";
+ }
}
else if (IsSampler2D(textureFunction.sampler) || IsSamplerCube(textureFunction.sampler))
{
out << " uint width; uint height; uint numberOfLevels;\n"
<< " " << textureReference
- << ".GetDimensions(baseLevel + lod, width, height, numberOfLevels);\n";
+ << ".GetDimensions(baseLevel, width, height, numberOfLevels);\n"
+ << " width = max(width >> lod, 1);\n"
+ << " height = max(height >> lod, 1);\n";
}
else
UNREACHABLE();
@@ -1249,7 +1267,9 @@
return textureFunction.name();
}
-void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out, const ShShaderOutput outputType)
+void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out,
+ const ShShaderOutput outputType,
+ bool getDimensionsIgnoresBaseLevel)
{
for (const TextureFunction &textureFunction : mUsesTexture)
{
@@ -1272,7 +1292,8 @@
if (textureFunction.method == TextureFunction::SIZE)
{
- OutputTextureSizeFunctionBody(out, textureFunction, textureReference);
+ OutputTextureSizeFunctionBody(out, textureFunction, textureReference,
+ getDimensionsIgnoresBaseLevel);
}
else
{