Commit 7bd16666 by Jamie Madill

Vulkan: Allow in-flight Framebuffer changes.

This allows the app to alter Framebuffer attachments while there are existing command buffers using the resources and attachments. BUG=angleproject:2200 Change-Id: I3298dafef5e3bd2c6efda8e8a32a6cf7febc13dc Reviewed-on: https://chromium-review.googlesource.com/742370Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 640d597d
......@@ -355,13 +355,15 @@ bool FramebufferVk::checkStatus(const gl::Context *context) const
void FramebufferVk::syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits)
{
auto contextVk = GetImplAs<ContextVk>(context);
ContextVk *contextVk = GetImplAs<ContextVk>(context);
RendererVk *renderer = contextVk->getRenderer();
ASSERT(dirtyBits.any());
// TODO(jmadill): Smarter update.
mRenderPass.destroy(contextVk->getDevice());
mFramebuffer.destroy(contextVk->getDevice());
renderer->releaseResource(*this, &mRenderPass);
renderer->releaseResource(*this, &mFramebuffer);
renderer->onReleaseRenderPass(this);
// TODO(jmadill): Use pipeline cache.
contextVk->invalidateCurrentPipeline();
......
......@@ -813,4 +813,12 @@ void RendererVk::endRenderPass()
}
}
void RendererVk::onReleaseRenderPass(const FramebufferVk *framebufferVk)
{
if (mCurrentRenderPassFramebuffer == framebufferVk)
{
endRenderPass();
}
}
} // namespace rx
......@@ -102,6 +102,9 @@ class RendererVk : angle::NonCopyable
gl::Error ensureInRenderPass(const gl::Context *context, FramebufferVk *framebufferVk);
void endRenderPass();
// This is necessary to update the cached current RenderPass Framebuffer.
void onReleaseRenderPass(const FramebufferVk *framebufferVk);
private:
void ensureCapsInitialized() const;
void generateCaps(gl::Caps *outCaps,
......
......@@ -754,6 +754,7 @@ class SimpleStateChangeTest : public ANGLETest
}
void simpleDrawWithBuffer(GLBuffer *buffer);
void simpleDrawWithColor(const GLColor &color);
};
constexpr char kSimpleVertexShader[] = R"(attribute vec2 position;
......@@ -790,6 +791,15 @@ void SimpleStateChangeTest::simpleDrawWithBuffer(GLBuffer *buffer)
ASSERT_GL_NO_ERROR();
}
void SimpleStateChangeTest::simpleDrawWithColor(const GLColor &color)
{
std::vector<GLColor> colors(6, color);
GLBuffer colorBuffer;
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(GLColor), colors.data(), GL_STATIC_DRAW);
simpleDrawWithBuffer(&colorBuffer);
}
// Handles deleting a Buffer when it's being used.
TEST_P(SimpleStateChangeTest, DeleteBufferInUse)
{
......@@ -959,6 +969,47 @@ TEST_P(SimpleStateChangeTest, DeleteFramebufferInUse)
ASSERT_GL_NO_ERROR();
}
// Tests deleting a Framebuffer that is in use.
TEST_P(SimpleStateChangeTest, RedefineFramebufferInUse)
{
constexpr int kSize = 16;
// Create a simple framebuffer.
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
glViewport(0, 0, kSize, kSize);
// Draw red to the framebuffer.
simpleDrawWithColor(GLColor::red);
// Change the framebuffer while the call is in flight to a new texture.
GLTexture otherTexture;
glBindTexture(GL_TEXTURE_2D, otherTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, otherTexture, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
// Draw green to the framebuffer. Verify the color.
simpleDrawWithColor(GLColor::green);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// Make a new framebuffer so we can read back the first texture and verify red.
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
ASSERT_GL_NO_ERROR();
}
} // anonymous namespace
ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());
......
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