Vulkan: Output the reason for RP closure in command buffer

To make it easier when viewing the command buffer in a graphics
debugger, this change inserts a marker just before closing the render
pass that specifies why the render pass was closed.

Bug: angleproject:2472
Change-Id: I862e500cd58332d6e199c853315c560fe6a73dc2
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3265609
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Tim Van Patten <timvp@google.com>
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Shahbaz Youssefi 2021-11-06 01:09:26 -04:00 коммит произвёл Angle LUCI CQ
Родитель a9f2e87ec9
Коммит dbc0c646c4
22 изменённых файлов: 351 добавлений и 142 удалений

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

@ -64,15 +64,6 @@ struct FeaturesVk : FeatureSetBase
"The depth value is not clamped to [0,1] for floating point depth buffers.", &members,
"http://anglebug.com/3970"};
// On some android devices, the memory barrier between the compute shader that converts vertex
// attributes and the vertex shader that reads from it is ineffective. Only known workaround is
// to perform a flush after the conversion. http://anglebug.com/3016
Feature flushAfterVertexConversion = {
"flushAfterVertexConversion", FeatureCategory::VulkanWorkarounds,
"The memory barrier between the compute shader that converts vertex attributes and the "
"vertex shader that reads from it is ineffective",
&members, "http://anglebug.com/3016"};
Feature supportsRenderpass2 = {"supportsRenderpass2", FeatureCategory::VulkanFeatures,
"VkDevice supports the VK_KHR_create_renderpass2 extension",
&members};

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

@ -577,8 +577,9 @@ angle::Result BufferVk::handleDeviceLocalBufferMap(ContextVk *contextVk,
VkBufferCopy copyRegion = {mBufferOffset + offset, mHostVisibleBufferOffset, size};
ANGLE_TRY(hostVisibleBuffer->copyFromBuffer(contextVk, mBuffer, 1, &copyRegion));
ANGLE_TRY(
hostVisibleBuffer->waitForIdle(contextVk, "GPU stall due to mapping device local buffer"));
ANGLE_TRY(hostVisibleBuffer->waitForIdle(contextVk,
"GPU stall due to mapping device local buffer",
RenderPassClosureReason::DeviceLocalBufferMap));
return angle::Result::Continue;
}
@ -699,7 +700,8 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk,
// If there are pending commands for the resource, flush them.
if (mBuffer->usedInRecordedCommands())
{
ANGLE_TRY(contextVk->flushImpl(nullptr));
ANGLE_TRY(
contextVk->flushImpl(nullptr, RenderPassClosureReason::BufferWriteThenMap));
}
ANGLE_TRY(mBuffer->finishGPUWriteCommands(contextVk));
}
@ -742,7 +744,8 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk,
else if ((access & GL_MAP_UNSYNCHRONIZED_BIT) == 0)
{
ANGLE_TRY(mBuffer->waitForIdle(
contextVk, "GPU stall due to mapping buffer in use by the GPU"));
contextVk, "GPU stall due to mapping buffer in use by the GPU",
RenderPassClosureReason::BufferInUseWhenSynchronizedMap));
}
}

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

