Commit 9ff9c773 by Luc Ferron Committed by Commit Bot

Vulkan: Add driver uniforms for point coords flipping

This new driver uniform allows us to dynamically decide if we flip the y coordinate of the gl_PointCoord variable. We only flip the coordinate if we render downside-up, and otherwise we cancel the flipping since the y coordinate doesn't need modification anymore. This completes all end2end and deqp gles2 tests success when viewport flipping is enabled on Windows Nvidia. Bug: angleproject: 2673 Change-Id: I570e01ef4965933428375f6ebd8eac83ef16fbff Reviewed-on: https://chromium-review.googlesource.com/1133584 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 6c70bd8a
...@@ -153,7 +153,9 @@ constexpr ImmutableString kFlippedPointCoordName = ImmutableString("flippedPoint ...@@ -153,7 +153,9 @@ constexpr ImmutableString kFlippedPointCoordName = ImmutableString("flippedPoint
// Declares a new variable to replace gl_PointCoord with a version that is flipping the Y // Declares a new variable to replace gl_PointCoord with a version that is flipping the Y
// coordinate. // coordinate.
void FlipGLPointCoord(TIntermBlock *root, TSymbolTable *symbolTable) void FlipGLPointCoord(TIntermBlock *root,
const TVariable *driverUniforms,
TSymbolTable *symbolTable)
{ {
// Create a symbol reference to "gl_PointCoord" // Create a symbol reference to "gl_PointCoord"
const TVariable *pointCoord = BuiltInVariable::gl_PointCoord(); const TVariable *pointCoord = BuiltInVariable::gl_PointCoord();
...@@ -177,25 +179,45 @@ void FlipGLPointCoord(TIntermBlock *root, TSymbolTable *symbolTable) ...@@ -177,25 +179,45 @@ void FlipGLPointCoord(TIntermBlock *root, TSymbolTable *symbolTable)
DeclareGlobalVariable(root, replacementVar); DeclareGlobalVariable(root, replacementVar);
TIntermSymbol *flippedPointCoordsRef = new TIntermSymbol(replacementVar); TIntermSymbol *flippedPointCoordsRef = new TIntermSymbol(replacementVar);
// Create a constant "-1.0"
const TType *constantType = StaticType::GetBasic<EbtFloat>(); const TType *constantType = StaticType::GetBasic<EbtFloat>();
TConstantUnion *constantValueMinusOne = new TConstantUnion();
constantValueMinusOne->setFConst(-1.0f);
TIntermConstantUnion *minusOne = new TIntermConstantUnion(constantValueMinusOne, *constantType);
// Create a constant "1.0" // Create a constant "0.5"
TConstantUnion *constantValueOne = new TConstantUnion(); TConstantUnion *constantValuePointFive = new TConstantUnion();
constantValueOne->setFConst(1.0f); constantValuePointFive->setFConst(0.5f);
TIntermConstantUnion *one = new TIntermConstantUnion(constantValueOne, *constantType); TIntermConstantUnion *pointFive =
new TIntermConstantUnion(constantValuePointFive, *constantType);
// Create the expression "gl_PointCoord.y * -1.0 + 1.0"
TIntermBinary *inverseY = new TIntermBinary(EOpMul, pointCoordY, minusOne); // Create a constant "-0.5"
TIntermBinary *plusOne = new TIntermBinary(EOpAdd, inverseY, one); TConstantUnion *constantValueMinusPointFive = new TConstantUnion();
constantValueMinusPointFive->setFConst(-0.5f);
TIntermConstantUnion *minusPointFive =
new TIntermConstantUnion(constantValueMinusPointFive, *constantType);
// ANGLEUniforms.viewportScaleFactor
TIntermSymbol *angleUniformsRef = new TIntermSymbol(driverUniforms);
TConstantUnion *viewportScaleFactorConstant = new TConstantUnion;
viewportScaleFactorConstant->setIConst(1);
TIntermConstantUnion *viewportScaleFactorIndex =
new TIntermConstantUnion(viewportScaleFactorConstant, *StaticType::GetBasic<EbtInt>());
TIntermBinary *viewportScaleFactorRef =
new TIntermBinary(EOpIndexDirectInterfaceBlock, angleUniformsRef, viewportScaleFactorIndex);
// Creates a swizzle to ANGLEUniforms.viewportScaleFactor.y
TVector<int> viewportScaleSwizzleOffsetY;
viewportScaleSwizzleOffsetY.push_back(1);
TIntermSwizzle *viewportScaleY =
new TIntermSwizzle(viewportScaleFactorRef->deepCopy(), viewportScaleSwizzleOffsetY);
// Create the expression "(gl_PointCoord.y - 0.5) * ANGLEUniforms.viewportScaleFactor.y +
// 0.5
TIntermBinary *removePointFive = new TIntermBinary(EOpAdd, pointCoordY, minusPointFive);
TIntermBinary *inverseY = new TIntermBinary(EOpMul, removePointFive, viewportScaleY);
TIntermBinary *plusPointFive = new TIntermBinary(EOpAdd, inverseY, pointFive);
// Create the new vec2 using the modified Y // Create the new vec2 using the modified Y
TIntermSequence *sequence = new TIntermSequence(); TIntermSequence *sequence = new TIntermSequence();
sequence->push_back(pointCoordX); sequence->push_back(pointCoordX);
sequence->push_back(plusOne); sequence->push_back(plusPointFive);
TIntermAggregate *aggregate = TIntermAggregate *aggregate =
TIntermAggregate::CreateConstructor(BuiltInVariable::gl_PointCoord()->getType(), sequence); TIntermAggregate::CreateConstructor(BuiltInVariable::gl_PointCoord()->getType(), sequence);
...@@ -271,6 +293,13 @@ const TVariable *AddDriverUniformsToShader(TIntermBlock *root, TSymbolTable *sym ...@@ -271,6 +293,13 @@ const TVariable *AddDriverUniformsToShader(TIntermBlock *root, TSymbolTable *sym
TSourceLoc(), SymbolType::AngleInternal); TSourceLoc(), SymbolType::AngleInternal);
driverFieldList->push_back(driverViewportSize); driverFieldList->push_back(driverViewportSize);
// Add a vec4 field "viewportScaleFactor" to the driver uniform fields.
TType *driverViewportScaleFactorType = new TType(EbtFloat, 4);
TField *driverViewportScaleFactorSize =
new TField(driverViewportScaleFactorType, ImmutableString("viewportScaleFactor"),
TSourceLoc(), SymbolType::AngleInternal);
driverFieldList->push_back(driverViewportScaleFactorSize);
// Define a driver uniform block "ANGLEUniformBlock". // Define a driver uniform block "ANGLEUniformBlock".
TLayoutQualifier driverLayoutQualifier = TLayoutQualifier::Create(); TLayoutQualifier driverLayoutQualifier = TLayoutQualifier::Create();
TInterfaceBlock *interfaceBlock = TInterfaceBlock *interfaceBlock =
...@@ -353,7 +382,7 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -353,7 +382,7 @@ void TranslatorVulkan::translate(TIntermBlock *root,
sink << "};\n"; sink << "};\n";
} }
AddDriverUniformsToShader(root, &getSymbolTable()); const TVariable *driverUniformsVariable = AddDriverUniformsToShader(root, &getSymbolTable());
// Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
// if it's core profile shaders and they are used. // if it's core profile shaders and they are used.
...@@ -397,7 +426,7 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -397,7 +426,7 @@ void TranslatorVulkan::translate(TIntermBlock *root,
if (inputVarying.name == "gl_PointCoord") if (inputVarying.name == "gl_PointCoord")
{ {
FlipGLPointCoord(root, &getSymbolTable()); FlipGLPointCoord(root, driverUniformsVariable, &getSymbolTable());
break; break;
} }
} }
......
...@@ -591,6 +591,7 @@ gl::Error ContextVk::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -591,6 +591,7 @@ gl::Error ContextVk::syncState(const gl::Context *context, const gl::State::Dirt
break; break;
case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
{ {
ANGLE_TRY(updateDriverUniforms());
updateFlipViewportDrawFramebuffer(context->getGLState()); updateFlipViewportDrawFramebuffer(context->getGLState());
FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer()); FramebufferVk *framebufferVk = vk::GetImpl(glState.getDrawFramebuffer());
mPipelineDesc->updateViewport(framebufferVk, glState.getViewport(), mPipelineDesc->updateViewport(framebufferVk, glState.getViewport(),
...@@ -703,6 +704,7 @@ gl::Error ContextVk::onMakeCurrent(const gl::Context *context) ...@@ -703,6 +704,7 @@ gl::Error ContextVk::onMakeCurrent(const gl::Context *context)
const gl::State &glState = context->getGLState(); const gl::State &glState = context->getGLState();
updateFlipViewportDrawFramebuffer(glState); updateFlipViewportDrawFramebuffer(glState);
updateFlipViewportReadFramebuffer(glState); updateFlipViewportReadFramebuffer(glState);
ANGLE_TRY(updateDriverUniforms());
return gl::NoError(); return gl::NoError();
} }
...@@ -893,11 +895,14 @@ vk::Error ContextVk::updateDriverUniforms() ...@@ -893,11 +895,14 @@ vk::Error ContextVk::updateDriverUniforms()
bool newBufferAllocated = false; bool newBufferAllocated = false;
ANGLE_TRY(mDriverUniformsBuffer.allocate(mRenderer, sizeof(DriverUniforms), &ptr, &buffer, ANGLE_TRY(mDriverUniformsBuffer.allocate(mRenderer, sizeof(DriverUniforms), &ptr, &buffer,
&offset, &newBufferAllocated)); &offset, &newBufferAllocated));
float scaleY = isViewportFlipEnabledForDrawFBO() ? 1.0f : -1.0f;
// Copy and flush to the device. // Copy and flush to the device.
DriverUniforms *driverUniforms = reinterpret_cast<DriverUniforms *>(ptr); DriverUniforms *driverUniforms = reinterpret_cast<DriverUniforms *>(ptr);
*driverUniforms = {static_cast<float>(glViewport.x), static_cast<float>(glViewport.y), *driverUniforms = {
static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)}; {static_cast<float>(glViewport.x), static_cast<float>(glViewport.y),
static_cast<float>(glViewport.width), static_cast<float>(glViewport.height)},
{1.0f, scaleY, 1.0f, 1.0f}};
ANGLE_TRY(mDriverUniformsBuffer.flush(getDevice())); ANGLE_TRY(mDriverUniformsBuffer.flush(getDevice()));
......
...@@ -216,6 +216,7 @@ class ContextVk : public ContextImpl ...@@ -216,6 +216,7 @@ class ContextVk : public ContextImpl
struct DriverUniforms struct DriverUniforms
{ {
std::array<float, 4> viewport; std::array<float, 4> viewport;
std::array<float, 4> viewportScaleFactor;
}; };
vk::DynamicBuffer mDriverUniformsBuffer; vk::DynamicBuffer mDriverUniformsBuffer;
VkDescriptorSet mDriverUniformsDescriptorSet; VkDescriptorSet mDriverUniformsDescriptorSet;
......
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