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,
angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
const gl::Rectangle &scissoredRenderArea,
vk::CommandBuffer **commandBufferOut)
vk::CommandBuffer **commandBufferOut,
bool *renderPassDescChangedOut)
{
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
......@@ -2536,13 +2537,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
// or the existence of resolve attachments in single subpass render passes. The modification
// here can add/remove a subpass, or modify its input attachments.
gl::DrawBufferMask unresolveColorMask = mRenderPassDesc.getColorUnresolveAttachmentMask();
bool unresolveDepth = mRenderPassDesc.hasDepthUnresolveAttachment();
bool unresolveStencil = mRenderPassDesc.hasStencilUnresolveAttachment();
if (previousUnresolveColorMask != unresolveColorMask ||
previousUnresolveDepth != unresolveDepth || previousUnresolveStencil != unresolveStencil)
const bool unresolveDepth = mRenderPassDesc.hasDepthUnresolveAttachment();
const bool unresolveStencil = mRenderPassDesc.hasStencilUnresolveAttachment();
const bool unresolveChanged = previousUnresolveColorMask != unresolveColorMask ||
previousUnresolveDepth != unresolveDepth ||
previousUnresolveStencil != unresolveStencil;
if (unresolveChanged)
{
contextVk->onDrawFramebufferRenderPassDescChange(this);
// Make sure framebuffer is recreated.
mFramebuffer = nullptr;
......@@ -2580,7 +2581,8 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
mCurrentFramebufferDesc.getLayerCount());
}
if (unresolveColorMask.any() || unresolveDepth || unresolveStencil)
const bool anyUnresolve = unresolveColorMask.any() || unresolveDepth || unresolveStencil;
if (anyUnresolve)
{
// Unresolve attachments if any.
UtilsVk::UnresolveParameters params;
......@@ -2594,6 +2596,13 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
contextVk->startNextSubpass();
}
if (unresolveChanged || anyUnresolve)
{
contextVk->onDrawFramebufferRenderPassDescChange(this);
// Notify that the render pass desc has changed.
*renderPassDescChangedOut = true;
}
return angle::Result::Continue;
}
......@@ -2701,7 +2710,7 @@ angle::Result FramebufferVk::flushDeferredClears(ContextVk *contextVk)
return angle::Result::Continue;
}
return contextVk->startRenderPass(getRotatedCompleteRenderArea(contextVk), nullptr);
return contextVk->startRenderPass(getRotatedCompleteRenderArea(contextVk), nullptr, nullptr);
}
void FramebufferVk::updateRenderPassReadOnlyDepthMode(ContextVk *contextVk,
......
......@@ -138,7 +138,8 @@ class FramebufferVk : public FramebufferImpl
angle::Result startNewRenderPass(ContextVk *contextVk,
const gl::Rectangle &scissoredRenderArea,
vk::CommandBuffer **commandBufferOut);
vk::CommandBuffer **commandBufferOut,
bool *renderPassDescChangedOut);
RenderTargetVk *getFirstRenderTarget() const;
GLint getSamples() const;
......
......@@ -996,7 +996,7 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk,
pipelineAndSerial->updateSerial(serial);
commandBuffer->bindComputePipeline(pipelineAndSerial->get());
contextVk->invalidateComputePipeline();
contextVk->invalidateComputePipelineBinding();
}
else
{
......@@ -1017,7 +1017,7 @@ angle::Result UtilsVk::setupProgram(ContextVk *contextVk,
helper->updateSerial(serial);
commandBuffer->bindGraphicsPipeline(helper->getPipeline());
contextVk->invalidateGraphicsPipeline();
contextVk->invalidateGraphicsPipelineBinding();
}
if (descriptorSet != VK_NULL_HANDLE)
......@@ -1492,7 +1492,9 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
}
else
{
ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer));
bool renderPassDescChanged = false;
ANGLE_TRY(contextVk->startRenderPass(scissoredRenderArea, &commandBuffer,
&renderPassDescChanged));
}
if (params.clearStencil || params.clearDepth)
......@@ -1810,7 +1812,7 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk,
pipelineDesc.setScissor(gl_vk::GetRect(params.blitArea));
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,
src);
......
......@@ -943,6 +943,63 @@ TEST_P(StateChangeTest, VertexBufferUpdatedAfterDraw)
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_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