зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
b7418a177f
Коммит
6d37651a23
|
@ -154,6 +154,8 @@ angle_translator_sources = [
|
|||
"src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h",
|
||||
"src/compiler/translator/tree_ops/RewriteAtomicFunctionExpressions.cpp",
|
||||
"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.h",
|
||||
"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.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.h",
|
||||
"src/compiler/translator/tree_util/FindSymbolNode.cpp",
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
#include "compiler/translator/OutputVulkanGLSL.h"
|
||||
#include "compiler/translator/StaticType.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_util/BuiltIn_autogen.h"
|
||||
#include "compiler/translator/tree_util/FindFunction.h"
|
||||
#include "compiler/translator/tree_util/FindMain.h"
|
||||
#include "compiler/translator/tree_util/IntermNode_util.h"
|
||||
#include "compiler/translator/tree_util/ReplaceVariable.h"
|
||||
|
@ -388,12 +390,13 @@ const TVariable *AddDriverUniformsToShader(TIntermBlock *root, TSymbolTable *sym
|
|||
TIntermSymbol *driverUniformsDeclarator = new TIntermSymbol(driverUniformsVar);
|
||||
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;
|
||||
insertSequence->push_back(driverUniformsDecl);
|
||||
|
||||
size_t mainIndex = FindMainIndex(root);
|
||||
root->insertChildNodes(mainIndex, *insertSequence);
|
||||
size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
|
||||
root->insertChildNodes(firstFunctionIndex, *insertSequence);
|
||||
|
||||
return driverUniformsVar;
|
||||
}
|
||||
|
@ -766,6 +769,11 @@ void TranslatorVulkan::translate(TIntermBlock *root,
|
|||
InsertFragCoordCorrection(root, GetMainSequence(root), &getSymbolTable(),
|
||||
driverUniforms);
|
||||
}
|
||||
|
||||
{
|
||||
TIntermBinary *viewportYScale = CreateDriverUniformRef(driverUniforms, kViewportYScale);
|
||||
RewriteDfdy(root, getSymbolTable(), getShaderVersion(), viewportYScale);
|
||||
}
|
||||
}
|
||||
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.use_program = 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:
|
||||
3193 VULKAN : dEQP-GLES3.functional.vertex_arrays.single_attribute.*.int2_10_10_10.* = SKIP
|
||||
|
|
Загрузка…
Ссылка в новой задаче