Commit bc54342b by Jamie Madill Committed by Commit Bot

Vulkan: Make RenderTargetVk use ImageHelper.

Bug: angleproject:2318 Change-Id: I9bc4bb7f5bcd3029a31c8570809f253cf5e4b12a Reviewed-on: https://chromium-review.googlesource.com/980773 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarLuc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 62059a55
......@@ -140,17 +140,14 @@ void CommandGraphNode::storeRenderPassInfo(const Framebuffer &framebuffer,
void CommandGraphNode::appendColorRenderTarget(Serial serial, RenderTargetVk *colorRenderTarget)
{
// TODO(jmadill): Layout transition?
mRenderPassDesc.packColorAttachment(*colorRenderTarget->format, colorRenderTarget->samples);
mRenderPassDesc.packColorAttachment(*colorRenderTarget->image);
colorRenderTarget->resource->onWriteResource(this, serial);
}
void CommandGraphNode::appendDepthStencilRenderTarget(Serial serial,
RenderTargetVk *depthStencilRenderTarget)
{
// TODO(jmadill): Layout transition?
mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->format,
depthStencilRenderTarget->samples);
mRenderPassDesc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
depthStencilRenderTarget->resource->onWriteResource(this, serial);
}
......
......@@ -34,7 +34,8 @@ namespace
const gl::InternalFormat &GetReadAttachmentInfo(const gl::Context *context,
RenderTargetVk *renderTarget)
{
GLenum implFormat = renderTarget->format->textureFormat().fboImplementationInternalFormat;
GLenum implFormat =
renderTarget->image->getFormat().textureFormat().fboImplementationInternalFormat;
return gl::GetSizedInternalFormatInfo(implFormat);
}
} // anonymous namespace
......@@ -149,11 +150,11 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
RenderTargetVk *renderTarget = mRenderTargetCache.getDepthStencil();
renderTarget->resource->onWriteResource(writingNode, currentSerial);
renderTarget->image->changeLayoutWithStages(
renderTarget->image->getImage().changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleDepthStencilImage(*renderTarget->image, aspectFlags,
commandBuffer->clearSingleDepthStencilImage(renderTarget->image->getImage(), aspectFlags,
clearDepthStencilValue);
if ((mask & GL_COLOR_BUFFER_BIT) == 0)
......@@ -188,11 +189,11 @@ gl::Error FramebufferVk::clear(const gl::Context *context, GLbitfield mask)
ASSERT(colorRenderTarget);
colorRenderTarget->resource->onWriteResource(writingNode, currentSerial);
colorRenderTarget->image->changeLayoutWithStages(
colorRenderTarget->image->getImage().changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
commandBuffer->clearSingleColorImage(*colorRenderTarget->image,
commandBuffer->clearSingleColorImage(colorRenderTarget->image->getImage(),
contextVk->getClearColorValue().color);
}
......@@ -260,10 +261,10 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(renderTarget);
vk::Image *readImage = renderTarget->image;
vk::Image &readImage = renderTarget->image->getImage();
vk::ImageHelper stagingImage;
ANGLE_TRY(stagingImage.init2DStaging(
device, renderer->getMemoryProperties(), *renderTarget->format,
device, renderer->getMemoryProperties(), renderTarget->image->getFormat(),
gl::Extents(area.width, area.height, 1), vk::StagingUsage::Read));
vk::CommandBuffer *commandBuffer = nullptr;
......@@ -272,7 +273,7 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
stagingImage.getImage().changeLayoutTop(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
commandBuffer);
readImage->changeLayoutWithStages(
readImage.changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
......@@ -295,7 +296,7 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
region.extent.height = area.height;
region.extent.depth = 1;
commandBuffer->copyImage(*readImage, stagingImage.getImage(), 1, &region);
commandBuffer->copyImage(readImage, stagingImage.getImage(), 1, &region);
// Triggers a full finish.
// TODO(jmadill): Don't block on asynchronous readback.
......@@ -306,7 +307,7 @@ gl::Error FramebufferVk::readPixels(const gl::Context *context,
ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, stagingImage.getAllocatedMemorySize(),
0, &mapPointer));
const angle::Format &angleFormat = renderTarget->format->textureFormat();
const angle::Format &angleFormat = renderTarget->image->getFormat().textureFormat();
// TODO(jmadill): Use pixel bytes from the ANGLE format directly.
const auto &glFormat = gl::GetSizedInternalFormatInfo(angleFormat.glInternalFormat);
......@@ -384,14 +385,13 @@ const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc(const gl::Context *co
{
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndex];
ASSERT(colorRenderTarget);
desc.packColorAttachment(*colorRenderTarget->format, colorRenderTarget->samples);
desc.packColorAttachment(*colorRenderTarget->image);
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
desc.packDepthStencilAttachment(*depthStencilRenderTarget->format,
depthStencilRenderTarget->samples);
desc.packDepthStencilAttachment(*depthStencilRenderTarget->image);
}
mRenderPassDesc = desc;
......@@ -431,8 +431,9 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con
ASSERT(colorRenderTarget);
attachments.push_back(colorRenderTarget->imageView->getHandle());
ASSERT(attachmentsSize.empty() || attachmentsSize == colorRenderTarget->extents);
attachmentsSize = colorRenderTarget->extents;
ASSERT(attachmentsSize.empty() ||
attachmentsSize == colorRenderTarget->image->getExtents());
attachmentsSize = colorRenderTarget->image->getExtents();
}
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
......@@ -440,8 +441,9 @@ gl::ErrorOrResult<vk::Framebuffer *> FramebufferVk::getFramebuffer(const gl::Con
{
attachments.push_back(depthStencilRenderTarget->imageView->getHandle());
ASSERT(attachmentsSize.empty() || attachmentsSize == depthStencilRenderTarget->extents);
attachmentsSize = depthStencilRenderTarget->extents;
ASSERT(attachmentsSize.empty() ||
attachmentsSize == depthStencilRenderTarget->image->getExtents());
attachmentsSize = depthStencilRenderTarget->image->getExtents();
}
ASSERT(!attachments.empty());
......@@ -547,7 +549,7 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
ASSERT(colorRenderTarget);
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
colorRenderTarget->image->changeLayoutWithStages(
colorRenderTarget->image->getImage().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,
commandBuffer);
......@@ -559,11 +561,11 @@ gl::Error FramebufferVk::getCommandGraphNodeForDraw(const gl::Context *context,
if (depthStencilRenderTarget)
{
// TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
const angle::Format &format = depthStencilRenderTarget->format->textureFormat();
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(
depthStencilRenderTarget->image->getImage().changeLayoutWithStages(
aspectFlags, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
commandBuffer);
......
......@@ -11,20 +11,7 @@
namespace rx
{
RenderTargetVk::RenderTargetVk()
RenderTargetVk::RenderTargetVk() : image(nullptr), imageView(nullptr), resource(nullptr)
{
reset();
}
void RenderTargetVk::reset()
{
format = nullptr;
image = nullptr;
imageView = nullptr;
extents = gl::Extents();
samples = VK_SAMPLE_COUNT_1_BIT;
resource = nullptr;
}
} // namespace rx
......@@ -20,10 +20,9 @@ class ResourceVk;
namespace vk
{
struct Format;
class Image;
class ImageHelper;
class ImageView;
}
} // 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
......@@ -33,13 +32,8 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
public:
RenderTargetVk();
void reset();
const vk::Format *format;
vk::Image *image;
vk::ImageHelper *image;
vk::ImageView *imageView;
gl::Extents extents;
VkSampleCountFlagBits samples;
ResourceVk *resource;
};
......
......@@ -25,7 +25,7 @@ constexpr VkClearColorValue kBlackClearColorValue = {{0}};
RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state) : RenderbufferImpl(state)
{
mRenderTarget.image = &mImage.getImage();
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.resource = this;
}
......@@ -70,13 +70,6 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
}
}
// Init RenderTarget.
mRenderTarget.extents.width = static_cast<int>(width);
mRenderTarget.extents.height = static_cast<int>(height);
mRenderTarget.extents.depth = 1;
mRenderTarget.format = &vkFormat;
mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT; // TODO(jmadill): Multisample bits.
if (!mImage.valid() && (width != 0 || height != 0))
{
const angle::Format &textureFormat = vkFormat.textureFormat();
......@@ -87,7 +80,8 @@ gl::Error RenderbufferVk::setStorage(const gl::Context *context,
(textureFormat.redBits > 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0) |
(isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
ANGLE_TRY(mImage.init2D(device, mRenderTarget.extents, vkFormat, 1, usage));
gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
ANGLE_TRY(mImage.init2D(device, extents, vkFormat, 1, usage));
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(mImage.initMemory(device, renderer->getMemoryProperties(), flags));
......
......@@ -128,13 +128,13 @@ class WindowSurfaceVk : public SurfaceImpl, public ResourceVk
// problem with needing to know the next available image index before we acquire it.
vk::Semaphore mAcquireNextImageSemaphore;
struct SwapchainImage
struct SwapchainImage : angle::NonCopyable
{
SwapchainImage();
SwapchainImage(SwapchainImage &&other);
~SwapchainImage();
vk::Image image;
vk::ImageHelper image;
vk::ImageView imageView;
vk::Framebuffer framebuffer;
vk::Semaphore imageAcquiredSemaphore;
......@@ -143,8 +143,7 @@ class WindowSurfaceVk : public SurfaceImpl, public ResourceVk
std::vector<SwapchainImage> mSwapchainImages;
vk::Image mDepthStencilImage;
vk::DeviceMemory mDepthStencilDeviceMemory;
vk::ImageHelper mDepthStencilImage;
vk::ImageView mDepthStencilImageView;
};
......
......@@ -52,6 +52,9 @@ void MapSwizzleState(GLenum internalFormat,
TextureVk::TextureVk(const gl::TextureState &state) : TextureImpl(state)
{
mRenderTarget.image = &mImage;
mRenderTarget.imageView = &mImageView;
mRenderTarget.resource = this;
}
TextureVk::~TextureVk()
......@@ -105,8 +108,6 @@ gl::Error TextureVk::setImage(const gl::Context *context,
}
}
mRenderTarget.reset();
// Early-out on empty textures, don't create a zero-sized storage.
if (size.width == 0 || size.height == 0 || size.depth == 0)
{
......@@ -173,13 +174,6 @@ gl::Error TextureVk::setImage(const gl::Context *context,
ANGLE_TRY(mSampler.init(device, samplerInfo));
}
mRenderTarget.image = &mImage.getImage();
mRenderTarget.imageView = &mImageView;
mRenderTarget.format = &vkFormat;
mRenderTarget.extents = size;
mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT;
mRenderTarget.resource = this;
// Handle initial data.
if (pixels)
{
......@@ -212,8 +206,8 @@ gl::Error TextureVk::setSubImageImpl(ContextVk *contextVk,
{
RendererVk *renderer = contextVk->getRenderer();
VkDevice device = renderer->getDevice();
const gl::Extents &size = mRenderTarget.extents;
const vk::Format &vkFormat = *mRenderTarget.format;
const gl::Extents &size = mImage.getExtents();
const vk::Format &vkFormat = mImage.getFormat();
vk::ImageHelper stagingImage;
ANGLE_TRY(stagingImage.init2DStaging(device, renderer->getMemoryProperties(), vkFormat, size,
......
......@@ -232,29 +232,30 @@ RenderPassDesc::RenderPassDesc(const RenderPassDesc &other)
memcpy(this, &other, sizeof(RenderPassDesc));
}
void RenderPassDesc::packAttachment(uint32_t index, const vk::Format &format, GLsizei samples)
void RenderPassDesc::packAttachment(uint32_t index, const ImageHelper &imageHelper)
{
PackedAttachmentDesc &desc = mAttachmentDescs[index];
// TODO(jmadill): We would only need this flag for duplicated attachments.
desc.flags = VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT;
ASSERT(desc.samples < std::numeric_limits<uint8_t>::max());
desc.samples = static_cast<uint8_t>(samples);
ASSERT(imageHelper.getSamples() < std::numeric_limits<uint8_t>::max());
desc.samples = static_cast<uint8_t>(imageHelper.getSamples());
const Format &format = imageHelper.getFormat();
ASSERT(format.vkTextureFormat < std::numeric_limits<uint16_t>::max());
desc.format = static_cast<uint16_t>(format.vkTextureFormat);
}
void RenderPassDesc::packColorAttachment(const vk::Format &format, GLsizei samples)
void RenderPassDesc::packColorAttachment(const ImageHelper &imageHelper)
{
ASSERT(mDepthStencilAttachmentCount == 0);
ASSERT(mColorAttachmentCount < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
packAttachment(mColorAttachmentCount++, format, samples);
packAttachment(mColorAttachmentCount++, imageHelper);
}
void RenderPassDesc::packDepthStencilAttachment(const vk::Format &format, GLsizei samples)
void RenderPassDesc::packDepthStencilAttachment(const ImageHelper &imageHelper)
{
ASSERT(mDepthStencilAttachmentCount == 0);
packAttachment(mColorAttachmentCount + mDepthStencilAttachmentCount++, format, samples);
packAttachment(mColorAttachmentCount + mDepthStencilAttachmentCount++, imageHelper);
}
RenderPassDesc &RenderPassDesc::operator=(const RenderPassDesc &other)
......
......@@ -54,8 +54,8 @@ class RenderPassDesc final
RenderPassDesc &operator=(const RenderPassDesc &other);
// Depth stencil attachments must be packed after color attachments.
void packColorAttachment(const Format &format, GLsizei samples);
void packDepthStencilAttachment(const Format &format, GLsizei samples);
void packColorAttachment(const ImageHelper &imageHelper);
void packDepthStencilAttachment(const ImageHelper &imageHelper);
size_t hash() const;
......@@ -65,7 +65,7 @@ class RenderPassDesc final
const PackedAttachmentDesc &operator[](size_t index) const;
private:
void packAttachment(uint32_t index, const vk::Format &format, GLsizei samples);
void packAttachment(uint32_t index, const ImageHelper &imageHelper);
uint32_t mColorAttachmentCount;
uint32_t mDepthStencilAttachmentCount;
......
......@@ -1425,6 +1425,16 @@ ImageHelper::ImageHelper() : mFormat(nullptr), mSamples(0), mAllocatedMemorySize
{
}
ImageHelper::ImageHelper(ImageHelper &&other)
: mImage(std::move(other.mImage)),
mDeviceMemory(std::move(other.mDeviceMemory)),
mExtents(other.mExtents),
mFormat(other.mFormat),
mSamples(other.mSamples),
mAllocatedMemorySize(other.mAllocatedMemorySize)
{
}
ImageHelper::~ImageHelper()
{
ASSERT(!valid());
......@@ -1480,6 +1490,7 @@ Error ImageHelper::initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags)
{
// TODO(jmadill): Memory sub-allocation. http://anglebug.com/2162
ANGLE_TRY(AllocateBufferOrImageMemory(device, memoryProperties, flags, &mImage, &mDeviceMemory,
&mAllocatedMemorySize));
return NoError();
......@@ -1517,6 +1528,20 @@ void ImageHelper::destroy(VkDevice device)
mDeviceMemory.destroy(device);
}
void ImageHelper::init2DWeakReference(VkImage handle,
const gl::Extents &extents,
const Format &format,
GLint samples)
{
ASSERT(!valid());
mExtents = extents;
mFormat = &format;
mSamples = samples;
mImage.setHandle(handle);
}
Error ImageHelper::init2DStaging(VkDevice device,
const MemoryProperties &memoryProperties,
const Format &format,
......
......@@ -707,6 +707,7 @@ class ImageHelper final : angle::NonCopyable
{
public:
ImageHelper();
ImageHelper(ImageHelper &&other);
~ImageHelper();
bool valid() const;
......@@ -716,6 +717,10 @@ class ImageHelper final : angle::NonCopyable
const Format &format,
GLint samples,
VkImageUsageFlags usage);
void init2DWeakReference(VkImage handle,
const gl::Extents &extents,
const Format &format,
GLint samples);
Error initMemory(VkDevice device,
const MemoryProperties &memoryProperties,
VkMemoryPropertyFlags flags);
......
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