blob: 53e1a5f99557ae11943adbac4b3d689357130486 [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// RenderbufferVk.cpp:
7// Implements the class methods for RenderbufferVk.
8//
9
10#include "libANGLE/renderer/vulkan/RenderbufferVk.h"
11
Jamie Madill12eb3d72018-02-14 12:34:45 -050012#include "libANGLE/Context.h"
Geoff Langfe59f6b2019-01-16 09:34:30 -050013#include "libANGLE/Image.h"
Jamie Madill12eb3d72018-02-14 12:34:45 -050014#include "libANGLE/renderer/vulkan/ContextVk.h"
Geoff Langfe59f6b2019-01-16 09:34:30 -050015#include "libANGLE/renderer/vulkan/ImageVk.h"
Jamie Madill12eb3d72018-02-14 12:34:45 -050016#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill9e54b5a2016-05-25 12:57:39 -040017
18namespace rx
19{
Jamie Madillbcf467f2018-05-23 09:46:00 -040020RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
Geoff Langfe59f6b2019-01-16 09:34:30 -050021 : RenderbufferImpl(state), mOwnsImage(false), mImage(nullptr)
Jamie Madillb980c562018-11-27 11:34:27 -050022{}
Jamie Madill9e54b5a2016-05-25 12:57:39 -040023
Jamie Madillb980c562018-11-27 11:34:27 -050024RenderbufferVk::~RenderbufferVk() {}
Jamie Madill9e54b5a2016-05-25 12:57:39 -040025
Jamie Madillc2328a12018-10-18 15:00:29 -040026void RenderbufferVk::onDestroy(const gl::Context *context)
Jamie Madill12eb3d72018-02-14 12:34:45 -050027{
28 ContextVk *contextVk = vk::GetImpl(context);
29 RendererVk *renderer = contextVk->getRenderer();
Geoff Langfe59f6b2019-01-16 09:34:30 -050030 releaseAndDeleteImage(context, renderer);
Jamie Madill12eb3d72018-02-14 12:34:45 -050031}
32
Jamie Madillc2328a12018-10-18 15:00:29 -040033angle::Result RenderbufferVk::setStorage(const gl::Context *context,
34 GLenum internalformat,
35 size_t width,
36 size_t height)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040037{
Jamie Madill12eb3d72018-02-14 12:34:45 -050038 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill57fbfd82018-02-14 12:45:34 -050039 RendererVk *renderer = contextVk->getRenderer();
40 const vk::Format &vkFormat = renderer->getFormat(internalformat);
Jamie Madill12eb3d72018-02-14 12:34:45 -050041
Geoff Langfe59f6b2019-01-16 09:34:30 -050042 if (!mOwnsImage)
43 {
44 releaseAndDeleteImage(context, renderer);
45 }
46
Geoff Langf3e823d2019-01-14 12:40:34 -050047 if (mImage != nullptr && mImage->valid())
Jamie Madill7b213812018-03-06 10:13:13 -050048 {
49 // Check against the state if we need to recreate the storage.
50 if (internalformat != mState.getFormat().info->internalFormat ||
51 static_cast<GLsizei>(width) != mState.getWidth() ||
52 static_cast<GLsizei>(height) != mState.getHeight())
53 {
Geoff Langfe59f6b2019-01-16 09:34:30 -050054 releaseImage(context, renderer);
Jamie Madill7b213812018-03-06 10:13:13 -050055 }
56 }
Jamie Madill0cbfa582018-02-15 14:45:41 -050057
Geoff Langf3e823d2019-01-14 12:40:34 -050058 if ((mImage == nullptr || !mImage->valid()) && (width != 0 && height != 0))
Jamie Madill7b213812018-03-06 10:13:13 -050059 {
Geoff Langf3e823d2019-01-14 12:40:34 -050060 if (mImage == nullptr)
61 {
Geoff Langfe59f6b2019-01-16 09:34:30 -050062 mImage = new vk::ImageHelper();
63 mOwnsImage = true;
Geoff Langf3e823d2019-01-14 12:40:34 -050064 }
65
Jamie Madill0631e192019-04-18 16:09:12 -040066 const angle::Format &textureFormat = vkFormat.imageFormat();
Luc Ferrone6a40d02018-03-22 10:30:57 -040067 bool isDepthOrStencilFormat = textureFormat.depthBits > 0 || textureFormat.stencilBits > 0;
Jamie Madill7b213812018-03-06 10:13:13 -050068 const VkImageUsageFlags usage =
Luc Ferrone6a40d02018-03-22 10:30:57 -040069 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
70 VK_IMAGE_USAGE_SAMPLED_BIT |
71 (textureFormat.redBits > 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0) |
72 (isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
Jamie Madill7b213812018-03-06 10:13:13 -050073
Jamie Madillbc543422018-03-30 10:43:19 -040074 gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
Geoff Langf3e823d2019-01-14 12:40:34 -050075 ANGLE_TRY(mImage->init(contextVk, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1, 1));
Jamie Madill7b213812018-03-06 10:13:13 -050076
77 VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
Geoff Langf3e823d2019-01-14 12:40:34 -050078 ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
Jamie Madill7b213812018-03-06 10:13:13 -050079
Geoff Lang9e141642018-06-27 11:43:18 -040080 VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
Jamie Madill7b213812018-03-06 10:13:13 -050081
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010082 // Note that LUMA textures are not color-renderable, so a read-view with swizzle is not
83 // needed.
Geoff Langf3e823d2019-01-14 12:40:34 -050084 ANGLE_TRY(mImage->initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
Geoff Lang4a298702019-01-18 10:49:36 -050085 &mImageView, 0, 1));
Jamie Madille4c5a232018-03-02 21:00:31 -050086
Shahbaz Youssefi65d10f32019-03-21 16:30:31 -040087 // Clear the renderbuffer if it has emulated channels.
Jamie Madill67220092019-05-20 11:12:53 -040088 mImage->clearIfEmulatedFormat(vk::GetImpl(context), gl::ImageIndex::Make2D(0), vkFormat);
Geoff Langf3e823d2019-01-14 12:40:34 -050089
Jamie Madill67220092019-05-20 11:12:53 -040090 mRenderTarget.init(mImage, &mImageView, 0, 0);
Jamie Madill7b213812018-03-06 10:13:13 -050091 }
92
Jamie Madill7c985f52018-11-29 18:16:17 -050093 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -040094}
95
Jamie Madillc2328a12018-10-18 15:00:29 -040096angle::Result RenderbufferVk::setStorageMultisample(const gl::Context *context,
97 size_t samples,
98 GLenum internalformat,
99 size_t width,
100 size_t height)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400101{
Jamie Madillc2328a12018-10-18 15:00:29 -0400102 ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
Jamie Madill7c985f52018-11-29 18:16:17 -0500103 return angle::Result::Stop;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400104}
105
Jamie Madillc2328a12018-10-18 15:00:29 -0400106angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context,
107 egl::Image *image)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400108{
Geoff Langfe59f6b2019-01-16 09:34:30 -0500109 ContextVk *contextVk = vk::GetImpl(context);
110 RendererVk *renderer = contextVk->getRenderer();
111
112 releaseAndDeleteImage(context, renderer);
113
114 ImageVk *imageVk = vk::GetImpl(image);
115 mImage = imageVk->getImage();
116 mOwnsImage = false;
117
118 const vk::Format &vkFormat = renderer->getFormat(image->getFormat().info->sizedInternalFormat);
Jamie Madill0631e192019-04-18 16:09:12 -0400119 const angle::Format &textureFormat = vkFormat.imageFormat();
Geoff Langfe59f6b2019-01-16 09:34:30 -0500120
121 VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
122
Geoff Lang009696c2019-01-31 14:47:07 -0500123 // Transfer the image to this queue if needed
124 uint32_t rendererQueueFamilyIndex = contextVk->getRenderer()->getQueueFamilyIndex();
125 if (mImage->isQueueChangeNeccesary(rendererQueueFamilyIndex))
126 {
Shahbaz Youssefi2660b502019-03-21 12:08:40 -0400127 vk::CommandBuffer *commandBuffer = nullptr;
Geoff Lang009696c2019-01-31 14:47:07 -0500128 ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
129 mImage->changeLayoutAndQueue(aspect, vk::ImageLayout::ColorAttachment,
130 rendererQueueFamilyIndex, commandBuffer);
131 }
132
Geoff Langeca36cb2019-01-18 14:03:52 -0500133 ANGLE_TRY(mImage->initLayerImageView(contextVk, imageVk->getImageTextureType(), aspect,
134 gl::SwizzleState(), &mImageView, imageVk->getImageLevel(),
135 1, imageVk->getImageLayer(), 1));
Geoff Langfe59f6b2019-01-16 09:34:30 -0500136
Jamie Madill67220092019-05-20 11:12:53 -0400137 mRenderTarget.init(mImage, &mImageView, imageVk->getImageLevel(), imageVk->getImageLayer());
Geoff Langfe59f6b2019-01-16 09:34:30 -0500138
139 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400140}
141
Jamie Madill6f755b22018-10-09 12:48:54 -0400142angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *context,
143 GLenum binding,
144 const gl::ImageIndex &imageIndex,
145 FramebufferAttachmentRenderTarget **rtOut)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400146{
Geoff Langf3e823d2019-01-14 12:40:34 -0500147 ASSERT(mImage && mImage->valid());
Jamie Madill67220092019-05-20 11:12:53 -0400148 ANGLE_TRY(mRenderTarget.flushStagedUpdates(vk::GetImpl(context)));
Jamie Madill0cbfa582018-02-15 14:45:41 -0500149 *rtOut = &mRenderTarget;
Jamie Madill7c985f52018-11-29 18:16:17 -0500150 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400151}
152
Jamie Madill6f755b22018-10-09 12:48:54 -0400153angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
154 const gl::ImageIndex &imageIndex)
Jamie Madill05b35b22017-10-03 09:01:44 -0400155{
Shahbaz Youssefi65d10f32019-03-21 16:30:31 -0400156 mImage->stageSubresourceRobustClear(imageIndex, mImage->getFormat().angleFormat());
157 return mImage->flushAllStagedUpdates(vk::GetImpl(context));
Jamie Madill05b35b22017-10-03 09:01:44 -0400158}
159
Geoff Langfe59f6b2019-01-16 09:34:30 -0500160void RenderbufferVk::releaseOwnershipOfImage(const gl::Context *context)
161{
162 ContextVk *contextVk = vk::GetImpl(context);
163 RendererVk *renderer = contextVk->getRenderer();
164
165 mOwnsImage = false;
166 releaseAndDeleteImage(context, renderer);
167}
168
169void RenderbufferVk::releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer)
170{
171 releaseImage(context, renderer);
172 SafeDelete(mImage);
173}
174
175void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *renderer)
176{
177 if (mImage && mOwnsImage)
178 {
179 mImage->releaseImage(renderer);
180 mImage->releaseStagingBuffer(renderer);
181 }
182 else
183 {
184 mImage = nullptr;
185 }
186
187 renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
188}
189
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400190} // namespace rx