Commit 24f64249 by Charlie Lao Committed by Commit Bot

Vulkan: Track specialization constant usage bit and feedback to ctx

Right now context does not know which specialization constant is used by the shader. Whenever a specialization constant changes, we assume shader program is using it, we always reach into vulkan driver to ask for a new program. Instead we can track shader's usage of specialization constant so that context can utilize this information to avoid recompile pipeline program if an unused specialization constant has changed. This CL implements the plumbing the usage bits form compiler to program object, it does not actually utilize the usage bits to avoid unnecessary compilation yet. Bug: b/173461931 Change-Id: Iebc9d0638c17b1a282c8b6093ce6bae154246e57 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2542866Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
parent 565f1b16
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
// Version number for shader translation API. // Version number for shader translation API.
// It is incremented every time the API changes. // It is incremented every time the API changes.
#define ANGLE_SH_VERSION 244 #define ANGLE_SH_VERSION 245
enum ShShaderSpec enum ShShaderSpec
{ {
...@@ -720,6 +720,9 @@ int GetVertexShaderNumViews(const ShHandle handle); ...@@ -720,6 +720,9 @@ int GetVertexShaderNumViews(const ShHandle handle);
// Returns true if compiler has injected instructions for early fragment tests as an optimization // Returns true if compiler has injected instructions for early fragment tests as an optimization
bool HasEarlyFragmentTestsOptimization(const ShHandle handle); bool HasEarlyFragmentTestsOptimization(const ShHandle handle);
// Returns specialization constant usage bits
uint32_t GetShaderSpecConstUsageBits(const ShHandle handle);
// Returns true if the passed in variables pack in maxVectors followingthe packing rules from the // Returns true if the passed in variables pack in maxVectors followingthe packing rules from the
// GLSL 1.017 spec, Appendix A, section 7. // GLSL 1.017 spec, Appendix A, section 7.
// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS // Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
...@@ -830,6 +833,16 @@ enum class SurfaceRotation : uint32_t ...@@ -830,6 +833,16 @@ enum class SurfaceRotation : uint32_t
EnumCount = InvalidEnum, EnumCount = InvalidEnum,
}; };
enum class SpecConstUsage : uint32_t
{
LineRasterEmulation = 0,
YFlip = 1,
Rotation = 2,
InvalidEnum = 3,
EnumCount = InvalidEnum,
};
// Interface block name containing the aggregate default uniforms // Interface block name containing the aggregate default uniforms
extern const char kDefaultUniformsNameVS[]; extern const char kDefaultUniformsNameVS[];
extern const char kDefaultUniformsNameTCS[]; extern const char kDefaultUniformsNameTCS[];
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <GLSLANG/ShaderVars.h> #include <GLSLANG/ShaderVars.h>
#include "common/PackedEnums.h"
#include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/CallDAG.h" #include "compiler/translator/CallDAG.h"
#include "compiler/translator/Diagnostics.h" #include "compiler/translator/Diagnostics.h"
...@@ -36,6 +37,8 @@ class TParseContext; ...@@ -36,6 +37,8 @@ class TParseContext;
class TranslatorHLSL; class TranslatorHLSL;
#endif // ANGLE_ENABLE_HLSL #endif // ANGLE_ENABLE_HLSL
using SpecConstUsageBits = angle::PackedEnumBitSet<vk::SpecConstUsage, uint32_t>;
// //
// Helper function to check if the shader type is GLSL. // Helper function to check if the shader type is GLSL.
// //
...@@ -100,6 +103,7 @@ class TCompiler : public TShHandleBase ...@@ -100,6 +103,7 @@ class TCompiler : public TShHandleBase
bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; } bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
bool isEarlyFragmentTestsOptimized() const { return mEarlyFragmentTestsOptimized; } bool isEarlyFragmentTestsOptimized() const { return mEarlyFragmentTestsOptimized; }
SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
...@@ -193,6 +197,9 @@ class TCompiler : public TShHandleBase ...@@ -193,6 +197,9 @@ class TCompiler : public TShHandleBase
std::vector<sh::InterfaceBlock> mShaderStorageBlocks; std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
std::vector<sh::InterfaceBlock> mInBlocks; std::vector<sh::InterfaceBlock> mInBlocks;
// Specialization constant usage bits
SpecConstUsageBits mSpecConstUsageBits;
private: private:
// Initialize symbol-table with built-in symbols. // Initialize symbol-table with built-in symbols.
bool initBuiltInSymbolTable(const ShBuiltInResources &resources); bool initBuiltInSymbolTable(const ShBuiltInResources &resources);
......
...@@ -543,6 +543,16 @@ bool HasEarlyFragmentTestsOptimization(const ShHandle handle) ...@@ -543,6 +543,16 @@ bool HasEarlyFragmentTestsOptimization(const ShHandle handle)
return compiler->isEarlyFragmentTestsOptimized(); return compiler->isEarlyFragmentTestsOptimized();
} }
uint32_t GetShaderSpecConstUsageBits(const ShHandle handle)
{
TCompiler *compiler = GetCompilerFromHandle(handle);
if (compiler == nullptr)
{
return 0;
}
return compiler->getSpecConstUsageBits().bits();
}
bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables) bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables)
{ {
return CheckVariablesInPackingLimits(maxVectors, variables); return CheckVariablesInPackingLimits(maxVectors, variables);
......
...@@ -850,6 +850,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root, ...@@ -850,6 +850,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
{ {
return false; return false;
} }
mSpecConstUsageBits.set(vk::SpecConstUsage::LineRasterEmulation);
} }
bool hasGLFragColor = false; bool hasGLFragColor = false;
...@@ -970,6 +971,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root, ...@@ -970,6 +971,7 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
{ {
return false; return false;
} }
mSpecConstUsageBits.set(vk::SpecConstUsage::LineRasterEmulation);
} }
// Add a macro to declare transform feedback buffers. // Add a macro to declare transform feedback buffers.
...@@ -1028,6 +1030,9 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root, ...@@ -1028,6 +1030,9 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
surfaceRotationSpecConst.outputLayoutString(sink); surfaceRotationSpecConst.outputLayoutString(sink);
// Gather specialization constant usage bits so that we can feedback to context.
mSpecConstUsageBits |= surfaceRotationSpecConst.getSpecConstUsageBits();
if (!validateAST(root)) if (!validateAST(root))
{ {
return false; return false;
......
...@@ -220,7 +220,7 @@ TIntermTyped *CreateFloatArrayWithRotationIndex(const Vec2EnumMap &valuesEnumMap ...@@ -220,7 +220,7 @@ TIntermTyped *CreateFloatArrayWithRotationIndex(const Vec2EnumMap &valuesEnumMap
} }
} // anonymous namespace } // anonymous namespace
FlipRotateSpecConst::FlipRotateSpecConst() : mSpecConstSymbol(nullptr), mReferenced(false) {} FlipRotateSpecConst::FlipRotateSpecConst() : mSpecConstSymbol(nullptr) {}
FlipRotateSpecConst::~FlipRotateSpecConst() FlipRotateSpecConst::~FlipRotateSpecConst()
{ {
...@@ -241,7 +241,7 @@ void FlipRotateSpecConst::generateSymbol(TSymbolTable *symbolTable) ...@@ -241,7 +241,7 @@ void FlipRotateSpecConst::generateSymbol(TSymbolTable *symbolTable)
void FlipRotateSpecConst::outputLayoutString(TInfoSinkBase &sink) const void FlipRotateSpecConst::outputLayoutString(TInfoSinkBase &sink) const
{ {
// Only emit specialized const layout string if it has been referenced. // Only emit specialized const layout string if it has been referenced.
if (mReferenced) if (mUsageBits.any())
{ {
sink << "layout(constant_id=" sink << "layout(constant_id="
<< static_cast<uint32_t>(vk::SpecializationConstantId::SurfaceRotation) << static_cast<uint32_t>(vk::SpecializationConstantId::SurfaceRotation)
...@@ -255,7 +255,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdx() ...@@ -255,7 +255,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdx()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 0, 1, mSpecConstSymbol); return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 0, 1, mSpecConstSymbol);
} }
...@@ -265,7 +266,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdx() ...@@ -265,7 +266,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdx()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 1, 1, mSpecConstSymbol); return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdx, 1, 1, mSpecConstSymbol);
} }
...@@ -275,7 +277,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdy() ...@@ -275,7 +277,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierXForDFdy()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 0, 1, mSpecConstSymbol); return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 0, 1, mSpecConstSymbol);
} }
...@@ -285,7 +288,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdy() ...@@ -285,7 +288,8 @@ TIntermTyped *FlipRotateSpecConst::getMultiplierYForDFdy()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 1, 1, mSpecConstSymbol); return CreateFloatArrayWithRotationIndex(kRotatedFlipXYForDFdy, 1, 1, mSpecConstSymbol);
} }
...@@ -295,7 +299,7 @@ TIntermTyped *FlipRotateSpecConst::getPreRotationMatrix() ...@@ -295,7 +299,7 @@ TIntermTyped *FlipRotateSpecConst::getPreRotationMatrix()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::Rotation);
return GenerateMat2x2ArrayWithIndex(kPreRotationMatrices, mSpecConstSymbol); return GenerateMat2x2ArrayWithIndex(kPreRotationMatrices, mSpecConstSymbol);
} }
...@@ -305,7 +309,7 @@ TIntermTyped *FlipRotateSpecConst::getFragRotationMatrix() ...@@ -305,7 +309,7 @@ TIntermTyped *FlipRotateSpecConst::getFragRotationMatrix()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::Rotation);
return GenerateMat2x2ArrayWithIndex(kFragRotationMatrices, mSpecConstSymbol); return GenerateMat2x2ArrayWithIndex(kFragRotationMatrices, mSpecConstSymbol);
} }
...@@ -315,7 +319,7 @@ TIntermTyped *FlipRotateSpecConst::getFlipXY() ...@@ -315,7 +319,7 @@ TIntermTyped *FlipRotateSpecConst::getFlipXY()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateVec2ArrayWithIndex(kFlipXYValue, 1.0, mSpecConstSymbol); return CreateVec2ArrayWithIndex(kFlipXYValue, 1.0, mSpecConstSymbol);
} }
...@@ -325,7 +329,7 @@ TIntermTyped *FlipRotateSpecConst::getNegFlipXY() ...@@ -325,7 +329,7 @@ TIntermTyped *FlipRotateSpecConst::getNegFlipXY()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateVec2ArrayWithIndex(kFlipXYValue, -1.0, mSpecConstSymbol); return CreateVec2ArrayWithIndex(kFlipXYValue, -1.0, mSpecConstSymbol);
} }
...@@ -335,7 +339,7 @@ TIntermTyped *FlipRotateSpecConst::getFlipY() ...@@ -335,7 +339,7 @@ TIntermTyped *FlipRotateSpecConst::getFlipY()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, 1, mSpecConstSymbol); return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, 1, mSpecConstSymbol);
} }
...@@ -345,7 +349,7 @@ TIntermTyped *FlipRotateSpecConst::getNegFlipY() ...@@ -345,7 +349,7 @@ TIntermTyped *FlipRotateSpecConst::getNegFlipY()
{ {
return nullptr; return nullptr;
} }
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, -1, mSpecConstSymbol); return CreateFloatArrayWithRotationIndex(kFlipXYValue, 1, -1, mSpecConstSymbol);
} }
...@@ -374,7 +378,8 @@ TIntermTyped *FlipRotateSpecConst::getFragRotationMultiplyFlipXY() ...@@ -374,7 +378,8 @@ TIntermTyped *FlipRotateSpecConst::getFragRotationMultiplyFlipXY()
{vk::SurfaceRotation::FlippedRotated270Degrees, {vk::SurfaceRotation::FlippedRotated270Degrees,
CalcFragRotationMultiplyFlipXY(vk::SurfaceRotation::FlippedRotated270Degrees)}}}; CalcFragRotationMultiplyFlipXY(vk::SurfaceRotation::FlippedRotated270Degrees)}}};
mReferenced = true; mUsageBits.set(vk::SpecConstUsage::YFlip);
mUsageBits.set(vk::SpecConstUsage::Rotation);
return CreateVec2ArrayWithIndex(kFragRotationMultiplyFlipXY, 1.0, mSpecConstSymbol); return CreateVec2ArrayWithIndex(kFragRotationMultiplyFlipXY, 1.0, mSpecConstSymbol);
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_ #define COMPILER_TRANSLATOR_TREEUTIL_FLIPROTATESPECCONST_H_
#include "common/angleutils.h" #include "common/angleutils.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/SymbolTable.h" #include "compiler/translator/SymbolTable.h"
class TIntermTyped; class TIntermTyped;
...@@ -40,11 +41,12 @@ class FlipRotateSpecConst ...@@ -40,11 +41,12 @@ class FlipRotateSpecConst
void generateSymbol(TSymbolTable *symbolTable); void generateSymbol(TSymbolTable *symbolTable);
void outputLayoutString(TInfoSinkBase &sink) const; void outputLayoutString(TInfoSinkBase &sink) const;
SpecConstUsageBits getSpecConstUsageBits() const { return mUsageBits; }
private: private:
TIntermSymbol *mSpecConstSymbol; TIntermSymbol *mSpecConstSymbol;
// True if mSpecConstSymbol has been used // Bit is set if YFlip or Rotation has been used
bool mReferenced; SpecConstUsageBits mUsageBits;
}; };
} // namespace sh } // namespace sh
......
...@@ -1577,6 +1577,7 @@ angle::Result Program::linkImpl(const Context *context) ...@@ -1577,6 +1577,7 @@ angle::Result Program::linkImpl(const Context *context)
if (vertexShader) if (vertexShader)
{ {
mState.mNumViews = vertexShader->getNumViews(); mState.mNumViews = vertexShader->getNumViews();
mState.mSpecConstUsageBits |= vertexShader->getSpecConstUsageBits();
} }
gl::Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment]; gl::Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
...@@ -1584,6 +1585,7 @@ angle::Result Program::linkImpl(const Context *context) ...@@ -1584,6 +1585,7 @@ angle::Result Program::linkImpl(const Context *context)
{ {
mState.mEarlyFramentTestsOptimization = mState.mEarlyFramentTestsOptimization =
fragmentShader->hasEarlyFragmentTestsOptimization(); fragmentShader->hasEarlyFragmentTestsOptimization();
mState.mSpecConstUsageBits |= fragmentShader->getSpecConstUsageBits();
} }
InitUniformBlockLinker(mState, &mState.mExecutable->getResources().uniformBlockLinker); InitUniformBlockLinker(mState, &mState.mExecutable->getResources().uniformBlockLinker);
...@@ -1855,6 +1857,7 @@ void Program::unlink() ...@@ -1855,6 +1857,7 @@ void Program::unlink()
mState.mCachedBaseVertex = 0; mState.mCachedBaseVertex = 0;
mState.mCachedBaseInstance = 0; mState.mCachedBaseInstance = 0;
mState.mEarlyFramentTestsOptimization = false; mState.mEarlyFramentTestsOptimization = false;
mState.mSpecConstUsageBits.reset();
mValidated = false; mValidated = false;
...@@ -5174,6 +5177,7 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi ...@@ -5174,6 +5177,7 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi
stream.writeInt(mState.mNumViews); stream.writeInt(mState.mNumViews);
stream.writeBool(mState.mEarlyFramentTestsOptimization); stream.writeBool(mState.mEarlyFramentTestsOptimization);
stream.writeInt(mState.mSpecConstUsageBits.bits());
stream.writeInt(mState.getProgramInputs().size()); stream.writeInt(mState.getProgramInputs().size());
for (const sh::ShaderVariable &attrib : mState.getProgramInputs()) for (const sh::ShaderVariable &attrib : mState.getProgramInputs())
...@@ -5372,6 +5376,7 @@ angle::Result Program::deserialize(const Context *context, ...@@ -5372,6 +5376,7 @@ angle::Result Program::deserialize(const Context *context,
mState.mNumViews = stream.readInt<int>(); mState.mNumViews = stream.readInt<int>();
mState.mEarlyFramentTestsOptimization = stream.readBool(); mState.mEarlyFramentTestsOptimization = stream.readBool();
mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt<uint32_t>());
size_t attribCount = stream.readInt<size_t>(); size_t attribCount = stream.readInt<size_t>();
ASSERT(mState.mExecutable->getProgramInputs().empty()); ASSERT(mState.mExecutable->getProgramInputs().empty());
......
...@@ -323,6 +323,7 @@ class ProgramState final : angle::NonCopyable ...@@ -323,6 +323,7 @@ class ProgramState final : angle::NonCopyable
bool hasImages() const { return !getImageBindings().empty(); } bool hasImages() const { return !getImageBindings().empty(); }
bool hasEarlyFragmentTestsOptimization() const { return mEarlyFramentTestsOptimization; } bool hasEarlyFragmentTestsOptimization() const { return mEarlyFramentTestsOptimization; }
rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
bool isShaderMarkedForDetach(gl::ShaderType shaderType) const bool isShaderMarkedForDetach(gl::ShaderType shaderType) const
{ {
...@@ -416,6 +417,7 @@ class ProgramState final : angle::NonCopyable ...@@ -416,6 +417,7 @@ class ProgramState final : angle::NonCopyable
bool mBinaryRetrieveableHint; bool mBinaryRetrieveableHint;
bool mSeparable; bool mSeparable;
bool mEarlyFramentTestsOptimization; bool mEarlyFramentTestsOptimization;
rx::SpecConstUsageBits mSpecConstUsageBits;
// ANGLE_multiview. // ANGLE_multiview.
int mNumViews; int mNumViews;
......
...@@ -538,5 +538,4 @@ bool ProgramExecutable::isYUVOutput() const ...@@ -538,5 +538,4 @@ bool ProgramExecutable::isYUVOutput() const
{ {
return !isCompute() && mYUVOutput; return !isCompute() && mYUVOutput;
} }
} // namespace gl } // namespace gl
...@@ -156,6 +156,18 @@ void ProgramPipelineState::updateExecutableTextures() ...@@ -156,6 +156,18 @@ void ProgramPipelineState::updateExecutableTextures()
} }
} }
rx::SpecConstUsageBits ProgramPipelineState::getSpecConstUsageBits() const
{
rx::SpecConstUsageBits specConstUsageBits;
for (const ShaderType shaderType : mExecutable->getLinkedShaderStages())
{
const Program *program = getShaderProgram(shaderType);
ASSERT(program);
specConstUsageBits |= program->getState().getSpecConstUsageBits();
}
return specConstUsageBits;
}
ProgramPipeline::ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle) ProgramPipeline::ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle)
: RefCountObject(factory->generateSerial(), handle), : RefCountObject(factory->generateSerial(), handle),
mProgramPipelineImpl(factory->createProgramPipeline(mState)), mProgramPipelineImpl(factory->createProgramPipeline(mState)),
......
...@@ -65,6 +65,8 @@ class ProgramPipelineState final : angle::NonCopyable ...@@ -65,6 +65,8 @@ class ProgramPipelineState final : angle::NonCopyable
void updateExecutableTextures(); void updateExecutableTextures();
rx::SpecConstUsageBits getSpecConstUsageBits() const;
private: private:
void useProgramStage(const Context *context, void useProgramStage(const Context *context,
ShaderType shaderType, ShaderType shaderType,
......
...@@ -319,6 +319,7 @@ void Shader::compile(const Context *context) ...@@ -319,6 +319,7 @@ void Shader::compile(const Context *context)
mState.mGeometryShaderMaxVertices.reset(); mState.mGeometryShaderMaxVertices.reset();
mState.mGeometryShaderInvocations = 1; mState.mGeometryShaderInvocations = 1;
mState.mEarlyFragmentTestsOptimization = false; mState.mEarlyFragmentTestsOptimization = false;
mState.mSpecConstUsageBits.reset();
mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED; mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
mBoundCompiler.set(context, context->getCompiler()); mBoundCompiler.set(context, context->getCompiler());
...@@ -432,6 +433,8 @@ void Shader::resolveCompile() ...@@ -432,6 +433,8 @@ void Shader::resolveCompile()
mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle)); mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle));
mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle)); mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle)); mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
mState.mSpecConstUsageBits =
rx::SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle));
switch (mState.mShaderType) switch (mState.mShaderType)
{ {
......
...@@ -90,6 +90,7 @@ class ShaderState final : angle::NonCopyable ...@@ -90,6 +90,7 @@ class ShaderState final : angle::NonCopyable
const sh::WorkGroupSize &getLocalSize() const { return mLocalSize; } const sh::WorkGroupSize &getLocalSize() const { return mLocalSize; }
bool getEarlyFragmentTestsOptimization() const { return mEarlyFragmentTestsOptimization; } bool getEarlyFragmentTestsOptimization() const { return mEarlyFragmentTestsOptimization; }
rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
int getNumViews() const { return mNumViews; } int getNumViews() const { return mNumViews; }
...@@ -131,6 +132,7 @@ class ShaderState final : angle::NonCopyable ...@@ -131,6 +132,7 @@ class ShaderState final : angle::NonCopyable
std::vector<sh::ShaderVariable> mActiveOutputVariables; std::vector<sh::ShaderVariable> mActiveOutputVariables;
bool mEarlyFragmentTestsOptimization; bool mEarlyFragmentTestsOptimization;
rx::SpecConstUsageBits mSpecConstUsageBits;
// ANGLE_multiview. // ANGLE_multiview.
int mNumViews; int mNumViews;
...@@ -190,6 +192,7 @@ class Shader final : angle::NonCopyable, public LabeledObject ...@@ -190,6 +192,7 @@ class Shader final : angle::NonCopyable, public LabeledObject
{ {
return mState.mEarlyFragmentTestsOptimization; return mState.mEarlyFragmentTestsOptimization;
} }
rx::SpecConstUsageBits getSpecConstUsageBits() const { return mState.mSpecConstUsageBits; }
int getShaderVersion(); int getShaderVersion();
......
...@@ -646,6 +646,7 @@ void SerializeShaderState(gl::BinaryOutputStream *bos, const gl::ShaderState &sh ...@@ -646,6 +646,7 @@ void SerializeShaderState(gl::BinaryOutputStream *bos, const gl::ShaderState &sh
SerializeShaderVariablesVector(bos, shaderState.getActiveOutputVariables()); SerializeShaderVariablesVector(bos, shaderState.getActiveOutputVariables());
bos->writeBool(shaderState.getEarlyFragmentTestsOptimization()); bos->writeBool(shaderState.getEarlyFragmentTestsOptimization());
bos->writeInt(shaderState.getNumViews()); bos->writeInt(shaderState.getNumViews());
bos->writeInt(shaderState.getSpecConstUsageBits().bits());
if (shaderState.getGeometryShaderInputPrimitiveType().valid()) if (shaderState.getGeometryShaderInputPrimitiveType().valid())
{ {
bos->writeEnum(shaderState.getGeometryShaderInputPrimitiveType().value()); bos->writeEnum(shaderState.getGeometryShaderInputPrimitiveType().value());
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <limits> #include <limits>
#include <map> #include <map>
#include "GLSLANG/ShaderLang.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
...@@ -60,6 +61,8 @@ enum class SurfaceRotation ...@@ -60,6 +61,8 @@ enum class SurfaceRotation
EnumCount = InvalidEnum, EnumCount = InvalidEnum,
}; };
using SpecConstUsageBits = angle::PackedEnumBitSet<sh::vk::SpecConstUsage, uint32_t>;
void RotateRectangle(const SurfaceRotation rotation, void RotateRectangle(const SurfaceRotation rotation,
const bool flipY, const bool flipY,
const int framebufferWidth, const int framebufferWidth,
......
...@@ -288,6 +288,20 @@ ProgramVk *ProgramExecutableVk::getShaderProgram(const gl::State &glState, ...@@ -288,6 +288,20 @@ ProgramVk *ProgramExecutableVk::getShaderProgram(const gl::State &glState,
return nullptr; return nullptr;
} }
SpecConstUsageBits ProgramExecutableVk::getSpecConstUsageBits() const
{
if (mProgram)
{
return mProgram->getState().getSpecConstUsageBits();
}
else if (mProgramPipeline)
{
return mProgramPipeline->getState().getSpecConstUsageBits();
}
return SpecConstUsageBits();
}
// TODO: http://anglebug.com/3570: Move/Copy all of the necessary information into // TODO: http://anglebug.com/3570: Move/Copy all of the necessary information into
// the ProgramExecutable, so this function can be removed. // the ProgramExecutable, so this function can be removed.
void ProgramExecutableVk::fillProgramStateMap( void ProgramExecutableVk::fillProgramStateMap(
......
...@@ -181,6 +181,8 @@ class ProgramExecutableVk ...@@ -181,6 +181,8 @@ class ProgramExecutableVk
const PerfCounters getObjectPerfCounters() const { return mObjectPerfCounters; } const PerfCounters getObjectPerfCounters() const { return mObjectPerfCounters; }
SpecConstUsageBits getSpecConstUsageBits() const;
private: private:
friend class ProgramVk; friend class ProgramVk;
friend class ProgramPipelineVk; friend class ProgramPipelineVk;
......
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