Commit bcf467f2 by Jamie Madill Committed by Commit Bot

Vulkan: Encapsulate RenderTargetVk.

This makes the members private and adds more functionality. This moves more responsibility out of vk::CommandGraphNode and also makes the RenderPass init in the CommandGraphNode class better encapsulated. Bug: angleproject:2539 Change-Id: Ia16f3f39cf011548c6473805b8b28e284808e856 Reviewed-on: https://chromium-review.googlesource.com/1040279Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 29523298
......@@ -236,47 +236,15 @@ Error CommandGraphNode::beginInsideRenderPassRecording(RendererVk *renderer,
void CommandGraphNode::storeRenderPassInfo(const Framebuffer &framebuffer,
const gl::Rectangle renderArea,
const vk::RenderPassDesc &renderPassDesc,
const std::vector<VkClearValue> &clearValues)
{
mRenderPassDesc = renderPassDesc;
mRenderPassFramebuffer.setHandle(framebuffer.getHandle());
mRenderPassRenderArea = renderArea;
std::copy(clearValues.begin(), clearValues.end(), mRenderPassClearValues.begin());
}
void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget)
{
ASSERT(mOutsideRenderPassCommands.valid());
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
colorRenderTarget->image->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
&mOutsideRenderPassCommands);
mRenderPassDesc.packColorAttachment(*colorRenderTarget->image);
colorRenderTarget->resource->onWriteResource(this, serial);
}
void CommandGraphNode::appendDepthStencilRenderTarget(Serial serial,
RenderTargetVk *depthStencilRenderTarget)
{
ASSERT(mOutsideRenderPassCommands.valid());
ASSERT(depthStencilRenderTarget->image->getFormat().textureFormat().hasDepthOrStencilBits());
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = depthStencilRenderTarget->image->getFormat().textureFormat();
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
depthStencilRenderTarget->image->changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
&mOutsideRenderPassCommands);
mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
depthStencilRenderTarget->resource->onWriteResource(this, serial);
}
// static
void CommandGraphNode::SetHappensBeforeDependency(CommandGraphNode *beforeNode,
CommandGraphNode *afterNode)
......
......@@ -107,13 +107,9 @@ class CommandGraphNode final : angle::NonCopyable
// storeRenderPassInfo and append*RenderTarget store info relevant to the RenderPass.
void storeRenderPassInfo(const Framebuffer &framebuffer,
const gl::Rectangle renderArea,
const vk::RenderPassDesc &renderPassDesc,
const std::vector<VkClearValue> &clearValues);
// storeRenderPassInfo and append*RenderTarget store info relevant to the RenderPass.
// Note: RenderTargets must be added in order, with the depth/stencil being added last.
void appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget);
void appendDepthStencilRenderTarget(Serial serial, RenderTargetVk *depthStencilRenderTarget);
// Dependency commands order node execution in the command graph.
// Once a node has commands that must happen after it, recording is stopped and the node is
// frozen forever.
......
......@@ -36,10 +36,10 @@ const gl::InternalFormat &GetReadAttachmentInfo(const gl::Context *context,
RenderTargetVk *renderTarget)
{
GLenum implFormat =
renderTarget->image->getFormat().textureFormat().fboImplementationInternalFormat;
renderTarget->getImageFormat().textureFormat().fboImplementationInternalFormat;
return gl::GetSizedInternalFormatInfo(implFormat);
}
} // anonymous namespace<
} // anonymous namespace
// static
FramebufferVk *FramebufferVk::CreateUserFBO(const gl::FramebufferState &state)
......@@ -186,8 +186,8 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
(stencilAttachment ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
renderTarget->resource->onWriteResource(writingNode, currentSerial);
renderTarget->image->clearDepthStencil(aspectFlags, clearDepthStencilValue, commandBuffer);
vk::ImageHelper *image = renderTarget->getImageForWrite(currentSerial, writingNode);
image->clearDepthStencil(aspectFlags, clearDepthStencilValue, commandBuffer);
if (!clearColor)
{
......@@ -212,8 +212,8 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
{
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
colorRenderTarget->resource->onWriteResource(writingNode, currentSerial);
colorRenderTarget->image->clearColor(clearColorValue, commandBuffer);
vk::ImageHelper *image = colorRenderTarget->getImageForWrite(currentSerial, writingNode);
image->clearColor(clearColorValue, commandBuffer);
}
return gl::NoError();
......@@ -319,7 +319,7 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
RenderTargetVk *FramebufferVk::getColorReadRenderTarget() const
{
RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(renderTarget && renderTarget->image->valid());
ASSERT(renderTarget && renderTarget->getImage().valid());
return renderTarget;
}
......@@ -372,7 +372,7 @@ gl::Error FramebufferVk::syncState(const gl::Context *context,
RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndex];
if (renderTarget)
{
const angle::Format &format = renderTarget->image->getFormat().textureFormat();
const angle::Format &format = renderTarget->getImageFormat().textureFormat();
updateActiveColorMasks(colorIndex, format.redBits > 0, format.greenBits > 0,
format.blueBits > 0, format.alphaBits > 0);
}
......@@ -415,13 +415,13 @@ const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc()
{
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
desc.packColorAttachment(*colorRenderTarget->image);
desc.packColorAttachment(colorRenderTarget->getImage());
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
desc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
desc.packDepthStencilAttachment(depthStencilRenderTarget->getImage());
}
mRenderPassDesc = desc;
......@@ -458,21 +458,20 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(RendererVk *r
{
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
attachments.push_back(colorRenderTarget->imageView->getHandle());
attachments.push_back(colorRenderTarget->getImageView()->getHandle());
ASSERT(attachmentsSize.empty() ||
attachmentsSize == colorRenderTarget->image->getExtents());
attachmentsSize = colorRenderTarget->image->getExtents();
ASSERT(attachmentsSize.empty() || attachmentsSize == colorRenderTarget->getImageExtents());
attachmentsSize = colorRenderTarget->getImageExtents();
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
attachments.push_back(depthStencilRenderTarget->imageView->getHandle());
attachments.push_back(depthStencilRenderTarget->getImageView()->getHandle());
ASSERT(attachmentsSize.empty() ||
attachmentsSize == depthStencilRenderTarget->image->getExtents());
attachmentsSize = depthStencilRenderTarget->image->getExtents();
attachmentsSize == depthStencilRenderTarget->getImageExtents());
attachmentsSize = depthStencilRenderTarget->getImageExtents();
}
ASSERT(!attachments.empty());
......@@ -699,6 +698,8 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(ContextVk *contextVk,
renderer->getDevice(), renderer->getCommandPool(), &commandBuffer));
}
vk::RenderPassDesc renderPassDesc;
// Initialize RenderPass info.
// TODO(jmadill): Support gaps in RenderTargets. http://anglebug.com/2394
const auto &colorRenderTargets = mRenderTargetCache.getColors();
......@@ -707,14 +708,14 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(ContextVk *contextVk,
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
(*nodeOut)->appendColorRenderTarget(currentSerial, colorRenderTarget);
colorRenderTarget->onColorDraw(currentSerial, *nodeOut, &renderPassDesc);
attachmentClearValues.emplace_back(contextVk->getClearColorValue());
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
(*nodeOut)->appendDepthStencilRenderTarget(currentSerial, depthStencilRenderTarget);
depthStencilRenderTarget->onDepthStencilDraw(currentSerial, *nodeOut, &renderPassDesc);
attachmentClearValues.emplace_back(contextVk->getClearDepthStencilValue());
}
......@@ -722,7 +723,8 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(ContextVk *contextVk,
gl::Rectangle(0, 0, mState.getDimensions().width, mState.getDimensions().height);
// Hard-code RenderPass to clear the first render target to the current clear value.
// TODO(jmadill): Proper clear value implementation. http://anglebug.com/2361
(*nodeOut)->storeRenderPassInfo(*framebuffer, renderArea, attachmentClearValues);
(*nodeOut)->storeRenderPassInfo(*framebuffer, renderArea, renderPassDesc,
attachmentClearValues);
return gl::NoError();
}
......@@ -754,13 +756,17 @@ gl::Error FramebufferVk::readPixelsImpl(const gl::Context *context,
RenderTargetVk *renderTarget = getColorReadRenderTarget();
vk::ImageHelper *renderTargetImage = renderTarget->image;
const angle::Format &angleFormat = renderTargetImage->getFormat().textureFormat();
VkBuffer bufferHandle = VK_NULL_HANDLE;
uint8_t *readPixelBuffer = nullptr;
bool newBufferAllocated = false;
uint32_t stagingOffset = 0;
size_t allocationSize = area.width * angleFormat.pixelBytes * area.height;
// Note that although we're reading from the image, we need to update the layout below.
// TODO(jmadill): Clearify read/write semantics. http://anglebug.com/2539
vk::ImageHelper *srcImage =
renderTarget->getImageForWrite(renderer->getCurrentQueueSerial(), getCurrentWritingNode());
const angle::Format &angleFormat = srcImage->getFormat().textureFormat();
VkBuffer bufferHandle = VK_NULL_HANDLE;
uint8_t *readPixelBuffer = nullptr;
bool newBufferAllocated = false;
uint32_t stagingOffset = 0;
size_t allocationSize = area.width * angleFormat.pixelBytes * area.height;
mReadPixelsBuffer.allocate(renderer, allocationSize, &readPixelBuffer, &bufferHandle,
&stagingOffset, &newBufferAllocated);
......@@ -780,13 +786,12 @@ gl::Error FramebufferVk::readPixelsImpl(const gl::Context *context,
region.imageSubresource.layerCount = 1;
region.imageSubresource.mipLevel = 0;
renderTargetImage->changeLayoutWithStages(
srcImage->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
commandBuffer->copyImageToBuffer(renderTargetImage->getImage(),
renderTargetImage->getCurrentLayout(), bufferHandle, 1,
&region);
commandBuffer->copyImageToBuffer(srcImage->getImage(), srcImage->getCurrentLayout(),
bufferHandle, 1, &region);
// Triggers a full finish.
// TODO(jmadill): Don't block on asynchronous readback.
......@@ -804,6 +809,6 @@ gl::Error FramebufferVk::readPixelsImpl(const gl::Context *context,
const gl::Extents &FramebufferVk::getReadImageExtents() const
{
return getColorReadRenderTarget()->image->getExtents();
return getColorReadRenderTarget()->getImageExtents();
}
} // namespace rx
......@@ -9,9 +9,108 @@
#include "libANGLE/renderer/vulkan/RenderTargetVk.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/vk_format_utils.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"
namespace rx
{
RenderTargetVk::RenderTargetVk() : image(nullptr), imageView(nullptr), resource(nullptr)
RenderTargetVk::RenderTargetVk(vk::ImageHelper *image,
vk::ImageView *imageView,
vk::CommandGraphResource *resource)
: mImage(image), mImageView(imageView), mResource(resource)
{
}
RenderTargetVk::~RenderTargetVk()
{
}
void RenderTargetVk::onColorDraw(Serial currentSerial,
vk::CommandGraphNode *writingNode,
vk::RenderPassDesc *renderPassDesc)
{
ASSERT(writingNode->getOutsideRenderPassCommands()->valid());
// Store the attachment info in the renderPassDesc.
renderPassDesc->packColorAttachment(*mImage);
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
mImage->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
writingNode->getOutsideRenderPassCommands());
// Set up dependencies between the new graph node and other current nodes in the resource.
mResource->onWriteResource(writingNode, currentSerial);
}
void RenderTargetVk::onDepthStencilDraw(Serial currentSerial,
vk::CommandGraphNode *writingNode,
vk::RenderPassDesc *renderPassDesc)
{
ASSERT(writingNode->getOutsideRenderPassCommands()->valid());
ASSERT(mImage->getFormat().textureFormat().hasDepthOrStencilBits());
// Store the attachment info in the renderPassDesc.
renderPassDesc->packDepthStencilAttachment(*mImage);
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = mImage->getFormat().textureFormat();
VkImageAspectFlags aspectFlags = (format.depthBits > 0 ? VK_IMAGE_ASPECT_DEPTH_BIT : 0) |
(format.stencilBits > 0 ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
mImage->changeLayoutWithStages(aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
writingNode->getOutsideRenderPassCommands());
// Set up dependencies between the new graph node and other current nodes in the resource.
mResource->onWriteResource(writingNode, currentSerial);
}
const vk::ImageHelper &RenderTargetVk::getImage() const
{
ASSERT(mImage && mImage->valid());
return *mImage;
}
vk::ImageView *RenderTargetVk::getImageView() const
{
ASSERT(mImageView && mImageView->valid());
return mImageView;
}
vk::CommandGraphResource *RenderTargetVk::getResource() const
{
return mResource;
}
const vk::Format &RenderTargetVk::getImageFormat() const
{
ASSERT(mImage && mImage->valid());
return mImage->getFormat();
}
const gl::Extents &RenderTargetVk::getImageExtents() const
{
ASSERT(mImage && mImage->valid());
return mImage->getExtents();
}
void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageView *imageView)
{
ASSERT(image && image->valid() && imageView && imageView->valid());
mImage = image;
mImageView = imageView;
}
vk::ImageHelper *RenderTargetVk::getImageForWrite(Serial currentSerial,
vk::CommandGraphNode *writingNode) const
{
ASSERT(mImage && mImage->valid());
mResource->onWriteResource(writingNode, currentSerial);
return mImage;
}
} // namespace rx
......@@ -13,27 +13,57 @@
#include <vulkan/vulkan.h>
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/renderer/renderer_utils.h"
namespace rx
{
namespace vk
{
class CommandGraphNode;
class CommandGraphResource;
struct Format;
class ImageHelper;
class ImageView;
class RenderPassDesc;
} // namespace vk
// This is a very light-weight class that does not own to the resources it points to.
// It's meant only to copy across some information from a FramebufferAttachment to the
// business rendering logic.
// business rendering logic. It stores Images and ImageView by pointer for performance.
class RenderTargetVk final : public FramebufferAttachmentRenderTarget
{
public:
RenderTargetVk();
RenderTargetVk(vk::ImageHelper *image,
vk::ImageView *imageView,
vk::CommandGraphResource *resource);
~RenderTargetVk();
vk::ImageHelper *image;
vk::ImageView *imageView;
vk::CommandGraphResource *resource;
// Note: RenderTargets should be called in order, with the depth/stencil onRender last.
void onColorDraw(Serial currentSerial,
vk::CommandGraphNode *writingNode,
vk::RenderPassDesc *renderPassDesc);
void onDepthStencilDraw(Serial currentSerial,
vk::CommandGraphNode *writingNode,
vk::RenderPassDesc *renderPassDesc);
const vk::ImageHelper &getImage() const;
vk::ImageHelper *getImageForWrite(Serial currentSerial,
vk::CommandGraphNode *writingNode) const;
vk::ImageView *getImageView() const;
vk::CommandGraphResource *getResource() const;
const vk::Format &getImageFormat() const;
const gl::Extents &getImageExtents() const;
// Special mutator for Surface RenderTargets. Allows the Framebuffer to keep a single
// RenderTargetVk pointer.
void updateSwapchainImage(vk::ImageHelper *image, vk::ImageView *imageView);
private:
vk::ImageHelper *mImage;
vk::ImageView *mImageView;
vk::CommandGraphResource *mResource;
};
} // namespace rx
......
......@@ -23,11 +23,9 @@ constexpr VkClearColorValue kBlackClearColorValue = {{0}};
} // anonymous namespace
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state) : RenderbufferImpl(state)
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
: RenderbufferImpl(state), mRenderTarget(&mImage, &mImageView, this)
{
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.resource = this;
}
RenderbufferVk::~RenderbufferVk()
......
......@@ -174,11 +174,10 @@ WindowSurfaceVk::WindowSurfaceVk(const egl::SurfaceState &surfaceState,
mSurface(VK_NULL_HANDLE),
mInstance(VK_NULL_HANDLE),
mSwapchain(VK_NULL_HANDLE),
mColorRenderTarget(),
mDepthStencilRenderTarget(),
mColorRenderTarget(nullptr, nullptr, this),
mDepthStencilRenderTarget(&mDepthStencilImage, &mDepthStencilImageView, this),
mCurrentSwapchainImageIndex(0)
{
mColorRenderTarget.resource = this;
}
WindowSurfaceVk::~WindowSurfaceVk()
......@@ -437,10 +436,6 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
ANGLE_TRY(mDepthStencilImage.initImageView(device, gl::TextureType::_2D, aspect,
gl::SwizzleState(), &mDepthStencilImageView, 1));
mDepthStencilRenderTarget.resource = this;
mDepthStencilRenderTarget.image = &mDepthStencilImage;
mDepthStencilRenderTarget.imageView = &mDepthStencilImageView;
// TODO(jmadill): Figure out how to pass depth/stencil image views to the RenderTargetVk.
}
......@@ -501,8 +496,7 @@ vk::Error WindowSurfaceVk::nextSwapchainImage(RendererVk *renderer)
std::swap(image.imageAcquiredSemaphore, mAcquireNextImageSemaphore);
// Update RenderTarget pointers.
mColorRenderTarget.image = &image.image;
mColorRenderTarget.imageView = &image.imageView;
mColorRenderTarget.updateSwapchainImage(&image.image, &image.imageView);
return vk::NoError();
}
......@@ -549,12 +543,12 @@ void WindowSurfaceVk::setSwapInterval(EGLint interval)
EGLint WindowSurfaceVk::getWidth() const
{
return static_cast<EGLint>(mColorRenderTarget.image->getExtents().width);
return static_cast<EGLint>(mColorRenderTarget.getImageExtents().width);
}
EGLint WindowSurfaceVk::getHeight() const
{
return static_cast<EGLint>(mColorRenderTarget.image->getExtents().height);
return static_cast<EGLint>(mColorRenderTarget.getImageExtents().height);
}
EGLint WindowSurfaceVk::isPostSubBufferSupported() const
......@@ -601,7 +595,7 @@ gl::ErrorOrResult<vk::Framebuffer *> WindowSurfaceVk::getCurrentFramebuffer(
VkFramebufferCreateInfo framebufferInfo;
const gl::Extents &extents = mColorRenderTarget.image->getExtents();
const gl::Extents &extents = mColorRenderTarget.getImageExtents();
std::array<VkImageView, 2> imageViews = {{VK_NULL_HANDLE, mDepthStencilImageView.getHandle()}};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
......
......@@ -286,11 +286,8 @@ PixelBuffer::SubresourceUpdate::SubresourceUpdate(const SubresourceUpdate &other
// TextureVk implementation.
TextureVk::TextureVk(const gl::TextureState &state, RendererVk *renderer)
: TextureImpl(state), mPixelBuffer(renderer)
: TextureImpl(state), mRenderTarget(&mImage, &mBaseLevelImageView, this), mPixelBuffer(renderer)
{
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mBaseLevelImageView;
mRenderTarget.resource = this;
}
TextureVk::~TextureVk()
......
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