Commit 64508f44 by Charlie Lao Committed by Commit Bot

Vulkan: Reduce driver uniform data to minimum if specConst is used

If specialization constant is used, driver uniform data structure should be reduced to minimum to increase cache locality. Bug: b/175479076 Change-Id: I1fc50666542c6763c60bfe011cde5bc77ccc08e1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2588549Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Commit-Queue: Charlie Lao <cclao@google.com>
parent 8f9e17d5
...@@ -42,7 +42,10 @@ const char kRasterizerDiscardEnabledConstName[] = "ANGLERasterizerDisabled"; ...@@ -42,7 +42,10 @@ const char kRasterizerDiscardEnabledConstName[] = "ANGLERasterizerDisabled";
namespace namespace
{ {
// Metal specific driver uniforms // Metal specific driver uniforms
constexpr const char kCoverageMask[] = "coverageMask"; constexpr const char kHalfRenderArea[] = "halfRenderArea";
constexpr const char kFlipXY[] = "flipXY";
constexpr const char kNegFlipXY[] = "negFlipXY";
constexpr const char kCoverageMask[] = "coverageMask";
constexpr ImmutableString kSampleMaskWriteFuncName = ImmutableString("ANGLEWriteSampleMask"); constexpr ImmutableString kSampleMaskWriteFuncName = ImmutableString("ANGLEWriteSampleMask");
...@@ -111,20 +114,58 @@ ANGLE_NO_DISCARD bool InitializeUnusedOutputs(TIntermBlock *root, ...@@ -111,20 +114,58 @@ ANGLE_NO_DISCARD bool InitializeUnusedOutputs(TIntermBlock *root,
} }
} // anonymous namespace } // anonymous namespace
// class DriverUniformMetal
TFieldList *DriverUniformMetal::createUniformFields(TSymbolTable *symbolTable) const TFieldList *DriverUniformMetal::createUniformFields(TSymbolTable *symbolTable) const
{ {
TFieldList *driverFieldList = DriverUniform::createUniformFields(symbolTable); TFieldList *driverFieldList = DriverUniform::createUniformFields(symbolTable);
// Add coverage mask to driver uniform. Metal doesn't have built-in GL_SAMPLE_COVERAGE_VALUE constexpr size_t kNumGraphicsDriverUniformsMetal = 4;
// equivalent functionality, needs to emulate it using fragment shader's [[sample_mask]] output constexpr std::array<const char *, kNumGraphicsDriverUniformsMetal>
// value. kGraphicsDriverUniformNamesMetal = {{kHalfRenderArea, kFlipXY, kNegFlipXY, kCoverageMask}};
TField *coverageMaskField = new TField(new TType(EbtUInt), ImmutableString(kCoverageMask),
TSourceLoc(), SymbolType::AngleInternal); const std::array<TType *, kNumGraphicsDriverUniformsMetal> kDriverUniformTypesMetal = {{
driverFieldList->push_back(coverageMaskField); new TType(EbtFloat, 2), // halfRenderArea
new TType(EbtFloat, 2), // flipXY
new TType(EbtFloat, 2), // negFlipXY
new TType(EbtUInt), // kCoverageMask
}};
for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniformsMetal; ++uniformIndex)
{
TField *driverUniformField =
new TField(kDriverUniformTypesMetal[uniformIndex],
ImmutableString(kGraphicsDriverUniformNamesMetal[uniformIndex]),
TSourceLoc(), SymbolType::AngleInternal);
driverFieldList->push_back(driverUniformField);
}
return driverFieldList; return driverFieldList;
} }
TIntermBinary *DriverUniformMetal::getHalfRenderAreaRef() const
{
return createDriverUniformRef(kHalfRenderArea);
}
TIntermBinary *DriverUniformMetal::getFlipXYRef() const
{
return createDriverUniformRef(kFlipXY);
}
TIntermBinary *DriverUniformMetal::getNegFlipXYRef() const
{
return createDriverUniformRef(kNegFlipXY);
}
TIntermSwizzle *DriverUniformMetal::getNegFlipYRef() const
{
// Create a swizzle to "negFlipXY.y"
TIntermBinary *negFlipXY = createDriverUniformRef(kNegFlipXY);
TVector<int> swizzleOffsetY = {1};
TIntermSwizzle *negFlipY = new TIntermSwizzle(negFlipXY, swizzleOffsetY);
return negFlipY;
}
TIntermBinary *DriverUniformMetal::getCoverageMaskFieldRef() const TIntermBinary *DriverUniformMetal::getCoverageMaskFieldRef() const
{ {
return createDriverUniformRef(kCoverageMask); return createDriverUniformRef(kCoverageMask);
......
...@@ -41,6 +41,10 @@ class DriverUniformMetal : public DriverUniform ...@@ -41,6 +41,10 @@ class DriverUniformMetal : public DriverUniform
DriverUniformMetal() : DriverUniform() {} DriverUniformMetal() : DriverUniform() {}
~DriverUniformMetal() override {} ~DriverUniformMetal() override {}
TIntermBinary *getHalfRenderAreaRef() const override;
TIntermBinary *getFlipXYRef() const override;
TIntermBinary *getNegFlipXYRef() const override;
TIntermSwizzle *getNegFlipYRef() const override;
TIntermBinary *getCoverageMaskFieldRef() const; TIntermBinary *getCoverageMaskFieldRef() const;
protected: protected:
......
...@@ -1061,11 +1061,24 @@ bool TranslatorVulkan::translate(TIntermBlock *root, ...@@ -1061,11 +1061,24 @@ bool TranslatorVulkan::translate(TIntermBlock *root,
enablePrecision, compileOptions); enablePrecision, compileOptions);
SpecConst specConst(&getSymbolTable(), compileOptions); SpecConst specConst(&getSymbolTable(), compileOptions);
DriverUniform driverUniforms;
if (!translateImpl(root, compileOptions, perfDiagnostics, &specConst, &driverUniforms, if (compileOptions & SH_USE_SPECIALIZATION_CONSTANT)
&outputGLSL))
{ {
return false; DriverUniform driverUniforms;
if (!translateImpl(root, compileOptions, perfDiagnostics, &specConst, &driverUniforms,
&outputGLSL))
{
return false;
}
}
else
{
DriverUniformExtended driverUniformsExt;
if (!translateImpl(root, compileOptions, perfDiagnostics, &specConst, &driverUniformsExt,
&outputGLSL))
{
return false;
}
} }
// Write translated shader. // Write translated shader.
......
...@@ -25,33 +25,28 @@ namespace ...@@ -25,33 +25,28 @@ namespace
constexpr ImmutableString kEmulatedDepthRangeParams = ImmutableString("ANGLEDepthRangeParams"); constexpr ImmutableString kEmulatedDepthRangeParams = ImmutableString("ANGLEDepthRangeParams");
constexpr const char kViewport[] = "viewport"; constexpr const char kViewport[] = "viewport";
constexpr const char kHalfRenderArea[] = "halfRenderArea";
constexpr const char kFlipXY[] = "flipXY";
constexpr const char kNegFlipXY[] = "negFlipXY";
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";
constexpr const char kXfbBufferOffsets[] = "xfbBufferOffsets"; constexpr const char kXfbBufferOffsets[] = "xfbBufferOffsets";
constexpr const char kAcbBufferOffsets[] = "acbBufferOffsets"; constexpr const char kAcbBufferOffsets[] = "acbBufferOffsets";
constexpr const char kDepthRange[] = "depthRange"; constexpr const char kDepthRange[] = "depthRange";
constexpr const char kPreRotation[] = "preRotation";
constexpr const char kFragRotation[] = "fragRotation";
constexpr const char kNumSamples[] = "numSamples"; constexpr const char kNumSamples[] = "numSamples";
constexpr size_t kNumGraphicsDriverUniforms = 13; constexpr const char kHalfRenderArea[] = "halfRenderArea";
constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = { constexpr const char kFlipXY[] = "flipXY";
{kViewport, kHalfRenderArea, kFlipXY, kNegFlipXY, kClipDistancesEnabled, kXfbActiveUnpaused, constexpr const char kNegFlipXY[] = "negFlipXY";
kXfbVerticesPerDraw, kNumSamples, kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange, constexpr const char kPreRotation[] = "preRotation";
kPreRotation, kFragRotation}}; constexpr const char kFragRotation[] = "fragRotation";
constexpr size_t kNumComputeDriverUniforms = 1;
constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = {
{kAcbBufferOffsets}};
} // anonymous namespace } // anonymous namespace
// Class DriverUniform
bool DriverUniform::addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable) bool DriverUniform::addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable)
{ {
constexpr size_t kNumComputeDriverUniforms = 1;
constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = {
{kAcbBufferOffsets}};
ASSERT(!mDriverUniforms); ASSERT(!mDriverUniforms);
// This field list mirrors the structure of ComputeDriverUniforms in ContextVk.cpp. // This field list mirrors the structure of ComputeDriverUniforms in ContextVk.cpp.
TFieldList *driverFieldList = new TFieldList; TFieldList *driverFieldList = new TFieldList;
...@@ -78,24 +73,23 @@ bool DriverUniform::addComputeDriverUniformsToShader(TIntermBlock *root, TSymbol ...@@ -78,24 +73,23 @@ bool DriverUniform::addComputeDriverUniformsToShader(TIntermBlock *root, TSymbol
TFieldList *DriverUniform::createUniformFields(TSymbolTable *symbolTable) const TFieldList *DriverUniform::createUniformFields(TSymbolTable *symbolTable) const
{ {
constexpr size_t kNumGraphicsDriverUniforms = 8;
constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = {
{kViewport, kClipDistancesEnabled, kXfbActiveUnpaused, kXfbVerticesPerDraw, kNumSamples,
kXfbBufferOffsets, kAcbBufferOffsets, kDepthRange}};
// This field list mirrors the structure of GraphicsDriverUniforms in ContextVk.cpp. // This field list mirrors the structure of GraphicsDriverUniforms in ContextVk.cpp.
TFieldList *driverFieldList = new TFieldList; TFieldList *driverFieldList = new TFieldList;
const std::array<TType *, kNumGraphicsDriverUniforms> kDriverUniformTypes = {{ const std::array<TType *, kNumGraphicsDriverUniforms> kDriverUniformTypes = {{
new TType(EbtFloat, 4), new TType(EbtFloat, 4),
new TType(EbtFloat, 2),
new TType(EbtFloat, 2),
new TType(EbtFloat, 2),
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),
new TType(EbtInt), new TType(EbtInt),
// NOTE: There's a vec2 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),
createEmulatedDepthRangeType(symbolTable), createEmulatedDepthRangeType(symbolTable),
new TType(EbtFloat, 2, 2),
new TType(EbtFloat, 2, 2),
}}; }};
for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniforms; ++uniformIndex) for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniforms; ++uniformIndex)
...@@ -175,52 +169,82 @@ TIntermBinary *DriverUniform::createDriverUniformRef(const char *fieldName) cons ...@@ -175,52 +169,82 @@ TIntermBinary *DriverUniform::createDriverUniformRef(const char *fieldName) cons
return new TIntermBinary(EOpIndexDirectInterfaceBlock, angleUniformsRef, indexRef); return new TIntermBinary(EOpIndexDirectInterfaceBlock, angleUniformsRef, indexRef);
} }
TIntermBinary *DriverUniform::getFlipXYRef() const TIntermBinary *DriverUniform::getViewportRef() const
{ {
return createDriverUniformRef(kFlipXY); return createDriverUniformRef(kViewport);
} }
TIntermBinary *DriverUniform::getNegFlipXYRef() const TIntermBinary *DriverUniform::getAbcBufferOffsets() const
{ {
return createDriverUniformRef(kNegFlipXY); return createDriverUniformRef(kAcbBufferOffsets);
} }
TIntermBinary *DriverUniform::getFragRotationMatrixRef() const TIntermBinary *DriverUniform::getClipDistancesEnabled() const
{ {
return createDriverUniformRef(kFragRotation); return createDriverUniformRef(kClipDistancesEnabled);
} }
TIntermBinary *DriverUniform::getPreRotationMatrixRef() const TIntermBinary *DriverUniform::getDepthRangeRef() const
{ {
return createDriverUniformRef(kPreRotation); return createDriverUniformRef(kDepthRange);
} }
TIntermBinary *DriverUniform::getViewportRef() const TIntermBinary *DriverUniform::getDepthRangeReservedFieldRef() const
{ {
return createDriverUniformRef(kViewport); TIntermBinary *depthRange = createDriverUniformRef(kDepthRange);
return new TIntermBinary(EOpIndexDirectStruct, depthRange, CreateIndexNode(3));
} }
TIntermBinary *DriverUniform::getHalfRenderAreaRef() const TIntermBinary *DriverUniform::getNumSamplesRef() const
{ {
return createDriverUniformRef(kHalfRenderArea); return createDriverUniformRef(kNumSamples);
} }
TIntermBinary *DriverUniform::getAbcBufferOffsets() const //
// Class DriverUniformExtended
//
TFieldList *DriverUniformExtended::createUniformFields(TSymbolTable *symbolTable) const
{ {
return createDriverUniformRef(kAcbBufferOffsets); TFieldList *driverFieldList = DriverUniform::createUniformFields(symbolTable);
constexpr size_t kNumGraphicsDriverUniformsExt = 5;
constexpr std::array<const char *, kNumGraphicsDriverUniformsExt>
kGraphicsDriverUniformNamesExt = {
{kHalfRenderArea, kFlipXY, kNegFlipXY, kPreRotation, kFragRotation}};
const std::array<TType *, kNumGraphicsDriverUniformsExt> kDriverUniformTypesExt = {{
new TType(EbtFloat, 2),
new TType(EbtFloat, 2),
new TType(EbtFloat, 2),
// NOTE: There's a vec2 gap here that can be used in the future
new TType(EbtFloat, 2, 2),
new TType(EbtFloat, 2, 2),
}};
for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniformsExt; ++uniformIndex)
{
TField *driverUniformField =
new TField(kDriverUniformTypesExt[uniformIndex],
ImmutableString(kGraphicsDriverUniformNamesExt[uniformIndex]), TSourceLoc(),
SymbolType::AngleInternal);
driverFieldList->push_back(driverUniformField);
}
return driverFieldList;
} }
TIntermBinary *DriverUniform::getClipDistancesEnabled() const TIntermBinary *DriverUniformExtended::getFlipXYRef() const
{ {
return createDriverUniformRef(kClipDistancesEnabled); return createDriverUniformRef(kFlipXY);
} }
TIntermBinary *DriverUniform::getDepthRangeRef() const TIntermBinary *DriverUniformExtended::getNegFlipXYRef() const
{ {
return createDriverUniformRef(kDepthRange); return createDriverUniformRef(kNegFlipXY);
} }
TIntermSwizzle *DriverUniform::getNegFlipYRef() const TIntermSwizzle *DriverUniformExtended::getNegFlipYRef() const
{ {
// Create a swizzle to "negFlipXY.y" // Create a swizzle to "negFlipXY.y"
TIntermBinary *negFlipXY = createDriverUniformRef(kNegFlipXY); TIntermBinary *negFlipXY = createDriverUniformRef(kNegFlipXY);
...@@ -229,16 +253,19 @@ TIntermSwizzle *DriverUniform::getNegFlipYRef() const ...@@ -229,16 +253,19 @@ TIntermSwizzle *DriverUniform::getNegFlipYRef() const
return negFlipY; return negFlipY;
} }
TIntermBinary *DriverUniform::getDepthRangeReservedFieldRef() const TIntermBinary *DriverUniformExtended::getFragRotationMatrixRef() const
{ {
TIntermBinary *depthRange = createDriverUniformRef(kDepthRange); return createDriverUniformRef(kFragRotation);
}
return new TIntermBinary(EOpIndexDirectStruct, depthRange, CreateIndexNode(3)); TIntermBinary *DriverUniformExtended::getPreRotationMatrixRef() const
{
return createDriverUniformRef(kPreRotation);
} }
TIntermBinary *DriverUniform::getNumSamplesRef() const TIntermBinary *DriverUniformExtended::getHalfRenderAreaRef() const
{ {
return createDriverUniformRef(kNumSamples); return createDriverUniformRef(kHalfRenderArea);
} }
} // namespace sh } // namespace sh
...@@ -32,19 +32,20 @@ class DriverUniform ...@@ -32,19 +32,20 @@ class DriverUniform
bool addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable); bool addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable);
bool addGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable); bool addGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable);
TIntermBinary *getFlipXYRef() const;
TIntermBinary *getNegFlipXYRef() const;
TIntermBinary *getFragRotationMatrixRef() const;
TIntermBinary *getPreRotationMatrixRef() const;
TIntermBinary *getViewportRef() const; TIntermBinary *getViewportRef() const;
TIntermBinary *getHalfRenderAreaRef() const;
TIntermBinary *getAbcBufferOffsets() const; TIntermBinary *getAbcBufferOffsets() const;
TIntermBinary *getClipDistancesEnabled() const; TIntermBinary *getClipDistancesEnabled() const;
TIntermSwizzle *getNegFlipYRef() const;
TIntermBinary *getDepthRangeRef() const; TIntermBinary *getDepthRangeRef() const;
TIntermBinary *getDepthRangeReservedFieldRef() const; TIntermBinary *getDepthRangeReservedFieldRef() const;
TIntermBinary *getNumSamplesRef() const; TIntermBinary *getNumSamplesRef() const;
virtual TIntermBinary *getFlipXYRef() const { return nullptr; }
virtual TIntermBinary *getNegFlipXYRef() const { return nullptr; }
virtual TIntermBinary *getFragRotationMatrixRef() const { return nullptr; }
virtual TIntermBinary *getPreRotationMatrixRef() const { return nullptr; }
virtual TIntermBinary *getHalfRenderAreaRef() const { return nullptr; }
virtual TIntermSwizzle *getNegFlipYRef() const { return nullptr; }
protected: protected:
TIntermBinary *createDriverUniformRef(const char *fieldName) const; TIntermBinary *createDriverUniformRef(const char *fieldName) const;
virtual TFieldList *createUniformFields(TSymbolTable *symbolTable) const; virtual TFieldList *createUniformFields(TSymbolTable *symbolTable) const;
...@@ -53,6 +54,23 @@ class DriverUniform ...@@ -53,6 +54,23 @@ class DriverUniform
const TVariable *mDriverUniforms; const TVariable *mDriverUniforms;
}; };
class DriverUniformExtended : public DriverUniform
{
public:
DriverUniformExtended() : DriverUniform() {}
virtual ~DriverUniformExtended() override {}
TIntermBinary *getFlipXYRef() const override;
TIntermBinary *getNegFlipXYRef() const override;
TIntermBinary *getFragRotationMatrixRef() const override;
TIntermBinary *getPreRotationMatrixRef() const override;
TIntermBinary *getHalfRenderAreaRef() const override;
TIntermSwizzle *getNegFlipYRef() const override;
protected:
virtual TFieldList *createUniformFields(TSymbolTable *symbolTable) const override;
};
} // namespace sh } // namespace sh
#endif // COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_ #endif // COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_
...@@ -478,17 +478,13 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -478,17 +478,13 @@ class ContextMtl : public ContextImpl, public mtl::Context
{ {
float viewport[4]; float viewport[4];
float halfRenderArea[2];
float flipXY[2];
float negFlipXY[2];
// 32 bits for 32 clip distances // 32 bits for 32 clip distances
uint32_t enabledClipDistances; uint32_t enabledClipDistances;
uint32_t xfbActiveUnpaused; uint32_t xfbActiveUnpaused;
uint32_t xfbVerticesPerDraw; uint32_t xfbVerticesPerDraw;
// NOTE: Explicit padding. Fill in with useful data when needed in the future.
int32_t padding[3]; int32_t numSamples;
int32_t xfbBufferOffsets[4]; int32_t xfbBufferOffsets[4];
uint32_t acbBufferOffsets[4]; uint32_t acbBufferOffsets[4];
...@@ -496,19 +492,12 @@ class ContextMtl : public ContextImpl, public mtl::Context ...@@ -496,19 +492,12 @@ class ContextMtl : public ContextImpl, public mtl::Context
// We'll use x, y, z, w for near / far / diff / zscale respectively. // We'll use x, y, z, w for near / far / diff / zscale respectively.
float depthRange[4]; float depthRange[4];
// Used to pre-rotate gl_Position for Vulkan swapchain images on Android (a mat2, which is // Metal specific
// padded to the size of two vec4's). float halfRenderArea[2];
// Unused in Metal. float flipXY[2];
float preRotation[8] = {}; float negFlipXY[2];
// Used to pre-rotate gl_FragCoord for Vulkan swapchain images on Android (a mat2, which is
// padded to the size of two vec4's).
// Unused in Metal.
float fragRotation[8] = {};
uint32_t coverageMask; uint32_t coverageMask;
uint32_t padding;
float padding2[3];
}; };
struct DefaultAttribute struct DefaultAttribute
......
...@@ -60,11 +60,6 @@ struct GraphicsDriverUniforms ...@@ -60,11 +60,6 @@ struct GraphicsDriverUniforms
{ {
std::array<float, 4> viewport; std::array<float, 4> viewport;
// 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;
std::array<float, 2> negFlipXY;
// 32 bits for 32 clip planes // 32 bits for 32 clip planes
uint32_t enabledClipPlanes; uint32_t enabledClipPlanes;
...@@ -74,8 +69,6 @@ struct GraphicsDriverUniforms ...@@ -74,8 +69,6 @@ struct GraphicsDriverUniforms
// Used to replace gl_NumSamples. Because gl_NumSamples cannot be recognized in SPIR-V. // Used to replace gl_NumSamples. Because gl_NumSamples cannot be recognized in SPIR-V.
int32_t numSamples; int32_t numSamples;
std::array<int32_t, 2> padding;
std::array<int32_t, 4> xfbBufferOffsets; std::array<int32_t, 4> xfbBufferOffsets;
// .xy contain packed 8-bit values for atomic counter buffer offsets. These offsets are // .xy contain packed 8-bit values for atomic counter buffer offsets. These offsets are
...@@ -87,6 +80,20 @@ struct GraphicsDriverUniforms ...@@ -87,6 +80,20 @@ struct GraphicsDriverUniforms
// We'll use x, y, z for near / far / diff respectively. // We'll use x, y, z for near / far / diff respectively.
std::array<float, 4> depthRange; std::array<float, 4> depthRange;
};
static_assert(sizeof(GraphicsDriverUniforms) % (sizeof(uint32_t) * 4) == 0,
"GraphicsDriverUniforms should 16bytes aligned");
// TODO: http://issuetracker.google.com/173636783 Once the bug is fixed, we should remove this.
struct GraphicsDriverUniformsExtended
{
GraphicsDriverUniforms common;
// 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;
std::array<float, 2> negFlipXY;
std::array<int32_t, 2> padding;
// Used to pre-rotate gl_Position for swapchain images on Android (a mat2, which is padded to // Used to pre-rotate gl_Position for swapchain images on Android (a mat2, which is padded to
// the size of two vec4's). // the size of two vec4's).
...@@ -3729,56 +3736,91 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co ...@@ -3729,56 +3736,91 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co
vk::CommandBuffer *commandBuffer) vk::CommandBuffer *commandBuffer)
{ {
// Allocate a new region in the dynamic buffer. // Allocate a new region in the dynamic buffer.
bool useGraphicsDriverUniformsExtended = getFeatures().forceDriverUniformOverSpecConst.enabled;
uint8_t *ptr; uint8_t *ptr;
bool newBuffer; bool newBuffer;
ANGLE_TRY(allocateDriverUniforms(sizeof(GraphicsDriverUniforms), GraphicsDriverUniforms *driverUniforms;
&mDriverUniforms[PipelineType::Graphics], &ptr, &newBuffer)); size_t driverUniformSize;
if (useGraphicsDriverUniformsExtended)
{
driverUniformSize = sizeof(GraphicsDriverUniformsExtended);
}
else
{
driverUniformSize = sizeof(GraphicsDriverUniforms);
}
ANGLE_TRY(allocateDriverUniforms(driverUniformSize, &mDriverUniforms[PipelineType::Graphics],
&ptr, &newBuffer));
if (useGraphicsDriverUniformsExtended)
{
float halfRenderAreaWidth =
static_cast<float>(mDrawFramebuffer->getState().getDimensions().width) * 0.5f;
float halfRenderAreaHeight =
static_cast<float>(mDrawFramebuffer->getState().getDimensions().height) * 0.5f;
float flipX = 1.0f;
float flipY = -1.0f;
// Y-axis flipping only comes into play with the default framebuffer (i.e. a swapchain
// image). For 0-degree rotation, an FBO or pbuffer could be the draw framebuffer, and so we
// must check whether flipY should be positive or negative. All other rotations, will be to
// the default framebuffer, and so the value of isViewportFlipEnabledForDrawFBO() is assumed
// true; the appropriate flipY value is chosen such that gl_FragCoord is positioned at the
// lower-left corner of the window.
switch (mCurrentRotationDrawFramebuffer)
{
case SurfaceRotation::Identity:
flipX = 1.0f;
flipY = isViewportFlipEnabledForDrawFBO() ? -1.0f : 1.0f;
break;
case SurfaceRotation::Rotated90Degrees:
ASSERT(isViewportFlipEnabledForDrawFBO());
flipX = 1.0f;
flipY = 1.0f;
std::swap(halfRenderAreaWidth, halfRenderAreaHeight);
break;
case SurfaceRotation::Rotated180Degrees:
ASSERT(isViewportFlipEnabledForDrawFBO());
flipX = -1.0f;
flipY = 1.0f;
break;
case SurfaceRotation::Rotated270Degrees:
ASSERT(isViewportFlipEnabledForDrawFBO());
flipX = -1.0f;
flipY = -1.0f;
break;
default:
UNREACHABLE();
break;
}
GraphicsDriverUniformsExtended *driverUniformsExt =
reinterpret_cast<GraphicsDriverUniformsExtended *>(ptr);
driverUniformsExt->halfRenderArea = {halfRenderAreaWidth, halfRenderAreaHeight};
driverUniformsExt->flipXY = {flipX, flipY};
driverUniformsExt->negFlipXY = {flipX, -flipY};
memcpy(&driverUniformsExt->preRotation,
&kPreRotationMatrices[mCurrentRotationDrawFramebuffer],
sizeof(PreRotationMatrixValues));
memcpy(&driverUniformsExt->fragRotation,
&kFragRotationMatrices[mCurrentRotationDrawFramebuffer],
sizeof(PreRotationMatrixValues));
driverUniforms = &driverUniformsExt->common;
}
else
{
driverUniforms = reinterpret_cast<GraphicsDriverUniforms *>(ptr);
}
gl::Rectangle glViewport = mState.getViewport(); gl::Rectangle glViewport = mState.getViewport();
float halfRenderAreaWidth =
static_cast<float>(mDrawFramebuffer->getState().getDimensions().width) * 0.5f;
float halfRenderAreaHeight =
static_cast<float>(mDrawFramebuffer->getState().getDimensions().height) * 0.5f;
if (isRotatedAspectRatioForDrawFBO()) if (isRotatedAspectRatioForDrawFBO())
{ {
// The surface is rotated 90/270 degrees. This changes the aspect ratio of the surface. // The surface is rotated 90/270 degrees. This changes the aspect ratio of the surface.
std::swap(glViewport.x, glViewport.y); std::swap(glViewport.x, glViewport.y);
std::swap(glViewport.width, glViewport.height); std::swap(glViewport.width, glViewport.height);
} }
float flipX = 1.0f;
float flipY = -1.0f;
// Y-axis flipping only comes into play with the default framebuffer (i.e. a swapchain image).
// For 0-degree rotation, an FBO or pbuffer could be the draw framebuffer, and so we must check
// whether flipY should be positive or negative. All other rotations, will be to the default
// framebuffer, and so the value of isViewportFlipEnabledForDrawFBO() is assumed true; the
// appropriate flipY value is chosen such that gl_FragCoord is positioned at the lower-left
// corner of the window.
switch (mCurrentRotationDrawFramebuffer)
{
case SurfaceRotation::Identity:
flipX = 1.0f;
flipY = isViewportFlipEnabledForDrawFBO() ? -1.0f : 1.0f;
break;
case SurfaceRotation::Rotated90Degrees:
ASSERT(isViewportFlipEnabledForDrawFBO());
flipX = 1.0f;
flipY = 1.0f;
std::swap(halfRenderAreaWidth, halfRenderAreaHeight);
break;
case SurfaceRotation::Rotated180Degrees:
ASSERT(isViewportFlipEnabledForDrawFBO());
flipX = -1.0f;
flipY = 1.0f;
break;
case SurfaceRotation::Rotated270Degrees:
ASSERT(isViewportFlipEnabledForDrawFBO());
flipX = -1.0f;
flipY = -1.0f;
break;
default:
UNREACHABLE();
break;
}
uint32_t xfbActiveUnpaused = mState.isTransformFeedbackActiveUnpaused(); uint32_t xfbActiveUnpaused = mState.isTransformFeedbackActiveUnpaused();
...@@ -3788,27 +3830,16 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co ...@@ -3788,27 +3830,16 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co
int32_t numSamples = mDrawFramebuffer->getSamples(); int32_t numSamples = mDrawFramebuffer->getSamples();
// Copy and flush to the device. // Copy and flush to the device.
GraphicsDriverUniforms *driverUniforms = reinterpret_cast<GraphicsDriverUniforms *>(ptr); *driverUniforms = {
*driverUniforms = {
{static_cast<float>(glViewport.x), static_cast<float>(glViewport.y), {static_cast<float>(glViewport.x), static_cast<float>(glViewport.y),
static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)}, static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)},
{halfRenderAreaWidth, halfRenderAreaHeight},
{flipX, flipY},
{flipX, -flipY},
mState.getEnabledClipDistances().bits(), mState.getEnabledClipDistances().bits(),
xfbActiveUnpaused, xfbActiveUnpaused,
mXfbVertexCountPerInstance, mXfbVertexCountPerInstance,
numSamples, numSamples,
{}, {},
{}, {},
{}, {depthRangeNear, depthRangeFar, depthRangeDiff, 0.0f}};
{depthRangeNear, depthRangeFar, depthRangeDiff, 0.0f},
{},
{}};
memcpy(&driverUniforms->preRotation, &kPreRotationMatrices[mCurrentRotationDrawFramebuffer],
sizeof(PreRotationMatrixValues));
memcpy(&driverUniforms->fragRotation, &kFragRotationMatrices[mCurrentRotationDrawFramebuffer],
sizeof(PreRotationMatrixValues));
if (xfbActiveUnpaused) if (xfbActiveUnpaused)
{ {
...@@ -3825,7 +3856,7 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co ...@@ -3825,7 +3856,7 @@ angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *co
driverUniforms->acbBufferOffsets.size()); driverUniforms->acbBufferOffsets.size());
} }
return updateDriverUniformsDescriptorSet(newBuffer, sizeof(GraphicsDriverUniforms), return updateDriverUniformsDescriptorSet(newBuffer, driverUniformSize,
&mDriverUniforms[PipelineType::Graphics]); &mDriverUniforms[PipelineType::Graphics]);
} }
......
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