Commit c75473c2 by Charlie Lao Committed by Commit Bot

Vulkan: Generalize FlipRotationSpecConst to SpecializationConstant

Specialization constant are used not just for flip/rotation. It also used for other things. This CL merges all specialization constant usage (lineRasterEmulation, flip, rotation, halfRenderArea) into one class and rename FlipRotationSpecConst to SpecConst. Bug: b/173800146 Change-Id: I8dc3354b6caedbb183cec29855fc1c301ec8872a Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2555812 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent dcc0bebf
......@@ -346,7 +346,7 @@ const ShCompileOptions SH_ADD_PRE_ROTATION = UINT64_C(1) << 56;
const ShCompileOptions SH_FORCE_SHADER_PRECISION_HIGHP_TO_MEDIUMP = UINT64_C(1) << 57;
// Allow compiler to use specialization constant to do pre-rotation and y flip.
const ShCompileOptions SH_USE_ROTATION_SPECIALIZATION_CONSTANT = UINT64_C(1) << 58;
const ShCompileOptions SH_USE_SPECIALIZATION_CONSTANT = UINT64_C(1) << 58;
// Defines alternate strategies for implementing array index clamping.
enum ShArrayIndexClampingStrategy
......
......@@ -220,8 +220,6 @@ 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",
......@@ -243,6 +241,8 @@ angle_translator_sources = [
"src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h",
"src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp",
"src/compiler/translator/tree_util/RunAtTheEndOfShader.h",
"src/compiler/translator/tree_util/SpecializationConstant.cpp",
"src/compiler/translator/tree_util/SpecializationConstant.h",
"src/compiler/translator/tree_util/Visit.h",
"src/compiler/translator/util.cpp",
"src/compiler/translator/util.h",
......
......@@ -143,9 +143,10 @@ bool TranslatorMetal::translate(TIntermBlock *root,
getNameMap(), &getSymbolTable(), getShaderType(),
getShaderVersion(), getOutputType(), false, true, compileOptions);
SpecConstMetal specConst(&getSymbolTable(), compileOptions);
DriverUniformMetal driverUniforms;
if (!TranslatorVulkan::translateImpl(root, compileOptions, perfDiagnostics, &driverUniforms,
&outputGLSL))
if (!TranslatorVulkan::translateImpl(root, compileOptions, perfDiagnostics, &specConst,
&driverUniforms, &outputGLSL))
{
return false;
}
......
......@@ -17,10 +17,24 @@
#include "compiler/translator/TranslatorVulkan.h"
#include "compiler/translator/tree_util/DriverUniform.h"
#include "compiler/translator/tree_util/SpecializationConstant.h"
namespace sh
{
// TODO: http://anglebug.com/5339 Implement it using actual specialization constant. For now we are
// redirecting to driver uniforms
class SpecConstMetal : public SpecConst
{
public:
SpecConstMetal(TSymbolTable *symbolTable, ShCompileOptions compileOptions)
: SpecConst(symbolTable, compileOptions)
{}
~SpecConstMetal() override {}
private:
};
class DriverUniformMetal : public DriverUniform
{
public:
......
......@@ -32,12 +32,12 @@
#include "compiler/translator/tree_util/DriverUniform.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"
#include "compiler/translator/tree_util/RewriteSampleMaskVariable.h"
#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
#include "compiler/translator/tree_util/SpecializationConstant.h"
#include "compiler/translator/util.h"
namespace sh
......@@ -174,10 +174,6 @@ constexpr gl::ShaderMap<const char *> kDefaultUniformNames = {
{gl::ShaderType::Compute, vk::kDefaultUniformsNameCS},
};
// Specialization constant names
constexpr ImmutableString kLineRasterEmulationSpecConstVarName =
ImmutableString("ANGLELineRasterEmulation");
// 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,
......@@ -318,10 +314,10 @@ ANGLE_NO_DISCARD bool AppendVertexShaderDepthCorrectionToMain(TCompiler *compile
ANGLE_NO_DISCARD bool AppendPreRotation(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
TIntermTyped *preRotationRef = rotationSpecConst->getPreRotationMatrix();
TIntermTyped *preRotationRef = specConst->getPreRotationMatrix();
if (!preRotationRef)
{
preRotationRef = driverUniforms->getPreRotationMatrixRef();
......@@ -352,14 +348,6 @@ ANGLE_NO_DISCARD bool AppendTransformFeedbackOutputToMain(TCompiler *compiler,
return RunAtTheEndOfShader(compiler, root, new TIntermSymbol(xfbPlaceholder), symbolTable);
}
TIntermSymbol *GenerateLineRasterSpecConstRef(TSymbolTable *symbolTable)
{
TVariable *specConstVar =
new TVariable(symbolTable, kLineRasterEmulationSpecConstVarName,
StaticType::GetBasic<EbtBool>(), SymbolType::AngleInternal);
return new TIntermSymbol(specConstVar);
}
TVariable *AddANGLEPositionVaryingDeclaration(TIntermBlock *root,
TSymbolTable *symbolTable,
TQualifier qualifier)
......@@ -386,6 +374,7 @@ TVariable *AddANGLEPositionVaryingDeclaration(TIntermBlock *root,
ANGLE_NO_DISCARD bool AddBresenhamEmulationVS(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
TVariable *anglePosition = AddANGLEPositionVaryingDeclaration(root, symbolTable, EvqVaryingOut);
......@@ -445,7 +434,7 @@ ANGLE_NO_DISCARD bool AddBresenhamEmulationVS(TCompiler *compiler,
emulationBlock->appendStatement(clampedDecl);
emulationBlock->appendStatement(varyingAssign);
TIntermIfElse *ifEmulation =
new TIntermIfElse(GenerateLineRasterSpecConstRef(symbolTable), emulationBlock, nullptr);
new TIntermIfElse(specConst->getLineRasterEmulation(), emulationBlock, nullptr);
// Ensure the statements run at the end of the main() function.
TIntermFunctionDefinition *main = FindMain(root);
......@@ -459,16 +448,16 @@ ANGLE_NO_DISCARD bool InsertFragCoordCorrection(TCompiler *compiler,
TIntermBlock *root,
TIntermSequence *insertSequence,
TSymbolTable *symbolTable,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
TIntermTyped *flipXY = rotationSpecConst->getFlipXY();
TIntermTyped *flipXY = specConst->getFlipXY();
if (!flipXY)
{
flipXY = driverUniforms->getFlipXYRef();
}
TIntermBinary *pivot = rotationSpecConst->getHalfRenderArea();
TIntermBinary *pivot = specConst->getHalfRenderArea();
if (!pivot)
{
pivot = driverUniforms->getHalfRenderAreaRef();
......@@ -477,7 +466,7 @@ ANGLE_NO_DISCARD bool InsertFragCoordCorrection(TCompiler *compiler,
TIntermTyped *fragRotation = nullptr;
if (compileOptions & SH_ADD_PRE_ROTATION)
{
fragRotation = rotationSpecConst->getFragRotationMatrix();
fragRotation = specConst->getFragRotationMatrix();
if (!fragRotation)
{
fragRotation = driverUniforms->getFragRotationMatrixRef();
......@@ -526,7 +515,7 @@ ANGLE_NO_DISCARD bool AddBresenhamEmulationFS(TCompiler *compiler,
TInfoSinkBase &sink,
TIntermBlock *root,
TSymbolTable *symbolTable,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms,
bool usesFragCoord)
{
......@@ -612,7 +601,7 @@ ANGLE_NO_DISCARD bool AddBresenhamEmulationFS(TCompiler *compiler,
emulationSequence->insert(emulationSequence->begin(), nodes.begin(), nodes.end());
TIntermIfElse *ifEmulation =
new TIntermIfElse(GenerateLineRasterSpecConstRef(symbolTable), emulationBlock, nullptr);
new TIntermIfElse(specConst->getLineRasterEmulation(), emulationBlock, nullptr);
// Ensure the line raster code runs at the beginning of main().
TIntermFunctionDefinition *main = FindMain(root);
......@@ -625,7 +614,7 @@ ANGLE_NO_DISCARD bool AddBresenhamEmulationFS(TCompiler *compiler,
if (!usesFragCoord)
{
if (!InsertFragCoordCorrection(compiler, compileOptions, root, emulationSequence,
symbolTable, rotationSpecConst, driverUniforms))
symbolTable, specConst, driverUniforms))
{
return false;
}
......@@ -642,6 +631,7 @@ TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
bool TranslatorVulkan::translateImpl(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics * /*perfDiagnostics*/,
SpecConst *specConst,
DriverUniform *driverUniforms,
TOutputVulkanGLSL *outputGLSL)
{
......@@ -762,13 +752,6 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
sink << "};\n";
}
FlipRotateSpecConst surfaceRotationSpecConst;
if (getShaderType() != GL_COMPUTE_SHADER &&
(compileOptions & SH_USE_ROTATION_SPECIALIZATION_CONSTANT))
{
surfaceRotationSpecConst.generateSymbol(&getSymbolTable());
}
if (getShaderType() == GL_COMPUTE_SHADER)
{
driverUniforms->addComputeDriverUniformsToShader(root, &getSymbolTable());
......@@ -804,15 +787,6 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
{
return false;
}
// Add specialization constant declarations. The default value of the specialization
// constant is irrelevant, as it will be set when creating the pipeline.
if (compileOptions & SH_ADD_BRESENHAM_LINE_RASTER_EMULATION)
{
sink << "layout(constant_id="
<< static_cast<uint32_t>(vk::SpecializationConstantId::LineRasterEmulation)
<< ") const bool " << kLineRasterEmulationSpecConstVarName << " = false;\n\n";
}
}
if (gl::ShaderTypeSupportsTransformFeedback(packedShaderType))
......@@ -865,12 +839,10 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (compileOptions & SH_ADD_BRESENHAM_LINE_RASTER_EMULATION)
{
if (!AddBresenhamEmulationFS(this, compileOptions, sink, root, &getSymbolTable(),
&surfaceRotationSpecConst, driverUniforms,
usesFragCoord))
specConst, driverUniforms, usesFragCoord))
{
return false;
}
mSpecConstUsageBits.set(vk::SpecConstUsage::LineRasterEmulation);
}
bool hasGLFragColor = false;
......@@ -914,7 +886,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (usesPointCoord)
{
TIntermTyped *flipNegXY = surfaceRotationSpecConst.getNegFlipXY();
TIntermTyped *flipNegXY = specConst->getNegFlipXY();
if (!flipNegXY)
{
flipNegXY = driverUniforms->getNegFlipXYRef();
......@@ -923,7 +895,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
TIntermTyped *fragRotation = nullptr;
if (usePreRotation)
{
fragRotation = surfaceRotationSpecConst.getFragRotationMatrix();
fragRotation = specConst->getFragRotationMatrix();
if (!fragRotation)
{
fragRotation = driverUniforms->getFragRotationMatrixRef();
......@@ -941,22 +913,20 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
if (usesFragCoord)
{
if (!InsertFragCoordCorrection(this, compileOptions, root, GetMainSequence(root),
&getSymbolTable(), &surfaceRotationSpecConst,
driverUniforms))
&getSymbolTable(), specConst, driverUniforms))
{
return false;
}
}
if (!RewriteDfdy(this, compileOptions, root, getSymbolTable(), getShaderVersion(),
&surfaceRotationSpecConst, driverUniforms))
specConst, driverUniforms))
{
return false;
}
if (!RewriteInterpolateAtOffset(this, compileOptions, root, getSymbolTable(),
getShaderVersion(), &surfaceRotationSpecConst,
driverUniforms))
getShaderVersion(), specConst, driverUniforms))
{
return false;
}
......@@ -994,11 +964,11 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
{
if (compileOptions & SH_ADD_BRESENHAM_LINE_RASTER_EMULATION)
{
if (!AddBresenhamEmulationVS(this, root, &getSymbolTable(), driverUniforms))
if (!AddBresenhamEmulationVS(this, root, &getSymbolTable(), specConst,
driverUniforms))
{
return false;
}
mSpecConstUsageBits.set(vk::SpecConstUsage::LineRasterEmulation);
}
// Search for the gl_ClipDistance usage, if its used, we need to do some replacements.
......@@ -1028,8 +998,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
return false;
}
if ((compileOptions & SH_ADD_PRE_ROTATION) != 0 &&
!AppendPreRotation(this, root, &getSymbolTable(), &surfaceRotationSpecConst,
driverUniforms))
!AppendPreRotation(this, root, &getSymbolTable(), specConst, driverUniforms))
{
return false;
}
......@@ -1060,10 +1029,10 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
break;
}
surfaceRotationSpecConst.outputLayoutString(sink);
specConst->outputLayoutString(sink);
// Gather specialization constant usage bits so that we can feedback to context.
mSpecConstUsageBits |= surfaceRotationSpecConst.getSpecConstUsageBits();
mSpecConstUsageBits = specConst->getSpecConstUsageBits();
if (!validateAST(root))
{
......@@ -1091,8 +1060,10 @@ bool TranslatorVulkan::translate(TIntermBlock *root,
getShaderVersion(), getOutputType(), precisionEmulation,
enablePrecision, compileOptions);
SpecConst specConst(&getSymbolTable(), compileOptions);
DriverUniform driverUniforms;
if (!translateImpl(root, compileOptions, perfDiagnostics, &driverUniforms, &outputGLSL))
if (!translateImpl(root, compileOptions, perfDiagnostics, &specConst, &driverUniforms,
&outputGLSL))
{
return false;
}
......
......@@ -18,6 +18,7 @@ namespace sh
{
class TOutputVulkanGLSL;
class SpecConst;
class DriverUniform;
class TranslatorVulkan : public TCompiler
......@@ -36,6 +37,7 @@ class TranslatorVulkan : public TCompiler
ANGLE_NO_DISCARD bool translateImpl(TIntermBlock *root,
ShCompileOptions compileOptions,
PerformanceDiagnostics *perfDiagnostics,
SpecConst *specConst,
DriverUniform *driverUniforms,
TOutputVulkanGLSL *outputGLSL);
......
......@@ -13,9 +13,9 @@
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/TranslatorVulkan.h"
#include "compiler/translator/tree_util/DriverUniform.h"
#include "compiler/translator/tree_util/FlipRotateSpecConst.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
#include "compiler/translator/tree_util/SpecializationConstant.h"
namespace sh
{
......@@ -30,30 +30,30 @@ class Traverser : public TIntermTraverser
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms);
private:
Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms);
bool visitUnary(Visit visit, TIntermUnary *node) override;
bool visitUnaryWithRotation(Visit visit, TIntermUnary *node);
bool visitUnaryWithoutRotation(Visit visit, TIntermUnary *node);
FlipRotateSpecConst *mRotationSpecConst = nullptr;
const DriverUniform *mDriverUniforms = nullptr;
bool mUsePreRotation = false;
SpecConst *mRotationSpecConst = nullptr;
const DriverUniform *mDriverUniforms = nullptr;
bool mUsePreRotation = false;
};
Traverser::Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
: TIntermTraverser(true, false, false, symbolTable),
mRotationSpecConst(rotationSpecConst),
mRotationSpecConst(specConst),
mDriverUniforms(driverUniforms),
mUsePreRotation((compileOptions & SH_ADD_PRE_ROTATION) != 0)
{}
......@@ -63,11 +63,11 @@ bool Traverser::Apply(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable);
Traverser traverser(pSymbolTable, compileOptions, rotationSpecConst, driverUniforms);
Traverser traverser(pSymbolTable, compileOptions, specConst, driverUniforms);
root->traverse(&traverser);
return traverser.updateTree(compiler, root);
}
......@@ -217,15 +217,14 @@ bool RewriteDfdy(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
// dFdy is only valid in GLSL 3.0 and later.
if (shaderVersion < 300)
return true;
return Traverser::Apply(compiler, compileOptions, root, symbolTable, rotationSpecConst,
driverUniforms);
return Traverser::Apply(compiler, compileOptions, root, symbolTable, specConst, driverUniforms);
}
} // namespace sh
......@@ -26,7 +26,7 @@ class TIntermBinary;
class TIntermTyped;
class TSymbolTable;
class TVariable;
class FlipRotateSpecConst;
class SpecConst;
class DriverUniform;
// If fragRotation = nullptr, no rotation will be applied.
......@@ -35,7 +35,7 @@ ANGLE_NO_DISCARD bool RewriteDfdy(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms);
} // namespace sh
......
......@@ -13,9 +13,9 @@
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/TranslatorVulkan.h"
#include "compiler/translator/tree_util/DriverUniform.h"
#include "compiler/translator/tree_util/FlipRotateSpecConst.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
#include "compiler/translator/tree_util/SpecializationConstant.h"
namespace sh
{
......@@ -31,33 +31,33 @@ class Traverser : public TIntermTraverser
TIntermNode *root,
const TSymbolTable &symbolTable,
int ShaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms);
private:
Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
int shaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms);
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
const TSymbolTable *symbolTable = nullptr;
const int shaderVersion;
FlipRotateSpecConst *mRotationSpecConst = nullptr;
const DriverUniform *mDriverUniforms = nullptr;
bool mUsePreRotation = false;
SpecConst *mRotationSpecConst = nullptr;
const DriverUniform *mDriverUniforms = nullptr;
bool mUsePreRotation = false;
};
Traverser::Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
int shaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
: TIntermTraverser(true, false, false, symbolTable),
symbolTable(symbolTable),
shaderVersion(shaderVersion),
mRotationSpecConst(rotationSpecConst),
mRotationSpecConst(specConst),
mDriverUniforms(driverUniforms),
mUsePreRotation((compileOptions & SH_ADD_PRE_ROTATION) != 0)
{}
......@@ -68,12 +68,11 @@ bool Traverser::Apply(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable);
Traverser traverser(pSymbolTable, compileOptions, shaderVersion, rotationSpecConst,
driverUniforms);
Traverser traverser(pSymbolTable, compileOptions, shaderVersion, specConst, driverUniforms);
root->traverse(&traverser);
return traverser.updateTree(compiler, root);
}
......@@ -144,7 +143,7 @@ bool RewriteInterpolateAtOffset(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
// interpolateAtOffset is only valid in GLSL 3.0 and later.
......@@ -153,8 +152,8 @@ bool RewriteInterpolateAtOffset(TCompiler *compiler,
return true;
}
return Traverser::Apply(compiler, compileOptions, root, symbolTable, shaderVersion,
rotationSpecConst, driverUniforms);
return Traverser::Apply(compiler, compileOptions, root, symbolTable, shaderVersion, specConst,
driverUniforms);
}
} // namespace sh
......@@ -31,7 +31,7 @@ ANGLE_NO_DISCARD bool RewriteInterpolateAtOffset(TCompiler *compiler,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
FlipRotateSpecConst *rotationSpecConst,
SpecConst *specConst,
const DriverUniform *driverUniforms);
} // namespace sh
......
......@@ -3,12 +3,10 @@
// 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.
// SpecializationConst.cpp: Add code to generate AST node for various specialization constants.
//
#include "compiler/translator/tree_util/FlipRotateSpecConst.h"
#include "compiler/translator/tree_util/SpecializationConstant.h"
#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "compiler/translator/StaticType.h"
......@@ -20,6 +18,9 @@ namespace sh
namespace
{
// Specialization constant names
constexpr ImmutableString kLineRasterEmulationSpecConstVarName =
ImmutableString("ANGLELineRasterEmulation");
constexpr ImmutableString kSurfaceRotationSpecConstVarName =
ImmutableString("ANGLESurfaceRotation");
constexpr ImmutableString kDrawableWidthSpecConstVarName = ImmutableString("ANGLEDrawableWidth");
......@@ -82,7 +83,7 @@ TIntermAggregate *CreateMat2x2(const Mat2x2EnumMap &matrix, vk::SurfaceRotation
}
// Generates an array of vec2 and then use rotation to retrieve the desired flipXY out.
TIntermTyped *GenerateMat2x2ArrayWithIndex(const Mat2x2EnumMap &matrix, TIntermSymbol *specConst)
TIntermTyped *GenerateMat2x2ArrayWithIndex(const Mat2x2EnumMap &matrix, TIntermSymbol *rotation)
{
auto mat2Type = new TType(EbtFloat, 2, 2);
TType *typeMat2Array = new TType(*mat2Type);
......@@ -99,7 +100,7 @@ TIntermTyped *GenerateMat2x2ArrayWithIndex(const Mat2x2EnumMap &matrix, TIntermS
CreateMat2x2(matrix, vk::SurfaceRotation::FlippedRotated180Degrees),
CreateMat2x2(matrix, vk::SurfaceRotation::FlippedRotated270Degrees)});
TIntermTyped *array = TIntermAggregate::CreateConstructor(*typeMat2Array, sequences);
return new TIntermBinary(EOpIndexDirect, array, specConst->deepCopy());
return new TIntermBinary(EOpIndexDirect, array, rotation);
}
using Vec2 = std::array<float, 2>;
......@@ -140,7 +141,7 @@ TIntermAggregate *CreateVec2(Vec2EnumMap vec2Values, float yscale, vk::SurfaceRo
// Generates an array of vec2 and then use rotation to retrieve the desired flipXY out.
TIntermTyped *CreateVec2ArrayWithIndex(Vec2EnumMap vec2Values,
float yscale,
TIntermSymbol *rotationSpecConst)
TIntermSymbol *rotation)
{
auto vec2Type = new TType(EbtFloat, 2);
TType *typeVec2Array = new TType(*vec2Type);
......@@ -157,7 +158,7 @@ TIntermTyped *CreateVec2ArrayWithIndex(Vec2EnumMap vec2Values,
CreateVec2(vec2Values, yscale, vk::SurfaceRotation::FlippedRotated180Degrees),
CreateVec2(vec2Values, yscale, vk::SurfaceRotation::FlippedRotated270Degrees)});
TIntermTyped *vec2Array = TIntermAggregate::CreateConstructor(*typeVec2Array, sequences);
return new TIntermBinary(EOpIndexDirect, vec2Array, rotationSpecConst->deepCopy());
return new TIntermBinary(EOpIndexDirect, vec2Array, rotation);
}
// Returns [flipX*m0, flipY*m1], where [m0 m1] is the first column of kFragRotation matrix.
......@@ -231,33 +232,28 @@ TIntermTyped *CreateFloatArrayWithRotationIndex(const Vec2EnumMap &valuesEnumMap
scale)});
TIntermTyped *array = TIntermAggregate::CreateConstructor(*typeFloat8, sequences);
return new TIntermBinary(EOpIndexDirect, array, rotation->deepCopy());
return new TIntermBinary(EOpIndexDirect, array, rotation);
}
} // anonymous namespace
FlipRotateSpecConst::FlipRotateSpecConst() : mSymbolTable(nullptr), mSpecConstSymbol(nullptr) {}
SpecConst::SpecConst(TSymbolTable *symbolTable, ShCompileOptions compileOptions)
: mSymbolTable(symbolTable), mCompileOptions(compileOptions)
{}
SpecConst::~SpecConst() {}
FlipRotateSpecConst::~FlipRotateSpecConst()
void SpecConst::outputLayoutString(TInfoSinkBase &sink) const
{
if (mSpecConstSymbol)
// Add specialization constant declarations. The default value of the specialization
// constant is irrelevant, as it will be set when creating the pipeline.
// Only emit specialized const layout string if it has been referenced.
if (mUsageBits.test(vk::SpecConstUsage::LineRasterEmulation))
{
delete mSpecConstSymbol;
sink << "layout(constant_id="
<< static_cast<uint32_t>(vk::SpecializationConstantId::LineRasterEmulation)
<< ") const bool " << kLineRasterEmulationSpecConstVarName << " = false;\n\n";
}
}
void FlipRotateSpecConst::generateSymbol(TSymbolTable *symbolTable)
{
TVariable *specConstVar =
new TVariable(symbolTable, kSurfaceRotationSpecConstVarName,
StaticType::GetBasic<EbtUInt>(), SymbolType::AngleInternal);
mSpecConstSymbol = new TIntermSymbol(specConstVar);
mSymbolTable = symbolTable;
}
void FlipRotateSpecConst::outputLayoutString(TInfoSinkBase &sink) const
{
// Only emit specialized const layout string if it has been referenced.
if (mUsageBits.test(vk::SpecConstUsage::YFlip) || mUsageBits.test(vk::SpecConstUsage::Rotation))
{
sink << "layout(constant_id="
......@@ -276,123 +272,144 @@ void FlipRotateSpecConst::outputLayoutString(TInfoSinkBase &sink) const
}
}
TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdx()
TIntermSymbol *SpecConst::getLineRasterEmulation()
{
if (!(mCompileOptions & SH_ADD_BRESENHAM_LINE_RASTER_EMULATION))
{
return nullptr;
}
TVariable *specConstVar =
new TVariable(mSymbolTable, kLineRasterEmulationSpecConstVarName,
StaticType::GetBasic<EbtBool>(), SymbolType::AngleInternal);
mUsageBits.set(vk::SpecConstUsage::LineRasterEmulation);
return new TIntermSymbol(specConstVar);
}
TIntermSymbol *SpecConst::getFlipRotation()
{
TVariable *specConstVar =
new TVariable(mSymbolTable, kSurfaceRotationSpecConstVarName,
StaticType::GetBasic<EbtUInt>(), SymbolType::AngleInternal);
return new TIntermSymbol(specConstVar);
}
TIntermTyped *SpecConst::getMultiplierXForDFdx()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 0, 1, mSpecConstSymbol);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 0, 1, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdx()
TIntermTyped *SpecConst::getMultiplierYForDFdx()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 1, 1, mSpecConstSymbol);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 1, 1, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdy()
TIntermTyped *SpecConst::getMultiplierXForDFdy()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 0, 1, mSpecConstSymbol);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 0, 1, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdy()
TIntermTyped *SpecConst::getMultiplierYForDFdy()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 1, 1, mSpecConstSymbol);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 1, 1, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getPreRotationMatrix()
TIntermTyped *SpecConst::getPreRotationMatrix()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::Rotation);
return GenerateMat2x2ArrayWithIndex(kPreRotationMatrices, mSpecConstSymbol);
return GenerateMat2x2ArrayWithIndex(kPreRotationMatrices, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getFragRotationMatrix()
TIntermTyped *SpecConst::getFragRotationMatrix()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::Rotation);
return GenerateMat2x2ArrayWithIndex(kFragRotationMatrices, mSpecConstSymbol);
return GenerateMat2x2ArrayWithIndex(kFragRotationMatrices, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getHalfRenderAreaRotationMatrix()
TIntermTyped *SpecConst::getHalfRenderAreaRotationMatrix()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::Rotation);
return GenerateMat2x2ArrayWithIndex(kHalfRenderAreaRotationMatrices, mSpecConstSymbol);
return GenerateMat2x2ArrayWithIndex(kHalfRenderAreaRotationMatrices, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getFlipXY()
TIntermTyped *SpecConst::getFlipXY()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateVec2ArrayWithIndex(kFlipXYValue, 1.0, mSpecConstSymbol);
return CreateVec2ArrayWithIndex(kFlipXYValue, 1.0, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getNegFlipXY()
TIntermTyped *SpecConst::getNegFlipXY()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateVec2ArrayWithIndex(kFlipXYValue, -1.0, mSpecConstSymbol);
return CreateVec2ArrayWithIndex(kFlipXYValue, -1.0, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getFlipY()
TIntermTyped *SpecConst::getFlipY()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, 1, mSpecConstSymbol);
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, 1, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getNegFlipY()
TIntermTyped *SpecConst::getNegFlipY()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, -1, mSpecConstSymbol);
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, -1, getFlipRotation());
}
TIntermTyped *FlipRotateSpecConst::getFragRotationMultiplyFlipXY()
TIntermTyped *SpecConst::getFragRotationMultiplyFlipXY()
{
if (!mSpecConstSymbol)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
......@@ -417,10 +434,10 @@ TIntermTyped *FlipRotateSpecConst::getFragRotationMultiplyFlipXY()
mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateVec2ArrayWithIndex(kFragRotationMultiplyFlipXY, 1.0, mSpecConstSymbol);
return CreateVec2ArrayWithIndex(kFragRotationMultiplyFlipXY, 1.0, getFlipRotation());
}
TIntermSymbol *FlipRotateSpecConst::getDrawableWidth()
TIntermSymbol *SpecConst::getDrawableWidth()
{
TVariable *widthSpecConstVar =
new TVariable(mSymbolTable, kDrawableWidthSpecConstVarName,
......@@ -429,7 +446,7 @@ TIntermSymbol *FlipRotateSpecConst::getDrawableWidth()
return drawableWidth;
}
TIntermSymbol *FlipRotateSpecConst::getDrawableHeight()
TIntermSymbol *SpecConst::getDrawableHeight()
{
TVariable *heightSpecConstVar =
new TVariable(mSymbolTable, kDrawableHeightSpecConstVarName,
......@@ -438,9 +455,9 @@ TIntermSymbol *FlipRotateSpecConst::getDrawableHeight()
return drawableHeight;
}
TIntermBinary *FlipRotateSpecConst::getHalfRenderArea()
TIntermBinary *SpecConst::getHalfRenderArea()
{
if (!mSymbolTable)
if (!(mCompileOptions & SH_USE_SPECIALIZATION_CONSTANT))
{
return nullptr;
}
......
......@@ -3,12 +3,11 @@
// 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.
// SpecializationConst.h: Add code to generate AST node for specialization constant.
//
#ifndef COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_
#define COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_
#ifndef COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
#define COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
#include "common/angleutils.h"
#include "compiler/translator/Compiler.h"
......@@ -21,12 +20,16 @@ class TVariable;
namespace sh
{
class FlipRotateSpecConst
class SpecConst
{
public:
FlipRotateSpecConst();
~FlipRotateSpecConst();
SpecConst(TSymbolTable *symbolTable, ShCompileOptions compileOptions);
virtual ~SpecConst();
// Line rasterizaton emulation
TIntermSymbol *getLineRasterEmulation();
// Flip/rotation
TIntermTyped *getMultiplierXForDFdx();
TIntermTyped *getMultiplierYForDFdx();
TIntermTyped *getMultiplierXForDFdy();
......@@ -36,24 +39,28 @@ class FlipRotateSpecConst
TIntermTyped *getFlipXY();
TIntermTyped *getNegFlipXY();
TIntermTyped *getFlipY();
TIntermTyped *getNegFlipY();
TIntermTyped *getFragRotationMultiplyFlipXY();
// Half render area
TIntermBinary *getHalfRenderArea();
TIntermTyped *getHalfRenderAreaRotationMatrix();
void generateSymbol(TSymbolTable *symbolTable);
void outputLayoutString(TInfoSinkBase &sink) const;
SpecConstUsageBits getSpecConstUsageBits() const { return mUsageBits; }
private:
TIntermSymbol *getFlipRotation();
TIntermTyped *getNegFlipY();
TIntermSymbol *getDrawableWidth();
TIntermSymbol *getDrawableHeight();
TIntermTyped *getHalfRenderAreaRotationMatrix();
// If unsupported, this should be set to null.
TSymbolTable *mSymbolTable;
TIntermSymbol *mSpecConstSymbol;
ShCompileOptions mCompileOptions;
// Bit is set if YFlip or Rotation has been used
SpecConstUsageBits mUsageBits;
};
} // namespace sh
#endif // COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_
#endif // COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
......@@ -75,7 +75,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte
// Let compiler use specialized constant for pre-rotation.
if (!contextVk->getFeatures().forceDriverUniformOverSpecConst.enabled)
{
compileOptions |= SH_USE_ROTATION_SPECIALIZATION_CONSTANT;
compileOptions |= SH_USE_SPECIALIZATION_CONSTANT;
}
if (contextVk->getFeatures().enablePreRotateSurfaces.enabled ||
......
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