@ -198,24 +198,18 @@ bool IsRenderPassStartedAndUsesImage(const vk::CommandBufferHelper &renderPassCo
//
// Note: these are mat2's that are appropriately padded (4 floats per row).
using PreRotationMatrixValues = std::array<float, 8>;
constexpr angle::PackedEnumMap<rx::SurfaceRotation,
PreRotationMatrixValues,
angle::EnumSize<rx::SurfaceRotation>()>
kFragRotationMatrices = {
{{rx::SurfaceRotation::Identity, {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{rx::SurfaceRotation::Rotated90Degrees,
{{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}},
{rx::SurfaceRotation::Rotated180Degrees,
{{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{rx::SurfaceRotation::Rotated270Degrees,
{{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}},
{rx::SurfaceRotation::FlippedIdentity, {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{rx::SurfaceRotation::FlippedRotated90Degrees,
{{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}},
{rx::SurfaceRotation::FlippedRotated180Degrees,
{{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{rx::SurfaceRotation::FlippedRotated270Degrees,
{{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}}}};
constexpr angle::PackedEnumMap<rx::SurfaceRotation, PreRotationMatrixValues> kFragRotationMatrices =
{{{SurfaceRotation::Identity, {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{SurfaceRotation::Rotated90Degrees, {{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}},
{SurfaceRotation::Rotated180Degrees, {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{SurfaceRotation::Rotated270Degrees, {{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}},
{SurfaceRotation::FlippedIdentity, {{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{SurfaceRotation::FlippedRotated90Degrees,
{{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}},
{SurfaceRotation::FlippedRotated180Degrees,
{{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}}},
{SurfaceRotation::FlippedRotated270Degrees,
{{0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f}}}}};
bool IsRotatedAspectRatio(SurfaceRotation rotation)
{
@ -337,6 +331,102 @@ void AppendBufferVectorToDesc(vk::ShaderBuffersDescriptorDesc *desc,
desc->append32BitValue(std::numeric_limits<uint32_t>::max());
}
constexpr angle::PackedEnumMap<RenderPassClosureReason, const char *> kRenderPassClosureReason = {{
{RenderPassClosureReason::AlreadySpecifiedElsewhere, nullptr},
{RenderPassClosureReason::ContextDestruction, "Render pass closed due to context destruction"},
{RenderPassClosureReason::ContextChange, "Render pass closed due to context change"},
{RenderPassClosureReason::GLFlush, "Render pass closed due to glFlush()"},
{RenderPassClosureReason::GLFinish, "Render pass closed due to glFinish()"},
{RenderPassClosureReason::EGLSwapBuffers, "Render pass closed due to eglSwapBuffers()"},
{RenderPassClosureReason::EGLWaitClient, "Render pass closed due to eglWaitClient()"},
{RenderPassClosureReason::FramebufferBindingChange,
"Render pass closed due to framebuffer binding change"},
{RenderPassClosureReason::FramebufferChange, "Render pass closed due to framebuffer change"},
{RenderPassClosureReason::NewRenderPass,
"Render pass closed due to starting a new render pass"},
{RenderPassClosureReason::BufferUseThenXfbWrite,
"Render pass closed due to buffer use as transform feedback output after prior use in render "
"pass"},
{RenderPassClosureReason::XfbWriteThenVertexIndexBuffer,
"Render pass closed due to transform feedback buffer use as vertex/index input"},
{RenderPassClosureReason::XfbWriteThenIndirectDrawBuffer,
"Render pass closed due to indirect draw buffer previously used as transform feedback output "
"in render pass"},
{RenderPassClosureReason::XfbResumeAfterDrawBasedClear,
"Render pass closed due to transform feedback resume after clear through draw"},
{RenderPassClosureReason::DepthStencilUseInFeedbackLoop,
"Render pass closed due to depth/stencil attachment use under feedback loop"},
{RenderPassClosureReason::DepthStencilWriteAfterFeedbackLoop,
"Render pass closed due to depth/stencil attachment write after feedback loop"},
{RenderPassClosureReason::PipelineBindWhileXfbActive,
"Render pass closed due to graphics pipeline change while transform feedback is active"},
{RenderPassClosureReason::BufferWriteThenMap,
"Render pass closed due to mapping buffer being written to by said render pass"},
{RenderPassClosureReason::BufferUseThenOutOfRPRead,
"Render pass closed due to non-render-pass read of buffer that was written to in render pass"},
{RenderPassClosureReason::BufferUseThenOutOfRPWrite,
"Render pass closed due to non-render-pass write of buffer that was used in render pass"},
{RenderPassClosureReason::ImageUseThenOutOfRPRead,
"Render pass closed due to non-render-pass read of image that was used in render pass"},
{RenderPassClosureReason::ImageUseThenOutOfRPWrite,
"Render pass closed due to non-render-pass write of image that was used in render pass"},
{RenderPassClosureReason::XfbWriteThenComputeRead,
"Render pass closed due to compute read of buffer previously used as transform feedback "
"output in render pass"},
{RenderPassClosureReason::XfbWriteThenIndirectDispatchBuffer,
"Render pass closed due to indirect dispatch buffer previously used as transform feedback "
"output in render pass"},
{RenderPassClosureReason::ImageAttachmentThenComputeRead,
"Render pass closed due to compute read of image previously used as framebuffer attachment in "
"render pass"},
{RenderPassClosureReason::GetQueryResult, "Render pass closed due to getting query result"},
{RenderPassClosureReason::BeginNonRenderPassQuery,
"Render pass closed due to non-render-pass query begin"},
{RenderPassClosureReason::EndNonRenderPassQuery,
"Render pass closed due to non-render-pass query end"},
{RenderPassClosureReason::TimestampQuery, "Render pass closed due to timestamp query"},
{RenderPassClosureReason::GLReadPixels, "Render pass closed due to glReadPixels()"},
{RenderPassClosureReason::BufferUseThenReleaseToExternal,
"Render pass closed due to buffer (used by render pass) release to external"},
{RenderPassClosureReason::ImageUseThenReleaseToExternal,
"Render pass closed due to image (used by render pass) release to external"},
{RenderPassClosureReason::BufferInUseWhenSynchronizedMap,
"Render pass closed due to mapping buffer in use by GPU without GL_MAP_UNSYNCHRONIZED_BIT"},
{RenderPassClosureReason::ImageOrphan, "Render pass closed due to EGL image being orphaned"},
{RenderPassClosureReason::GLMemoryBarrierThenStorageResource,
"Render pass closed due to glMemoryBarrier before storage output in render pass"},
{RenderPassClosureReason::StorageResourceUseThenGLMemoryBarrier,
"Render pass closed due to glMemoryBarrier after storage output in render pass"},
{RenderPassClosureReason::ExternalSemaphoreSignal,
"Render pass closed due to external semaphore signal"},
{RenderPassClosureReason::SyncObjectInit, "Render pass closed due to sync object insertion"},
{RenderPassClosureReason::SyncObjectWithFdInit,
"Render pass closed due to sync object with fd insertion"},
{RenderPassClosureReason::SyncObjectClientWait,
"Render pass closed due to sync object client wait"},
{RenderPassClosureReason::SyncObjectServerWait,
"Render pass closed due to sync object server wait"},
{RenderPassClosureReason::XfbPause, "Render pass closed due to transform feedback pause"},
{RenderPassClosureReason::FramebufferFetchEmulation,
"Render pass closed due to framebuffer fetch emulation"},
{RenderPassClosureReason::ColorBufferInvalidate,
"Render pass closed due to glInvalidateFramebuffer() on a color buffer"},
{RenderPassClosureReason::GenerateMipmapOnCPU,
"Render pass closed due to fallback to CPU when generating mipmaps"},
{RenderPassClosureReason::CopyTextureOnCPU,
"Render pass closed due to fallback to CPU when copying texture"},
{RenderPassClosureReason::TextureReformatToRenderable,
"Render pass closed due to reformatting texture to a renderable fallback"},
{RenderPassClosureReason::DeviceLocalBufferMap,
"Render pass closed due to mapping device local buffer"},
{RenderPassClosureReason::TemporaryForImageClear,
"Temporary render pass used for image clear closed"},
{RenderPassClosureReason::TemporaryForImageCopy,
"Temporary render pass used for image copy closed"},
{RenderPassClosureReason::OverlayFontCreation,
"Render pass closed due to creating Overlay font"},
}};
} // anonymous namespace
// Not necessary once upgraded to C++17.
@ -363,10 +453,21 @@ void ContextVk::flushDescriptorSetUpdates()
mDescriptorImageInfos.clear();
}
ANGLE_INLINE void ContextVk::onRenderPassFinished()
ANGLE_INLINE void ContextVk::onRenderPassFinished(RenderPassClosureReason reason)
{
pauseRenderPassQueriesIfActive();
if (mRenderPassCommandBuffer != nullptr)
{
// If reason is specified, add it to the command buffer right before ending the render pass,
// so it will show up in GPU debuggers.
const char *reasonText = kRenderPassClosureReason[reason];
if (reasonText)
{
insertEventMarkerImpl(reasonText);
}
}
mRenderPassCommandBuffer = nullptr;
mGraphicsDirtyBits.set(DIRTY_BIT_RENDER_PASS);
}
@ -586,7 +687,7 @@ void ContextVk::onDestroy(const gl::Context *context)
mIncompleteTextures.onDestroy(context);
// Flush and complete current outstanding work before destruction.
(void)finishImpl();
(void)finishImpl(RenderPassClosureReason::ContextDestruction);
VkDevice device = getDevice();
@ -810,12 +911,12 @@ angle::Result ContextVk::flush(const gl::Context *context)
return angle::Result::Continue;
}
return flushImpl(nullptr);
return flushImpl(nullptr, RenderPassClosureReason::GLFlush);
}
angle::Result ContextVk::finish(const gl::Context *context)
{
return finishImpl();
return finishImpl(RenderPassClosureReason::GLFinish);
}
angle::Result ContextVk::setupDraw(const gl::Context *context,
@ -974,7 +1075,8 @@ angle::Result ContextVk::setupIndirectDraw(const gl::Context *context,
// feedback.
if (mCurrentTransformFeedbackBuffers.contains(indirectBuffer))
{
ANGLE_TRY(flushCommandsAndEndRenderPass());
ANGLE_TRY(
flushCommandsAndEndRenderPass(RenderPassClosureReason::XfbWriteThenIndirectDrawBuffer));
}
ANGLE_TRY(setupDraw(context, mode, firstVertex, vertexCount, instanceCount,
@ -1245,11 +1347,14 @@ angle::Result ContextVk::handleDirtyMemoryBarrierImpl(DirtyBits::Iterator *dirty
// dirty bits directly (if called during handling of compute dirty bits).
if (dirtyBitsIterator)
{
return flushDirtyGraphicsRenderPass(dirtyBitsIterator, dirtyBitMask);
return flushDirtyGraphicsRenderPass(
dirtyBitsIterator, dirtyBitMask,
RenderPassClosureReason::GLMemoryBarrierThenStorageResource);
}
else
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(
RenderPassClosureReason::GLMemoryBarrierThenStorageResource);
}
}
@ -1414,7 +1519,8 @@ angle::Result ContextVk::handleDirtyGraphicsPipelineDesc(DirtyBits::Iterator *di
// feedback counter buffer.
if (mRenderPassCommands->started() && mRenderPassCommands->isTransformFeedbackActiveUnpaused())
{
ANGLE_TRY(flushDirtyGraphicsRenderPass(dirtyBitsIterator, dirtyBitMask));
ANGLE_TRY(flushDirtyGraphicsRenderPass(
dirtyBitsIterator, dirtyBitMask, RenderPassClosureReason::PipelineBindWhileXfbActive));
dirtyBitsIterator->setLaterBit(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME);
}
@ -1433,7 +1539,8 @@ angle::Result ContextVk::handleDirtyGraphicsRenderPass(DirtyBits::Iterator *dirt
if (mRenderPassCommands->started())
{
ANGLE_TRY(flushDirtyGraphicsRenderPass(dirtyBitsIterator,
dirtyBitMask & ~DirtyBits{DIRTY_BIT_RENDER_PASS}));
dirtyBitMask & ~DirtyBits{DIRTY_BIT_RENDER_PASS},
RenderPassClosureReason::AlreadySpecifiedElsewhere));
}
gl::Rectangle scissoredRenderArea = mDrawFramebuffer->getRotatedScissoredRenderArea(this);
@ -2162,7 +2269,7 @@ angle::Result ContextVk::submitFrame(const vk::Semaphore *signalSemaphore, Seria
getShareGroupVk()->releaseResourceUseLists(),
std::move(mCurrentGarbage), &mCommandPool, submitSerialOut));
onRenderPassFinished();
onRenderPassFinished(RenderPassClosureReason::AlreadySpecifiedElsewhere);
mComputeDirtyBits |= mNewComputeCommandBufferDirtyBits;
if (mGpuEventsEnabled)
@ -3468,7 +3575,8 @@ angle::Result ContextVk::invalidateProgramExecutableHelper(const gl::Context *co
if (mLastProgramUsesFramebufferFetch != executable->usesFramebufferFetch())
{
mLastProgramUsesFramebufferFetch = executable->usesFramebufferFetch();
ANGLE_TRY(flushCommandsAndEndRenderPass());
ANGLE_TRY(
flushCommandsAndEndRenderPass(RenderPassClosureReason::FramebufferFetchEmulation));
ASSERT(mDrawFramebuffer);
mDrawFramebuffer->onSwitchProgramFramebufferFetch(this,
@ -3682,7 +3790,7 @@ angle::Result ContextVk::syncState(const gl::Context *context,
// as some optimizations in non-draw commands require the render pass to remain
// open, such as invalidate or blit. Note that we always start a new command buffer
// because we currently can only support one open RenderPass at a time.
onRenderPassFinished();
onRenderPassFinished(RenderPassClosureReason::FramebufferBindingChange);
if (mRenderer->getFeatures().preferSubmitAtFBOBoundary.enabled)
{
// This will behave as if user called glFlush, but the actual flush will be
@ -3941,7 +4049,7 @@ angle::Result ContextVk::onMakeCurrent(const gl::Context *context)
angle::Result ContextVk::onUnMakeCurrent(const gl::Context *context)
{
ANGLE_TRY(flushImpl(nullptr));
ANGLE_TRY(flushImpl(nullptr, RenderPassClosureReason::ContextChange));
mCurrentWindowSurface = nullptr;
return angle::Result::Continue;
}
@ -4289,7 +4397,7 @@ angle::Result ContextVk::onFramebufferChange(FramebufferVk *framebufferVk, gl::C
// Always consider the render pass finished. FramebufferVk::syncState (caller of this function)
// normally closes the render pass, except for blit to allow an optimization. The following
// code nevertheless must treat the render pass closed.
onRenderPassFinished();
onRenderPassFinished(RenderPassClosureReason::FramebufferChange);
// Ensure that the pipeline description is updated.
if (mGraphicsPipelineDesc->getRasterizationSamples() !=
@ -4398,7 +4506,7 @@ angle::Result ContextVk::onBeginTransformFeedback(
if (shouldEndRenderPass)
{
ANGLE_TRY(flushCommandsAndEndRenderPass());
ANGLE_TRY(flushCommandsAndEndRenderPass(RenderPassClosureReason::BufferUseThenXfbWrite));
}
populateTransformFeedbackBufferSet(bufferCount, buffers);
@ -4444,7 +4552,7 @@ angle::Result ContextVk::onPauseTransformFeedback()
// settings in the render pass.
if (mRenderPassCommands->isTransformFeedbackActiveUnpaused())
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(RenderPassClosureReason::XfbPause);
}
}
else if (getFeatures().emulateTransformFeedback.enabled)
@ -4512,7 +4620,8 @@ angle::Result ContextVk::dispatchComputeIndirect(const gl::Context *context, GLi
// feedback.
if (mCurrentTransformFeedbackBuffers.contains(&buffer))
{
ANGLE_TRY(flushCommandsAndEndRenderPass());
ANGLE_TRY(flushCommandsAndEndRenderPass(
RenderPassClosureReason::XfbWriteThenIndirectDispatchBuffer));
}
ANGLE_TRY(setupDispatch(context));
@ -4589,7 +4698,8 @@ angle::Result ContextVk::memoryBarrier(const gl::Context *context, GLbitfield ba
if (mRenderPassCommands->hasShaderStorageOutput())
{
// Break the render pass if necessary as future non-draw commands can't know if they should.
ANGLE_TRY(flushCommandsAndEndRenderPass());
ANGLE_TRY(flushCommandsAndEndRenderPass(
RenderPassClosureReason::StorageResourceUseThenGLMemoryBarrier));
}
else if (mOutsideRenderPassCommands->hasShaderStorageOutput())
{
@ -5078,7 +5188,8 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context, gl::Co
{
// To enter depth feedback loop, we must flush and start a new renderpass.
// Otherwise it will stick with writable layout and cause validation error.
ANGLE_TRY(flushCommandsAndEndRenderPass());
ANGLE_TRY(flushCommandsAndEndRenderPass(
RenderPassClosureReason::DepthStencilUseInFeedbackLoop));
}
else
{
@ -5279,14 +5390,16 @@ bool ContextVk::hasRecordedCommands()
return !mOutsideRenderPassCommands->empty() || mRenderPassCommands->started();
}
angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore,
RenderPassClosureReason renderPassClosureReason)
{
Serial unusedSerial;
return flushAndGetSerial(signalSemaphore, &unusedSerial);
return flushAndGetSerial(signalSemaphore, &unusedSerial, renderPassClosureReason);
}
angle::Result ContextVk::flushAndGetSerial(const vk::Semaphore *signalSemaphore,
Serial *submitSerialOut)
Serial *submitSerialOut,
RenderPassClosureReason renderPassClosureReason)
{
ANGLE_TRACE_EVENT0("gpu.angle", "ContextVk::flushImpl");
@ -5295,7 +5408,7 @@ angle::Result ContextVk::flushAndGetSerial(const vk::Semaphore *signalSemaphore,
mHasDeferredFlush = false;
// Avoid calling vkQueueSubmit() twice, since submitFrame() below will do that.
ANGLE_TRY(flushCommandsAndEndRenderPassWithoutQueueSubmit());
ANGLE_TRY(flushCommandsAndEndRenderPassWithoutQueueSubmit(renderPassClosureReason));
if (mIsAnyHostVisibleBufferWritten)
{
@ -5366,11 +5479,11 @@ angle::Result ContextVk::flushAndGetSerial(const vk::Semaphore *signalSemaphore,
return angle::Result::Continue;
}
angle::Result ContextVk::finishImpl()
angle::Result ContextVk::finishImpl(RenderPassClosureReason renderPassClosureReason)
{
ANGLE_TRACE_EVENT0("gpu.angle", "ContextVk::finishImpl");
ANGLE_TRY(flushImpl(nullptr));
ANGLE_TRY(flushImpl(nullptr, renderPassClosureReason));
ANGLE_TRY(mRenderer->finish(this, hasProtectedContent()));
clearAllGarbage();
@ -5578,7 +5691,8 @@ angle::Result ContextVk::onBufferReleaseToExternal(const vk::BufferHelper &buffe
{
if (mRenderPassCommands->usesBuffer(buffer))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(
RenderPassClosureReason::BufferUseThenReleaseToExternal);
}
return angle::Result::Continue;
}
@ -5587,7 +5701,8 @@ angle::Result ContextVk::onImageReleaseToExternal(const vk::ImageHelper &image)
{
if (IsRenderPassStartedAndUsesImage(*mRenderPassCommands, image))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(
RenderPassClosureReason::ImageUseThenReleaseToExternal);
}
return angle::Result::Continue;
}
@ -5602,8 +5717,9 @@ angle::Result ContextVk::beginNewRenderPass(
const vk::PackedClearValuesArray &clearValues,
vk::CommandBuffer **commandBufferOut)
{
// Next end any currently outstanding renderPass
ANGLE_TRY(flushCommandsAndEndRenderPass());
// Next end any currently outstanding render pass. The render pass is normally closed before
// reaching here for various reasons, except typically when UtilsVk needs to start one.
ANGLE_TRY(flushCommandsAndEndRenderPass(RenderPassClosureReason::NewRenderPass));
mPerfCounters.renderPasses++;
return mRenderPassCommands->beginRenderPass(
@ -5684,7 +5800,8 @@ uint32_t ContextVk::getCurrentViewCount() const
return drawFBO->getRenderPassDesc().viewCount();
}
angle::Result ContextVk::flushCommandsAndEndRenderPassImpl(QueueSubmitType queueSubmit)
angle::Result ContextVk::flushCommandsAndEndRenderPassImpl(QueueSubmitType queueSubmit,
RenderPassClosureReason reason)
{
// Ensure we flush the RenderPass *after* the prior commands.
ANGLE_TRY(flushOutsideRenderPassCommands());
@ -5692,7 +5809,7 @@ angle::Result ContextVk::flushCommandsAndEndRenderPassImpl(QueueSubmitType queue
if (!mRenderPassCommands->started())
{
onRenderPassFinished();
onRenderPassFinished(RenderPassClosureReason::AlreadySpecifiedElsewhere);
return angle::Result::Continue;
}
@ -5716,7 +5833,7 @@ angle::Result ContextVk::flushCommandsAndEndRenderPassImpl(QueueSubmitType queue
populateTransformFeedbackBufferSet(xfbBufferCount, transformFeedbackVk->getBufferHelpers());
}
onRenderPassFinished();
onRenderPassFinished(reason);
if (mGpuEventsEnabled)
{
@ -5756,28 +5873,30 @@ angle::Result ContextVk::flushCommandsAndEndRenderPassImpl(QueueSubmitType queue
if (mHasDeferredFlush && queueSubmit == QueueSubmitType::PerformQueueSubmit)
{
// If we have deferred glFlush call in the middle of renderpass, flush them now.
ANGLE_TRY(flushImpl(nullptr));
ANGLE_TRY(flushImpl(nullptr, RenderPassClosureReason::AlreadySpecifiedElsewhere));
}
return angle::Result::Continue;
}
angle::Result ContextVk::flushCommandsAndEndRenderPass()
angle::Result ContextVk::flushCommandsAndEndRenderPass(RenderPassClosureReason reason)
{
return flushCommandsAndEndRenderPassImpl(QueueSubmitType::PerformQueueSubmit);
return flushCommandsAndEndRenderPassImpl(QueueSubmitType::PerformQueueSubmit, reason);
}
angle::Result ContextVk::flushCommandsAndEndRenderPassWithoutQueueSubmit()
angle::Result ContextVk::flushCommandsAndEndRenderPassWithoutQueueSubmit(
RenderPassClosureReason reason)
{
return flushCommandsAndEndRenderPassImpl(QueueSubmitType::SkipQueueSubmit);
return flushCommandsAndEndRenderPassImpl(QueueSubmitType::SkipQueueSubmit, reason);
}
angle::Result ContextVk::flushDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
DirtyBits dirtyBitMask)
DirtyBits dirtyBitMask,
RenderPassClosureReason reason)
{
ASSERT(mRenderPassCommands->started());
ANGLE_TRY(flushCommandsAndEndRenderPassImpl(QueueSubmitType::PerformQueueSubmit));
ANGLE_TRY(flushCommandsAndEndRenderPassImpl(QueueSubmitType::PerformQueueSubmit, reason));
// Set dirty bits that need processing on new render pass on the dirty bits iterator that's
// being processed right now.
@ -6158,7 +6277,8 @@ angle::Result ContextVk::updateRenderPassDepthStencilAccess()
// renderpass here. Otherwise, updating it to writeable layout will produce a writable
// feedback loop that is illegal in vulkan and will trigger validation errors that depth
// texture is using the writable layout.
ANGLE_TRY(flushCommandsAndEndRenderPass());
ANGLE_TRY(flushCommandsAndEndRenderPass(
RenderPassClosureReason::DepthStencilWriteAfterFeedbackLoop));
// Clear read-only depth feedback mode.
mDrawFramebuffer->setReadOnlyDepthFeedbackLoopMode(false);
}
@ -6260,7 +6380,7 @@ angle::Result ContextVk::flushCommandBuffersIfNecessary(const vk::CommandBufferA
// the render pass. http://anglebug.com/4984
if (IsRenderPassStartedAndUsesImage(*mRenderPassCommands, *imageAccess.image))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(RenderPassClosureReason::ImageUseThenOutOfRPRead);
}
}
@ -6269,7 +6389,7 @@ angle::Result ContextVk::flushCommandBuffersIfNecessary(const vk::CommandBufferA
{
if (IsRenderPassStartedAndUsesImage(*mRenderPassCommands, *imageWrite.access.image))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(RenderPassClosureReason::ImageUseThenOutOfRPWrite);
}
}
@ -6280,7 +6400,7 @@ angle::Result ContextVk::flushCommandBuffersIfNecessary(const vk::CommandBufferA
{
if (mRenderPassCommands->usesBufferForWrite(*bufferAccess.buffer))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(RenderPassClosureReason::BufferUseThenOutOfRPRead);
}
else if (mOutsideRenderPassCommands->usesBufferForWrite(*bufferAccess.buffer))
{
@ -6293,7 +6413,8 @@ angle::Result ContextVk::flushCommandBuffersIfNecessary(const vk::CommandBufferA
{
if (mRenderPassCommands->usesBuffer(*bufferAccess.buffer))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(
RenderPassClosureReason::BufferUseThenOutOfRPWrite);
}
else if (mOutsideRenderPassCommands->usesBuffer(*bufferAccess.buffer))
{
@ -6349,7 +6470,8 @@ angle::Result ContextVk::endRenderPassIfComputeReadAfterTransformFeedbackWrite()
vk::GetImpl(bufferBinding.get())->getBufferAndOffset(&bufferOffset);
if (mCurrentTransformFeedbackBuffers.contains(&buffer))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(
RenderPassClosureReason::XfbWriteThenComputeRead);
}
}
}
@ -6385,7 +6507,8 @@ angle::Result ContextVk::endRenderPassIfComputeReadAfterAttachmentWrite()
if (IsRenderPassStartedAndUsesImage(*mRenderPassCommands, image))
{
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(
RenderPassClosureReason::ImageAttachmentThenComputeRead);
}
}

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

@ -63,7 +63,7 @@ enum class GraphicsEventCmdBuf
EnumCount = 3,
};
enum QueueSubmitType
enum class QueueSubmitType
{
PerformQueueSubmit,
SkipQueueSubmit,
@ -407,9 +407,12 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
angle::Result onIndexBufferChange(const vk::BufferHelper *currentIndexBuffer);
angle::Result flushImpl(const vk::Semaphore *semaphore);
angle::Result flushAndGetSerial(const vk::Semaphore *semaphore, Serial *submitSerialOut);
angle::Result finishImpl();
angle::Result flushImpl(const vk::Semaphore *semaphore,
RenderPassClosureReason renderPassClosureReason);
angle::Result flushAndGetSerial(const vk::Semaphore *semaphore,
Serial *submitSerialOut,
RenderPassClosureReason renderPassClosureReason);
angle::Result finishImpl(RenderPassClosureReason renderPassClosureReason);
void addWaitSemaphore(VkSemaphore semaphore, VkPipelineStageFlags stageMask);
@ -575,8 +578,8 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
vk::CommandBuffer **commandBufferOut,
bool *renderPassDescChangedOut);
void startNextSubpass();
angle::Result flushCommandsAndEndRenderPass();
angle::Result flushCommandsAndEndRenderPassWithoutQueueSubmit();
angle::Result flushCommandsAndEndRenderPass(RenderPassClosureReason reason);
angle::Result flushCommandsAndEndRenderPassWithoutQueueSubmit(RenderPassClosureReason reason);
angle::Result syncExternalMemory();
@ -923,11 +926,13 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
// flushCommandsAndEndRenderPass() and flushDirtyGraphicsRenderPass() will set the dirty bits
// directly or through the iterator respectively. Outside those two functions, this shouldn't
// be called directly.
angle::Result flushCommandsAndEndRenderPassImpl(QueueSubmitType queueSubmit);
angle::Result flushCommandsAndEndRenderPassImpl(QueueSubmitType queueSubmit,
RenderPassClosureReason reason);
angle::Result flushDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
DirtyBits dirtyBitMask);
DirtyBits dirtyBitMask,
RenderPassClosureReason reason);
void onRenderPassFinished();
void onRenderPassFinished(RenderPassClosureReason reason);
void initIndexTypeMap();
@ -1204,7 +1209,7 @@ ANGLE_INLINE angle::Result ContextVk::endRenderPassIfTransformFeedbackBuffer(
return angle::Result::Continue;
}
return flushCommandsAndEndRenderPass();
return flushCommandsAndEndRenderPass(RenderPassClosureReason::XfbWriteThenVertexIndexBuffer);
}
ANGLE_INLINE angle::Result ContextVk::onIndexBufferChange(

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

@ -111,7 +111,8 @@ egl::Error DisplayVk::waitClient(const gl::Context *context)
{
ANGLE_TRACE_EVENT0("gpu.angle", "DisplayVk::waitClient");
ContextVk *contextVk = vk::GetImpl(context);
return angle::ToEGL(contextVk->finishImpl(), this, EGL_BAD_ACCESS);
return angle::ToEGL(contextVk->finishImpl(RenderPassClosureReason::EGLWaitClient), this,
EGL_BAD_ACCESS);
}
egl::Error DisplayVk::waitNative(const gl::Context *context, EGLint engine)

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

@ -1419,7 +1419,8 @@ angle::Result FramebufferVk::resolveColorWithSubpass(ContextVk *contextVk,
// End the render pass now since we don't (yet) support subpass dependencies.
drawRenderTarget->onColorResolve(contextVk, mCurrentFramebufferDesc.getLayerCount());
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
RenderPassClosureReason::AlreadySpecifiedElsewhere));
// Remove the resolve attachment from the source framebuffer.
srcFramebufferVk->removeColorResolveAttachment(readColorIndexGL);
@ -1608,7 +1609,8 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
//
// Since we are not aware of any application that invalidates a color buffer and
// continues to draw to it, we leave that unoptimized.
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
RenderPassClosureReason::ColorBufferInvalidate));
}
}
@ -1933,7 +1935,8 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
// multisampled-render-to-texture, then srcFramebuffer->getSamples(context) gives > 1, but
// there's no resolve happening as the read buffer's single sampled image will be used as
// blit src. FramebufferVk::blit() will handle those details for us.
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(
contextVk->flushCommandsAndEndRenderPass(RenderPassClosureReason::FramebufferChange));
}
updateRenderPassDesc(contextVk);
@ -2409,7 +2412,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
vk::CommandBuffer **commandBufferOut,
bool *renderPassDescChangedOut)
{
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(RenderPassClosureReason::NewRenderPass));
// Initialize RenderPass info.
vk::AttachmentOpsArray renderPassAttachmentOps;

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

@ -160,9 +160,7 @@ angle::Result ImageVk::orphan(const gl::Context *context, egl::ImageSibling *sib
ContextVk *contextVk = vk::GetImpl(context);
// Flush the context to make sure the fence has been submitted.
ANGLE_TRY(contextVk->flushImpl(nullptr));
return angle::Result::Continue;
return contextVk->flushImpl(nullptr, RenderPassClosureReason::ImageOrphan);
}
} // namespace rx

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

@ -69,7 +69,7 @@ angle::Result OverlayVk::init(const gl::Context *context, bool *successOut)
mRefreshCulledWidgets = true;
ANGLE_TRY(contextVk->flushImpl(nullptr));
ANGLE_TRY(contextVk->flushImpl(nullptr, RenderPassClosureReason::OverlayFontCreation));
*successOut = true;
return angle::Result::Continue;
}

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

@ -521,7 +521,7 @@ angle::Result QueryVk::getResult(const gl::Context *context, bool wait)
if (isUsedInRecordedCommands())
{
ANGLE_TRY(contextVk->flushImpl(nullptr));
ANGLE_TRY(contextVk->flushImpl(nullptr, RenderPassClosureReason::GetQueryResult));
ASSERT(!mQueryHelperTimeElapsedBegin.usedInRecordedCommands());
ASSERT(!mQueryHelper.get().usedInRecordedCommands());

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

@ -2523,13 +2523,6 @@ void RendererVk::initFeatures(DisplayVk *displayVk,
ExtensionFound(VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, deviceExtensionNames) &&
(!IsLinux() || nvidiaVersion.major > 418u));
// Work around ineffective compute-graphics barriers on Nexus 5X.
// TODO(syoussefi): Figure out which other vendors and driver versions are affected.
// http://anglebug.com/3019
ANGLE_FEATURE_CONDITION(&mFeatures, flushAfterVertexConversion,
IsAndroid() && IsNexus5X(mPhysicalDeviceProperties.vendorID,
mPhysicalDeviceProperties.deviceID));
ANGLE_FEATURE_CONDITION(
&mFeatures, supportsRenderpass2,
ExtensionFound(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, deviceExtensionNames));

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

@ -23,12 +23,15 @@ angle::Result FinishRunningCommands(ContextVk *contextVk, Serial serial)
}
template <typename T>
angle::Result WaitForIdle(ContextVk *contextVk, const char *debugMessage, T *resource)
angle::Result WaitForIdle(ContextVk *contextVk,
T *resource,
const char *debugMessage,
RenderPassClosureReason reason)
{
// If there are pending commands for the resource, flush them.
if (resource->usedInRecordedCommands())
{
ANGLE_TRY(contextVk->flushImpl(nullptr));
ANGLE_TRY(contextVk->flushImpl(nullptr, reason));
}
// Make sure the driver is done with the resource.
@ -68,9 +71,11 @@ angle::Result Resource::finishRunningCommands(ContextVk *contextVk)
return FinishRunningCommands(contextVk, mUse.getSerial());
}
angle::Result Resource::waitForIdle(ContextVk *contextVk, const char *debugMessage)
angle::Result Resource::waitForIdle(ContextVk *contextVk,
const char *debugMessage,
RenderPassClosureReason reason)
{
return WaitForIdle(contextVk, debugMessage, this);
return WaitForIdle(contextVk, this, debugMessage, reason);
}
// Resource implementation.
@ -104,9 +109,11 @@ angle::Result ReadWriteResource::finishGPUWriteCommands(ContextVk *contextVk)
return FinishRunningCommands(contextVk, mReadWriteUse.getSerial());
}
angle::Result ReadWriteResource::waitForIdle(ContextVk *contextVk, const char *debugMessage)
angle::Result ReadWriteResource::waitForIdle(ContextVk *contextVk,
const char *debugMessage,
RenderPassClosureReason reason)
{
return WaitForIdle(contextVk, debugMessage, this);
return WaitForIdle(contextVk, this, debugMessage, reason);
}
// SharedGarbage implementation.

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

@ -184,7 +184,9 @@ class Resource : angle::NonCopyable
angle::Result finishRunningCommands(ContextVk *contextVk);
// Complete all recorded and in-flight commands involving this resource
angle::Result waitForIdle(ContextVk *contextVk, const char *debugMessage);
angle::Result waitForIdle(ContextVk *contextVk,
const char *debugMessage,
RenderPassClosureReason reason);
// Adds the resource to a resource use list.
void retain(ResourceUseList *resourceUseList) const;
@ -236,7 +238,9 @@ class ReadWriteResource : public angle::NonCopyable
angle::Result finishGPUWriteCommands(ContextVk *contextVk);
// Complete all recorded and in-flight commands involving this resource
angle::Result waitForIdle(ContextVk *contextVk, const char *debugMessage);
angle::Result waitForIdle(ContextVk *contextVk,
const char *debugMessage,
RenderPassClosureReason reason);
// Adds the resource to a resource use list.
void retainReadOnly(ResourceUseList *resourceUseList) const;

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

@ -219,7 +219,7 @@ angle::Result SemaphoreVk::signal(gl::Context *context,
ANGLE_TRY(contextVk->syncExternalMemory());
}
ANGLE_TRY(contextVk->flushImpl(&mSemaphore));
ANGLE_TRY(contextVk->flushImpl(&mSemaphore, RenderPassClosureReason::ExternalSemaphoreSignal));
// The external has asked for the semaphore to be signaled. It will wait on this semaphore and
// so we must ensure that the above flush (resulting in vkQueueSubmit) has actually been

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

@ -1560,7 +1560,8 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
// present can be destroyed.
presentHistory.oldSwapchains = std::move(mOldSwapchains);
ANGLE_TRY(contextVk->flushAndGetSerial(presentSemaphore, swapSerial));
ANGLE_TRY(contextVk->flushAndGetSerial(presentSemaphore, swapSerial,
RenderPassClosureReason::EGLSwapBuffers));
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;

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

@ -94,7 +94,7 @@ angle::Result SyncHelper::initialize(ContextVk *contextVk, bool isEglSyncObject)
// (for example when a buffer is mapped).
//
retain(&contextVk->getResourceUseList());
return contextVk->flushImpl(nullptr);
return contextVk->flushImpl(nullptr, RenderPassClosureReason::SyncObjectInit);
}
angle::Result SyncHelper::clientWait(Context *context,
@ -224,7 +224,7 @@ angle::Result SyncHelperNativeFence::initializeWithFd(ContextVk *contextVk, int
with the newly created sync object.
*/
// Flush first because the fence comes after current pending set of commands.
ANGLE_TRY(contextVk->flushImpl(nullptr));
ANGLE_TRY(contextVk->flushImpl(nullptr, RenderPassClosureReason::SyncObjectWithFdInit));
retain(&contextVk->getResourceUseList());
@ -274,7 +274,7 @@ angle::Result SyncHelperNativeFence::clientWait(Context *context,
if (flushCommands && contextVk)
{
ANGLE_TRY(contextVk->flushImpl(nullptr));
ANGLE_TRY(contextVk->flushImpl(nullptr, RenderPassClosureReason::SyncObjectClientWait));
}
VkResult status = VK_SUCCESS;
@ -318,7 +318,7 @@ angle::Result SyncHelperNativeFence::serverWait(ContextVk *contextVk)
ANGLE_VK_TRY(contextVk, waitSemaphore.get().importFd(device, importFdInfo));
// Flush current work, block after current pending commands.
ANGLE_TRY(contextVk->flushImpl(nullptr));
ANGLE_TRY(contextVk->flushImpl(nullptr, RenderPassClosureReason::SyncObjectServerWait));
// Add semaphore to next submit job.
contextVk->addWaitSemaphore(waitSemaphore.get().getHandle(),

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

@ -866,8 +866,9 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
// Read back the requested region of the source texture
uint8_t *sourceData = nullptr;
ANGLE_TRY(source->copyImageDataToBufferAndGetData(contextVk, sourceLevelGL, sourceBox.depth,
sourceBox, &sourceData));
ANGLE_TRY(source->copyImageDataToBufferAndGetData(
contextVk, sourceLevelGL, sourceBox.depth, sourceBox,
RenderPassClosureReason::CopyTextureOnCPU, &sourceData));
const angle::Format &srcTextureFormat = source->getImage().getActualFormat();
const angle::Format &dstTextureFormat =
@ -1673,6 +1674,7 @@ angle::Result TextureVk::copyImageDataToBufferAndGetData(ContextVk *contextVk,
gl::LevelIndex sourceLevelGL,
uint32_t layerCount,
const gl::Box &sourceArea,
RenderPassClosureReason reason,
uint8_t **outDataPtr)
{
ANGLE_TRACE_EVENT0("gpu.angle", "TextureVk::copyImageDataToBufferAndGetData");
@ -1701,7 +1703,7 @@ angle::Result TextureVk::copyImageDataToBufferAndGetData(ContextVk *contextVk,
&sourceCopyOffsets, outDataPtr));
// Explicitly finish. If new use cases arise where we don't want to block we can change this.
ANGLE_TRY(contextVk->finishImpl());
ANGLE_TRY(contextVk->finishImpl(reason));
return angle::Result::Continue;
}
@ -1880,6 +1882,7 @@ angle::Result TextureVk::generateMipmapsWithCPU(const gl::Context *context)
baseLevelExtents.depth);
ANGLE_TRY(copyImageDataToBufferAndGetData(contextVk, baseLevelGL, imageLayerCount, imageArea,
RenderPassClosureReason::GenerateMipmapOnCPU,
&imageData));
const angle::Format &angleFormat = mImage->getActualFormat();
@ -2097,10 +2100,7 @@ angle::Result TextureVk::reinitImageAsRenderable(ContextVk *contextVk,
return angle::Result::Continue;
}
ANGLE_VK_PERF_WARNING(contextVk, GL_DEBUG_SEVERITY_LOW,
"Copying data due to texture format fallback");
// Make sure the source is initialized and it's staged updates are flushed.
// Make sure the source is initialized and its staged updates are flushed.
ANGLE_TRY(flushImageStagedUpdates(contextVk));
const angle::Format &srcFormat = mImage->getActualFormat();
@ -2112,6 +2112,9 @@ angle::Result TextureVk::reinitImageAsRenderable(ContextVk *contextVk,
// staged updates that we just staged inside the loop which is wrong.
if (levelCount == 1 && layerCount == 1)
{
ANGLE_VK_PERF_WARNING(contextVk, GL_DEBUG_SEVERITY_LOW,
"Copying image data due to texture format fallback");
ASSERT(CanCopyWithDraw(renderer, mImage->getActualFormatID(), mImage->getTilingMode(),
format.getActualImageFormatID(getRequiredImageAccess()),
getTilingMode()));
@ -2134,6 +2137,9 @@ angle::Result TextureVk::reinitImageAsRenderable(ContextVk *contextVk,
continue;
}
ANGLE_VK_PERF_WARNING(contextVk, GL_DEBUG_SEVERITY_HIGH,
"GPU stall due to texture format fallback");
gl::Box sourceBox(gl::kOffsetZero, mImage->getLevelExtents(levelVk));
// copy and stage entire layer
const gl::ImageIndex index =
@ -2150,7 +2156,7 @@ angle::Result TextureVk::reinitImageAsRenderable(ContextVk *contextVk,
// Explicitly finish. If new use cases arise where we don't want to block we can change
// this.
ANGLE_TRY(contextVk->finishImpl());
ANGLE_TRY(contextVk->finishImpl(RenderPassClosureReason::TextureReformatToRenderable));
size_t dstBufferSize = sourceBox.width * sourceBox.height * sourceBox.depth *
dstFormat.pixelBytes * layerCount;

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

@ -351,6 +351,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
gl::LevelIndex sourceLevelGL,
uint32_t layerCount,
const gl::Box &sourceArea,
RenderPassClosureReason reason,
uint8_t **outDataPtr);
angle::Result copyBufferDataToImage(ContextVk *contextVk,

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

@ -2109,7 +2109,8 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
// render pass.
if (isTransformFeedbackActiveUnpaused)
{
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
RenderPassClosureReason::XfbResumeAfterDrawBasedClear));
}
return angle::Result::Continue;
@ -2207,7 +2208,8 @@ angle::Result UtilsVk::clearImage(ContextVk *contextVk,
contextVk->addGarbage(&destViewObject);
// Close the render pass for this temporary framebuffer.
return contextVk->flushCommandsAndEndRenderPass();
return contextVk->flushCommandsAndEndRenderPass(
RenderPassClosureReason::TemporaryForImageClear);
}
angle::Result UtilsVk::colorBlitResolve(ContextVk *contextVk,
@ -2877,7 +2879,7 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
descriptorPoolBinding.reset();
// Close the render pass for this temporary framebuffer.
return contextVk->flushCommandsAndEndRenderPass();
return contextVk->flushCommandsAndEndRenderPass(RenderPassClosureReason::TemporaryForImageCopy);
}
angle::Result UtilsVk::copyImageBits(ContextVk *contextVk,

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

@ -589,7 +589,6 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
GLuint stride;
// Init attribute offset to the front-end value
mCurrentArrayBufferRelativeOffsets[attribIndex] = attrib.relativeOffset;
bool anyVertexBufferConvertedOnGpu = false;
gl::Buffer *bufferGL = binding.getBuffer().get();
// Emulated and/or client-side attribs will be streamed
bool isStreamingVertexAttrib =
@ -643,7 +642,6 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
ANGLE_TRY(convertVertexBufferGPU(contextVk, bufferVk, binding, attribIndex,
vertexFormat, conversion,
attrib.relativeOffset, compressed));
anyVertexBufferConvertedOnGpu = true;
}
else
{
@ -729,12 +727,6 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
mCurrentArrayBufferStrides[attribIndex] = stride;
mCurrentArrayBufferCompressed[attribIndex] = compressed;
}
if (anyVertexBufferConvertedOnGpu &&
renderer->getFeatures().flushAfterVertexConversion.enabled)
{
ANGLE_TRY(contextVk->flushImpl(nullptr));
}
}
else
{

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

@ -139,7 +139,7 @@ egl::Error IOSurfaceSurfaceVkMac::unMakeCurrent(const gl::Context *context)
ASSERT(context != nullptr);
ContextVk *contextVk = vk::GetImpl(context);
DisplayVk *displayVk = vk::GetImpl(context->getDisplay());
angle::Result result = contextVk->flushImpl(nullptr);
angle::Result result = contextVk->flushImpl(nullptr, RenderPassClosureReason::ContextChange);
return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
}

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

@ -2982,7 +2982,8 @@ angle::Result QueryHelper::beginQuery(ContextVk *contextVk)
{
if (contextVk->hasStartedRenderPass())
{
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
RenderPassClosureReason::BeginNonRenderPassQuery));
}
CommandBuffer *commandBuffer;
@ -2999,7 +3000,8 @@ angle::Result QueryHelper::endQuery(ContextVk *contextVk)
{
if (contextVk->hasStartedRenderPass())
{
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass(
RenderPassClosureReason::EndNonRenderPassQuery));
}
CommandBuffer *commandBuffer;
@ -3037,7 +3039,8 @@ angle::Result QueryHelper::flushAndWriteTimestamp(ContextVk *contextVk)
{
if (contextVk->hasStartedRenderPass())
{
ANGLE_TRY(contextVk->flushCommandsAndEndRenderPass());
ANGLE_TRY(
contextVk->flushCommandsAndEndRenderPass(RenderPassClosureReason::TimestampQuery));
}
CommandBuffer *commandBuffer;
@ -7349,7 +7352,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
// Triggers a full finish.
// TODO(jmadill): Don't block on asynchronous readback.
ANGLE_TRY(contextVk->finishImpl());
ANGLE_TRY(contextVk->finishImpl(RenderPassClosureReason::GLReadPixels));
// The buffer we copied to needs to be invalidated before we read from it because its not been
// created with the host coherent bit.

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

@ -1082,6 +1082,82 @@ GLuint GetSampleCount(VkSampleCountFlags supportedCounts, GLuint requestedCount)
gl::LevelIndex GetLevelIndex(vk::LevelIndex levelVk, gl::LevelIndex baseLevel);
} // namespace vk_gl
enum class RenderPassClosureReason
{
// Don't specify the reason (it should already be specified elsewhere)
AlreadySpecifiedElsewhere,
// Implicit closures due to flush/wait/etc.
ContextDestruction,
ContextChange,
GLFlush,
GLFinish,
EGLSwapBuffers,
EGLWaitClient,
// Closure due to switching rendering to another framebuffer.
FramebufferBindingChange,
FramebufferChange,
NewRenderPass,
// Incompatible use of resource in the same render pass
BufferUseThenXfbWrite,
XfbWriteThenVertexIndexBuffer,
XfbWriteThenIndirectDrawBuffer,
XfbResumeAfterDrawBasedClear,
DepthStencilUseInFeedbackLoop,
DepthStencilWriteAfterFeedbackLoop,
PipelineBindWhileXfbActive,
// Use of resource after render pass
BufferWriteThenMap,
BufferUseThenOutOfRPRead,
BufferUseThenOutOfRPWrite,
ImageUseThenOutOfRPRead,
ImageUseThenOutOfRPWrite,
XfbWriteThenComputeRead,
XfbWriteThenIndirectDispatchBuffer,
ImageAttachmentThenComputeRead,
GetQueryResult,
BeginNonRenderPassQuery,
EndNonRenderPassQuery,
TimestampQuery,
GLReadPixels,
// Synchronization
BufferUseThenReleaseToExternal,
ImageUseThenReleaseToExternal,
BufferInUseWhenSynchronizedMap,
ImageOrphan,
GLMemoryBarrierThenStorageResource,
StorageResourceUseThenGLMemoryBarrier,
ExternalSemaphoreSignal,
SyncObjectInit,
SyncObjectWithFdInit,
SyncObjectClientWait,
SyncObjectServerWait,
// Closures that ANGLE could have avoided, but doesn't for simplicity or optimization of more
// common cases.
XfbPause,
FramebufferFetchEmulation,
ColorBufferInvalidate,
GenerateMipmapOnCPU,
CopyTextureOnCPU,
TextureReformatToRenderable,
DeviceLocalBufferMap,
// UtilsVk
TemporaryForImageClear,
TemporaryForImageCopy,
// Misc
OverlayFontCreation,
InvalidEnum,
EnumCount = InvalidEnum,
};
} // namespace rx
#define ANGLE_VK_TRY(context, command) \