Vulkan: Retain precision of uniform variables
When gathering in a uniform block, the precision of default uniforms was
dropped.
Bug: angleproject:4889
Bug: angleproject:6132
Change-Id: Ie6a8e2e7cef7cd3808cee08d20f886fc4e762cd5
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3076124
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler.gni b/src/compiler.gni
index 24bb387..a4cf350 100644
--- a/src/compiler.gni
+++ b/src/compiler.gni
@@ -149,6 +149,8 @@
"src/compiler/translator/tree_ops/PruneEmptyCases.h",
"src/compiler/translator/tree_ops/PruneNoOps.cpp",
"src/compiler/translator/tree_ops/PruneNoOps.h",
+ "src/compiler/translator/tree_ops/RecordConstantPrecision.cpp",
+ "src/compiler/translator/tree_ops/RecordConstantPrecision.h",
"src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp",
"src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h",
"src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp",
@@ -248,8 +250,6 @@
"src/compiler/translator/OutputESSL.cpp",
"src/compiler/translator/OutputESSL.h",
"src/compiler/translator/TranslatorESSL.cpp",
- "src/compiler/translator/tree_ops/gl/RecordConstantPrecision.cpp",
- "src/compiler/translator/tree_ops/gl/RecordConstantPrecision.h",
]
angle_translator_glsl_sources = [
"src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp",
diff --git a/src/compiler/translator/TranslatorESSL.cpp b/src/compiler/translator/TranslatorESSL.cpp
index 80afd04..f315233 100644
--- a/src/compiler/translator/TranslatorESSL.cpp
+++ b/src/compiler/translator/TranslatorESSL.cpp
@@ -9,7 +9,7 @@
#include "angle_gl.h"
#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
#include "compiler/translator/OutputESSL.h"
-#include "compiler/translator/tree_ops/gl/RecordConstantPrecision.h"
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
namespace sh
{
diff --git a/src/compiler/translator/TranslatorVulkan.cpp b/src/compiler/translator/TranslatorVulkan.cpp
index 8ddcf06..c482cd6 100644
--- a/src/compiler/translator/TranslatorVulkan.cpp
+++ b/src/compiler/translator/TranslatorVulkan.cpp
@@ -22,6 +22,7 @@
#include "compiler/translator/StaticType.h"
#include "compiler/translator/glslang_wrapper.h"
#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
#include "compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h"
#include "compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h"
#include "compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h"
@@ -146,7 +147,6 @@
if (IsDefaultUniform(type))
{
TType *fieldType = new TType(type);
- fieldType->setPrecision(EbpUndefined);
uniformList->push_back(new TField(fieldType, symbol->getName(), symbol->getLine(),
symbol->variable().symbolType()));
@@ -168,7 +168,6 @@
const TVariable *variable = uniformVars[fieldIndex];
TType *replacementType = new TType(variable->getType());
- replacementType->setPrecision(EbpUndefined);
replacementType->setInterfaceBlockField(uniformBlock->getType().getInterfaceBlock(),
fieldIndex);
@@ -1382,6 +1381,15 @@
}
#endif
+ // When generating text, glslang cannot know the precision of folded constants so it may infer
+ // the wrong precisions. The following transformation gives constants names with precision to
+ // guide glslang. This is not an issue for SPIR-V generation because the precision information
+ // is present in the tree already.
+ if (!RecordConstantPrecision(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
// Write translated shader.
TOutputVulkanGLSL outputGLSL(this, sink, enablePrecision, compileOptions);
root->traverse(&outputGLSL);
diff --git a/src/compiler/translator/tree_ops/gl/RecordConstantPrecision.cpp b/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
similarity index 98%
rename from src/compiler/translator/tree_ops/gl/RecordConstantPrecision.cpp
rename to src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
index e08d16b..ea15ab7 100644
--- a/src/compiler/translator/tree_ops/gl/RecordConstantPrecision.cpp
+++ b/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
@@ -14,7 +14,7 @@
// in case that is required for correct precision propagation.
//
-#include "compiler/translator/tree_ops/gl/RecordConstantPrecision.h"
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
diff --git a/src/compiler/translator/tree_ops/gl/RecordConstantPrecision.h b/src/compiler/translator/tree_ops/RecordConstantPrecision.h
similarity index 85%
rename from src/compiler/translator/tree_ops/gl/RecordConstantPrecision.h
rename to src/compiler/translator/tree_ops/RecordConstantPrecision.h
index bf37100..b3ebb8c 100644
--- a/src/compiler/translator/tree_ops/gl/RecordConstantPrecision.h
+++ b/src/compiler/translator/tree_ops/RecordConstantPrecision.h
@@ -14,8 +14,8 @@
// in case that is required for correct precision propagation.
//
-#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_RECORDCONSTANTPRECISION_H_
-#define COMPILER_TRANSLATOR_TREEOPS_GL_RECORDCONSTANTPRECISION_H_
+#ifndef COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
#include "common/angleutils.h"
@@ -30,4 +30,4 @@
TSymbolTable *symbolTable);
} // namespace sh
-#endif // COMPILER_TRANSLATOR_TREEOPS_GL_RECORDCONSTANTPRECISION_H_
+#endif // COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 1cfbd32..9c64493 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -13102,6 +13102,36 @@
runTest(kFS);
}
+TEST_P(GLSLTest, AAA)
+{
+ constexpr char kFS[] = R"(
+// It is assumed that uTest is set to 0. It's here to make the expression not constant.
+uniform mediump float uTest;
+void main() {
+ // exact representation of 4096.5 requires 13 bits of relative precision.
+ const highp float c = 4096.5;
+ mediump float a = 0.0;
+ // Below, addition should be evaluated at highp, since one of the operands has the highp qualifier.
+ // Thus fract should also be evaluated at highp.
+ // See OpenGL ES Shading Language spec section 4.5.2.
+ // This should make the result 0.5, since highp provides at least 16 bits of relative precision.
+ // (exceptions for operation precision are allowed for a small number of computationally
+ // intensive built-in functions, but it is reasonable to think that fract is not one of those).
+ // However, if fract() is incorrectly evaluated at minimum precision fulfilling mediump criteria,
+ // or at IEEE half float precision, the result is 0.0.
+ a = fract(c + uTest);
+ // Multiply by 2.0 to make the color green.
+ gl_FragColor = vec4(0.0, 2.0 * a, 0.0, 1.0);
+})";
+
+ ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS);
+
+ drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
+ EXPECT_GL_NO_ERROR();
+
+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
+}
+
} // anonymous namespace
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(GLSLTest, WithDirectSPIRVGeneration(ES2_VULKAN()));