зеркало из https://github.com/AvaloniaUI/angle.git
Vulkan: Fold glClear into draw call when command graph is disabled
This sets ContextVk::mRenderPassCommandBuffer properly when glClear get called so that it wonr end up start anotyer render pass during setupDraw call. Bug: angleproject:4395 Change-Id: Id2110719ad4d70b4c410062466d32381fb5e1f88 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2050966 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
94c191427a
Коммит
ef599fb0f4
|
@ -46,6 +46,10 @@ namespace rx
|
|||
|
||||
namespace
|
||||
{
|
||||
// The value to assign an alpha channel that's emulated. The type is unsigned int, though it will
|
||||
// automatically convert to the actual data type.
|
||||
constexpr unsigned int kEmulatedAlphaValue = 1;
|
||||
|
||||
// For shader uniforms such as gl_DepthRange and the viewport size.
|
||||
struct GraphicsDriverUniforms
|
||||
{
|
||||
|
@ -2188,6 +2192,93 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context,
|
|||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result ContextVk::clearWithRenderPassOp(
|
||||
const gl::Rectangle &clearArea,
|
||||
gl::DrawBufferMask clearColorBuffers,
|
||||
bool clearDepth,
|
||||
bool clearStencil,
|
||||
const VkClearColorValue &clearColorValue,
|
||||
const VkClearDepthStencilValue &clearDepthStencilValue)
|
||||
{
|
||||
ASSERT(!commandGraphEnabled());
|
||||
// Start a new render pass if:
|
||||
//
|
||||
// - no render pass has started,
|
||||
// - there is a render pass started but it contains commands; we cannot modify its ops, so new
|
||||
// render pass is needed,
|
||||
// - the current render area doesn't match the clear area. We need the render area to be
|
||||
// exactly as specified by the scissor for the loadOp to clear only that area. See
|
||||
// ContextVk::updateScissor for more information.
|
||||
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
|
||||
if (!framebuffer->valid() || !framebuffer->renderPassStartedButEmpty() ||
|
||||
framebuffer->getRenderPassRenderArea() != clearArea)
|
||||
{
|
||||
mGraphicsDirtyBits |= mNewGraphicsCommandBufferDirtyBits;
|
||||
|
||||
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, clearArea, &mRenderPassCommandBuffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
mOutsideRenderPassCommands.flushToPrimary(&mPrimaryCommands);
|
||||
}
|
||||
|
||||
size_t attachmentIndexVk = 0;
|
||||
|
||||
// Go through clearColorBuffers and set the appropriate loadOp and clear values.
|
||||
for (size_t colorIndexGL : mDrawFramebuffer->getState().getEnabledDrawBuffers())
|
||||
{
|
||||
if (clearColorBuffers.test(colorIndexGL))
|
||||
{
|
||||
RenderTargetVk *renderTarget = mDrawFramebuffer->getColorDrawRenderTarget(colorIndexGL);
|
||||
|
||||
// If the render target doesn't have alpha, but its emulated format has it, clear the
|
||||
// alpha to 1.
|
||||
VkClearColorValue value = clearColorValue;
|
||||
if (mDrawFramebuffer->getEmulatedAlphaAttachmentMask()[colorIndexGL])
|
||||
{
|
||||
const vk::Format &format = renderTarget->getImageFormat();
|
||||
if (format.vkFormatIsInt)
|
||||
{
|
||||
if (format.vkFormatIsUnsigned)
|
||||
{
|
||||
value.uint32[3] = kEmulatedAlphaValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
value.int32[3] = kEmulatedAlphaValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value.float32[3] = kEmulatedAlphaValue;
|
||||
}
|
||||
}
|
||||
|
||||
mRenderPassCommands.clearRenderPassColorAttachment(attachmentIndexVk, value);
|
||||
}
|
||||
++attachmentIndexVk;
|
||||
}
|
||||
|
||||
// Set the appropriate loadOp and clear values for depth and stencil.
|
||||
RenderTargetVk *depthStencilRenderTarget = mDrawFramebuffer->getDepthStencilRenderTarget();
|
||||
if (depthStencilRenderTarget)
|
||||
{
|
||||
if (clearDepth)
|
||||
{
|
||||
getRenderPassCommandBuffer().clearRenderPassDepthAttachment(
|
||||
attachmentIndexVk, clearDepthStencilValue.depth);
|
||||
}
|
||||
|
||||
if (clearStencil)
|
||||
{
|
||||
getRenderPassCommandBuffer().clearRenderPassStencilAttachment(
|
||||
attachmentIndexVk, clearDepthStencilValue.stencil);
|
||||
}
|
||||
}
|
||||
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
gl::GraphicsResetStatus ContextVk::getResetStatus()
|
||||
{
|
||||
if (mRenderer->isDeviceLost())
|
||||
|
|
|
@ -314,6 +314,12 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
|
|||
gl::PrimitiveMode mode,
|
||||
gl::DrawElementsType type,
|
||||
const void *indirect) override;
|
||||
angle::Result clearWithRenderPassOp(const gl::Rectangle &clearArea,
|
||||
gl::DrawBufferMask clearColorBuffers,
|
||||
bool clearDepth,
|
||||
bool clearStencil,
|
||||
const VkClearColorValue &clearColorValue,
|
||||
const VkClearDepthStencilValue &clearDepthStencilValue);
|
||||
|
||||
// Device loss
|
||||
gl::GraphicsResetStatus getResetStatus() override;
|
||||
|
|
|
@ -292,9 +292,19 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
|
|||
{
|
||||
clearBuffersWithRenderPassLoadOp = clearColorBuffers;
|
||||
}
|
||||
ANGLE_TRY(clearWithRenderPassOp(
|
||||
contextVk, scissoredRenderArea, clearBuffersWithRenderPassLoadOp, clearDepth,
|
||||
clearStencilWithRenderPassLoadOp, clearColorValue, modifiedDepthStencilValue));
|
||||
|
||||
if (contextVk->commandGraphEnabled())
|
||||
{
|
||||
ANGLE_TRY(clearWithRenderPassOp(
|
||||
contextVk, scissoredRenderArea, clearBuffersWithRenderPassLoadOp, clearDepth,
|
||||
clearStencilWithRenderPassLoadOp, clearColorValue, modifiedDepthStencilValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
ANGLE_TRY(contextVk->clearWithRenderPassOp(
|
||||
scissoredRenderArea, clearBuffersWithRenderPassLoadOp, clearDepth,
|
||||
clearStencilWithRenderPassLoadOp, clearColorValue, modifiedDepthStencilValue));
|
||||
}
|
||||
|
||||
// Fallback to other methods for whatever isn't cleared here.
|
||||
clearDepth = false;
|
||||
|
@ -1246,6 +1256,7 @@ angle::Result FramebufferVk::clearWithRenderPassOp(
|
|||
const VkClearColorValue &clearColorValue,
|
||||
const VkClearDepthStencilValue &clearDepthStencilValue)
|
||||
{
|
||||
ASSERT(contextVk->commandGraphEnabled());
|
||||
// Start a new render pass if:
|
||||
//
|
||||
// - no render pass has started,
|
||||
|
|
Загрузка…
Ссылка в новой задаче