Commit 5242d5bf by Luc Ferron Committed by Commit Bot

Vulkan: Implement scissored clears.

Bug: angleproject:2356 Change-Id: I33888f9b4ebaf4b0b5af4ad59b12ad963325a790 Reviewed-on: https://chromium-review.googlesource.com/921882 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent bc918e7d
...@@ -160,6 +160,7 @@ class ContextVk : public ContextImpl ...@@ -160,6 +160,7 @@ class ContextVk : public ContextImpl
const VkClearValue &getClearColorValue() const; const VkClearValue &getClearColorValue() const;
const VkClearValue &getClearDepthStencilValue() const; const VkClearValue &getClearDepthStencilValue() const;
const VkRect2D &getScissor() const { return mPipelineDesc->getScissor(); }
private: private:
gl::Error initPipeline(const gl::Context *context); gl::Error initPipeline(const gl::Context *context);
......
...@@ -136,7 +136,15 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask) ...@@ -136,7 +136,15 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
return gl::NoError(); return gl::NoError();
} }
// TODO(jmadill): Scissored clears. if (context->getGLState().isScissorTestEnabled())
{
// With scissor test enabled, we clear very differently and we don't need to access
// the image inside each attachment we can just use clearCmdAttachments with our
// scissor region instead.
ANGLE_TRY(clearColorAttachmentsWithScissorRegion(context));
return gl::NoError();
}
const auto *attachment = mState.getFirstNonNullAttachment(); const auto *attachment = mState.getFirstNonNullAttachment();
ASSERT(attachment && attachment->isAttached()); ASSERT(attachment && attachment->isAttached());
const auto &size = attachment->getSize(); const auto &size = attachment->getSize();
...@@ -461,6 +469,50 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con ...@@ -461,6 +469,50 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con
return &mFramebuffer; return &mFramebuffer;
} }
gl::Error FramebufferVk::clearColorAttachmentsWithScissorRegion(const gl::Context *context)
{
ContextVk *contextVk = vk::GetImpl(context);
RendererVk *renderer = contextVk->getRenderer();
// This command can only happen inside a render pass, so obtain one if its already happening
// or create a new one if not.
vk::CommandGraphNode *node = nullptr;
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(getCommandGraphNodeForDraw(context, &node));
if (node->getInsideRenderPassCommands()->valid())
{
commandBuffer = node->getInsideRenderPassCommands();
}
else
{
ANGLE_TRY(node->beginInsideRenderPassRecording(renderer, &commandBuffer));
}
const std::vector<gl::FramebufferAttachment> &colorAttachments = mState.getColorAttachments();
gl::AttachmentArray<VkClearAttachment> clearAttachments;
int clearAttachmentIndex = 0;
for (auto colorIndex : mState.getEnabledDrawBuffers())
{
VkClearAttachment &clearAttachment = clearAttachments[clearAttachmentIndex];
clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
clearAttachment.colorAttachment = static_cast<uint32_t>(colorIndex);
clearAttachment.clearValue = contextVk->getClearColorValue();
++clearAttachmentIndex;
}
// We assume for now that we always need to clear only 1 layer starting at the
// baseArrayLayer 0, this might need to change depending how we'll implement
// cube maps, 3d textures and array textures.
VkClearRect clearRect;
clearRect.baseArrayLayer = 0;
clearRect.layerCount = 1;
clearRect.rect = contextVk->getScissor();
commandBuffer->clearAttachments(static_cast<uint32_t>(colorAttachments.size()),
clearAttachments.data(), 1, &clearRect);
return gl::NoError();
}
gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const gl::Error FramebufferVk::getSamplePosition(size_t index, GLfloat *xy) const
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -95,6 +95,8 @@ class FramebufferVk : public FramebufferImpl, public ResourceVk ...@@ -95,6 +95,8 @@ class FramebufferVk : public FramebufferImpl, public ResourceVk
gl::ErrorOrResult<vk::Framebuffer *> getFramebuffer(const gl::Context *context, gl::ErrorOrResult<vk::Framebuffer *> getFramebuffer(const gl::Context *context,
RendererVk *rendererVk); RendererVk *rendererVk);
gl::Error clearColorAttachmentsWithScissorRegion(const gl::Context *context);
WindowSurfaceVk *mBackbuffer; WindowSurfaceVk *mBackbuffer;
Optional<vk::RenderPassDesc> mRenderPassDesc; Optional<vk::RenderPassDesc> mRenderPassDesc;
......
...@@ -579,7 +579,6 @@ void PipelineDesc::updateViewport(const gl::Rectangle &viewport, float nearPlane ...@@ -579,7 +579,6 @@ void PipelineDesc::updateViewport(const gl::Rectangle &viewport, float nearPlane
mViewport.minDepth = nearPlane; mViewport.minDepth = nearPlane;
mViewport.maxDepth = farPlane; mViewport.maxDepth = farPlane;
// TODO(jmadill): Scissor.
mScissor.offset.x = viewport.x; mScissor.offset.x = viewport.x;
mScissor.offset.y = viewport.y; mScissor.offset.y = viewport.y;
mScissor.extent.width = viewport.width; mScissor.extent.width = viewport.width;
......
...@@ -289,6 +289,7 @@ class PipelineDesc final ...@@ -289,6 +289,7 @@ class PipelineDesc final
void updateRenderPassDesc(const RenderPassDesc &renderPassDesc); void updateRenderPassDesc(const RenderPassDesc &renderPassDesc);
// Scissor support // Scissor support
const VkRect2D &getScissor() const { return mScissor; }
void updateScissor(const gl::Rectangle &rect); void updateScissor(const gl::Rectangle &rect);
// Blend states // Blend states
......
...@@ -514,6 +514,16 @@ void CommandBuffer::clearDepthStencilImage(const vk::Image &image, ...@@ -514,6 +514,16 @@ void CommandBuffer::clearDepthStencilImage(const vk::Image &image,
rangeCount, ranges); rangeCount, ranges);
} }
void CommandBuffer::clearAttachments(uint32_t attachmentCount,
const VkClearAttachment *attachments,
uint32_t rectCount,
const VkClearRect *rects)
{
ASSERT(valid());
vkCmdClearAttachments(mHandle, attachmentCount, attachments, rectCount, rects);
}
void CommandBuffer::copySingleImage(const vk::Image &srcImage, void CommandBuffer::copySingleImage(const vk::Image &srcImage,
const vk::Image &destImage, const vk::Image &destImage,
const gl::Box &copyRegion, const gl::Box &copyRegion,
......
...@@ -333,6 +333,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer> ...@@ -333,6 +333,7 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
const VkBufferMemoryBarrier &bufferBarrier); const VkBufferMemoryBarrier &bufferBarrier);
void clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color); void clearSingleColorImage(const vk::Image &image, const VkClearColorValue &color);
void clearSingleDepthStencilImage(const vk::Image &image, void clearSingleDepthStencilImage(const vk::Image &image,
VkImageAspectFlags aspectFlags, VkImageAspectFlags aspectFlags,
const VkClearDepthStencilValue &depthStencil); const VkClearDepthStencilValue &depthStencil);
...@@ -342,6 +343,11 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer> ...@@ -342,6 +343,11 @@ class CommandBuffer : public WrappedObject<CommandBuffer, VkCommandBuffer>
uint32_t rangeCount, uint32_t rangeCount,
const VkImageSubresourceRange *ranges); const VkImageSubresourceRange *ranges);
void clearAttachments(uint32_t attachmentCount,
const VkClearAttachment *attachments,
uint32_t rectCount,
const VkClearRect *rects);
void copyBuffer(const vk::Buffer &srcBuffer, void copyBuffer(const vk::Buffer &srcBuffer,
const vk::Buffer &destBuffer, const vk::Buffer &destBuffer,
uint32_t regionCount, uint32_t regionCount,
......
...@@ -434,17 +434,12 @@ class ScissoredClearTest : public ANGLETest ...@@ -434,17 +434,12 @@ class ScissoredClearTest : public ANGLETest
// Simple scissored clear. // Simple scissored clear.
TEST_P(ScissoredClearTest, BasicScissoredColorClear) TEST_P(ScissoredClearTest, BasicScissoredColorClear)
{ {
// The Vulkan back-end does not implement scissored clears yet.
// TODO(jmadill): Enable this when we implement scissored clears in Vulkan.
// http://anglebug.com/2356
ANGLE_SKIP_TEST_IF(IsVulkan());
const int w = getWindowWidth(); const int w = getWindowWidth();
const int h = getWindowHeight(); const int h = getWindowHeight();
const int whalf = w >> 1; const int whalf = w >> 1;
const int hhalf = h >> 1; const int hhalf = h >> 1;
// Clear who region to red. // Clear whole region to red.
glClearColor(1.0, 0.0, 0.0, 1.0); glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment