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 ...@@ -35,7 +35,7 @@ namespace
ANGLE_NO_DISCARD bool AppendVertexShaderPositionYCorrectionToMain(TCompiler *compiler, ANGLE_NO_DISCARD bool AppendVertexShaderPositionYCorrectionToMain(TCompiler *compiler,
TIntermBlock *root, TIntermBlock *root,
TSymbolTable *symbolTable, TSymbolTable *symbolTable,
TIntermBinary *negFlipY) TIntermSwizzle *negFlipY)
{ {
// Create a symbol reference to "gl_Position" // Create a symbol reference to "gl_Position"
const TVariable *position = BuiltInVariable::gl_Position(); const TVariable *position = BuiltInVariable::gl_Position();
......
...@@ -176,8 +176,7 @@ constexpr ImmutableString kLineRasterEmulationSpecConstVarName = ...@@ -176,8 +176,7 @@ constexpr ImmutableString kLineRasterEmulationSpecConstVarName =
constexpr const char kViewport[] = "viewport"; constexpr const char kViewport[] = "viewport";
constexpr const char kHalfRenderArea[] = "halfRenderArea"; constexpr const char kHalfRenderArea[] = "halfRenderArea";
constexpr const char kFlipXY[] = "flipXY"; constexpr const char kFlipXY[] = "flipXY";
constexpr const char kViewportYScale[] = "viewportYScale"; constexpr const char kNegFlipXY[] = "negFlipXY";
constexpr const char kNegFlipY[] = "negFlipY";
constexpr const char kClipDistancesEnabled[] = "clipDistancesEnabled"; constexpr const char kClipDistancesEnabled[] = "clipDistancesEnabled";
constexpr const char kXfbActiveUnpaused[] = "xfbActiveUnpaused"; constexpr const char kXfbActiveUnpaused[] = "xfbActiveUnpaused";
constexpr const char kXfbVerticesPerDraw[] = "xfbVerticesPerDraw"; constexpr const char kXfbVerticesPerDraw[] = "xfbVerticesPerDraw";
...@@ -187,11 +186,11 @@ constexpr const char kDepthRange[] = "depthRange"; ...@@ -187,11 +186,11 @@ constexpr const char kDepthRange[] = "depthRange";
constexpr const char kPreRotation[] = "preRotation"; constexpr const char kPreRotation[] = "preRotation";
constexpr const char kFragRotation[] = "fragRotation"; constexpr const char kFragRotation[] = "fragRotation";
constexpr size_t kNumGraphicsDriverUniforms = 13; constexpr size_t kNumGraphicsDriverUniforms = 12;
constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = { constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = {
{kViewport, kHalfRenderArea, kFlipXY, kViewportYScale, kNegFlipY, kClipDistancesEnabled, {kViewport, kHalfRenderArea, kFlipXY, kNegFlipXY, kClipDistancesEnabled, kXfbActiveUnpaused,
kXfbActiveUnpaused, kXfbVerticesPerDraw, kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange, kXfbVerticesPerDraw, kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange, kPreRotation,
kPreRotation, kFragRotation}}; kFragRotation}};
constexpr size_t kNumComputeDriverUniforms = 1; constexpr size_t kNumComputeDriverUniforms = 1;
constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = { constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = {
...@@ -223,59 +222,6 @@ TIntermBinary *CreateDriverUniformRef(const TVariable *driverUniforms, const cha ...@@ -223,59 +222,6 @@ TIntermBinary *CreateDriverUniformRef(const TVariable *driverUniforms, const cha
return new TIntermBinary(EOpIndexDirectInterfaceBlock, angleUniformsRef, indexRef); 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. // Replaces a builtin variable with a version that is rotated and corrects the X and Y coordinates.
ANGLE_NO_DISCARD bool RotateAndFlipBuiltinVariable(TCompiler *compiler, ANGLE_NO_DISCARD bool RotateAndFlipBuiltinVariable(TCompiler *compiler,
TIntermBlock *root, TIntermBlock *root,
...@@ -478,12 +424,11 @@ const TVariable *AddGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTa ...@@ -478,12 +424,11 @@ const TVariable *AddGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTa
new TType(EbtFloat, 4), new TType(EbtFloat, 4),
new TType(EbtFloat, 2), new TType(EbtFloat, 2),
new TType(EbtFloat, 2), new TType(EbtFloat, 2),
new TType(EbtFloat), new TType(EbtFloat, 2),
new TType(EbtFloat),
new TType(EbtUInt), // uint clipDistancesEnabled; // 32 bits for 32 clip distances max new TType(EbtUInt), // uint clipDistancesEnabled; // 32 bits for 32 clip distances max
new TType(EbtUInt), new TType(EbtUInt),
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(EbtInt, 4),
new TType(EbtUInt, 4), new TType(EbtUInt, 4),
emulatedDepthRangeType, emulatedDepthRangeType,
...@@ -1029,11 +974,12 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root, ...@@ -1029,11 +974,12 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (usesPointCoord) if (usesPointCoord)
{ {
TIntermBinary *viewportYScale = CreateDriverUniformRef(driverUniforms, kNegFlipY); TIntermBinary *flipXY = CreateDriverUniformRef(driverUniforms, kNegFlipXY);
TIntermConstantUnion *pivot = CreateFloatNode(0.5f); TIntermConstantUnion *pivot = CreateFloatNode(0.5f);
if (!FlipBuiltinVariable(this, root, GetMainSequence(root), viewportYScale, TIntermBinary *fragRotation = CreateDriverUniformRef(driverUniforms, kFragRotation);
&getSymbolTable(), BuiltInVariable::gl_PointCoord(), if (!RotateAndFlipBuiltinVariable(this, root, GetMainSequence(root), flipXY,
kFlippedPointCoordName, pivot)) &getSymbolTable(), BuiltInVariable::gl_PointCoord(),
kFlippedPointCoordName, pivot, fragRotation))
{ {
return false; return false;
} }
...@@ -1049,8 +995,10 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root, ...@@ -1049,8 +995,10 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
} }
{ {
TIntermBinary *viewportYScale = CreateDriverUniformRef(driverUniforms, kViewportYScale); TIntermBinary *flipXY = CreateDriverUniformRef(driverUniforms, kFlipXY);
if (!RewriteDfdy(this, root, getSymbolTable(), getShaderVersion(), viewportYScale)) TVector<int> swizzleOffsetY = {1};
TIntermSwizzle *flipY = new TIntermSwizzle(flipXY, swizzleOffsetY);
if (!RewriteDfdy(this, root, getSymbolTable(), getShaderVersion(), flipY))
{ {
return false; return false;
} }
...@@ -1168,9 +1116,13 @@ bool TranslatorVulkan::shouldFlattenPragmaStdglInvariantAll() ...@@ -1168,9 +1116,13 @@ bool TranslatorVulkan::shouldFlattenPragmaStdglInvariantAll()
return false; 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( TIntermBinary *TranslatorVulkan::getDriverUniformDepthRangeReservedFieldRef(
......
...@@ -30,7 +30,7 @@ class TranslatorVulkan : public TCompiler ...@@ -30,7 +30,7 @@ class TranslatorVulkan : public TCompiler
PerformanceDiagnostics *perfDiagnostics) override; PerformanceDiagnostics *perfDiagnostics) override;
bool shouldFlattenPragmaStdglInvariantAll() override; bool shouldFlattenPragmaStdglInvariantAll() override;
TIntermBinary *getDriverUniformNegFlipYRef(const TVariable *driverUniforms) const; TIntermSwizzle *getDriverUniformNegFlipYRef(const TVariable *driverUniforms) const;
TIntermBinary *getDriverUniformDepthRangeReservedFieldRef( TIntermBinary *getDriverUniformDepthRangeReservedFieldRef(
const TVariable *driverUniforms) const; const TVariable *driverUniforms) const;
// Subclass can call this method to transform the AST before writing the final output. // Subclass can call this method to transform the AST before writing the final output.
......
...@@ -25,16 +25,16 @@ class Traverser : public TIntermTraverser ...@@ -25,16 +25,16 @@ class Traverser : public TIntermTraverser
ANGLE_NO_DISCARD static bool Apply(TCompiler *compiler, ANGLE_NO_DISCARD static bool Apply(TCompiler *compiler,
TIntermNode *root, TIntermNode *root,
const TSymbolTable &symbolTable, const TSymbolTable &symbolTable,
TIntermBinary *viewportYScale); TIntermSwizzle *viewportYScale);
private: private:
Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable); Traverser(TIntermSwizzle *viewportYScale, TSymbolTable *symbolTable);
bool visitUnary(Visit visit, TIntermUnary *node) override; 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) : TIntermTraverser(true, false, false, symbolTable), mViewportYScale(viewportYScale)
{} {}
...@@ -42,7 +42,7 @@ Traverser::Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable) ...@@ -42,7 +42,7 @@ Traverser::Traverser(TIntermBinary *viewportYScale, TSymbolTable *symbolTable)
bool Traverser::Apply(TCompiler *compiler, bool Traverser::Apply(TCompiler *compiler,
TIntermNode *root, TIntermNode *root,
const TSymbolTable &symbolTable, const TSymbolTable &symbolTable,
TIntermBinary *viewportYScale) TIntermSwizzle *viewportYScale)
{ {
TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable); TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable);
Traverser traverser(viewportYScale, pSymbolTable); Traverser traverser(viewportYScale, pSymbolTable);
...@@ -81,7 +81,7 @@ bool RewriteDfdy(TCompiler *compiler, ...@@ -81,7 +81,7 @@ bool RewriteDfdy(TCompiler *compiler,
TIntermNode *root, TIntermNode *root,
const TSymbolTable &symbolTable, const TSymbolTable &symbolTable,
int shaderVersion, int shaderVersion,
TIntermBinary *viewportYScale) TIntermSwizzle *viewportYScale)
{ {
// dFdy is only valid in GLSL 3.0 and later. // dFdy is only valid in GLSL 3.0 and later.
if (shaderVersion < 300) if (shaderVersion < 300)
......
...@@ -20,14 +20,14 @@ namespace sh ...@@ -20,14 +20,14 @@ namespace sh
class TCompiler; class TCompiler;
class TIntermNode; class TIntermNode;
class TIntermBinary; class TIntermSwizzle;
class TSymbolTable; class TSymbolTable;
ANGLE_NO_DISCARD bool RewriteDfdy(TCompiler *compiler, ANGLE_NO_DISCARD bool RewriteDfdy(TCompiler *compiler,
TIntermNode *root, TIntermNode *root,
const TSymbolTable &symbolTable, const TSymbolTable &symbolTable,
int shaderVersion, int shaderVersion,
TIntermBinary *viewportYScale); TIntermSwizzle *viewportYScale);
} // namespace sh } // namespace sh
......
...@@ -379,8 +379,7 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -379,8 +379,7 @@ class ContextMtl : public ContextImpl, public mtl::Context
float halfRenderArea[2]; float halfRenderArea[2];
float flipXY[2]; float flipXY[2];
float viewportYScale; float negFlipXY[2];
float negViewportYScale;
// 32 bits for 32 clip distances // 32 bits for 32 clip distances
uint32_t enabledClipDistances; uint32_t enabledClipDistances;
......
...@@ -1598,10 +1598,10 @@ angle::Result ContextMtl::handleDirtyDriverUniforms(const gl::Context *context) ...@@ -1598,10 +1598,10 @@ angle::Result ContextMtl::handleDirtyDriverUniforms(const gl::Context *context)
static_cast<float>(mDrawFramebuffer->getState().getDimensions().width) * 0.5f; static_cast<float>(mDrawFramebuffer->getState().getDimensions().width) * 0.5f;
mDriverUniforms.halfRenderArea[1] = mDriverUniforms.halfRenderArea[1] =
static_cast<float>(mDrawFramebuffer->getState().getDimensions().height) * 0.5f; static_cast<float>(mDrawFramebuffer->getState().getDimensions().height) * 0.5f;
mDriverUniforms.flipXY[0] = 1.0f; mDriverUniforms.flipXY[0] = 1.0f;
mDriverUniforms.flipXY[1] = mDrawFramebuffer->flipY() ? -1.0f : 1.0f; mDriverUniforms.flipXY[1] = mDrawFramebuffer->flipY() ? -1.0f : 1.0f;
mDriverUniforms.viewportYScale = mDrawFramebuffer->flipY() ? -1.0f : 1.0f; mDriverUniforms.negFlipXY[0] = mDriverUniforms.flipXY[0];
mDriverUniforms.negViewportYScale = -mDriverUniforms.viewportYScale; mDriverUniforms.negFlipXY[1] = -mDriverUniforms.flipXY[1];
mDriverUniforms.enabledClipDistances = mState.getEnabledClipDistances().bits(); mDriverUniforms.enabledClipDistances = mState.getEnabledClipDistances().bits();
......
...@@ -55,21 +55,13 @@ struct GraphicsDriverUniforms ...@@ -55,21 +55,13 @@ struct GraphicsDriverUniforms
// Used to flip gl_FragCoord (both .xy for Android pre-rotation; only .y for desktop) // Used to flip gl_FragCoord (both .xy for Android pre-rotation; only .y for desktop)
std::array<float, 2> halfRenderArea; std::array<float, 2> halfRenderArea;
std::array<float, 2> flipXY; std::array<float, 2> flipXY;
// TODO(ianelliott): Remove the following while doing pre-rotation for gl_PointCoord & dFdy() std::array<float, 2> negFlipXY;
// https://issuetracker.google.com/issues/157476696
// https://issuetracker.google.com/issues/157476241
float viewportYScale;
float negFlipY;
// 32 bits for 32 clip planes // 32 bits for 32 clip planes
uint32_t enabledClipPlanes; uint32_t enabledClipPlanes;
uint32_t xfbActiveUnpaused; uint32_t xfbActiveUnpaused;
uint32_t xfbVerticesPerDraw; 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, 3> padding;
std::array<int32_t, 4> xfbBufferOffsets; std::array<int32_t, 4> xfbBufferOffsets;
...@@ -3460,8 +3452,7 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co ...@@ -3460,8 +3452,7 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co
static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)}, static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)},
{halfRenderAreaWidth, halfRenderAreaHeight}, {halfRenderAreaWidth, halfRenderAreaHeight},
{flipX, flipY}, {flipX, flipY},
flipY, {flipX, -flipY},
-flipY,
mState.getEnabledClipDistances().bits(), mState.getEnabledClipDistances().bits(),
xfbActiveUnpaused, xfbActiveUnpaused,
mXfbVertexCountPerInstance, 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