Vulkan: Optimize ContextVk::setupDraw.
This improves performance significantly in the Vulkan CPU overhead
test.
Bug: angleproject:2786
Change-Id: I911bc66a6b2d11dd3848ffa90927b314aeadfc24
Reviewed-on: https://chromium-review.googlesource.com/1194301
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 491b699..72ce9a8 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -354,6 +354,8 @@
bool hasAttachedShader() const;
+ const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; }
+
private:
friend class MemoryProgramCache;
friend class Program;
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 7cff59d..e3152d2 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -257,21 +257,16 @@
const DirtyBits &dirtyBitsMask,
vk::CommandBuffer **commandBufferOut)
{
+ // Set any dirty bits that depend on draw call parameters or other objects.
if (drawCallParams.mode() != mCurrentDrawMode)
{
invalidateCurrentPipeline();
mCurrentDrawMode = drawCallParams.mode();
}
- const gl::State &state = mState.getState();
- const gl::Program *programGL = state.getProgram();
-
- vk::RecordingMode mode;
- ANGLE_TRY(mDrawFramebuffer->getCommandBufferForDraw(this, commandBufferOut, &mode));
-
- // Set any dirty bits that depend on draw call parameters or other objects.
- if (mode == vk::RecordingMode::Start)
+ if (!mDrawFramebuffer->appendToStartedRenderPass(mRenderer, commandBufferOut))
{
+ ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, commandBufferOut));
mDirtyBits |= mNewCommandBufferDirtyBits;
}
@@ -317,7 +312,7 @@
// TODO(jmadill): Should probably merge this for loop with programVk's descriptor
// update.
- for (size_t textureIndex : programGL->getActiveSamplersMask())
+ for (size_t textureIndex : mProgram->getState().getActiveSamplersMask())
{
// Ensure any writes to the textures are flushed before we read from them.
TextureVk *textureVk = mActiveTextures[textureIndex];
@@ -348,7 +343,7 @@
case DIRTY_BIT_VERTEX_BUFFERS:
{
BindNonNullVertexBufferRanges(*commandBufferOut,
- programGL->getActiveAttribLocationsMask(),
+ mProgram->getState().getActiveAttribLocationsMask(),
mProgram->getState().getMaxActiveAttribLocation(),
mVertexArray->getCurrentArrayBufferHandles(),
mVertexArray->getCurrentArrayBufferOffsets());
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 0b72091..e1ad661 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -1087,6 +1087,12 @@
return angle::Result::Continue();
}
+ return startNewRenderPass(contextVk, commandBufferOut);
+}
+
+angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
+ vk::CommandBuffer **commandBufferOut)
+{
vk::Framebuffer *framebuffer = nullptr;
ANGLE_TRY(getFramebuffer(contextVk, &framebuffer));
@@ -1120,7 +1126,6 @@
gl::Rectangle renderArea =
gl::Rectangle(0, 0, mState.getDimensions().width, mState.getDimensions().height);
- *modeOut = vk::RecordingMode::Start;
return beginRenderPass(contextVk, *framebuffer, renderArea, mRenderPassDesc.value(),
attachmentClearValues, commandBufferOut);
}
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.h b/src/libANGLE/renderer/vulkan/FramebufferVk.h
index 133eb73..059f96a 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.h
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.h
@@ -90,9 +90,6 @@
GLfloat *xy) const override;
RenderTargetVk *getDepthStencilRenderTarget() const;
const vk::RenderPassDesc &getRenderPassDesc();
- angle::Result getCommandBufferForDraw(ContextVk *contextVk,
- vk::CommandBuffer **commandBufferOut,
- vk::RecordingMode *modeOut);
// Internal helper function for readPixels operations.
angle::Result readPixelsImpl(ContextVk *contextVk,
@@ -107,11 +104,21 @@
gl::DrawBufferMask getEmulatedAlphaAttachmentMask();
RenderTargetVk *getColorReadRenderTarget() const;
+ // This will clear the current write operation if it is complete.
+ using CommandGraphResource::appendToStartedRenderPass;
+
+ angle::Result startNewRenderPass(ContextVk *context, vk::CommandBuffer **commandBufferOut);
+
private:
FramebufferVk(RendererVk *renderer,
const gl::FramebufferState &state,
WindowSurfaceVk *backbuffer);
+ // Helper for appendToStarted/else startNewRenderPass.
+ angle::Result getCommandBufferForDraw(ContextVk *contextVk,
+ vk::CommandBuffer **commandBufferOut,
+ vk::RecordingMode *modeOut);
+
// The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'.
void blitWithCommand(vk::CommandBuffer *commandBuffer,
const gl::Rectangle &readRectIn,