Vulkan: dFdy is incorrect when the framebuffer is flipped

To account for framebuffer flipping, `dFdy()` expressions
must be changed to:

    dFdy() * ANGLEUniforms.viewportYScale

Bug: angleproject:3487
Test: dEQP-GLES3.functional.shaders.derivate.dfdy.*
Change-Id: I38f25ba37fb8c5ae61cee5ac911df88ec4a93fef
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1678404
Commit-Queue: Tim Van Patten <timvp@google.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Tim Van Patten 2019-06-26 13:13:09 -06:00 коммит произвёл Commit Bot
Родитель b7418a177f
Коммит 6d37651a23
7 изменённых файлов: 187 добавлений и 4 удалений

Просмотреть файл

@ -154,6 +154,8 @@ angle_translator_sources = [
"src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h", "src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h",
"src/compiler/translator/tree_ops/RewriteAtomicFunctionExpressions.cpp", "src/compiler/translator/tree_ops/RewriteAtomicFunctionExpressions.cpp",
"src/compiler/translator/tree_ops/RewriteAtomicFunctionExpressions.h", "src/compiler/translator/tree_ops/RewriteAtomicFunctionExpressions.h",
"src/compiler/translator/tree_ops/RewriteDfdy.cpp",
"src/compiler/translator/tree_ops/RewriteDfdy.h",
"src/compiler/translator/tree_ops/RewriteDoWhile.cpp", "src/compiler/translator/tree_ops/RewriteDoWhile.cpp",
"src/compiler/translator/tree_ops/RewriteDoWhile.h", "src/compiler/translator/tree_ops/RewriteDoWhile.h",
"src/compiler/translator/tree_ops/RewriteExpressionsWithShaderStorageBlock.cpp", "src/compiler/translator/tree_ops/RewriteExpressionsWithShaderStorageBlock.cpp",
@ -183,6 +185,8 @@ angle_translator_sources = [
"src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.cpp", "src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.cpp",
"src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h", "src/compiler/translator/tree_ops/VectorizeVectorScalarArithmetic.h",
"src/compiler/translator/tree_util/BuiltIn_autogen.h", "src/compiler/translator/tree_util/BuiltIn_autogen.h",
"src/compiler/translator/tree_util/FindFunction.cpp",
"src/compiler/translator/tree_util/FindFunction.h",
"src/compiler/translator/tree_util/FindMain.cpp", "src/compiler/translator/tree_util/FindMain.cpp",
"src/compiler/translator/tree_util/FindMain.h", "src/compiler/translator/tree_util/FindMain.h",
"src/compiler/translator/tree_util/FindSymbolNode.cpp", "src/compiler/translator/tree_util/FindSymbolNode.cpp",

Просмотреть файл

@ -17,8 +17,10 @@
#include "compiler/translator/OutputVulkanGLSL.h" #include "compiler/translator/OutputVulkanGLSL.h"
#include "compiler/translator/StaticType.h" #include "compiler/translator/StaticType.h"
#include "compiler/translator/tree_ops/NameEmbeddedUniformStructs.h" #include "compiler/translator/tree_ops/NameEmbeddedUniformStructs.h"
#include "compiler/translator/tree_ops/RewriteDfdy.h"
#include "compiler/translator/tree_ops/RewriteStructSamplers.h" #include "compiler/translator/tree_ops/RewriteStructSamplers.h"
#include "compiler/translator/tree_util/BuiltIn_autogen.h" #include "compiler/translator/tree_util/BuiltIn_autogen.h"
#include "compiler/translator/tree_util/FindFunction.h"
#include "compiler/translator/tree_util/FindMain.h" #include "compiler/translator/tree_util/FindMain.h"
#include "compiler/translator/tree_util/IntermNode_util.h" #include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/ReplaceVariable.h" #include "compiler/translator/tree_util/ReplaceVariable.h"
@ -388,12 +390,13 @@ const TVariable *AddDriverUniformsToShader(TIntermBlock *root, TSymbolTable *sym
TIntermSymbol *driverUniformsDeclarator = new TIntermSymbol(driverUniformsVar); TIntermSymbol *driverUniformsDeclarator = new TIntermSymbol(driverUniformsVar);
driverUniformsDecl->appendDeclarator(driverUniformsDeclarator); driverUniformsDecl->appendDeclarator(driverUniformsDeclarator);
// Insert the declarations before Main. // Insert the declarations before first function, since functions before main() may refer to
// these values.
TIntermSequence *insertSequence = new TIntermSequence; TIntermSequence *insertSequence = new TIntermSequence;
insertSequence->push_back(driverUniformsDecl); insertSequence->push_back(driverUniformsDecl);
size_t mainIndex = FindMainIndex(root); size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
root->insertChildNodes(mainIndex, *insertSequence); root->insertChildNodes(firstFunctionIndex, *insertSequence);
return driverUniformsVar; return driverUniformsVar;
} }
@ -766,6 +769,11 @@ void TranslatorVulkan::translate(TIntermBlock *root,
InsertFragCoordCorrection(root, GetMainSequence(root), &getSymbolTable(), InsertFragCoordCorrection(root, GetMainSequence(root), &getSymbolTable(),
driverUniforms); driverUniforms);
} }
{
TIntermBinary *viewportYScale = CreateDriverUniformRef(driverUniforms, kViewportYScale);
RewriteDfdy(root, getSymbolTable(), getShaderVersion(), viewportYScale);
}
} }
else else
{ {

Просмотреть файл

@ -0,0 +1,89 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Implementation of dFdy viewport transformation.
// See header for more info.
#include "compiler/translator/tree_ops/RewriteDfdy.h"
#include "common/angleutils.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
namespace sh
{
namespace
{
class Traverser : public TIntermTraverser
{
public:
static void Apply(TIntermNode *root,
const TSymbolTable &symbolTable,
TIntermBinary *viewportYScale);
private:
Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable);
bool visitUnary(Visit visit, TIntermUnary *node) override;
TIntermBinary *mViewportYScale = nullptr;
};
Traverser::Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable)
: TIntermTraverser(true, false, false, symbolTable), mViewportYScale(viewportYScale)
{}
// static
void Traverser::Apply(TIntermNode *root,
const TSymbolTable &symbolTable,
TIntermBinary *viewportYScale)
{
TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable);
Traverser traverser(viewportYScale, pSymbolTable);
root->traverse(&traverser);
traverser.updateTree();
}
bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
{
// Decide if the node represents a call to dFdy()
if (node->getOp() != EOpDFdy)
{
return true;
}
// Copy the dFdy node so we can replace it with the corrected value
TIntermUnary *newDfdy = node->deepCopy()->getAsUnaryNode();
size_t objectSize = node->getType().getObjectSize();
TOperator multiplyOp = (objectSize == 1) ? EOpMul : EOpVectorTimesScalar;
// Correct dFdy()'s value:
// (dFdy() * ANGLEUniforms.viewportYScale)
TIntermBinary *correctedDfdy = new TIntermBinary(multiplyOp, newDfdy, mViewportYScale);
// Replace the old dFdy node with the new node that contains the corrected value
queueReplacement(correctedDfdy, OriginalNode::IS_DROPPED);
return true;
}
} // anonymous namespace
void RewriteDfdy(TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
TIntermBinary *viewportYScale)
{
// dFdy is only valid in GLSL 3.0 and later.
if (shaderVersion < 300)
return;
Traverser::Apply(root, symbolTable, viewportYScale);
}
} // namespace sh

