xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // RenderbufferVk.cpp:
7*8975f5c5SAndroid Build Coastguard Worker //    Implements the class methods for RenderbufferVk.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/RenderbufferVk.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/ContextVk.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/ImageVk.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/TextureVk.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_renderer.h"
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker namespace rx
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker namespace
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker angle::SubjectIndex kRenderbufferImageSubjectIndex = 0;
24*8975f5c5SAndroid Build Coastguard Worker }  // namespace
25*8975f5c5SAndroid Build Coastguard Worker 
RenderbufferVk(const gl::RenderbufferState & state)26*8975f5c5SAndroid Build Coastguard Worker RenderbufferVk::RenderbufferVk(const gl::RenderbufferState &state)
27*8975f5c5SAndroid Build Coastguard Worker     : RenderbufferImpl(state),
28*8975f5c5SAndroid Build Coastguard Worker       mOwnsImage(false),
29*8975f5c5SAndroid Build Coastguard Worker       mImage(nullptr),
30*8975f5c5SAndroid Build Coastguard Worker       mImageObserverBinding(this, kRenderbufferImageSubjectIndex)
31*8975f5c5SAndroid Build Coastguard Worker {}
32*8975f5c5SAndroid Build Coastguard Worker 
~RenderbufferVk()33*8975f5c5SAndroid Build Coastguard Worker RenderbufferVk::~RenderbufferVk() {}
34*8975f5c5SAndroid Build Coastguard Worker 
onDestroy(const gl::Context * context)35*8975f5c5SAndroid Build Coastguard Worker void RenderbufferVk::onDestroy(const gl::Context *context)
36*8975f5c5SAndroid Build Coastguard Worker {
37*8975f5c5SAndroid Build Coastguard Worker     ContextVk *contextVk = vk::GetImpl(context);
38*8975f5c5SAndroid Build Coastguard Worker     releaseAndDeleteImage(contextVk);
39*8975f5c5SAndroid Build Coastguard Worker }
40*8975f5c5SAndroid Build Coastguard Worker 
setStorageImpl(const gl::Context * context,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,gl::MultisamplingMode mode)41*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::setStorageImpl(const gl::Context *context,
42*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei samples,
43*8975f5c5SAndroid Build Coastguard Worker                                              GLenum internalformat,
44*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei width,
45*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei height,
46*8975f5c5SAndroid Build Coastguard Worker                                              gl::MultisamplingMode mode)
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker     ContextVk *contextVk            = vk::GetImpl(context);
49*8975f5c5SAndroid Build Coastguard Worker     vk::Renderer *renderer          = contextVk->getRenderer();
50*8975f5c5SAndroid Build Coastguard Worker     const vk::Format &format        = renderer->getFormat(internalformat);
51*8975f5c5SAndroid Build Coastguard Worker     angle::FormatID textureFormatID = format.getActualRenderableImageFormatID();
52*8975f5c5SAndroid Build Coastguard Worker 
53*8975f5c5SAndroid Build Coastguard Worker     if (!mOwnsImage)
54*8975f5c5SAndroid Build Coastguard Worker     {
55*8975f5c5SAndroid Build Coastguard Worker         releaseAndDeleteImage(contextVk);
56*8975f5c5SAndroid Build Coastguard Worker     }
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker     if (mImage != nullptr && mImage->valid())
59*8975f5c5SAndroid Build Coastguard Worker     {
60*8975f5c5SAndroid Build Coastguard Worker         // Check against the state if we need to recreate the storage.
61*8975f5c5SAndroid Build Coastguard Worker         if (internalformat != mState.getFormat().info->internalFormat ||
62*8975f5c5SAndroid Build Coastguard Worker             width != mState.getWidth() || height != mState.getHeight() ||
63*8975f5c5SAndroid Build Coastguard Worker             samples != mState.getSamples() || mode != mState.getMultisamplingMode())
64*8975f5c5SAndroid Build Coastguard Worker         {
65*8975f5c5SAndroid Build Coastguard Worker             releaseImage(contextVk);
66*8975f5c5SAndroid Build Coastguard Worker         }
67*8975f5c5SAndroid Build Coastguard Worker     }
68*8975f5c5SAndroid Build Coastguard Worker 
69*8975f5c5SAndroid Build Coastguard Worker     if ((mImage != nullptr && mImage->valid()) || width == 0 || height == 0)
70*8975f5c5SAndroid Build Coastguard Worker     {
71*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
72*8975f5c5SAndroid Build Coastguard Worker     }
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker     if (mImage == nullptr)
75*8975f5c5SAndroid Build Coastguard Worker     {
76*8975f5c5SAndroid Build Coastguard Worker         mImage              = new vk::ImageHelper();
77*8975f5c5SAndroid Build Coastguard Worker         mOwnsImage          = true;
78*8975f5c5SAndroid Build Coastguard Worker         mImageSiblingSerial = {};
79*8975f5c5SAndroid Build Coastguard Worker         mImageObserverBinding.bind(mImage);
80*8975f5c5SAndroid Build Coastguard Worker         mImageViews.init(renderer);
81*8975f5c5SAndroid Build Coastguard Worker     }
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker     const angle::Format &textureFormat = format.getActualRenderableImageFormat();
84*8975f5c5SAndroid Build Coastguard Worker     const bool isDepthStencilFormat    = textureFormat.hasDepthOrStencilBits();
85*8975f5c5SAndroid Build Coastguard Worker     ASSERT(textureFormat.redBits > 0 || isDepthStencilFormat);
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker     const bool isRenderToTexture = mode == gl::MultisamplingMode::MultisampledRenderToTexture;
88*8975f5c5SAndroid Build Coastguard Worker     const bool hasRenderToTextureEXT =
89*8975f5c5SAndroid Build Coastguard Worker         renderer->getFeatures().supportsMultisampledRenderToSingleSampled.enabled;
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker     // Transfer and sampled usage are used for various utilities such as readback or blit.
92*8975f5c5SAndroid Build Coastguard Worker     VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
93*8975f5c5SAndroid Build Coastguard Worker                               VK_IMAGE_USAGE_SAMPLED_BIT;
94*8975f5c5SAndroid Build Coastguard Worker 
95*8975f5c5SAndroid Build Coastguard Worker     // Renderbuffer's normal usage is as framebuffer attachment.
96*8975f5c5SAndroid Build Coastguard Worker     usage |= isDepthStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
97*8975f5c5SAndroid Build Coastguard Worker                                   : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker     // When used to emulate multisampled render to texture, it can be read as input attachment.
100*8975f5c5SAndroid Build Coastguard Worker     if (isRenderToTexture && !hasRenderToTextureEXT)
101*8975f5c5SAndroid Build Coastguard Worker     {
102*8975f5c5SAndroid Build Coastguard Worker         usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
103*8975f5c5SAndroid Build Coastguard Worker     }
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     // For framebuffer fetch and advanced blend emulation, color will be read as input attachment.
106*8975f5c5SAndroid Build Coastguard Worker     // For depth/stencil framebuffer fetch, depth/stencil will also be read as input attachment.
107*8975f5c5SAndroid Build Coastguard Worker     if (!isDepthStencilFormat ||
108*8975f5c5SAndroid Build Coastguard Worker         renderer->getFeatures().supportsShaderFramebufferFetchDepthStencil.enabled)
109*8975f5c5SAndroid Build Coastguard Worker     {
110*8975f5c5SAndroid Build Coastguard Worker         usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
111*8975f5c5SAndroid Build Coastguard Worker     }
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker     VkImageCreateFlags createFlags = vk::kVkImageCreateFlagsNone;
114*8975f5c5SAndroid Build Coastguard Worker     if (isRenderToTexture &&
115*8975f5c5SAndroid Build Coastguard Worker         renderer->getFeatures().supportsMultisampledRenderToSingleSampled.enabled)
116*8975f5c5SAndroid Build Coastguard Worker     {
117*8975f5c5SAndroid Build Coastguard Worker         createFlags |= VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT;
118*8975f5c5SAndroid Build Coastguard Worker     }
119*8975f5c5SAndroid Build Coastguard Worker 
120*8975f5c5SAndroid Build Coastguard Worker     if (contextVk->getFeatures().limitSampleCountTo2.enabled)
121*8975f5c5SAndroid Build Coastguard Worker     {
122*8975f5c5SAndroid Build Coastguard Worker         samples = std::min(samples, 2);
123*8975f5c5SAndroid Build Coastguard Worker     }
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker     const uint32_t imageSamples = isRenderToTexture ? 1 : samples;
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     bool robustInit = contextVk->isRobustResourceInitEnabled();
128*8975f5c5SAndroid Build Coastguard Worker 
129*8975f5c5SAndroid Build Coastguard Worker     VkExtent3D extents = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1u};
130*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImage->initExternal(
131*8975f5c5SAndroid Build Coastguard Worker         contextVk, gl::TextureType::_2D, extents, format.getIntendedFormatID(), textureFormatID,
132*8975f5c5SAndroid Build Coastguard Worker         imageSamples, usage, createFlags, vk::ImageLayout::Undefined, nullptr, gl::LevelIndex(0), 1,
133*8975f5c5SAndroid Build Coastguard Worker         1, robustInit, false, vk::YcbcrConversionDesc{}, nullptr));
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
136*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(contextVk->initImageAllocation(mImage, false, renderer->getMemoryProperties(), flags,
137*8975f5c5SAndroid Build Coastguard Worker                                              vk::MemoryAllocationType::RenderBufferStorageImage));
138*8975f5c5SAndroid Build Coastguard Worker 
139*8975f5c5SAndroid Build Coastguard Worker     // If multisampled render to texture, an implicit multisampled image is created which is used as
140*8975f5c5SAndroid Build Coastguard Worker     // the color or depth/stencil attachment.  At the end of the render pass, this image is
141*8975f5c5SAndroid Build Coastguard Worker     // automatically resolved into |mImage| and its contents are discarded.
142*8975f5c5SAndroid Build Coastguard Worker     if (isRenderToTexture && !hasRenderToTextureEXT)
143*8975f5c5SAndroid Build Coastguard Worker     {
144*8975f5c5SAndroid Build Coastguard Worker         mMultisampledImageViews.init(renderer);
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(mMultisampledImage.initImplicitMultisampledRenderToTexture(
147*8975f5c5SAndroid Build Coastguard Worker             contextVk, false, renderer->getMemoryProperties(), gl::TextureType::_2D, samples,
148*8975f5c5SAndroid Build Coastguard Worker             *mImage, mImage->getExtents(), robustInit));
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker         mRenderTarget.init(&mMultisampledImage, &mMultisampledImageViews, mImage, &mImageViews,
151*8975f5c5SAndroid Build Coastguard Worker                            mImageSiblingSerial, gl::LevelIndex(0), 0, 1,
152*8975f5c5SAndroid Build Coastguard Worker                            RenderTargetTransience::MultisampledTransient);
153*8975f5c5SAndroid Build Coastguard Worker     }
154*8975f5c5SAndroid Build Coastguard Worker     else
155*8975f5c5SAndroid Build Coastguard Worker     {
156*8975f5c5SAndroid Build Coastguard Worker         mRenderTarget.init(mImage, &mImageViews, nullptr, nullptr, mImageSiblingSerial,
157*8975f5c5SAndroid Build Coastguard Worker                            gl::LevelIndex(0), 0, 1, RenderTargetTransience::Default);
158*8975f5c5SAndroid Build Coastguard Worker     }
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
161*8975f5c5SAndroid Build Coastguard Worker }
162*8975f5c5SAndroid Build Coastguard Worker 
setStorage(const gl::Context * context,GLenum internalformat,GLsizei width,GLsizei height)163*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::setStorage(const gl::Context *context,
164*8975f5c5SAndroid Build Coastguard Worker                                          GLenum internalformat,
165*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei width,
166*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei height)
167*8975f5c5SAndroid Build Coastguard Worker {
168*8975f5c5SAndroid Build Coastguard Worker     // The ES 3.0 spec(section 4.4.2.1) states that RenderbufferStorage is equivalent to calling
169*8975f5c5SAndroid Build Coastguard Worker     // RenderbufferStorageMultisample with samples equal to zero.
170*8975f5c5SAndroid Build Coastguard Worker     return setStorageImpl(context, 0, internalformat, width, height,
171*8975f5c5SAndroid Build Coastguard Worker                           gl::MultisamplingMode::Regular);
172*8975f5c5SAndroid Build Coastguard Worker }
173*8975f5c5SAndroid Build Coastguard Worker 
setStorageMultisample(const gl::Context * context,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,gl::MultisamplingMode mode)174*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::setStorageMultisample(const gl::Context *context,
175*8975f5c5SAndroid Build Coastguard Worker                                                     GLsizei samples,
176*8975f5c5SAndroid Build Coastguard Worker                                                     GLenum internalformat,
177*8975f5c5SAndroid Build Coastguard Worker                                                     GLsizei width,
178*8975f5c5SAndroid Build Coastguard Worker                                                     GLsizei height,
179*8975f5c5SAndroid Build Coastguard Worker                                                     gl::MultisamplingMode mode)
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker     return setStorageImpl(context, samples, internalformat, width, height, mode);
182*8975f5c5SAndroid Build Coastguard Worker }
183*8975f5c5SAndroid Build Coastguard Worker 
setStorageEGLImageTarget(const gl::Context * context,egl::Image * image)184*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *context,
185*8975f5c5SAndroid Build Coastguard Worker                                                        egl::Image *image)
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker     ContextVk *contextVk   = vk::GetImpl(context);
188*8975f5c5SAndroid Build Coastguard Worker     vk::Renderer *renderer = contextVk->getRenderer();
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(contextVk->getShareGroup()->lockDefaultContextsPriority(contextVk));
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     releaseAndDeleteImage(contextVk);
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker     ImageVk *imageVk    = vk::GetImpl(image);
195*8975f5c5SAndroid Build Coastguard Worker     mImage              = imageVk->getImage();
196*8975f5c5SAndroid Build Coastguard Worker     mOwnsImage          = false;
197*8975f5c5SAndroid Build Coastguard Worker     mImageSiblingSerial = imageVk->generateSiblingSerial();
198*8975f5c5SAndroid Build Coastguard Worker     mImageObserverBinding.bind(mImage);
199*8975f5c5SAndroid Build Coastguard Worker     mImageViews.init(renderer);
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker     // Update ImageViewHelper's colorspace related state
202*8975f5c5SAndroid Build Coastguard Worker     EGLenum imageColorspaceAttribute = image->getColorspaceAttribute();
203*8975f5c5SAndroid Build Coastguard Worker     if (imageColorspaceAttribute != EGL_GL_COLORSPACE_DEFAULT_EXT)
204*8975f5c5SAndroid Build Coastguard Worker     {
205*8975f5c5SAndroid Build Coastguard Worker         egl::ImageColorspace imageColorspace =
206*8975f5c5SAndroid Build Coastguard Worker             (imageColorspaceAttribute == EGL_GL_COLORSPACE_SRGB_KHR) ? egl::ImageColorspace::SRGB
207*8975f5c5SAndroid Build Coastguard Worker                                                                      : egl::ImageColorspace::Linear;
208*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mImage != nullptr);
209*8975f5c5SAndroid Build Coastguard Worker         mImageViews.updateEglImageColorspace(*mImage, imageColorspace);
210*8975f5c5SAndroid Build Coastguard Worker     }
211*8975f5c5SAndroid Build Coastguard Worker 
212*8975f5c5SAndroid Build Coastguard Worker     // Transfer the image to this queue if needed
213*8975f5c5SAndroid Build Coastguard Worker     if (mImage->isQueueFamilyChangeNeccesary(contextVk->getDeviceQueueIndex()))
214*8975f5c5SAndroid Build Coastguard Worker     {
215*8975f5c5SAndroid Build Coastguard Worker         vk::OutsideRenderPassCommandBuffer *commandBuffer;
216*8975f5c5SAndroid Build Coastguard Worker         vk::CommandBufferAccess access;
217*8975f5c5SAndroid Build Coastguard Worker         access.onExternalAcquireRelease(mImage);
218*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &commandBuffer));
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker         const vk::Format &vkFormat =
221*8975f5c5SAndroid Build Coastguard Worker             renderer->getFormat(image->getFormat().info->sizedInternalFormat);
222*8975f5c5SAndroid Build Coastguard Worker         const angle::Format &textureFormat = vkFormat.getActualRenderableImageFormat();
223*8975f5c5SAndroid Build Coastguard Worker         VkImageAspectFlags aspect          = vk::GetFormatAspectFlags(textureFormat);
224*8975f5c5SAndroid Build Coastguard Worker 
225*8975f5c5SAndroid Build Coastguard Worker         mImage->changeLayoutAndQueue(contextVk, aspect, vk::ImageLayout::ColorWrite,
226*8975f5c5SAndroid Build Coastguard Worker                                      contextVk->getDeviceQueueIndex(), commandBuffer);
227*8975f5c5SAndroid Build Coastguard Worker 
228*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(contextVk->onEGLImageQueueChange());
229*8975f5c5SAndroid Build Coastguard Worker     }
230*8975f5c5SAndroid Build Coastguard Worker 
231*8975f5c5SAndroid Build Coastguard Worker     mRenderTarget.init(mImage, &mImageViews, nullptr, nullptr, mImageSiblingSerial,
232*8975f5c5SAndroid Build Coastguard Worker                        imageVk->getImageLevel(), imageVk->getImageLayer(), 1,
233*8975f5c5SAndroid Build Coastguard Worker                        RenderTargetTransience::Default);
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
236*8975f5c5SAndroid Build Coastguard Worker }
237*8975f5c5SAndroid Build Coastguard Worker 
copyRenderbufferSubData(const gl::Context * context,const gl::Renderbuffer * srcBuffer,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)238*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::copyRenderbufferSubData(const gl::Context *context,
239*8975f5c5SAndroid Build Coastguard Worker                                                       const gl::Renderbuffer *srcBuffer,
240*8975f5c5SAndroid Build Coastguard Worker                                                       GLint srcLevel,
241*8975f5c5SAndroid Build Coastguard Worker                                                       GLint srcX,
242*8975f5c5SAndroid Build Coastguard Worker                                                       GLint srcY,
243*8975f5c5SAndroid Build Coastguard Worker                                                       GLint srcZ,
244*8975f5c5SAndroid Build Coastguard Worker                                                       GLint dstLevel,
245*8975f5c5SAndroid Build Coastguard Worker                                                       GLint dstX,
246*8975f5c5SAndroid Build Coastguard Worker                                                       GLint dstY,
247*8975f5c5SAndroid Build Coastguard Worker                                                       GLint dstZ,
248*8975f5c5SAndroid Build Coastguard Worker                                                       GLsizei srcWidth,
249*8975f5c5SAndroid Build Coastguard Worker                                                       GLsizei srcHeight,
250*8975f5c5SAndroid Build Coastguard Worker                                                       GLsizei srcDepth)
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker     RenderbufferVk *sourceVk = vk::GetImpl(srcBuffer);
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker     // Make sure the source/destination targets are initialized and all staged updates are flushed.
255*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(sourceVk->ensureImageInitialized(context));
256*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(ensureImageInitialized(context));
257*8975f5c5SAndroid Build Coastguard Worker 
258*8975f5c5SAndroid Build Coastguard Worker     return vk::ImageHelper::CopyImageSubData(context, sourceVk->getImage(), srcLevel, srcX, srcY,
259*8975f5c5SAndroid Build Coastguard Worker                                              srcZ, mImage, dstLevel, dstX, dstY, dstZ, srcWidth,
260*8975f5c5SAndroid Build Coastguard Worker                                              srcHeight, srcDepth);
261*8975f5c5SAndroid Build Coastguard Worker }
262*8975f5c5SAndroid Build Coastguard Worker 
copyTextureSubData(const gl::Context * context,const gl::Texture * srcTexture,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)263*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::copyTextureSubData(const gl::Context *context,
264*8975f5c5SAndroid Build Coastguard Worker                                                  const gl::Texture *srcTexture,
265*8975f5c5SAndroid Build Coastguard Worker                                                  GLint srcLevel,
266*8975f5c5SAndroid Build Coastguard Worker                                                  GLint srcX,
267*8975f5c5SAndroid Build Coastguard Worker                                                  GLint srcY,
268*8975f5c5SAndroid Build Coastguard Worker                                                  GLint srcZ,
269*8975f5c5SAndroid Build Coastguard Worker                                                  GLint dstLevel,
270*8975f5c5SAndroid Build Coastguard Worker                                                  GLint dstX,
271*8975f5c5SAndroid Build Coastguard Worker                                                  GLint dstY,
272*8975f5c5SAndroid Build Coastguard Worker                                                  GLint dstZ,
273*8975f5c5SAndroid Build Coastguard Worker                                                  GLsizei srcWidth,
274*8975f5c5SAndroid Build Coastguard Worker                                                  GLsizei srcHeight,
275*8975f5c5SAndroid Build Coastguard Worker                                                  GLsizei srcDepth)
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker     ContextVk *contextVk = vk::GetImpl(context);
278*8975f5c5SAndroid Build Coastguard Worker     TextureVk *sourceVk  = vk::GetImpl(srcTexture);
279*8975f5c5SAndroid Build Coastguard Worker 
280*8975f5c5SAndroid Build Coastguard Worker     // Make sure the source/destination targets are initialized and all staged updates are flushed.
281*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(sourceVk->ensureImageInitialized(contextVk, ImageMipLevels::EnabledLevels));
282*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(ensureImageInitialized(context));
283*8975f5c5SAndroid Build Coastguard Worker 
284*8975f5c5SAndroid Build Coastguard Worker     return vk::ImageHelper::CopyImageSubData(context, &sourceVk->getImage(), srcLevel, srcX, srcY,
285*8975f5c5SAndroid Build Coastguard Worker                                              srcZ, mImage, dstLevel, dstX, dstY, dstZ, srcWidth,
286*8975f5c5SAndroid Build Coastguard Worker                                              srcHeight, srcDepth);
287*8975f5c5SAndroid Build Coastguard Worker }
288*8975f5c5SAndroid Build Coastguard Worker 
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)289*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::getAttachmentRenderTarget(const gl::Context *context,
290*8975f5c5SAndroid Build Coastguard Worker                                                         GLenum binding,
291*8975f5c5SAndroid Build Coastguard Worker                                                         const gl::ImageIndex &imageIndex,
292*8975f5c5SAndroid Build Coastguard Worker                                                         GLsizei samples,
293*8975f5c5SAndroid Build Coastguard Worker                                                         FramebufferAttachmentRenderTarget **rtOut)
294*8975f5c5SAndroid Build Coastguard Worker {
295*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
296*8975f5c5SAndroid Build Coastguard Worker     *rtOut = &mRenderTarget;
297*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
298*8975f5c5SAndroid Build Coastguard Worker }
299*8975f5c5SAndroid Build Coastguard Worker 
initializeContents(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex)300*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::initializeContents(const gl::Context *context,
301*8975f5c5SAndroid Build Coastguard Worker                                                  GLenum binding,
302*8975f5c5SAndroid Build Coastguard Worker                                                  const gl::ImageIndex &imageIndex)
303*8975f5c5SAndroid Build Coastguard Worker {
304*8975f5c5SAndroid Build Coastguard Worker     // Note: stageSubresourceRobustClear only uses the intended format to count channels.
305*8975f5c5SAndroid Build Coastguard Worker     mImage->stageRobustResourceClear(imageIndex);
306*8975f5c5SAndroid Build Coastguard Worker     return mImage->flushAllStagedUpdates(vk::GetImpl(context));
307*8975f5c5SAndroid Build Coastguard Worker }
308*8975f5c5SAndroid Build Coastguard Worker 
releaseOwnershipOfImage(const gl::Context * context)309*8975f5c5SAndroid Build Coastguard Worker void RenderbufferVk::releaseOwnershipOfImage(const gl::Context *context)
310*8975f5c5SAndroid Build Coastguard Worker {
311*8975f5c5SAndroid Build Coastguard Worker     ContextVk *contextVk = vk::GetImpl(context);
312*8975f5c5SAndroid Build Coastguard Worker 
313*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mImageSiblingSerial.valid());
314*8975f5c5SAndroid Build Coastguard Worker 
315*8975f5c5SAndroid Build Coastguard Worker     mOwnsImage = false;
316*8975f5c5SAndroid Build Coastguard Worker     releaseAndDeleteImage(contextVk);
317*8975f5c5SAndroid Build Coastguard Worker }
318*8975f5c5SAndroid Build Coastguard Worker 
releaseAndDeleteImage(ContextVk * contextVk)319*8975f5c5SAndroid Build Coastguard Worker void RenderbufferVk::releaseAndDeleteImage(ContextVk *contextVk)
320*8975f5c5SAndroid Build Coastguard Worker {
321*8975f5c5SAndroid Build Coastguard Worker     releaseImage(contextVk);
322*8975f5c5SAndroid Build Coastguard Worker     SafeDelete(mImage);
323*8975f5c5SAndroid Build Coastguard Worker     mImageObserverBinding.bind(nullptr);
324*8975f5c5SAndroid Build Coastguard Worker }
325*8975f5c5SAndroid Build Coastguard Worker 
releaseImage(ContextVk * contextVk)326*8975f5c5SAndroid Build Coastguard Worker void RenderbufferVk::releaseImage(ContextVk *contextVk)
327*8975f5c5SAndroid Build Coastguard Worker {
328*8975f5c5SAndroid Build Coastguard Worker     vk::Renderer *renderer = contextVk->getRenderer();
329*8975f5c5SAndroid Build Coastguard Worker     if (mImage == nullptr)
330*8975f5c5SAndroid Build Coastguard Worker     {
331*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mImageViews.isImageViewGarbageEmpty() &&
332*8975f5c5SAndroid Build Coastguard Worker                mMultisampledImageViews.isImageViewGarbageEmpty());
333*8975f5c5SAndroid Build Coastguard Worker     }
334*8975f5c5SAndroid Build Coastguard Worker     else
335*8975f5c5SAndroid Build Coastguard Worker     {
336*8975f5c5SAndroid Build Coastguard Worker         mRenderTarget.releaseImageAndViews(contextVk);
337*8975f5c5SAndroid Build Coastguard Worker         mImageViews.release(renderer, mImage->getResourceUse());
338*8975f5c5SAndroid Build Coastguard Worker         mMultisampledImageViews.release(renderer, mImage->getResourceUse());
339*8975f5c5SAndroid Build Coastguard Worker     }
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker     if (mImage && mOwnsImage)
342*8975f5c5SAndroid Build Coastguard Worker     {
343*8975f5c5SAndroid Build Coastguard Worker         mImage->releaseImageFromShareContexts(renderer, contextVk, mImageSiblingSerial);
344*8975f5c5SAndroid Build Coastguard Worker         mImage->releaseStagedUpdates(renderer);
345*8975f5c5SAndroid Build Coastguard Worker     }
346*8975f5c5SAndroid Build Coastguard Worker     else
347*8975f5c5SAndroid Build Coastguard Worker     {
348*8975f5c5SAndroid Build Coastguard Worker         if (mImage)
349*8975f5c5SAndroid Build Coastguard Worker         {
350*8975f5c5SAndroid Build Coastguard Worker             mImage->finalizeImageLayoutInShareContexts(renderer, contextVk, mImageSiblingSerial);
351*8975f5c5SAndroid Build Coastguard Worker         }
352*8975f5c5SAndroid Build Coastguard Worker         mImage = nullptr;
353*8975f5c5SAndroid Build Coastguard Worker         mImageObserverBinding.bind(nullptr);
354*8975f5c5SAndroid Build Coastguard Worker     }
355*8975f5c5SAndroid Build Coastguard Worker 
356*8975f5c5SAndroid Build Coastguard Worker     if (mMultisampledImage.valid())
357*8975f5c5SAndroid Build Coastguard Worker     {
358*8975f5c5SAndroid Build Coastguard Worker         mMultisampledImage.releaseImageFromShareContexts(renderer, contextVk, mImageSiblingSerial);
359*8975f5c5SAndroid Build Coastguard Worker     }
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker 
getImplementationSizedFormat() const362*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &RenderbufferVk::getImplementationSizedFormat() const
363*8975f5c5SAndroid Build Coastguard Worker {
364*8975f5c5SAndroid Build Coastguard Worker     GLenum internalFormat = mImage->getActualFormat().glInternalFormat;
365*8975f5c5SAndroid Build Coastguard Worker     return gl::GetSizedInternalFormatInfo(internalFormat);
366*8975f5c5SAndroid Build Coastguard Worker }
367*8975f5c5SAndroid Build Coastguard Worker 
getColorReadFormat(const gl::Context * context)368*8975f5c5SAndroid Build Coastguard Worker GLenum RenderbufferVk::getColorReadFormat(const gl::Context *context)
369*8975f5c5SAndroid Build Coastguard Worker {
370*8975f5c5SAndroid Build Coastguard Worker     const gl::InternalFormat &sizedFormat = getImplementationSizedFormat();
371*8975f5c5SAndroid Build Coastguard Worker     return sizedFormat.format;
372*8975f5c5SAndroid Build Coastguard Worker }
373*8975f5c5SAndroid Build Coastguard Worker 
getColorReadType(const gl::Context * context)374*8975f5c5SAndroid Build Coastguard Worker GLenum RenderbufferVk::getColorReadType(const gl::Context *context)
375*8975f5c5SAndroid Build Coastguard Worker {
376*8975f5c5SAndroid Build Coastguard Worker     const gl::InternalFormat &sizedFormat = getImplementationSizedFormat();
377*8975f5c5SAndroid Build Coastguard Worker     return sizedFormat.type;
378*8975f5c5SAndroid Build Coastguard Worker }
379*8975f5c5SAndroid Build Coastguard Worker 
getRenderbufferImage(const gl::Context * context,const gl::PixelPackState & packState,gl::Buffer * packBuffer,GLenum format,GLenum type,void * pixels)380*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::getRenderbufferImage(const gl::Context *context,
381*8975f5c5SAndroid Build Coastguard Worker                                                    const gl::PixelPackState &packState,
382*8975f5c5SAndroid Build Coastguard Worker                                                    gl::Buffer *packBuffer,
383*8975f5c5SAndroid Build Coastguard Worker                                                    GLenum format,
384*8975f5c5SAndroid Build Coastguard Worker                                                    GLenum type,
385*8975f5c5SAndroid Build Coastguard Worker                                                    void *pixels)
386*8975f5c5SAndroid Build Coastguard Worker {
387*8975f5c5SAndroid Build Coastguard Worker     // Storage not defined.
388*8975f5c5SAndroid Build Coastguard Worker     if (!mImage || !mImage->valid())
389*8975f5c5SAndroid Build Coastguard Worker     {
390*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
391*8975f5c5SAndroid Build Coastguard Worker     }
392*8975f5c5SAndroid Build Coastguard Worker 
393*8975f5c5SAndroid Build Coastguard Worker     ContextVk *contextVk = vk::GetImpl(context);
394*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(mImage->flushAllStagedUpdates(contextVk));
395*8975f5c5SAndroid Build Coastguard Worker 
396*8975f5c5SAndroid Build Coastguard Worker     gl::MaybeOverrideLuminance(format, type, getColorReadFormat(context),
397*8975f5c5SAndroid Build Coastguard Worker                                getColorReadType(context));
398*8975f5c5SAndroid Build Coastguard Worker 
399*8975f5c5SAndroid Build Coastguard Worker     return mImage->readPixelsForGetImage(contextVk, packState, packBuffer, gl::LevelIndex(0), 0, 0,
400*8975f5c5SAndroid Build Coastguard Worker                                          format, type, pixels);
401*8975f5c5SAndroid Build Coastguard Worker }
402*8975f5c5SAndroid Build Coastguard Worker 
ensureImageInitialized(const gl::Context * context)403*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderbufferVk::ensureImageInitialized(const gl::Context *context)
404*8975f5c5SAndroid Build Coastguard Worker {
405*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(setStorage(context, mState.getFormat().info->internalFormat, mState.getWidth(),
406*8975f5c5SAndroid Build Coastguard Worker                          mState.getHeight()));
407*8975f5c5SAndroid Build Coastguard Worker 
408*8975f5c5SAndroid Build Coastguard Worker     return mImage->flushAllStagedUpdates(vk::GetImpl(context));
409*8975f5c5SAndroid Build Coastguard Worker }
410*8975f5c5SAndroid Build Coastguard Worker 
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)411*8975f5c5SAndroid Build Coastguard Worker void RenderbufferVk::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
412*8975f5c5SAndroid Build Coastguard Worker {
413*8975f5c5SAndroid Build Coastguard Worker     ASSERT(index == kRenderbufferImageSubjectIndex &&
414*8975f5c5SAndroid Build Coastguard Worker            (message == angle::SubjectMessage::SubjectChanged ||
415*8975f5c5SAndroid Build Coastguard Worker             message == angle::SubjectMessage::InitializationComplete));
416*8975f5c5SAndroid Build Coastguard Worker 
417*8975f5c5SAndroid Build Coastguard Worker     // Forward the notification to the parent class that the staging buffer changed.
418*8975f5c5SAndroid Build Coastguard Worker     if (message == angle::SubjectMessage::SubjectChanged)
419*8975f5c5SAndroid Build Coastguard Worker     {
420*8975f5c5SAndroid Build Coastguard Worker         onStateChange(angle::SubjectMessage::SubjectChanged);
421*8975f5c5SAndroid Build Coastguard Worker     }
422*8975f5c5SAndroid Build Coastguard Worker }
423*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
424