Commit 45a493ea by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Use a dirty bit to start the render pass

Some dirty bits need to run before the render pass starts. An upcoming change for example needs to break the render pass when the program pipeline is changed while transform feedback is active. Another upcoming change may need to do the same based on a preceding glMemoryBarrier. This change adds a new dirty bit to start the render pass after some dirty bits have already been processed. Bug: angleproject:5528 Change-Id: I993c9efefed4c8fee268b218a8dd66a582d4e7cd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2678863 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent dccec125
...@@ -2318,7 +2318,8 @@ angle::Result FramebufferVk::getSamplePosition(const gl::Context *context, ...@@ -2318,7 +2318,8 @@ angle::Result FramebufferVk::getSamplePosition(const gl::Context *context,
angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
const gl::Rectangle &scissoredRenderArea, const gl::Rectangle &scissoredRenderArea,
vk::CommandBuffer **commandBufferOut) vk::CommandBuffer **commandBufferOut,
bool *renderPassDescChangedOut)
{ {
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass()); ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
...@@ -2536,13 +2537,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -2536,13 +2537,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
// or the existence of resolve attachments in single subpass render passes. The modification // or the existence of resolve attachments in single subpass render passes. The modification
// here can add/remove a subpass, or modify its input attachments. // here can add/remove a subpass, or modify its input attachments.
gl::DrawBufferMask unresolveColorMask = mRenderPassDesc.getColorUnresolveAttachmentMask(); gl::DrawBufferMask unresolveColorMask = mRenderPassDesc.getColorUnresolveAttachmentMask();
bool unresolveDepth = mRenderPassDesc.hasDepthUnresolveAttachment(); const bool unresolveDepth = mRenderPassDesc.hasDepthUnresolveAttachment();
bool unresolveStencil = mRenderPassDesc.hasStencilUnresolveAttachment(); const bool unresolveStencil = mRenderPassDesc.hasStencilUnresolveAttachment();
if (previousUnresolveColorMask != unresolveColorMask || const bool unresolveChanged = previousUnresolveColorMask != unresolveColorMask ||
previousUnresolveDepth != unresolveDepth || previousUnresolveStencil != unresolveStencil) previousUnresolveDepth != unresolveDepth ||
previousUnresolveStencil != unresolveStencil;
if (unresolveChanged)
{ {
contextVk->onDrawFramebufferRenderPassDescChange(this);
// Make sure framebuffer is recreated. // Make sure framebuffer is recreated.
mFramebuffer = nullptr; mFramebuffer = nullptr;
...@@ -2580,7 +2581,8 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -2580,7 +2581,8 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
mCurrentFramebufferDesc.getLayerCount()); mCurrentFramebufferDesc.getLayerCount());
} }
if (unresolveColorMask.any() || unresolveDepth || unresolveStencil) const bool anyUnresolve = unresolveColorMask.any() || unresolveDepth || unresolveStencil;
if (anyUnresolve)
{ {
// Unresolve attachments if any. // Unresolve attachments if any.
UtilsVk::UnresolveParameters params; UtilsVk::UnresolveParameters params;
...@@ -2594,6 +2596,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk, ...@@ -2594,6 +2596,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
contextVk->startNextSubpass(); contextVk->startNextSubpass();
} }
if (unresolveChanged || anyUnresolve)
{
contextVk->onDrawFramebufferRenderPassDescChange(this);
// Notify that the render pass desc has changed.
*renderPassDescChangedOut = true;
}
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -2701,7 +2710,7 @@ angle::Result FramebufferVk::flushDeferredClears(ContextVk *contextVk) ...@@ -2701,7 +2710,7 @@ angle::Result FramebufferVk::flushDeferredClears(ContextVk *contextVk)
return angle::Result::Continue; return angle::Result::Continue;
} }
return contextVk->startRenderPass(getRotatedCompleteRenderArea(contextVk), nullptr); return contextVk->startRenderPass(getRotatedCompleteRenderArea(contextVk), nullptr, nullptr);
} }
void FramebufferVk::updateRenderPassReadOnlyDepthMode(ContextVk *contextVk, void FramebufferVk::updateRenderPassReadOnlyDepthMode(ContextVk *contextVk,
......
...@@ -138,7 +138,8 @@ class FramebufferVk : public FramebufferImpl ...@@ -138,7 +138,8 @@ class FramebufferVk : public FramebufferImpl
angle::Result startNewRenderPass(ContextVk *contextVk, angle::Result startNewRenderPass(ContextVk *contextVk,
const gl::Rectangle &scissoredRenderArea, const gl::Rectangle &scissoredRenderArea,
vk::CommandBuffer **commandBufferOut); vk::CommandBuffer **commandBufferOut,
bool *renderPassDescChangedOut);
RenderTargetVk *getFirstRenderTarget() const; RenderTargetVk *getFirstRenderTarget() const;
GLint getSamples() const; GLint getSamples() const;
......
...@@ -996,7 +996,7 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk, ...@@ -996,7 +996,7 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk,
pipelineAndSerial->updateSerial(serial); pipelineAndSerial->updateSerial(serial);
commandBuffer->bindComputePipeline(pipelineAndSerial->get()); commandBuffer->bindComputePipeline(pipelineAndSerial->get());
contextVk->invalidateComputePipeline(); contextVk->invalidateComputePipelineBinding();
} }
else else
{ {
...@@ -1017,7 +1017,7 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk, ...@@ -1017,7 +1017,7 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk,
helper->updateSerial(serial); helper->updateSerial(serial);
commandBuffer->bindGraphicsPipeline(helper->getPipeline()); commandBuffer->bindGraphicsPipeline(helper->getPipeline());
contextVk->invalidateGraphicsPipeline(); contextVk->invalidateGraphicsPipelineBinding();
} }
if (descriptorSet != VK_NULL_HANDLE) if (descriptorSet != VK_NULL_HANDLE)
...@@ -1492,7 +1492,9 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk, ...@@ -1492,7 +1492,9 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
} }
else else
{ {
ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer)); bool renderPassDescChanged = false;
ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer,
&renderPassDescChanged));
} }
if (params.clearStencil || params.clearDepth) if (params.clearStencil || params.clearDepth)
...@@ -1810,7 +1812,7 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk, ...@@ -1810,7 +1812,7 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk,
pipelineDesc.setScissor(gl_vk::GetRect(params.blitArea)); pipelineDesc.setScissor(gl_vk::GetRect(params.blitArea));
vk::CommandBuffer *commandBuffer; vk::CommandBuffer *commandBuffer;
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer)); ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer, nullptr));
contextVk->onImageRenderPassRead(src->getAspectFlags(), vk::ImageLayout::FragmentShaderReadOnly, contextVk->onImageRenderPassRead(src->getAspectFlags(), vk::ImageLayout::FragmentShaderReadOnly,
src); src);
......
...@@ -943,6 +943,63 @@ TEST_P(StateChangeTest, VertexBufferUpdatedAfterDraw) ...@@ -943,6 +943,63 @@ TEST_P(StateChangeTest, VertexBufferUpdatedAfterDraw)
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
// Tests that drawing after flush without any state change works.
TEST_P(StateChangeTest, DrawAfterFlushWithNoStateChange)
{
// Draw (0.125, 0.25, 0.5, 0.5) once, using additive blend
ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
glUseProgram(drawColor);
GLint colorUniformLocation =
glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
ASSERT_NE(colorUniformLocation, -1);
GLint positionLocation = glGetAttribLocation(drawColor, essl1_shaders::PositionAttrib());
ASSERT_NE(-1, positionLocation);
// Setup VAO
const auto &quadVertices = GetQuadVertices();
GLBuffer vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * 6, quadVertices.data(), GL_STATIC_DRAW);
GLVertexArray vertexArray;
glBindVertexArray(vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(positionLocation);
ASSERT_GL_NO_ERROR();
// Clear and draw
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glUniform4f(colorUniformLocation, 0.125f, 0.25f, 0.5f, 0.5f);
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
// Make sure the work is submitted.
glFinish();
// Draw again with no state change
glDrawArrays(GL_TRIANGLES, 0, 6);
ASSERT_GL_NO_ERROR();
// Make sure the pixels have the correct colors.
const int h = getWindowHeight() - 1;
const int w = getWindowWidth() - 1;
const GLColor kExpected(63, 127, 255, 255);
EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, kExpected, 1);
EXPECT_PIXEL_COLOR_NEAR(0, h - 1, kExpected, 1);
EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, kExpected, 1);
}
// Test that switching VAOs keeps the disabled "current value" attributes up-to-date. // Test that switching VAOs keeps the disabled "current value" attributes up-to-date.
TEST_P(StateChangeTestES3, VertexArrayObjectAndDisabledAttributes) TEST_P(StateChangeTestES3, VertexArrayObjectAndDisabledAttributes)
{ {
......
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