Просмотреть файл

@ -0,0 +1,30 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This mutating tree traversal flips the output of dFdy() to account for framebuffer flipping.
//
// From: dFdy(p)
// To: (dFdy(p) * viewportYScale)
//
// See http://anglebug.com/3487
#ifndef COMPILER_TRANSLATOR_TREEOPS_FLIP_DFDY_H_
#define COMPILER_TRANSLATOR_TREEOPS_FLIP_DFDY_H_
class TIntermNode;
class TIntermBinary;
class TSymbolTable;
namespace sh
{
void RewriteDfdy(TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
TIntermBinary *viewportYScale);
} // namespace sh
#endif // COMPILER_TRANSLATOR_TREEOPS_FLIP_DFDY_H_

Просмотреть файл

@ -0,0 +1,32 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// FindFunction.cpp: Find functions.
#include "compiler/translator/tree_util/FindFunction.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/Symbol.h"
namespace sh
{
size_t FindFirstFunctionDefinitionIndex(TIntermBlock *root)
{
const TIntermSequence &sequence = *root->getSequence();
for (size_t index = 0; index < sequence.size(); ++index)
{
TIntermNode *node = sequence[index];
TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
if (nodeFunction != nullptr)
{
return index;
}
}
return std::numeric_limits<size_t>::max();
}
} // namespace sh

Просмотреть файл

@ -0,0 +1,21 @@
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// FindFunction.h: Adds functions to find functions
#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
#define COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
#include <cstddef>
namespace sh
{
class TIntermBlock;
size_t FindFirstFunctionDefinitionIndex(TIntermBlock *root);
} // namespace sh
#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_

Просмотреть файл

@ -660,7 +660,6 @@
3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.link_program = FAIL 3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.link_program = FAIL
3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.use_program = FAIL 3219 VULKAN : dEQP-GLES3.functional.negative_api.shader.use_program = FAIL
3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.10 = FAIL 3443 VULKAN : dEQP-GLES3.functional.ubo.random.basic_arrays.10 = FAIL
3487 VULKAN : dEQP-GLES3.functional.shaders.derivate.dfdy.* = FAIL
// New vertex attribute formats: // New vertex attribute formats:
3193 VULKAN : dEQP-GLES3.functional.vertex_arrays.single_attribute.*.int2_10_10_10.* = SKIP 3193 VULKAN : dEQP-GLES3.functional.vertex_arrays.single_attribute.*.int2_10_10_10.* = SKIP