Commit 4d7a3993 by Ian Elliott Committed by Commit Bot

Vulkan: Rotate gl_PointCoord for Android pre-rotation

This extends the current y-flip that's done for gl_PointCoord. Now, gl_PointCoord is rotated and then flips both the x and y-axis (similar to gl_FragCoord). The tests used to reproduce the problem and the fix are: angle_deqp_gles2_tests --local-output --gtest_filter=dEQP.GLES2/functional_shaders_builtin_variable_pointcoord* --use-angle=vulkan angle_end2end_tests --local-output --gtest_filter=*GLSLTest.PointCoordConsistency*Vulkan* Bug: b/157476696 Change-Id: Iada8680eda8322f7382ff242e4a9422a66114f07 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2216700 Commit-Queue: Ian Elliott <ianelliott@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 0652d0d6
......@@ -35,7 +35,7 @@ namespace
ANGLE_NO_DISCARD bool AppendVertexShaderPositionYCorrectionToMain(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable,
TIntermBinary *negFlipY)
TIntermSwizzle *negFlipY)
{
// Create a symbol reference to "gl_Position"
const TVariable *position = BuiltInVariable::gl_Position();
......
......@@ -176,8 +176,7 @@ constexpr ImmutableString kLineRasterEmulationSpecConstVarName =
constexpr const char kViewport[] = "viewport";
constexpr const char kHalfRenderArea[] = "halfRenderArea";
constexpr const char kFlipXY[] = "flipXY";
constexpr const char kViewportYScale[] = "viewportYScale";
constexpr const char kNegFlipY[] = "negFlipY";
constexpr const char kNegFlipXY[] = "negFlipXY";
constexpr const char kClipDistancesEnabled[] = "clipDistancesEnabled";
constexpr const char kXfbActiveUnpaused[] = "xfbActiveUnpaused";
constexpr const char kXfbVerticesPerDraw[] = "xfbVerticesPerDraw";
......@@ -187,11 +186,11 @@ constexpr const char kDepthRange[] = "depthRange";
constexpr const char kPreRotation[] = "preRotation";
constexpr const char kFragRotation[] = "fragRotation";
constexpr size_t kNumGraphicsDriverUniforms = 13;
constexpr size_t kNumGraphicsDriverUniforms = 12;
constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = {
{kViewport, kHalfRenderArea, kFlipXY, kViewportYScale, kNegFlipY, kClipDistancesEnabled,
kXfbActiveUnpaused, kXfbVerticesPerDraw, kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange,
kPreRotation, kFragRotation}};
{kViewport, kHalfRenderArea, kFlipXY, kNegFlipXY, kClipDistancesEnabled, kXfbActiveUnpaused,
kXfbVerticesPerDraw, kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange, kPreRotation,
kFragRotation}};
constexpr size_t kNumComputeDriverUniforms = 1;
constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = {
......@@ -223,59 +222,6 @@ TIntermBinary *CreateDriverUniformRef(const TVariable *driverUniforms, const cha
return new TIntermBinary(EOpIndexDirectInterfaceBlock, angleUniformsRef, indexRef);
}
// Replaces a builtin variable with a version that corrects the Y coordinate.
ANGLE_NO_DISCARD bool FlipBuiltinVariable(TCompiler *compiler,
TIntermBlock *root,
TIntermSequence *insertSequence,
TIntermTyped *viewportYScale,
TSymbolTable *symbolTable,
const TVariable *builtin,
const ImmutableString &flippedVariableName,
TIntermTyped *pivot)
{
// Create a symbol reference to 'builtin'.
TIntermSymbol *builtinRef = new TIntermSymbol(builtin);
// Create a swizzle to "builtin.y"
TVector<int> swizzleOffsetY = {1};
TIntermSwizzle *builtinY = new TIntermSwizzle(builtinRef, swizzleOffsetY);
// Create a symbol reference to our new variable that will hold the modified builtin.
const TType *type = StaticType::GetForVec<EbtFloat>(
EvqGlobal, static_cast<unsigned char>(builtin->getType().getNominalSize()));
TVariable *replacementVar =
new TVariable(symbolTable, flippedVariableName, type, SymbolType::AngleInternal);
DeclareGlobalVariable(root, replacementVar);
TIntermSymbol *flippedBuiltinRef = new TIntermSymbol(replacementVar);
// Use this new variable instead of 'builtin' everywhere.
if (!ReplaceVariable(compiler, root, builtin, replacementVar))
{
return false;
}
// Create the expression "(builtin.y - pivot) * viewportYScale + pivot
TIntermBinary *removePivot = new TIntermBinary(EOpSub, builtinY, pivot);
TIntermBinary *inverseY = new TIntermBinary(EOpMul, removePivot, viewportYScale);
TIntermBinary *plusPivot = new TIntermBinary(EOpAdd, inverseY, pivot->deepCopy());
// Create the corrected variable and copy the value of the original builtin.
TIntermSequence *sequence = new TIntermSequence();
sequence->push_back(builtinRef->deepCopy());
TIntermAggregate *aggregate = TIntermAggregate::CreateConstructor(builtin->getType(), sequence);
TIntermBinary *assignment = new TIntermBinary(EOpInitialize, flippedBuiltinRef, aggregate);
// Create an assignment to the replaced variable's y.
TIntermSwizzle *correctedY = new TIntermSwizzle(flippedBuiltinRef->deepCopy(), swizzleOffsetY);
TIntermBinary *assignToY = new TIntermBinary(EOpAssign, correctedY, plusPivot);
// Add this assigment at the beginning of the main function
insertSequence->insert(insertSequence->begin(), assignToY);
insertSequence->insert(insertSequence->begin(), assignment);
return compiler->validateAST(root);
}
// Replaces a builtin variable with a version that is rotated and corrects the X and Y coordinates.
ANGLE_NO_DISCARD bool RotateAndFlipBuiltinVariable(TCompiler *compiler,
TIntermBlock *root,
......@@ -478,12 +424,11 @@ const TVariable *AddGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTa
new TType(EbtFloat, 4),
new TType(EbtFloat, 2),
new TType(EbtFloat, 2),
new TType(EbtFloat),
new TType(EbtFloat),
new TType(EbtFloat, 2),
new TType(EbtUInt), // uint clipDistancesEnabled; // 32 bits for 32 clip distances max
new TType(EbtUInt),
new TType(EbtUInt),
// NOTE: There's a vec2 gap here that can be used in the future
// NOTE: There's a vec3 gap here that can be used in the future
new TType(EbtInt, 4),
new TType(EbtUInt, 4),
emulatedDepthRangeType,
......@@ -1029,11 +974,12 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (usesPointCoord)
{
TIntermBinary *viewportYScale = CreateDriverUniformRef(driverUniforms, kNegFlipY);
TIntermConstantUnion *pivot = CreateFloatNode(0.5f);
if (!FlipBuiltinVariable(this, root, GetMainSequence(root), viewportYScale,
&getSymbolTable(), BuiltInVariable::gl_PointCoord(),
kFlippedPointCoordName, pivot))
TIntermBinary *flipXY = CreateDriverUniformRef(driverUniforms, kNegFlipXY);
TIntermConstantUnion *pivot = CreateFloatNode(0.5f);
TIntermBinary *fragRotation = CreateDriverUniformRef(driverUniforms, kFragRotation);
if (!RotateAndFlipBuiltinVariable(this, root, GetMainSequence(root), flipXY,
&getSymbolTable(), BuiltInVariable::gl_PointCoord(),
kFlippedPointCoordName, pivot, fragRotation))
{
return false;
}
......@@ -1049,8 +995,10 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
}
{
TIntermBinary *viewportYScale = CreateDriverUniformRef(driverUniforms, kViewportYScale);
if (!RewriteDfdy(this, root, getSymbolTable(), getShaderVersion(), viewportYScale))
TIntermBinary *flipXY = CreateDriverUniformRef(driverUniforms, kFlipXY);
TVector<int> swizzleOffsetY = {1};
TIntermSwizzle *flipY = new TIntermSwizzle(flipXY, swizzleOffsetY);
if (!RewriteDfdy(this, root, getSymbolTable(), getShaderVersion(), flipY))
{
return false;
}
......@@ -1168,9 +1116,13 @@ bool TranslatorVulkan::shouldFlattenPragmaStdglInvariantAll()
return false;
}
TIntermBinary *TranslatorVulkan::getDriverUniformNegFlipYRef(const TVariable *driverUniforms) const
TIntermSwizzle *TranslatorVulkan::getDriverUniformNegFlipYRef(const TVariable *driverUniforms) const
{
return CreateDriverUniformRef(driverUniforms, kNegFlipY);
// Create a swizzle to "negFlipXY.y"
TIntermBinary *negFlipXY = CreateDriverUniformRef(driverUniforms, kNegFlipXY);
TVector<int> swizzleOffsetY = {1};
TIntermSwizzle *negFlipY = new TIntermSwizzle(negFlipXY, swizzleOffsetY);
return negFlipY;
}
TIntermBinary *TranslatorVulkan::getDriverUniformDepthRangeReservedFieldRef(
......
......@@ -30,7 +30,7 @@ class TranslatorVulkan : public TCompiler
PerformanceDiagnostics *perfDiagnostics) override;
bool shouldFlattenPragmaStdglInvariantAll() override;
TIntermBinary *getDriverUniformNegFlipYRef(const TVariable *driverUniforms) const;
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.
......
......@@ -25,16 +25,16 @@ class Traverser : public TIntermTraverser
ANGLE_NO_DISCARD static bool Apply(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
TIntermBinary *viewportYScale);
TIntermSwizzle *viewportYScale);
private:
Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable);
Traverser(TIntermSwizzle *viewportYScale, TSymbolTable *symbolTable);
bool visitUnary(Visit visit, TIntermUnary *node) override;
TIntermBinary *mViewportYScale = nullptr;
TIntermSwizzle *mViewportYScale = nullptr;
};
Traverser::Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable)
Traverser::Traverser(TIntermSwizzle *viewportYScale, TSymbolTable *symbolTable)
: TIntermTraverser(true, false, false, symbolTable), mViewportYScale(viewportYScale)
{}
......@@ -42,7 +42,7 @@ Traverser::Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable)
bool Traverser::Apply(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
TIntermBinary *viewportYScale)
TIntermSwizzle *viewportYScale)
{
TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable);
Traverser traverser(viewportYScale, pSymbolTable);
......@@ -81,7 +81,7 @@ bool RewriteDfdy(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
TIntermBinary *viewportYScale)
TIntermSwizzle *viewportYScale)
{
// dFdy is only valid in GLSL 3.0 and later.
if (shaderVersion < 300)
......
......@@ -20,14 +20,14 @@ namespace sh
class TCompiler;
class TIntermNode;
class TIntermBinary;
class TIntermSwizzle;
class TSymbolTable;
ANGLE_NO_DISCARD bool RewriteDfdy(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
TIntermBinary *viewportYScale);
TIntermSwizzle *viewportYScale);
} // namespace sh
......
......@@ -379,8 +379,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
float halfRenderArea[2];
float flipXY[2];
float viewportYScale;
float negViewportYScale;
float negFlipXY[2];
// 32 bits for 32 clip distances
uint32_t enabledClipDistances;
......
......@@ -1598,10 +1598,10 @@ angle::Result ContextMtl::handleDirtyDriverUniforms(const gl::Context *context)
static_cast<float>(mDrawFramebuffer->getState().getDimensions().width) * 0.5f;
mDriverUniforms.halfRenderArea[1] =
static_cast<float>(mDrawFramebuffer->getState().getDimensions().height) * 0.5f;
mDriverUniforms.flipXY[0] = 1.0f;
mDriverUniforms.flipXY[1] = mDrawFramebuffer->flipY() ? -1.0f : 1.0f;
mDriverUniforms.viewportYScale = mDrawFramebuffer->flipY() ? -1.0f : 1.0f;
mDriverUniforms.negViewportYScale = -mDriverUniforms.viewportYScale;
mDriverUniforms.flipXY[0] = 1.0f;
mDriverUniforms.flipXY[1] = mDrawFramebuffer->flipY() ? -1.0f : 1.0f;
mDriverUniforms.negFlipXY[0] = mDriverUniforms.flipXY[0];
mDriverUniforms.negFlipXY[1] = -mDriverUniforms.flipXY[1];
mDriverUniforms.enabledClipDistances = mState.getEnabledClipDistances().bits();
......
......@@ -55,21 +55,13 @@ struct GraphicsDriverUniforms
// Used to flip gl_FragCoord (both .xy for Android pre-rotation; only .y for desktop)
std::array<float, 2> halfRenderArea;
std::array<float, 2> flipXY;
// TODO(ianelliott): Remove the following while doing pre-rotation for gl_PointCoord & dFdy()
// https://issuetracker.google.com/issues/157476696
// https://issuetracker.google.com/issues/157476241
float viewportYScale;
float negFlipY;
std::array<float, 2> negFlipXY;
// 32 bits for 32 clip planes
uint32_t enabledClipPlanes;
uint32_t xfbActiveUnpaused;
uint32_t xfbVerticesPerDraw;
// TODO(ianelliott): Remove the following while doing pre-rotation for gl_PointCoord
// https://issuetracker.google.com/issues/157476696
// https://issuetracker.google.com/issues/157476241
// NOTE: Explicit padding. Fill in with useful data when needed in the future.
std::array<int32_t, 3> padding;
std::array<int32_t, 4> xfbBufferOffsets;
......@@ -3460,8 +3452,7 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co
static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)},
{halfRenderAreaWidth, halfRenderAreaHeight},
{flipX, flipY},
flipY,
-flipY,
{flipX, -flipY},
mState.getEnabledClipDistances().bits(),
xfbActiveUnpaused,
mXfbVertexCountPerInstance,
......
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