blob: ef49e387245075cd3915cc9b74cd477d56c94d26 [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{
20
Luc Ferrone6a40d02018-03-22 10:30:57 -040021namespace
22{
23constexpr VkClearDepthStencilValue kDefaultClearDepthStencilValue = {0.0f, 1};
24constexpr VkClearColorValue kBlackClearColorValue = {{0}};
25
26} // anonymous namespace
27
Jamie Madillbcf467f2018-05-23 09:46:00 -040028RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
Geoff Langfe59f6b2019-01-16 09:34:30 -050029 : RenderbufferImpl(state), mOwnsImage(false), mImage(nullptr)
Jamie Madillb980c562018-11-27 11:34:27 -050030{}
Jamie Madill9e54b5a2016-05-25 12:57:39 -040031
Jamie Madillb980c562018-11-27 11:34:27 -050032RenderbufferVk::~RenderbufferVk() {}
Jamie Madill9e54b5a2016-05-25 12:57:39 -040033
Jamie Madillc2328a12018-10-18 15:00:29 -040034void RenderbufferVk::onDestroy(const gl::Context *context)
Jamie Madill12eb3d72018-02-14 12:34:45 -050035{
36 ContextVk *contextVk = vk::GetImpl(context);
37 RendererVk *renderer = contextVk->getRenderer();
Geoff Langfe59f6b2019-01-16 09:34:30 -050038 releaseAndDeleteImage(context, renderer);
Jamie Madill12eb3d72018-02-14 12:34:45 -050039}
40
Jamie Madillc2328a12018-10-18 15:00:29 -040041angle::Result RenderbufferVk::setStorage(const gl::Context *context,
42 GLenum internalformat,
43 size_t width,
44 size_t height)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040045{
Jamie Madill12eb3d72018-02-14 12:34:45 -050046 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill57fbfd82018-02-14 12:45:34 -050047 RendererVk *renderer = contextVk->getRenderer();
48 const vk::Format &vkFormat = renderer->getFormat(internalformat);
Jamie Madill12eb3d72018-02-14 12:34:45 -050049
Geoff Langfe59f6b2019-01-16 09:34:30 -050050 if (!mOwnsImage)
51 {
52 releaseAndDeleteImage(context, renderer);
53 }
54
Geoff Langf3e823d2019-01-14 12:40:34 -050055 if (mImage != nullptr && mImage->valid())
Jamie Madill7b213812018-03-06 10:13:13 -050056 {
57 // Check against the state if we need to recreate the storage.
58 if (internalformat != mState.getFormat().info->internalFormat ||
59 static_cast<GLsizei>(width) != mState.getWidth() ||
60 static_cast<GLsizei>(height) != mState.getHeight())
61 {
Geoff Langfe59f6b2019-01-16 09:34:30 -050062 releaseImage(context, renderer);
Jamie Madill7b213812018-03-06 10:13:13 -050063 }
64 }
Jamie Madill0cbfa582018-02-15 14:45:41 -050065
Geoff Langf3e823d2019-01-14 12:40:34 -050066 if ((mImage == nullptr || !mImage->valid()) && (width != 0 && height != 0))
Jamie Madill7b213812018-03-06 10:13:13 -050067 {
Geoff Langf3e823d2019-01-14 12:40:34 -050068 if (mImage == nullptr)
69 {
Geoff Langfe59f6b2019-01-16 09:34:30 -050070 mImage = new vk::ImageHelper();
71 mOwnsImage = true;
Geoff Langf3e823d2019-01-14 12:40:34 -050072 }
73
Luc Ferrone6a40d02018-03-22 10:30:57 -040074 const angle::Format &textureFormat = vkFormat.textureFormat();
75 bool isDepthOrStencilFormat = textureFormat.depthBits > 0 || textureFormat.stencilBits > 0;
Jamie Madill7b213812018-03-06 10:13:13 -050076 const VkImageUsageFlags usage =
Luc Ferrone6a40d02018-03-22 10:30:57 -040077 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
78 VK_IMAGE_USAGE_SAMPLED_BIT |
79 (textureFormat.redBits > 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0) |
80 (isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
Jamie Madill7b213812018-03-06 10:13:13 -050081
Jamie Madillbc543422018-03-30 10:43:19 -040082 gl::Extents extents(static_cast<int>(width), static_cast<int>(height), 1);
Geoff Langf3e823d2019-01-14 12:40:34 -050083 ANGLE_TRY(mImage->init(contextVk, gl::TextureType::_2D, extents, vkFormat, 1, usage, 1, 1));
Jamie Madill7b213812018-03-06 10:13:13 -050084
85 VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
Geoff Langf3e823d2019-01-14 12:40:34 -050086 ANGLE_TRY(mImage->initMemory(contextVk, renderer->getMemoryProperties(), flags));
Jamie Madill7b213812018-03-06 10:13:13 -050087
Geoff Lang9e141642018-06-27 11:43:18 -040088 VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
Jamie Madill7b213812018-03-06 10:13:13 -050089
Shahbaz Youssefif83a28a2018-12-09 03:48:34 +010090 // Note that LUMA textures are not color-renderable, so a read-view with swizzle is not
91 // needed.
Geoff Langf3e823d2019-01-14 12:40:34 -050092 ANGLE_TRY(mImage->initImageView(contextVk, gl::TextureType::_2D, aspect, gl::SwizzleState(),
Geoff Lang4a298702019-01-18 10:49:36 -050093 &mImageView, 0, 1));
Jamie Madille4c5a232018-03-02 21:00:31 -050094
95 // TODO(jmadill): Fold this into the RenderPass load/store ops. http://anglebug.com/2361
96 vk::CommandBuffer *commandBuffer = nullptr;
Geoff Langf3e823d2019-01-14 12:40:34 -050097 ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
Jamie Madill93edca12018-03-30 10:43:18 -040098
Luc Ferrone6a40d02018-03-22 10:30:57 -040099 if (isDepthOrStencilFormat)
100 {
Geoff Langf3e823d2019-01-14 12:40:34 -0500101 mImage->clearDepthStencil(aspect, aspect, kDefaultClearDepthStencilValue,
102 commandBuffer);
Luc Ferrone6a40d02018-03-22 10:30:57 -0400103 }
104 else
105 {
Geoff Langf3e823d2019-01-14 12:40:34 -0500106 mImage->clearColor(kBlackClearColorValue, 0, 1, commandBuffer);
Luc Ferrone6a40d02018-03-22 10:30:57 -0400107 }
Geoff Langf3e823d2019-01-14 12:40:34 -0500108
Geoff Lang4a298702019-01-18 10:49:36 -0500109 mRenderTarget.init(mImage, &mImageView, 0, 0, nullptr);
Jamie Madill7b213812018-03-06 10:13:13 -0500110 }
111
Jamie Madill7c985f52018-11-29 18:16:17 -0500112 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400113}
114
Jamie Madillc2328a12018-10-18 15:00:29 -0400115angle::Result RenderbufferVk::setStorageMultisample(const gl::Context *context,
116 size_t samples,
117 GLenum internalformat,
118 size_t width,
119 size_t height)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400120{
Jamie Madillc2328a12018-10-18 15:00:29 -0400121 ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
Jamie Madill7c985f52018-11-29 18:16:17 -0500122 return angle::Result::Stop;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400123}
124
Jamie Madillc2328a12018-10-18 15:00:29 -0400125angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context,
126 egl::Image *image)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400127{
Geoff Langfe59f6b2019-01-16 09:34:30 -0500128 ContextVk *contextVk = vk::GetImpl(context);
129 RendererVk *renderer = contextVk->getRenderer();
130
131 releaseAndDeleteImage(context, renderer);
132
133 ImageVk *imageVk = vk::GetImpl(image);
134 mImage = imageVk->getImage();
135 mOwnsImage = false;
136
137 const vk::Format &vkFormat = renderer->getFormat(image->getFormat().info->sizedInternalFormat);
138 const angle::Format &textureFormat = vkFormat.textureFormat();
139
140 VkImageAspectFlags aspect = vk::GetFormatAspectFlags(textureFormat);
141
Geoff Langeca36cb2019-01-18 14:03:52 -0500142 ANGLE_TRY(mImage->initLayerImageView(contextVk, imageVk->getImageTextureType(), aspect,
143 gl::SwizzleState(), &mImageView, imageVk->getImageLevel(),
144 1, imageVk->getImageLayer(), 1));
Geoff Langfe59f6b2019-01-16 09:34:30 -0500145
Geoff Langeca36cb2019-01-18 14:03:52 -0500146 mRenderTarget.init(mImage, &mImageView, imageVk->getImageLevel(), imageVk->getImageLayer(),
147 nullptr);
Geoff Langfe59f6b2019-01-16 09:34:30 -0500148
149 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400150}
151
Jamie Madill6f755b22018-10-09 12:48:54 -0400152angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *context,
153 GLenum binding,
154 const gl::ImageIndex &imageIndex,
155 FramebufferAttachmentRenderTarget **rtOut)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400156{
Geoff Langf3e823d2019-01-14 12:40:34 -0500157 ASSERT(mImage && mImage->valid());
Jamie Madill0cbfa582018-02-15 14:45:41 -0500158 *rtOut = &mRenderTarget;
Jamie Madill7c985f52018-11-29 18:16:17 -0500159 return angle::Result::Continue;
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400160}
161
Jamie Madill6f755b22018-10-09 12:48:54 -0400162angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
163 const gl::ImageIndex &imageIndex)
Jamie Madill05b35b22017-10-03 09:01:44 -0400164{
165 UNIMPLEMENTED();
Jamie Madill7c985f52018-11-29 18:16:17 -0500166 return angle::Result::Continue;
Jamie Madill05b35b22017-10-03 09:01:44 -0400167}
168
Geoff Langfe59f6b2019-01-16 09:34:30 -0500169void RenderbufferVk::releaseOwnershipOfImage(const gl::Context *context)
170{
171 ContextVk *contextVk = vk::GetImpl(context);
172 RendererVk *renderer = contextVk->getRenderer();
173
174 mOwnsImage = false;
175 releaseAndDeleteImage(context, renderer);
176}
177
178void RenderbufferVk::releaseAndDeleteImage(const gl::Context *context, RendererVk *renderer)
179{
180 releaseImage(context, renderer);
181 SafeDelete(mImage);
182}
183
184void RenderbufferVk::releaseImage(const gl::Context *context, RendererVk *renderer)
185{
186 if (mImage && mOwnsImage)
187 {
188 mImage->releaseImage(renderer);
189 mImage->releaseStagingBuffer(renderer);
190 }
191 else
192 {
193 mImage = nullptr;
194 }
195
196 renderer->releaseObject(renderer->getCurrentQueueSerial(), &mImageView);
197}
198
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400199} // namespace rx