Commit 47b3db22 by Charlie Lao Committed by Commit Bot

Vulkan: Let shader use rotation specialized constant

If use rotation specialized constant is enabled via compiler options, this CL will use rotation specialized constant to generate flipXY, rotation matrix and negFlipXY. This allows the driver to optimize for the minimum instructions for rotation. Bug: b/171750979 Change-Id: I9851ac999d4d35b9f230f796e5445bca0dcb1e77 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2514773 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 8a90378c
......@@ -26,7 +26,7 @@
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 239
#define ANGLE_SH_VERSION 240
enum ShShaderSpec
{
......@@ -341,6 +341,9 @@ const ShCompileOptions SH_EARLY_FRAGMENT_TESTS_OPTIMIZATION = UINT64_C(1) << 55;
// Allow compiler to insert Android pre-rotation code.
const ShCompileOptions SH_ADD_PRE_ROTATION = UINT64_C(1) << 56;
// Allow compiler to use specialization constant to do pre-rotation and y flip.
const ShCompileOptions SH_USE_ROTATION_SPECIALIZATION_CONSTANT = UINT64_C(1) << 57;
// Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy
{
......@@ -780,6 +783,21 @@ enum class SpecializationConstantId : uint32_t
EnumCount = InvalidEnum,
};
enum class SurfaceRotation : uint32_t
{
Identity,
Rotated90Degrees,
Rotated180Degrees,
Rotated270Degrees,
FlippedIdentity,
FlippedRotated90Degrees,
FlippedRotated180Degrees,
FlippedRotated270Degrees,
InvalidEnum,
EnumCount = InvalidEnum,
};
// Interface block name containing the aggregate default uniforms
extern const char kDefaultUniformsNameVS[];
extern const char kDefaultUniformsNameTCS[];
......
......@@ -216,6 +216,8 @@ angle_translator_sources = [
"src/compiler/translator/tree_util/FindMain.h",
"src/compiler/translator/tree_util/FindSymbolNode.cpp",
"src/compiler/translator/tree_util/FindSymbolNode.h",
"src/compiler/translator/tree_util/FlipRotateSpecConst.cpp",
"src/compiler/translator/tree_util/FlipRotateSpecConst.h",
"src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp",
"src/compiler/translator/tree_util/IntermNodePatternMatcher.h",
"src/compiler/translator/tree_util/IntermNode_util.cpp",
......
......@@ -64,7 +64,7 @@ TIntermBinary *CreateDriverUniformRef(const TVariable *driverUniforms, const cha
ANGLE_NO_DISCARD bool AppendVertexShaderPositionYCorrectionToMain(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable,
TIntermSwizzle *negFlipY)
TIntermTyped *negFlipY)
{
// Create a symbol reference to "gl_Position"
const TVariable *position = BuiltInVariable::gl_Position();
......@@ -151,7 +151,7 @@ bool TranslatorMetal::translate(TIntermBlock *root,
if (getShaderType() == GL_VERTEX_SHADER)
{
auto negFlipY = getDriverUniformNegFlipYRef(driverUniforms);
TIntermTyped *negFlipY = GetDriverUniformNegFlipYRef(driverUniforms);
// Append gl_Position.y correction to main
if (!AppendVertexShaderPositionYCorrectionToMain(this, root, &getSymbolTable(), negFlipY))
......
......@@ -16,6 +16,7 @@
#include "common/utilities.h"
#include "compiler/translator/BuiltinsWorkaroundGLSL.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/OutputVulkanGLSL.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/tree_ops/FlagSamplersWithTexelFetch.h"
......@@ -30,6 +31,7 @@
#include "compiler/translator/tree_util/BuiltIn.h"
#include "compiler/translator/tree_util/FindFunction.h"
#include "compiler/translator/tree_util/FindMain.h"
#include "compiler/translator/tree_util/FlipRotateSpecConst.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/ReplaceClipDistanceVariable.h"
#include "compiler/translator/tree_util/ReplaceVariable.h"
......@@ -175,6 +177,7 @@ constexpr gl::ShaderMap<const char *> kDefaultUniformNames = {
constexpr ImmutableString kLineRasterEmulationSpecConstVarName =
ImmutableString("ANGLELineRasterEmulation");
/* Driver uniforms */
constexpr const char kViewport[] = "viewport";
constexpr const char kHalfRenderArea[] = "halfRenderArea";
constexpr const char kFlipXY[] = "flipXY";
......@@ -247,13 +250,12 @@ ANGLE_NO_DISCARD bool RotateAndFlipBuiltinVariable(TCompiler *compiler,
TIntermTyped *rotatedXY;
if (fragRotation)
{
rotatedXY = new TIntermBinary(EOpMatrixTimesVector, fragRotation->deepCopy(),
builtinXY->deepCopy());
rotatedXY = new TIntermBinary(EOpMatrixTimesVector, fragRotation, builtinXY);
}
else
{
// No rotation applied, use original variable.
rotatedXY = builtinXY->deepCopy();
rotatedXY = builtinXY;
}
// Create the expression "(builtin.xy - pivot) * flipXY + pivot
......@@ -331,8 +333,8 @@ ANGLE_NO_DISCARD bool AppendVertexShaderDepthCorrectionToMain(TCompiler *compile
TIntermSwizzle *positionW = new TIntermSwizzle(positionRef->deepCopy(), swizzleOffsetW);
// Create the expression "(gl_Position.z + gl_Position.w) * 0.5".
TIntermBinary *zPlusW = new TIntermBinary(EOpAdd, positionZ->deepCopy(), positionW->deepCopy());
TIntermBinary *halfZPlusW = new TIntermBinary(EOpMul, zPlusW, oneHalf->deepCopy());
TIntermBinary *zPlusW = new TIntermBinary(EOpAdd, positionZ, positionW);
TIntermBinary *halfZPlusW = new TIntermBinary(EOpMul, zPlusW, oneHalf);
// Create the assignment "gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5"
TIntermTyped *positionZLHS = positionZ->deepCopy();
......@@ -352,16 +354,20 @@ ANGLE_NO_DISCARD bool AppendVertexShaderDepthCorrectionToMain(TCompiler *compile
ANGLE_NO_DISCARD bool AppendPreRotation(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable,
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms)
{
TIntermBinary *preRotationRef = CreateDriverUniformRef(driverUniforms, kPreRotation);
TIntermSymbol *glPos = new TIntermSymbol(BuiltInVariable::gl_Position());
TVector<int> swizzleOffsetXY = {0, 1};
TIntermSwizzle *glPosXY = new TIntermSwizzle(glPos, swizzleOffsetXY);
TIntermTyped *preRotationRef = rotationSpecConst->getPreRotationMatrix();
if (!preRotationRef)
{
preRotationRef = TranslatorVulkan::GetDriverUniformPreRotationMatrixRef(driverUniforms);
}
TIntermSymbol *glPos = new TIntermSymbol(BuiltInVariable::gl_Position());
TVector<int> swizzleOffsetXY = {0, 1};
TIntermSwizzle *glPosXY = new TIntermSwizzle(glPos, swizzleOffsetXY);
// Create the expression "(gl_Position.xy * preRotation)"
TIntermBinary *zRotated =
new TIntermBinary(EOpMatrixTimesVector, preRotationRef->deepCopy(), glPosXY->deepCopy());
TIntermBinary *zRotated = new TIntermBinary(EOpMatrixTimesVector, preRotationRef, glPosXY);
// Create the assignment "gl_Position.xy = (gl_Position.xy * preRotation)"
TIntermBinary *assignment =
......@@ -586,13 +592,24 @@ ANGLE_NO_DISCARD bool InsertFragCoordCorrection(TCompiler *compiler,
TIntermBlock *root,
TIntermSequence *insertSequence,
TSymbolTable *symbolTable,
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms)
{
TIntermBinary *flipXY = CreateDriverUniformRef(driverUniforms, kFlipXY);
TIntermBinary *pivot = CreateDriverUniformRef(driverUniforms, kHalfRenderArea);
TIntermBinary *fragRotation = (compileOptions & SH_ADD_PRE_ROTATION)
? CreateDriverUniformRef(driverUniforms, kFragRotation)
: nullptr;
TIntermTyped *flipXY = rotationSpecConst->getFlipXY();
if (!flipXY)
{
flipXY = CreateDriverUniformRef(driverUniforms, kFlipXY);
}
TIntermBinary *pivot = CreateDriverUniformRef(driverUniforms, kHalfRenderArea);
TIntermTyped *fragRotation = nullptr;
if (compileOptions & SH_ADD_PRE_ROTATION)
{
fragRotation = rotationSpecConst->getFragRotationMatrix();
if (!fragRotation)
{
fragRotation = CreateDriverUniformRef(driverUniforms, kFragRotation);
}
}
return RotateAndFlipBuiltinVariable(compiler, root, insertSequence, flipXY, symbolTable,
BuiltInVariable::gl_FragCoord(), kFlippedFragCoordName,
pivot, fragRotation);
......@@ -636,6 +653,7 @@ ANGLE_NO_DISCARD bool AddBresenhamEmulationFS(TCompiler *compiler,
TInfoSinkBase &sink,
TIntermBlock *root,
TSymbolTable *symbolTable,
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms,
bool usesFragCoord)
{
......@@ -734,7 +752,7 @@ ANGLE_NO_DISCARD bool AddBresenhamEmulationFS(TCompiler *compiler,
if (!usesFragCoord)
{
if (!InsertFragCoordCorrection(compiler, compileOptions, root, emulationSequence,
symbolTable, driverUniforms))
symbolTable, rotationSpecConst, driverUniforms))
{
return false;
}
......@@ -742,7 +760,6 @@ ANGLE_NO_DISCARD bool AddBresenhamEmulationFS(TCompiler *compiler,
return compiler->validateAST(root);
}
} // anonymous namespace
TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
......@@ -871,6 +888,13 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
sink << "};\n";
}
FlipRotateSpecConst surfaceRotationSpecConst;
if (getShaderType() != GL_COMPUTE_SHADER &&
(compileOptions & SH_USE_ROTATION_SPECIALIZATION_CONSTANT))
{
surfaceRotationSpecConst.generateSymbol(&getSymbolTable());
}
const TVariable *driverUniforms;
if (getShaderType() == GL_COMPUTE_SHADER)
{
......@@ -954,7 +978,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (compileOptions & SH_ADD_BRESENHAM_LINE_RASTER_EMULATION)
{
if (!AddBresenhamEmulationFS(this, compileOptions, sink, root, &getSymbolTable(),
driverUniforms, usesFragCoord))
&surfaceRotationSpecConst, driverUniforms, usesFragCoord))
{
return false;
}
......@@ -991,11 +1015,22 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (usesPointCoord)
{
TIntermBinary *flipXY = CreateDriverUniformRef(driverUniforms, kNegFlipXY);
TIntermTyped *flipNegXY = surfaceRotationSpecConst.getNegFlipXY();
if (!flipNegXY)
{
flipNegXY = CreateDriverUniformRef(driverUniforms, kNegFlipXY);
}
TIntermConstantUnion *pivot = CreateFloatNode(0.5f);
TIntermBinary *fragRotation =
usePreRotation ? CreateDriverUniformRef(driverUniforms, kFragRotation) : nullptr;
if (!RotateAndFlipBuiltinVariable(this, root, GetMainSequence(root), flipXY,
TIntermTyped *fragRotation = nullptr;
if (usePreRotation)
{
fragRotation = surfaceRotationSpecConst.getFragRotationMatrix();
if (!fragRotation)
{
fragRotation = CreateDriverUniformRef(driverUniforms, kFragRotation);
}
}
if (!RotateAndFlipBuiltinVariable(this, root, GetMainSequence(root), flipNegXY,
&getSymbolTable(), BuiltInVariable::gl_PointCoord(),
kFlippedPointCoordName, pivot, fragRotation))
{
......@@ -1006,21 +1041,17 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (usesFragCoord)
{
if (!InsertFragCoordCorrection(this, compileOptions, root, GetMainSequence(root),
&getSymbolTable(), driverUniforms))
&getSymbolTable(), &surfaceRotationSpecConst,
driverUniforms))
{
return false;
}
}
if (!RewriteDfdy(this, compileOptions, root, getSymbolTable(), getShaderVersion(),
&surfaceRotationSpecConst, driverUniforms))
{
TIntermBinary *flipXY = CreateDriverUniformRef(driverUniforms, kFlipXY);
TIntermBinary *fragRotation =
usePreRotation ? CreateDriverUniformRef(driverUniforms, kFragRotation) : nullptr;
if (!RewriteDfdy(this, root, getSymbolTable(), getShaderVersion(), flipXY,
fragRotation))
{
return false;
}
return false;
}
{
......@@ -1082,7 +1113,8 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
return false;
}
if ((compileOptions & SH_ADD_PRE_ROTATION) != 0 &&
!AppendPreRotation(this, root, &getSymbolTable(), driverUniforms))
!AppendPreRotation(this, root, &getSymbolTable(), &surfaceRotationSpecConst,
driverUniforms))
{
return false;
}
......@@ -1099,6 +1131,8 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
EmitWorkGroupSizeGLSL(*this, sink);
}
surfaceRotationSpecConst.outputLayoutString(sink);
if (!validateAST(root))
{
return false;
......@@ -1147,7 +1181,7 @@ bool TranslatorVulkan::shouldFlattenPragmaStdglInvariantAll()
return false;
}
TIntermSwizzle *TranslatorVulkan::getDriverUniformNegFlipYRef(const TVariable *driverUniforms) const
TIntermTyped *TranslatorVulkan::GetDriverUniformNegFlipYRef(const TVariable *driverUniforms)
{
// Create a swizzle to "negFlipXY.y"
TIntermBinary *negFlipXY = CreateDriverUniformRef(driverUniforms, kNegFlipXY);
......@@ -1164,4 +1198,21 @@ TIntermBinary *TranslatorVulkan::getDriverUniformDepthRangeReservedFieldRef(
return new TIntermBinary(EOpIndexDirectStruct, depthRange, CreateIndexNode(3));
}
TIntermTyped *TranslatorVulkan::GetDriverUniformFlipXYRef(const TVariable *driverUniforms)
{
return CreateDriverUniformRef(driverUniforms, kFlipXY);
}
TIntermTyped *TranslatorVulkan::GetDriverUniformFragRotationMatrixRef(
const TVariable *driverUniforms)
{
return CreateDriverUniformRef(driverUniforms, kFragRotation);
}
TIntermTyped *TranslatorVulkan::GetDriverUniformPreRotationMatrixRef(
const TVariable *driverUniforms)
{
return CreateDriverUniformRef(driverUniforms, kPreRotation);
}
} // namespace sh
......@@ -24,15 +24,20 @@ class TranslatorVulkan : public TCompiler
public:
TranslatorVulkan(sh::GLenum type, ShShaderSpec spec);
static TIntermTyped *GetDriverUniformFlipXYRef(const TVariable *driverUniforms);
static TIntermTyped *GetDriverUniformNegFlipYRef(const TVariable *driverUniforms);
static TIntermTyped *GetDriverUniformFragRotationMatrixRef(const TVariable *driverUniforms);
static TIntermTyped *GetDriverUniformPreRotationMatrixRef(const TVariable *driverUniforms);
protected:
ANGLE_NO_DISCARD bool translate(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics) override;
bool shouldFlattenPragmaStdglInvariantAll() override;
TIntermSwizzle *getDriverUniformNegFlipYRef(const TVariable *driverUniforms) const;
TIntermBinary *getDriverUniformDepthRangeReservedFieldRef(
const TVariable *driverUniforms) const;
// Subclass can call this method to transform the AST before writing the final output.
// See TranslatorMetal.cpp.
ANGLE_NO_DISCARD bool translateImpl(TIntermBlock *root,
......
......@@ -11,6 +11,8 @@
#include "common/angleutils.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/TranslatorVulkan.h"
#include "compiler/translator/tree_util/FlipRotateSpecConst.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
......@@ -24,44 +26,54 @@ class Traverser : public TIntermTraverser
{
public:
ANGLE_NO_DISCARD static bool Apply(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
TIntermBinary *flipXY,
TIntermTyped *fragRotation);
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms);
private:
Traverser(TIntermBinary *flipXY, TIntermTyped *fragRotation, TSymbolTable *symbolTable);
Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms);
bool visitUnary(Visit visit, TIntermUnary *node) override;
bool visitUnaryWithRotation(Visit visit, TIntermUnary *node);
bool visitUnaryWithoutRotation(Visit visit, TIntermUnary *node);
TIntermBinary *mFlipXY = nullptr;
TIntermTyped *mFragRotation = nullptr;
FlipRotateSpecConst *mRotationSpecConst = nullptr;
const TVariable *mDriverUniforms = nullptr;
bool mUsePreRotation = false;
};
Traverser::Traverser(TIntermBinary *flipXY, TIntermTyped *fragRotation, TSymbolTable *symbolTable)
Traverser::Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms)
: TIntermTraverser(true, false, false, symbolTable),
mFlipXY(flipXY),
mFragRotation(fragRotation)
mRotationSpecConst(rotationSpecConst),
mDriverUniforms(driverUniforms),
mUsePreRotation(compileOptions & SH_ADD_PRE_ROTATION)
{}
// static
bool Traverser::Apply(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
TIntermBinary *flipXY,
TIntermTyped *fragRotation)
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms)
{
TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable);
Traverser traverser(flipXY, fragRotation, pSymbolTable);
Traverser traverser(pSymbolTable, compileOptions, rotationSpecConst, driverUniforms);
root->traverse(&traverser);
return traverser.updateTree(compiler, root);
}
bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
{
if (mFragRotation)
if (mUsePreRotation)
{
return visitUnaryWithRotation(visit, node);
}
......@@ -102,36 +114,52 @@ bool Traverser::visitUnaryWithRotation(Visit visit, TIntermUnary *node)
//
// correctedDfdx(operand) = dFdy(operand) * mFlipXY.y
// correctedDfdy(operand) = dFdx(operand) * mFlipXY.x
//
// TODO(ianelliott): Look at the performance of this approach and potentially optimize it
// http://anglebug.com/4678
// Get a vec2 with the correct half of ANGLEUniforms.fragRotation
TIntermBinary *halfRotationMat = nullptr;
TIntermTyped *multiplierX;
TIntermTyped *multiplierY;
if (node->getOp() == EOpDFdx)
{
halfRotationMat =
new TIntermBinary(EOpIndexDirect, mFragRotation->deepCopy(), CreateIndexNode(0));
multiplierX = mRotationSpecConst->getMultiplierXForDFdx();
multiplierY = mRotationSpecConst->getMultiplierYForDFdx();
}
else
{
halfRotationMat =
new TIntermBinary(EOpIndexDirect, mFragRotation->deepCopy(), CreateIndexNode(1));
multiplierX = mRotationSpecConst->getMultiplierXForDFdy();
multiplierY = mRotationSpecConst->getMultiplierYForDFdy();
}
// Multiply halfRotationMat by ANGLEUniforms.flipXY and store in a temporary variable
TIntermBinary *rotatedFlipXY = new TIntermBinary(EOpMul, mFlipXY->deepCopy(), halfRotationMat);
const TType *vec2Type = StaticType::GetBasic<EbtFloat, 2>();
TIntermSymbol *tmpRotFlipXY = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec2Type));
TIntermSequence *tmpDecl = new TIntermSequence;
tmpDecl->push_back(CreateTempInitDeclarationNode(&tmpRotFlipXY->variable(), rotatedFlipXY));
insertStatementsInParentBlock(*tmpDecl);
// Get the .x and .y swizzles to use as multipliers
TVector<int> swizzleOffsetX = {0};
TVector<int> swizzleOffsetY = {1};
TIntermSwizzle *multiplierX = new TIntermSwizzle(tmpRotFlipXY, swizzleOffsetX);
TIntermSwizzle *multiplierY = new TIntermSwizzle(tmpRotFlipXY->deepCopy(), swizzleOffsetY);
if (!multiplierX)
{
ASSERT(!multiplierY);
TIntermTyped *flipXY = TranslatorVulkan::GetDriverUniformFlipXYRef(mDriverUniforms);
TIntermTyped *fragRotation =
TranslatorVulkan::GetDriverUniformFragRotationMatrixRef(mDriverUniforms);
// Get a vec2 with the correct half of ANGLEUniforms.fragRotation
TIntermBinary *halfRotationMat = nullptr;
if (node->getOp() == EOpDFdx)
{
halfRotationMat = new TIntermBinary(EOpIndexDirect, fragRotation, CreateIndexNode(0));
}
else
{
halfRotationMat = new TIntermBinary(EOpIndexDirect, fragRotation, CreateIndexNode(1));
}
// Multiply halfRotationMat by ANGLEUniforms.flipXY and store in a temporary variable
TIntermBinary *rotatedFlipXY = new TIntermBinary(EOpMul, flipXY, halfRotationMat);
const TType *vec2Type = StaticType::GetBasic<EbtFloat, 2>();
TIntermSymbol *tmpRotFlipXY = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec2Type));
TIntermSequence *tmpDecl = new TIntermSequence;
tmpDecl->push_back(CreateTempInitDeclarationNode(&tmpRotFlipXY->variable(), rotatedFlipXY));
insertStatementsInParentBlock(*tmpDecl);
// Get the .x and .y swizzles to use as multipliers
TVector<int> swizzleOffsetX = {0};
TVector<int> swizzleOffsetY = {1};
multiplierX = new TIntermSwizzle(tmpRotFlipXY, swizzleOffsetX);
multiplierY = new TIntermSwizzle(tmpRotFlipXY->deepCopy(), swizzleOffsetY);
}
// Get the results of dFdx(operand) and dFdy(operand), and multiply them by the swizzles
TIntermTyped *operand = node->getOperand();
......@@ -166,8 +194,13 @@ bool Traverser::visitUnaryWithoutRotation(Visit visit, TIntermUnary *node)
size_t objectSize = node->getType().getObjectSize();
TOperator multiplyOp = (objectSize == 1) ? EOpMul : EOpVectorTimesScalar;
TIntermBinary *flipY =
new TIntermBinary(EOpIndexDirect, mFlipXY->deepCopy(), CreateIndexNode(1));
TIntermTyped *flipY = mRotationSpecConst->getFlipY();
if (!flipY)
{
TIntermTyped *flipXY = TranslatorVulkan::GetDriverUniformFlipXYRef(mDriverUniforms);
flipY = new TIntermBinary(EOpIndexDirect, flipXY, CreateIndexNode(1));
}
// Correct dFdy()'s value:
// (dFdy() * mFlipXY.y)
TIntermBinary *correctedDfdy = new TIntermBinary(multiplyOp, newDfdy, flipY);
......@@ -177,21 +210,22 @@ bool Traverser::visitUnaryWithoutRotation(Visit visit, TIntermUnary *node)
return true;
}
} // anonymous namespace
bool RewriteDfdy(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
TIntermBinary *flipXY,
TIntermTyped *fragRotation)
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms)
{
// dFdy is only valid in GLSL 3.0 and later.
if (shaderVersion < 300)
return true;
return Traverser::Apply(compiler, root, symbolTable, flipXY, fragRotation);
return Traverser::Apply(compiler, compileOptions, root, symbolTable, rotationSpecConst,
driverUniforms);
}
} // namespace sh
......@@ -14,23 +14,28 @@
#define COMPILER_TRANSLATOR_TREEOPS_FLIP_DFDY_H_
#include "common/angleutils.h"
#include "compiler/translator/Compiler.h"
namespace sh
{
class TCompiler;
class TIntermNode;
class TIntermSymbol;
class TIntermBinary;
class TIntermTyped;
class TSymbolTable;
class TVariable;
class FlipRotateSpecConst;
// If fragRotation = nullptr, no rotation will be applied.
ANGLE_NO_DISCARD bool RewriteDfdy(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
TIntermBinary *flipXY,
TIntermTyped *fragRotation);
FlipRotateSpecConst *rotationSpecConst,
const TVariable *driverUniforms);
} // namespace sh
......
//
// Copyright 2020 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.
//
// FlipRotationSpecConst.cpp: Add code to generate AST node for flip and rotation matrices and
// vectors.
//
#include "compiler/translator/tree_util/FlipRotateSpecConst.h"
#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
namespace sh
{
namespace
{
constexpr ImmutableString kSurfaceRotationSpecConstVarName =
ImmutableString("ANGLESurfaceRotation");
// When an Android surface is rotated differently than the device's native orientation, ANGLE must
// rotate gl_Position in the vertex shader and gl_FragCoord in the fragment shader. The following
// are the rotation matrices used.
//
// This is 2x2 matrix in column major. The first column is for dFdx and second column is for dFdy.
using Mat2x2 = std::array<float, 4>;
using Mat2x2EnumMap =
angle::PackedEnumMap<vk::SurfaceRotation, Mat2x2, angle::EnumSize<vk::SurfaceRotation>()>;
constexpr Mat2x2EnumMap kPreRotationMatrices = {
{{vk::SurfaceRotation::Identity, {{1.0f, 0.0f, 0.0f, 1.0f}}},
{vk::SurfaceRotation::Rotated90Degrees, {{0.0f, -1.0f, 1.0f, 0.0f}}},
{vk::SurfaceRotation::Rotated180Degrees, {{-1.0f, 0.0f, 0.0f, -1.0f}}},
{vk::SurfaceRotation::Rotated270Degrees, {{0.0f, 1.0f, -1.0f, 0.0f}}},
{vk::SurfaceRotation::FlippedIdentity, {{1.0f, 0.0f, 0.0f, 1.0f}}},
{vk::SurfaceRotation::FlippedRotated90Degrees, {{0.0f, -1.0f, 1.0f, 0.0f}}},
{vk::SurfaceRotation::FlippedRotated180Degrees, {{-1.0f, 0.0f, 0.0f, -1.0f}}},
{vk::SurfaceRotation::FlippedRotated270Degrees, {{0.0f, 1.0f, -1.0f, 0.0f}}}}};
constexpr Mat2x2EnumMap kFragRotationMatrices = {
{{vk::SurfaceRotation::Identity, {{1.0f, 0.0f, 0.0f, 1.0f}}},
{vk::SurfaceRotation::Rotated90Degrees, {{0.0f, 1.0f, 1.0f, 0.0f}}},
{vk::SurfaceRotation::Rotated180Degrees, {{1.0f, 0.0f, 0.0f, 1.0f}}},
{vk::SurfaceRotation::Rotated270Degrees, {{0.0f, 1.0f, 1.0f, 0.0f}}},
{vk::SurfaceRotation::FlippedIdentity, {{1.0f, 0.0f, 0.0f, 1.0f}}},
{vk::SurfaceRotation::FlippedRotated90Degrees, {{0.0f, 1.0f, 1.0f, 0.0f}}},
{vk::SurfaceRotation::FlippedRotated180Degrees, {{1.0f, 0.0f, 0.0f, 1.0f}}},
{vk::SurfaceRotation::FlippedRotated270Degrees, {{0.0f, 1.0f, 1.0f, 0.0f}}}}};
// Returns mat2(m0, m1, m2, m3)
TIntermAggregate *CreateMat2x2(const Mat2x2EnumMap &matrix, vk::SurfaceRotation rotation)
{
auto mat2Type = new TType(EbtFloat, 2, 2);
TIntermSequence *mat2Args = new TIntermSequence();
mat2Args->push_back(CreateFloatNode(matrix[rotation][0]));
mat2Args->push_back(CreateFloatNode(matrix[rotation][1]));
mat2Args->push_back(CreateFloatNode(matrix[rotation][2]));
mat2Args->push_back(CreateFloatNode(matrix[rotation][3]));
TIntermAggregate *constVarConstructor =
TIntermAggregate::CreateConstructor(*mat2Type, mat2Args);
return constVarConstructor;
}
// Generates an array of vec2 and then use rotation to retrieve the desired flipXY out.
TIntermTyped *GenerateMat2x2ArrayWithIndex(const Mat2x2EnumMap &matrix, TIntermSymbol *specConst)
{
auto mat2Type = new TType(EbtFloat, 2, 2);
TType *typeMat2Array = new TType(*mat2Type);
typeMat2Array->makeArray(static_cast<unsigned int>(vk::SurfaceRotation::EnumCount));
TIntermSequence *sequences;
sequences =
new TIntermSequence({CreateMat2x2(matrix, vk::SurfaceRotation::Identity),
CreateMat2x2(matrix, vk::SurfaceRotation::Rotated90Degrees),
CreateMat2x2(matrix, vk::SurfaceRotation::Rotated180Degrees),
CreateMat2x2(matrix, vk::SurfaceRotation::Rotated270Degrees),
CreateMat2x2(matrix, vk::SurfaceRotation::FlippedIdentity),
CreateMat2x2(matrix, vk::SurfaceRotation::FlippedRotated90Degrees),
CreateMat2x2(matrix, vk::SurfaceRotation::FlippedRotated180Degrees),
CreateMat2x2(matrix, vk::SurfaceRotation::FlippedRotated270Degrees)});
TIntermTyped *array = TIntermAggregate::CreateConstructor(*typeMat2Array, sequences);
return new TIntermBinary(EOpIndexDirect, array, specConst->deepCopy());
}
using Vec2 = std::array<float, 2>;
using Vec2EnumMap =
angle::PackedEnumMap<vk::SurfaceRotation, Vec2, angle::EnumSize<vk::SurfaceRotation>()>;
constexpr Vec2EnumMap kFlipXYValue = {
{{vk::SurfaceRotation::Identity, {{1.0f, 1.0f}}},
{vk::SurfaceRotation::Rotated90Degrees, {{1.0f, 1.0f}}},
{vk::SurfaceRotation::Rotated180Degrees, {{-1.0f, 1.0f}}},
{vk::SurfaceRotation::Rotated270Degrees, {{-1.0f, -1.0f}}},
{vk::SurfaceRotation::FlippedIdentity, {{1.0f, -1.0f}}},
{vk::SurfaceRotation::FlippedRotated90Degrees, {{1.0f, 1.0f}}},
{vk::SurfaceRotation::FlippedRotated180Degrees, {{1.0f, 1.0f}}},
{vk::SurfaceRotation::FlippedRotated270Degrees, {{-1.0f, -1.0f}}}}};
// Returns vec2(flip.x, flip.y) or vec2(flip.x, -flip.y) if negFlipY is true
TIntermAggregate *CreateFlipXY(vk::SurfaceRotation rotation, float yscale)
{
auto vec2Type = new TType(EbtFloat, 2);
TIntermSequence *vec2Args = new TIntermSequence();
vec2Args->push_back(CreateFloatNode(kFlipXYValue[rotation][0]));
vec2Args->push_back(CreateFloatNode(kFlipXYValue[rotation][1] * yscale));
TIntermAggregate *constVarConstructor =
TIntermAggregate::CreateConstructor(*vec2Type, vec2Args);
return constVarConstructor;
}
// Generates an array of vec2 and then use rotation to retrieve the desired flipXY out.
TIntermTyped *CreateFlipXYWithIndex(TIntermSymbol *rotationSpecConst, float yscale)
{
auto vec2Type = new TType(EbtFloat, 2);
TType *typeVec2Array = new TType(*vec2Type);
typeVec2Array->makeArray(static_cast<unsigned int>(vk::SurfaceRotation::EnumCount));
TIntermSequence *sequences;
sequences =
new TIntermSequence({CreateFlipXY(vk::SurfaceRotation::Identity, yscale),
CreateFlipXY(vk::SurfaceRotation::Rotated90Degrees, yscale),
CreateFlipXY(vk::SurfaceRotation::Rotated180Degrees, yscale),
CreateFlipXY(vk::SurfaceRotation::Rotated270Degrees, yscale),
CreateFlipXY(vk::SurfaceRotation::FlippedIdentity, yscale),
CreateFlipXY(vk::SurfaceRotation::FlippedRotated90Degrees, yscale),
CreateFlipXY(vk::SurfaceRotation::FlippedRotated180Degrees, yscale),
CreateFlipXY(vk::SurfaceRotation::FlippedRotated270Degrees, yscale)});
TIntermTyped *vec2Array = TIntermAggregate::CreateConstructor(*typeVec2Array, sequences);
return new TIntermBinary(EOpIndexDirect, vec2Array, rotationSpecConst->deepCopy());
}
// Returns [flipX*m0, flipY*m1], where [m0 m1] is the first column of kFragRotation matrix.
constexpr Vec2 CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation rotation)
{
return Vec2({kFlipXYValue[rotation][0] * kFragRotationMatrices[rotation][0],
kFlipXYValue[rotation][1] * kFragRotationMatrices[rotation][1]});
}
constexpr Vec2EnumMap kRotatedFlipXYForDFdx = {
{{vk::SurfaceRotation::Identity,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::Identity)},
{vk::SurfaceRotation::Rotated90Degrees,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::Rotated90Degrees)},
{vk::SurfaceRotation::Rotated180Degrees,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::Rotated180Degrees)},
{vk::SurfaceRotation::Rotated270Degrees,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::Rotated270Degrees)},
{vk::SurfaceRotation::FlippedIdentity,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::FlippedIdentity)},
{vk::SurfaceRotation::FlippedRotated90Degrees,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::FlippedRotated90Degrees)},
{vk::SurfaceRotation::FlippedRotated180Degrees,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::FlippedRotated180Degrees)},
{vk::SurfaceRotation::FlippedRotated270Degrees,
CreateRotatedFlipXYValueForDFdx(vk::SurfaceRotation::FlippedRotated270Degrees)}}};
// Returns [flipX*m2, flipY*m3], where [m2 m3] is the second column of kFragRotation matrix.
constexpr Vec2 CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation rotation)
{
return Vec2({kFlipXYValue[rotation][0] * kFragRotationMatrices[rotation][2],
kFlipXYValue[rotation][1] * kFragRotationMatrices[rotation][3]});
}
constexpr Vec2EnumMap kRotatedFlipXYForDFdy = {
{{vk::SurfaceRotation::Identity,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::Identity)},
{vk::SurfaceRotation::Rotated90Degrees,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::Rotated90Degrees)},
{vk::SurfaceRotation::Rotated180Degrees,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::Rotated180Degrees)},
{vk::SurfaceRotation::Rotated270Degrees,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::Rotated270Degrees)},
{vk::SurfaceRotation::FlippedIdentity,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::FlippedIdentity)},
{vk::SurfaceRotation::FlippedRotated90Degrees,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::FlippedRotated90Degrees)},
{vk::SurfaceRotation::FlippedRotated180Degrees,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::FlippedRotated180Degrees)},
{vk::SurfaceRotation::FlippedRotated270Degrees,
CreateRotatedFlipXYValueForDFdy(vk::SurfaceRotation::FlippedRotated270Degrees)}}};
// Returns an array of float and then use rotation to retrieve the desired float value out.
TIntermTyped *CreateFloatArrayWithRotationIndex(const Vec2EnumMap &valuesEnumMap,
int subscript,
float scale,
TIntermSymbol *rotation)
{
const TType *floatType = StaticType::GetBasic<EbtFloat>();
TType *typeFloat8 = new TType(*floatType);
typeFloat8->makeArray(static_cast<unsigned int>(vk::SurfaceRotation::EnumCount));
TIntermSequence *sequences;
sequences = new TIntermSequence(
{CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::Identity][subscript] * scale),
CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::Rotated90Degrees][subscript] * scale),
CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::Rotated180Degrees][subscript] * scale),
CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::Rotated270Degrees][subscript] * scale),
CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::FlippedIdentity][subscript] * scale),
CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::FlippedRotated90Degrees][subscript] *
scale),
CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::FlippedRotated180Degrees][subscript] *
scale),
CreateFloatNode(valuesEnumMap[vk::SurfaceRotation::FlippedRotated270Degrees][subscript] *
scale)});
TIntermTyped *array = TIntermAggregate::CreateConstructor(*typeFloat8, sequences);
return new TIntermBinary(EOpIndexDirect, array, rotation->deepCopy());
}
} // anonymous namespace
FlipRotateSpecConst::FlipRotateSpecConst() : mSpecConstSymbol(nullptr), mReferenced(false) {}
FlipRotateSpecConst::~FlipRotateSpecConst()
{
if (mSpecConstSymbol)
{
delete mSpecConstSymbol;
}
}
void FlipRotateSpecConst::generateSymbol(TSymbolTable *symbolTable)
{
TVariable *specConstVar =
new TVariable(symbolTable, kSurfaceRotationSpecConstVarName,
StaticType::GetBasic<EbtUInt>(), SymbolType::AngleInternal);
mSpecConstSymbol = new TIntermSymbol(specConstVar);
}
void FlipRotateSpecConst::outputLayoutString(TInfoSinkBase &sink) const
{
// Only emit specialized const layout string if it has been referenced.
if (mReferenced)
{
sink << "layout(constant_id="
<< static_cast<uint32_t>(vk::SpecializationConstantId::SurfaceRotation)
<< ") const uint " << kSurfaceRotationSpecConstVarName << " = 0;\n\n";
}
}
TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdx()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 0, 1, mSpecConstSymbol);
}
TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdx()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 1, 1, mSpecConstSymbol);
}
TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdy()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 0, 1, mSpecConstSymbol);
}
TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdy()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 1, 1, mSpecConstSymbol);
}
TIntermTyped *FlipRotateSpecConst::getPreRotationMatrix()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return GenerateMat2x2ArrayWithIndex(kPreRotationMatrices, mSpecConstSymbol);
}
TIntermTyped *FlipRotateSpecConst::getFragRotationMatrix()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return GenerateMat2x2ArrayWithIndex(kFragRotationMatrices, mSpecConstSymbol);
}
TIntermTyped *FlipRotateSpecConst::getFlipXY()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFlipXYWithIndex(mSpecConstSymbol, 1.0);
}
TIntermTyped *FlipRotateSpecConst::getNegFlipXY()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFlipXYWithIndex(mSpecConstSymbol, -1.0);
}
TIntermTyped *FlipRotateSpecConst::getFlipY()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, 1, mSpecConstSymbol);
}
TIntermTyped *FlipRotateSpecConst::getNegFlipY()
{
if (!mSpecConstSymbol)
{
return nullptr;
}
mReferenced = true;
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, -1, mSpecConstSymbol);
}
} // namespace sh
//
// Copyright 2020 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.
//
// FlipRotationSpecConst.h: Add code to generate AST node for flip and rotation matrices and
// vectors.
//
#ifndef COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_
#define COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_
#include "common/angleutils.h"
#include "compiler/translator/SymbolTable.h"
class TIntermTyped;
class TIntermSymbol;
class TVariable;
namespace sh
{
class FlipRotateSpecConst
{
public:
FlipRotateSpecConst();
~FlipRotateSpecConst();
TIntermTyped *getMultiplierXForDFdx();
TIntermTyped *getMultiplierYForDFdx();
TIntermTyped *getMultiplierXForDFdy();
TIntermTyped *getMultiplierYForDFdy();
TIntermTyped *getPreRotationMatrix();
TIntermTyped *getFragRotationMatrix();
TIntermTyped *getFlipXY();
TIntermTyped *getNegFlipXY();
TIntermTyped *getFlipY();
TIntermTyped *getNegFlipY();
void generateSymbol(TSymbolTable *symbolTable);
void outputLayoutString(TInfoSinkBase &sink) const;
private:
TIntermSymbol *mSpecConstSymbol;
// True if mSpecConstSymbol has been used
bool mReferenced;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_
......@@ -3127,13 +3127,23 @@ void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState)
mCurrentRotationDrawFramebuffer =
DetermineSurfaceRotation(drawFramebuffer, mCurrentWindowSurface);
if (mCurrentRotationDrawFramebuffer != mGraphicsPipelineDesc->getSurfaceRotation())
// DetermineSurfaceRotation() does not encode yflip information. Shader code uses
// SurfaceRotation specialization constant to determine yflip as well. We add yflip information
// to the SurfaceRotation here so the shader does yflip properly.
SurfaceRotation rotationAndFlip = mCurrentRotationDrawFramebuffer;
if (isViewportFlipEnabledForDrawFBO())
{
ASSERT(ToUnderlying(rotationAndFlip) < ToUnderlying(SurfaceRotation::FlippedIdentity));
rotationAndFlip = static_cast<SurfaceRotation>(
ToUnderlying(SurfaceRotation::FlippedIdentity) + ToUnderlying(rotationAndFlip));
}
if (rotationAndFlip != mGraphicsPipelineDesc->getSurfaceRotation())
{
// surface rotation are specialization constants, which affects program compilation. When
// rotation changes, we need to update GraphicsPipelineDesc so that the correct pipeline
// program object will be retrieved.
mGraphicsPipelineDesc->updateSurfaceRotation(&mGraphicsPipelineTransition,
mCurrentRotationDrawFramebuffer);
mGraphicsPipelineDesc->updateSurfaceRotation(&mGraphicsPipelineTransition, rotationAndFlip);
}
}
......
......@@ -72,6 +72,9 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte
// context state does not allow it
compileOptions |= SH_EARLY_FRAGMENT_TESTS_OPTIMIZATION;
// Let compiler use specialized constant for pre-rotation.
compileOptions |= SH_USE_ROTATION_SPECIALIZATION_CONSTANT;
if (contextVk->getFeatures().enablePreRotateSurfaces.enabled ||
contextVk->getFeatures().emulatedPrerotation90.enabled ||
contextVk->getFeatures().emulatedPrerotation180.enabled ||
......
......@@ -359,6 +359,12 @@
4344 VULKAN ANDROID : dEQP-GLES2.functional.fragment_ops.random.62 = FAIL
4344 VULKAN ANDROID : dEQP-GLES2.functional.fragment_ops.random.78 = FAIL
// Failing on the Pixel2.
172932466 VULKAN PIXEL2ORXL : dEQP-GLES2.functional.shaders.indexing.tmp_array.float_const_write_dynamic_read_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES2.functional.shaders.indexing.tmp_array.vec2_const_write_dynamic_read_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES2.functional.shaders.indexing.tmp_array.vec3_const_write_dynamic_read_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES2.functional.shaders.indexing.tmp_array.vec4_const_write_dynamic_read_vertex = FAIL
// These tests also fail on AMD windows driver as it is not allowed to use emulation due to errors.
3243 VULKAN WIN AMD : dEQP-GLES2.functional.shaders.texture_functions.vertex.texturecubelod = FAIL
3243 VULKAN WIN AMD : dEQP-GLES2.functional.texture.mipmap.cube.basic.linear_nearest = FAIL
......
......@@ -292,3 +292,7 @@
// Vulkan Android failures with these formats
5277 VULKAN ANDROID : dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgb10_a2* = FAIL
5277 VULKAN ANDROID : dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgb9_e5* = FAIL
// Skip on Pixel2 to reduce the bots test time so that it won't timeout
172936025 VULKAN PIXEL2ORXL : dEQP-GLES31.functional.copy_image.mixed.viewclass_128_bits_mixed.*.* = SKIP
172936025 VULKAN PIXEL2ORXL : dEQP-GLES31.functional.copy_image.compressed.viewclass_astc*.*.* = SKIP
......@@ -642,6 +642,13 @@
// 161540999 PIXEL2ORXL VULKAN : dEQP-GLES3.functional.fragment_ops.random.35 = FAIL
4344 VULKAN ANDROID : dEQP-GLES3.functional.fragment_ops.random.73 = FAIL
// Failing on the Pixel2.
172932466 VULKAN PIXEL2ORXL : dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_128_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.float_64_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_128_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_16_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_32_vertex = FAIL
172932466 VULKAN PIXEL2ORXL : dEQP-GLES3.functional.shaders.large_constant_arrays.indexing.vec4_64_vertex = FAIL
// Fails only with SwiftShader:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment