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 <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Tobin Ehlis <tobine@google.com>
This commit is contained in:
Jamie Madill 2020-01-24 09:55:01 -05:00 коммит произвёл Commit Bot
Родитель 564eb6f2a9
Коммит 52ef28dcfe
3 изменённых файлов: 38 добавлений и 19 удалений

Просмотреть файл

@ -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,

Просмотреть файл

@ -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

Просмотреть файл

@ -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();