From 52ef28dcfe09b0acef2865977d38246405e257bf Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Fri, 24 Jan 2020 09:55:01 -0500 Subject: [PATCH] Vulkan: Update active textures before setupDraw(). The linear command graph prohibits rendering outside the render pass *after* we begin a renderpass. The prior code would render outside a render pass (changing image layouts) even after a RenderPass was started in setupDraw(). The new code changes the image layouts in ContextVk::syncState so we no longer need to "prepend" image layout changes after we started a RenderPass. Now we record layout changes followed by the draw calls or other renderpass ops. Bug: angleproject:4029 Bug: angleproject:3539 Change-Id: I420858907ac38f995400c1b566c856d966a4e979 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2015940 Commit-Queue: Jamie Madill Reviewed-by: Shahbaz Youssefi Reviewed-by: Tobin Ehlis --- src/libANGLE/State.h | 2 +- src/libANGLE/renderer/vulkan/ContextVk.cpp | 50 +++++++++++++++------- src/libANGLE/renderer/vulkan/ContextVk.h | 5 +-- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h index 9e8a16f55..3aa7a54a5 100644 --- a/src/libANGLE/State.h +++ b/src/libANGLE/State.h @@ -568,8 +568,8 @@ class State : angle::NonCopyable DIRTY_BIT_PROGRAM_BINDING, DIRTY_BIT_PROGRAM_EXECUTABLE, // TODO(jmadill): Fine-grained dirty bits for each texture/sampler. - DIRTY_BIT_TEXTURE_BINDINGS, DIRTY_BIT_SAMPLER_BINDINGS, + DIRTY_BIT_TEXTURE_BINDINGS, DIRTY_BIT_IMAGE_BINDINGS, DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING, DIRTY_BIT_UNIFORM_BUFFER_BINDINGS, diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index 386ca6137..3301d95f5 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -1138,8 +1138,20 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl(const gl::Context vk::CommandBuffer *commandBuffer, vk::CommandGraphResource *recorder) { + if (commandGraphEnabled()) + { + ANGLE_TRY(updateActiveTextures(context)); - ANGLE_TRY(updateActiveTextures(context, recorder)); + const gl::ActiveTextureMask &activeTextures = mProgram->getState().getActiveSamplersMask(); + for (size_t textureUnit : activeTextures) + { + vk::TextureUnit &unit = mActiveTextures[textureUnit]; + TextureVk *textureVk = unit.texture; + ASSERT(textureVk); + vk::ImageHelper &image = textureVk->getImage(); + image.addReadDependency(this, recorder); + } + } if (mProgram->hasTextures()) { @@ -2300,8 +2312,9 @@ angle::Result ContextVk::syncState(const gl::Context *context, invalidateVertexAndIndexBuffers(); } - for (size_t dirtyBit : dirtyBits) + for (auto iter = dirtyBits.begin(), endIter = dirtyBits.end(); iter != endIter; ++iter) { + size_t dirtyBit = *iter; switch (dirtyBit) { case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: @@ -2525,7 +2538,9 @@ angle::Result ContextVk::syncState(const gl::Context *context, case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: { invalidateCurrentDefaultUniforms(); - invalidateCurrentTextures(); + ASSERT(gl::State::DIRTY_BIT_TEXTURE_BINDINGS > + gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE); + iter.setLaterBit(gl::State::DIRTY_BIT_TEXTURE_BINDINGS); invalidateCurrentShaderResources(); if (glState.getProgram()->isCompute()) { @@ -2545,11 +2560,15 @@ angle::Result ContextVk::syncState(const gl::Context *context, } break; } - case gl::State::DIRTY_BIT_TEXTURE_BINDINGS: - invalidateCurrentTextures(); - break; case gl::State::DIRTY_BIT_SAMPLER_BINDINGS: - invalidateCurrentTextures(); + { + ASSERT(gl::State::DIRTY_BIT_TEXTURE_BINDINGS > + gl::State::DIRTY_BIT_SAMPLER_BINDINGS); + iter.setLaterBit(gl::State::DIRTY_BIT_TEXTURE_BINDINGS); + break; + } + case gl::State::DIRTY_BIT_TEXTURE_BINDINGS: + ANGLE_TRY(invalidateCurrentTextures(context)); break; case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING: // Nothing to do. @@ -2789,7 +2808,7 @@ void ContextVk::invalidateCurrentDefaultUniforms() } } -void ContextVk::invalidateCurrentTextures() +angle::Result ContextVk::invalidateCurrentTextures(const gl::Context *context) { ASSERT(mProgram); if (mProgram->hasTextures()) @@ -2799,6 +2818,13 @@ void ContextVk::invalidateCurrentTextures() mComputeDirtyBits.set(DIRTY_BIT_TEXTURES); mComputeDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS); } + + if (!commandGraphEnabled()) + { + ANGLE_TRY(updateActiveTextures(context)); + } + + return angle::Result::Continue; } void ContextVk::invalidateCurrentShaderResources() @@ -3201,8 +3227,7 @@ void ContextVk::handleError(VkResult errorCode, mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line); } -angle::Result ContextVk::updateActiveTextures(const gl::Context *context, - vk::CommandGraphResource *recorder) +angle::Result ContextVk::updateActiveTextures(const gl::Context *context) { const gl::State &glState = mState; const gl::Program *program = glState.getProgram(); @@ -3276,11 +3301,6 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context, textureVk->onImageViewUse(&mResourceUseList); - if (commandGraphEnabled()) - { - image.addReadDependency(this, recorder); - } - mActiveTextures[textureUnit].texture = textureVk; mActiveTextures[textureUnit].sampler = samplerVk; // Cache serials from sampler and texture, but re-use texture if no sampler bound diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h index e26c9e8bc..b2bb0324b 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/src/libANGLE/renderer/vulkan/ContextVk.h @@ -691,8 +691,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO void updateFlipViewportDrawFramebuffer(const gl::State &glState); void updateFlipViewportReadFramebuffer(const gl::State &glState); - angle::Result updateActiveTextures(const gl::Context *context, - vk::CommandGraphResource *recorder); + angle::Result updateActiveTextures(const gl::Context *context); angle::Result updateActiveImages(const gl::Context *context, vk::CommandGraphResource *recorder); angle::Result updateDefaultAttribute(size_t attribIndex); @@ -708,7 +707,7 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO } void invalidateCurrentDefaultUniforms(); - void invalidateCurrentTextures(); + angle::Result invalidateCurrentTextures(const gl::Context *context); void invalidateCurrentShaderResources(); void invalidateGraphicsDriverUniforms(); void invalidateDriverUniforms();