xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/RenderTargetVk.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 // RenderTargetVk:
7*8975f5c5SAndroid Build Coastguard Worker //   Wrapper around a Vulkan renderable resource, using an ImageView.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/ContextVk.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/TextureVk.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_format_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_helpers.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/vulkan/vk_resource.h"
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker namespace rx
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker 
RenderTargetVk()21*8975f5c5SAndroid Build Coastguard Worker RenderTargetVk::RenderTargetVk()
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker     reset();
24*8975f5c5SAndroid Build Coastguard Worker }
25*8975f5c5SAndroid Build Coastguard Worker 
~RenderTargetVk()26*8975f5c5SAndroid Build Coastguard Worker RenderTargetVk::~RenderTargetVk()
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFramebufferCacheManager.empty());
29*8975f5c5SAndroid Build Coastguard Worker }
30*8975f5c5SAndroid Build Coastguard Worker 
RenderTargetVk(RenderTargetVk && other)31*8975f5c5SAndroid Build Coastguard Worker RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
32*8975f5c5SAndroid Build Coastguard Worker     : mImage(other.mImage),
33*8975f5c5SAndroid Build Coastguard Worker       mImageViews(other.mImageViews),
34*8975f5c5SAndroid Build Coastguard Worker       mResolveImage(other.mResolveImage),
35*8975f5c5SAndroid Build Coastguard Worker       mResolveImageViews(other.mResolveImageViews),
36*8975f5c5SAndroid Build Coastguard Worker       mImageSiblingSerial(other.mImageSiblingSerial),
37*8975f5c5SAndroid Build Coastguard Worker       mLevelIndexGL(other.mLevelIndexGL),
38*8975f5c5SAndroid Build Coastguard Worker       mLayerIndex(other.mLayerIndex),
39*8975f5c5SAndroid Build Coastguard Worker       mLayerCount(other.mLayerCount),
40*8975f5c5SAndroid Build Coastguard Worker       mFramebufferCacheManager(other.mFramebufferCacheManager)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     other.reset();
43*8975f5c5SAndroid Build Coastguard Worker }
44*8975f5c5SAndroid Build Coastguard Worker 
init(vk::ImageHelper * image,vk::ImageViewHelper * imageViews,vk::ImageHelper * resolveImage,vk::ImageViewHelper * resolveImageViews,UniqueSerial imageSiblingSerial,gl::LevelIndex levelIndexGL,uint32_t layerIndex,uint32_t layerCount,RenderTargetTransience transience)45*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::init(vk::ImageHelper *image,
46*8975f5c5SAndroid Build Coastguard Worker                           vk::ImageViewHelper *imageViews,
47*8975f5c5SAndroid Build Coastguard Worker                           vk::ImageHelper *resolveImage,
48*8975f5c5SAndroid Build Coastguard Worker                           vk::ImageViewHelper *resolveImageViews,
49*8975f5c5SAndroid Build Coastguard Worker                           UniqueSerial imageSiblingSerial,
50*8975f5c5SAndroid Build Coastguard Worker                           gl::LevelIndex levelIndexGL,
51*8975f5c5SAndroid Build Coastguard Worker                           uint32_t layerIndex,
52*8975f5c5SAndroid Build Coastguard Worker                           uint32_t layerCount,
53*8975f5c5SAndroid Build Coastguard Worker                           RenderTargetTransience transience)
54*8975f5c5SAndroid Build Coastguard Worker {
55*8975f5c5SAndroid Build Coastguard Worker     mImage              = image;
56*8975f5c5SAndroid Build Coastguard Worker     mImageViews         = imageViews;
57*8975f5c5SAndroid Build Coastguard Worker     mResolveImage       = resolveImage;
58*8975f5c5SAndroid Build Coastguard Worker     mResolveImageViews  = resolveImageViews;
59*8975f5c5SAndroid Build Coastguard Worker     mImageSiblingSerial = imageSiblingSerial;
60*8975f5c5SAndroid Build Coastguard Worker     mLevelIndexGL       = levelIndexGL;
61*8975f5c5SAndroid Build Coastguard Worker     mLayerIndex         = layerIndex;
62*8975f5c5SAndroid Build Coastguard Worker     mLayerCount         = layerCount;
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker     mTransience = transience;
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker 
invalidateImageAndViews()67*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::invalidateImageAndViews()
68*8975f5c5SAndroid Build Coastguard Worker {
69*8975f5c5SAndroid Build Coastguard Worker     mImage             = nullptr;
70*8975f5c5SAndroid Build Coastguard Worker     mImageViews        = nullptr;
71*8975f5c5SAndroid Build Coastguard Worker     mResolveImage      = nullptr;
72*8975f5c5SAndroid Build Coastguard Worker     mResolveImageViews = nullptr;
73*8975f5c5SAndroid Build Coastguard Worker }
74*8975f5c5SAndroid Build Coastguard Worker 
reset()75*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::reset()
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker     invalidateImageAndViews();
78*8975f5c5SAndroid Build Coastguard Worker     mImageSiblingSerial = {};
79*8975f5c5SAndroid Build Coastguard Worker     mLevelIndexGL       = gl::LevelIndex(0);
80*8975f5c5SAndroid Build Coastguard Worker     mLayerIndex         = 0;
81*8975f5c5SAndroid Build Coastguard Worker     mLayerCount         = 0;
82*8975f5c5SAndroid Build Coastguard Worker }
83*8975f5c5SAndroid Build Coastguard Worker 
getSubresourceSerialImpl(vk::ImageViewHelper * imageViews) const84*8975f5c5SAndroid Build Coastguard Worker vk::ImageOrBufferViewSubresourceSerial RenderTargetVk::getSubresourceSerialImpl(
85*8975f5c5SAndroid Build Coastguard Worker     vk::ImageViewHelper *imageViews) const
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker     ASSERT(imageViews);
88*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max());
89*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mLevelIndexGL.get() < std::numeric_limits<uint16_t>::max());
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker     vk::LayerMode layerMode = vk::GetLayerMode(*mImage, mLayerCount);
92*8975f5c5SAndroid Build Coastguard Worker     vk::ImageOrBufferViewSubresourceSerial imageViewSerial =
93*8975f5c5SAndroid Build Coastguard Worker         imageViews->getSubresourceSerial(mLevelIndexGL, 1, mLayerIndex, layerMode);
94*8975f5c5SAndroid Build Coastguard Worker     return imageViewSerial;
95*8975f5c5SAndroid Build Coastguard Worker }
96*8975f5c5SAndroid Build Coastguard Worker 
getDrawSubresourceSerial() const97*8975f5c5SAndroid Build Coastguard Worker vk::ImageOrBufferViewSubresourceSerial RenderTargetVk::getDrawSubresourceSerial() const
98*8975f5c5SAndroid Build Coastguard Worker {
99*8975f5c5SAndroid Build Coastguard Worker     return getSubresourceSerialImpl(mImageViews);
100*8975f5c5SAndroid Build Coastguard Worker }
101*8975f5c5SAndroid Build Coastguard Worker 
getResolveSubresourceSerial() const102*8975f5c5SAndroid Build Coastguard Worker vk::ImageOrBufferViewSubresourceSerial RenderTargetVk::getResolveSubresourceSerial() const
103*8975f5c5SAndroid Build Coastguard Worker {
104*8975f5c5SAndroid Build Coastguard Worker     return getSubresourceSerialImpl(mResolveImageViews);
105*8975f5c5SAndroid Build Coastguard Worker }
106*8975f5c5SAndroid Build Coastguard Worker 
onColorDraw(ContextVk * contextVk,uint32_t framebufferLayerCount,vk::PackedAttachmentIndex packedAttachmentIndex)107*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::onColorDraw(ContextVk *contextVk,
108*8975f5c5SAndroid Build Coastguard Worker                                  uint32_t framebufferLayerCount,
109*8975f5c5SAndroid Build Coastguard Worker                                  vk::PackedAttachmentIndex packedAttachmentIndex)
110*8975f5c5SAndroid Build Coastguard Worker {
111*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mImage->getActualFormat().hasDepthOrStencilBits());
112*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebufferLayerCount <= mLayerCount);
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker     contextVk->onColorDraw(mLevelIndexGL, mLayerIndex, framebufferLayerCount, mImage, mResolveImage,
115*8975f5c5SAndroid Build Coastguard Worker                            mImageSiblingSerial, packedAttachmentIndex);
116*8975f5c5SAndroid Build Coastguard Worker 
117*8975f5c5SAndroid Build Coastguard Worker     // Multisampled render to texture framebuffers cannot be layered.
118*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mResolveImage == nullptr || framebufferLayerCount == 1);
119*8975f5c5SAndroid Build Coastguard Worker }
120*8975f5c5SAndroid Build Coastguard Worker 
onColorResolve(ContextVk * contextVk,uint32_t framebufferLayerCount,size_t readColorIndexGL,const vk::ImageView & view)121*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::onColorResolve(ContextVk *contextVk,
122*8975f5c5SAndroid Build Coastguard Worker                                     uint32_t framebufferLayerCount,
123*8975f5c5SAndroid Build Coastguard Worker                                     size_t readColorIndexGL,
124*8975f5c5SAndroid Build Coastguard Worker                                     const vk::ImageView &view)
125*8975f5c5SAndroid Build Coastguard Worker {
126*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!mImage->getActualFormat().hasDepthOrStencilBits());
127*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebufferLayerCount <= mLayerCount);
128*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mResolveImage == nullptr);
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker     // The currently open render pass is from the read framebuffer.  This is the draw framebuffer's
131*8975f5c5SAndroid Build Coastguard Worker     // render target.  Ask the context to add this image as the resolve attachment to the read
132*8975f5c5SAndroid Build Coastguard Worker     // framebuffer's render pass, at the given color index.
133*8975f5c5SAndroid Build Coastguard Worker     contextVk->onColorResolve(mLevelIndexGL, mLayerIndex, framebufferLayerCount, mImage,
134*8975f5c5SAndroid Build Coastguard Worker                               view.getHandle(), mImageSiblingSerial, readColorIndexGL);
135*8975f5c5SAndroid Build Coastguard Worker }
136*8975f5c5SAndroid Build Coastguard Worker 
onDepthStencilDraw(ContextVk * contextVk,uint32_t framebufferLayerCount)137*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk, uint32_t framebufferLayerCount)
138*8975f5c5SAndroid Build Coastguard Worker {
139*8975f5c5SAndroid Build Coastguard Worker     const angle::Format &format = mImage->getActualFormat();
140*8975f5c5SAndroid Build Coastguard Worker     ASSERT(format.hasDepthOrStencilBits());
141*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebufferLayerCount <= mLayerCount);
142*8975f5c5SAndroid Build Coastguard Worker 
143*8975f5c5SAndroid Build Coastguard Worker     contextVk->onDepthStencilDraw(mLevelIndexGL, mLayerIndex, framebufferLayerCount, mImage,
144*8975f5c5SAndroid Build Coastguard Worker                                   mResolveImage, mImageSiblingSerial);
145*8975f5c5SAndroid Build Coastguard Worker }
146*8975f5c5SAndroid Build Coastguard Worker 
onDepthStencilResolve(ContextVk * contextVk,uint32_t framebufferLayerCount,VkImageAspectFlags aspects,const vk::ImageView & view)147*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::onDepthStencilResolve(ContextVk *contextVk,
148*8975f5c5SAndroid Build Coastguard Worker                                            uint32_t framebufferLayerCount,
149*8975f5c5SAndroid Build Coastguard Worker                                            VkImageAspectFlags aspects,
150*8975f5c5SAndroid Build Coastguard Worker                                            const vk::ImageView &view)
151*8975f5c5SAndroid Build Coastguard Worker {
152*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage->getActualFormat().hasDepthOrStencilBits());
153*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebufferLayerCount <= mLayerCount);
154*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mResolveImage == nullptr);
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker     contextVk->onDepthStencilResolve(mLevelIndexGL, mLayerIndex, framebufferLayerCount, aspects,
157*8975f5c5SAndroid Build Coastguard Worker                                      mImage, view.getHandle(), mImageSiblingSerial);
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker 
getImageForRenderPass()160*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper &RenderTargetVk::getImageForRenderPass()
161*8975f5c5SAndroid Build Coastguard Worker {
162*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
163*8975f5c5SAndroid Build Coastguard Worker     return *mImage;
164*8975f5c5SAndroid Build Coastguard Worker }
165*8975f5c5SAndroid Build Coastguard Worker 
getImageForRenderPass() const166*8975f5c5SAndroid Build Coastguard Worker const vk::ImageHelper &RenderTargetVk::getImageForRenderPass() const
167*8975f5c5SAndroid Build Coastguard Worker {
168*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
169*8975f5c5SAndroid Build Coastguard Worker     return *mImage;
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker 
getResolveImageForRenderPass()172*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper &RenderTargetVk::getResolveImageForRenderPass()
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mResolveImage && mResolveImage->valid());
175*8975f5c5SAndroid Build Coastguard Worker     return *mResolveImage;
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker 
getResolveImageForRenderPass() const178*8975f5c5SAndroid Build Coastguard Worker const vk::ImageHelper &RenderTargetVk::getResolveImageForRenderPass() const
179*8975f5c5SAndroid Build Coastguard Worker {
180*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mResolveImage && mResolveImage->valid());
181*8975f5c5SAndroid Build Coastguard Worker     return *mResolveImage;
182*8975f5c5SAndroid Build Coastguard Worker }
183*8975f5c5SAndroid Build Coastguard Worker 
getImageViewImpl(vk::Context * context,const vk::ImageHelper & image,vk::ImageViewHelper * imageViews,const vk::ImageView ** imageViewOut) const184*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getImageViewImpl(vk::Context *context,
185*8975f5c5SAndroid Build Coastguard Worker                                                const vk::ImageHelper &image,
186*8975f5c5SAndroid Build Coastguard Worker                                                vk::ImageViewHelper *imageViews,
187*8975f5c5SAndroid Build Coastguard Worker                                                const vk::ImageView **imageViewOut) const
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker     ASSERT(image.valid() && imageViews);
190*8975f5c5SAndroid Build Coastguard Worker     vk::LevelIndex levelVk = image.toVkLevel(getLevelIndexForImage(image));
191*8975f5c5SAndroid Build Coastguard Worker     if (mLayerCount == 1)
192*8975f5c5SAndroid Build Coastguard Worker     {
193*8975f5c5SAndroid Build Coastguard Worker         return imageViews->getLevelLayerDrawImageView(context, image, levelVk, mLayerIndex,
194*8975f5c5SAndroid Build Coastguard Worker                                                       imageViewOut);
195*8975f5c5SAndroid Build Coastguard Worker     }
196*8975f5c5SAndroid Build Coastguard Worker 
197*8975f5c5SAndroid Build Coastguard Worker     // Layered render targets view the whole level or a handful of layers in case of multiview.
198*8975f5c5SAndroid Build Coastguard Worker     return imageViews->getLevelDrawImageView(context, image, levelVk, mLayerIndex, mLayerCount,
199*8975f5c5SAndroid Build Coastguard Worker                                              imageViewOut);
200*8975f5c5SAndroid Build Coastguard Worker }
201*8975f5c5SAndroid Build Coastguard Worker 
getImageView(vk::Context * context,const vk::ImageView ** imageViewOut) const202*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getImageView(vk::Context *context,
203*8975f5c5SAndroid Build Coastguard Worker                                            const vk::ImageView **imageViewOut) const
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage);
206*8975f5c5SAndroid Build Coastguard Worker     return getImageViewImpl(context, *mImage, mImageViews, imageViewOut);
207*8975f5c5SAndroid Build Coastguard Worker }
208*8975f5c5SAndroid Build Coastguard Worker 
getImageViewWithColorspace(vk::Context * context,gl::SrgbWriteControlMode mode,const vk::ImageView ** imageViewOut) const209*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getImageViewWithColorspace(vk::Context *context,
210*8975f5c5SAndroid Build Coastguard Worker                                                          gl::SrgbWriteControlMode mode,
211*8975f5c5SAndroid Build Coastguard Worker                                                          const vk::ImageView **imageViewOut) const
212*8975f5c5SAndroid Build Coastguard Worker {
213*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage);
214*8975f5c5SAndroid Build Coastguard Worker     mImageViews->updateSrgbWiteControlMode(*mImage, mode);
215*8975f5c5SAndroid Build Coastguard Worker     return getImageViewImpl(context, *mImage, mImageViews, imageViewOut);
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker 
getResolveImageView(vk::Context * context,const vk::ImageView ** imageViewOut) const218*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getResolveImageView(vk::Context *context,
219*8975f5c5SAndroid Build Coastguard Worker                                                   const vk::ImageView **imageViewOut) const
220*8975f5c5SAndroid Build Coastguard Worker {
221*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mResolveImage);
222*8975f5c5SAndroid Build Coastguard Worker     return getImageViewImpl(context, *mResolveImage, mResolveImageViews, imageViewOut);
223*8975f5c5SAndroid Build Coastguard Worker }
224*8975f5c5SAndroid Build Coastguard Worker 
getDepthOrStencilImageView(vk::Context * context,VkImageAspectFlagBits aspect,const vk::ImageView ** imageViewOut) const225*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getDepthOrStencilImageView(vk::Context *context,
226*8975f5c5SAndroid Build Coastguard Worker                                                          VkImageAspectFlagBits aspect,
227*8975f5c5SAndroid Build Coastguard Worker                                                          const vk::ImageView **imageViewOut) const
228*8975f5c5SAndroid Build Coastguard Worker {
229*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage);
230*8975f5c5SAndroid Build Coastguard Worker     return getDepthOrStencilImageViewImpl(context, *mImage, mImageViews, aspect, imageViewOut);
231*8975f5c5SAndroid Build Coastguard Worker }
232*8975f5c5SAndroid Build Coastguard Worker 
getDepthOrStencilImageViewForCopy(vk::Context * context,VkImageAspectFlagBits aspect,const vk::ImageView ** imageViewOut) const233*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getDepthOrStencilImageViewForCopy(
234*8975f5c5SAndroid Build Coastguard Worker     vk::Context *context,
235*8975f5c5SAndroid Build Coastguard Worker     VkImageAspectFlagBits aspect,
236*8975f5c5SAndroid Build Coastguard Worker     const vk::ImageView **imageViewOut) const
237*8975f5c5SAndroid Build Coastguard Worker {
238*8975f5c5SAndroid Build Coastguard Worker     return isResolveImageOwnerOfData()
239*8975f5c5SAndroid Build Coastguard Worker                ? getResolveDepthOrStencilImageView(context, aspect, imageViewOut)
240*8975f5c5SAndroid Build Coastguard Worker                : getDepthOrStencilImageView(context, aspect, imageViewOut);
241*8975f5c5SAndroid Build Coastguard Worker }
242*8975f5c5SAndroid Build Coastguard Worker 
getResolveDepthOrStencilImageView(vk::Context * context,VkImageAspectFlagBits aspect,const vk::ImageView ** imageViewOut) const243*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getResolveDepthOrStencilImageView(
244*8975f5c5SAndroid Build Coastguard Worker     vk::Context *context,
245*8975f5c5SAndroid Build Coastguard Worker     VkImageAspectFlagBits aspect,
246*8975f5c5SAndroid Build Coastguard Worker     const vk::ImageView **imageViewOut) const
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mResolveImage);
249*8975f5c5SAndroid Build Coastguard Worker     return getDepthOrStencilImageViewImpl(context, *mResolveImage, mResolveImageViews, aspect,
250*8975f5c5SAndroid Build Coastguard Worker                                           imageViewOut);
251*8975f5c5SAndroid Build Coastguard Worker }
252*8975f5c5SAndroid Build Coastguard Worker 
getDepthOrStencilImageViewImpl(vk::Context * context,const vk::ImageHelper & image,vk::ImageViewHelper * imageViews,VkImageAspectFlagBits aspect,const vk::ImageView ** imageViewOut) const253*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getDepthOrStencilImageViewImpl(
254*8975f5c5SAndroid Build Coastguard Worker     vk::Context *context,
255*8975f5c5SAndroid Build Coastguard Worker     const vk::ImageHelper &image,
256*8975f5c5SAndroid Build Coastguard Worker     vk::ImageViewHelper *imageViews,
257*8975f5c5SAndroid Build Coastguard Worker     VkImageAspectFlagBits aspect,
258*8975f5c5SAndroid Build Coastguard Worker     const vk::ImageView **imageViewOut) const
259*8975f5c5SAndroid Build Coastguard Worker {
260*8975f5c5SAndroid Build Coastguard Worker     // If the image has only one aspect, the usual view is sufficient.
261*8975f5c5SAndroid Build Coastguard Worker     if (image.getAspectFlags() == aspect)
262*8975f5c5SAndroid Build Coastguard Worker     {
263*8975f5c5SAndroid Build Coastguard Worker         return getImageViewImpl(context, image, imageViews, imageViewOut);
264*8975f5c5SAndroid Build Coastguard Worker     }
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker     // Otherwise, for images with both the depth and stencil aspects, need to create special views
267*8975f5c5SAndroid Build Coastguard Worker     // that select only one such aspect.
268*8975f5c5SAndroid Build Coastguard Worker     ASSERT(image.valid() && imageViews);
269*8975f5c5SAndroid Build Coastguard Worker     vk::LevelIndex levelVk = image.toVkLevel(getLevelIndexForImage(image));
270*8975f5c5SAndroid Build Coastguard Worker     if (mLayerCount == 1)
271*8975f5c5SAndroid Build Coastguard Worker     {
272*8975f5c5SAndroid Build Coastguard Worker         return imageViews->getLevelLayerDepthOrStencilImageView(context, image, levelVk,
273*8975f5c5SAndroid Build Coastguard Worker                                                                 mLayerIndex, aspect, imageViewOut);
274*8975f5c5SAndroid Build Coastguard Worker     }
275*8975f5c5SAndroid Build Coastguard Worker 
276*8975f5c5SAndroid Build Coastguard Worker     // Layered render targets view the whole level or a handful of layers in case of multiview.
277*8975f5c5SAndroid Build Coastguard Worker     return imageViews->getLevelDepthOrStencilImageView(context, image, levelVk, mLayerIndex,
278*8975f5c5SAndroid Build Coastguard Worker                                                        mLayerCount, aspect, imageViewOut);
279*8975f5c5SAndroid Build Coastguard Worker }
280*8975f5c5SAndroid Build Coastguard Worker 
isResolveImageOwnerOfData() const281*8975f5c5SAndroid Build Coastguard Worker bool RenderTargetVk::isResolveImageOwnerOfData() const
282*8975f5c5SAndroid Build Coastguard Worker {
283*8975f5c5SAndroid Build Coastguard Worker     // If there's a resolve attachment and the image itself is transient, it's the resolve
284*8975f5c5SAndroid Build Coastguard Worker     // attachment that owns the data, so all non-render-pass accesses to the render target data
285*8975f5c5SAndroid Build Coastguard Worker     // should go through the resolve attachment.
286*8975f5c5SAndroid Build Coastguard Worker     return isImageTransient();
287*8975f5c5SAndroid Build Coastguard Worker }
288*8975f5c5SAndroid Build Coastguard Worker 
getOwnerOfData() const289*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper *RenderTargetVk::getOwnerOfData() const
290*8975f5c5SAndroid Build Coastguard Worker {
291*8975f5c5SAndroid Build Coastguard Worker     return isResolveImageOwnerOfData() ? mResolveImage : mImage;
292*8975f5c5SAndroid Build Coastguard Worker }
293*8975f5c5SAndroid Build Coastguard Worker 
getCopyImageView(vk::Context * context,const vk::ImageView ** imageViewOut) const294*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::getCopyImageView(vk::Context *context,
295*8975f5c5SAndroid Build Coastguard Worker                                                const vk::ImageView **imageViewOut) const
296*8975f5c5SAndroid Build Coastguard Worker {
297*8975f5c5SAndroid Build Coastguard Worker     const vk::ImageViewHelper *imageViews =
298*8975f5c5SAndroid Build Coastguard Worker         isResolveImageOwnerOfData() ? mResolveImageViews : mImageViews;
299*8975f5c5SAndroid Build Coastguard Worker 
300*8975f5c5SAndroid Build Coastguard Worker     // If the source of render target is a texture or renderbuffer, this will always be valid.  This
301*8975f5c5SAndroid Build Coastguard Worker     // is also where 3D or 2DArray images could be the source of the render target.
302*8975f5c5SAndroid Build Coastguard Worker     if (imageViews->hasCopyImageView())
303*8975f5c5SAndroid Build Coastguard Worker     {
304*8975f5c5SAndroid Build Coastguard Worker         *imageViewOut = &imageViews->getCopyImageView();
305*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
306*8975f5c5SAndroid Build Coastguard Worker     }
307*8975f5c5SAndroid Build Coastguard Worker 
308*8975f5c5SAndroid Build Coastguard Worker     // Otherwise, this must come from the surface, in which case the image is 2D, so the image view
309*8975f5c5SAndroid Build Coastguard Worker     // used to draw is just as good for fetching.  If resolve attachment is present, fetching is
310*8975f5c5SAndroid Build Coastguard Worker     // done from that.
311*8975f5c5SAndroid Build Coastguard Worker     return isResolveImageOwnerOfData() ? getResolveImageView(context, imageViewOut)
312*8975f5c5SAndroid Build Coastguard Worker                                        : getImageView(context, imageViewOut);
313*8975f5c5SAndroid Build Coastguard Worker }
314*8975f5c5SAndroid Build Coastguard Worker 
getImageActualFormatID() const315*8975f5c5SAndroid Build Coastguard Worker angle::FormatID RenderTargetVk::getImageActualFormatID() const
316*8975f5c5SAndroid Build Coastguard Worker {
317*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
318*8975f5c5SAndroid Build Coastguard Worker     return mImage->getActualFormatID();
319*8975f5c5SAndroid Build Coastguard Worker }
320*8975f5c5SAndroid Build Coastguard Worker 
getImageIntendedFormatID() const321*8975f5c5SAndroid Build Coastguard Worker angle::FormatID RenderTargetVk::getImageIntendedFormatID() const
322*8975f5c5SAndroid Build Coastguard Worker {
323*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
324*8975f5c5SAndroid Build Coastguard Worker     return mImage->getIntendedFormatID();
325*8975f5c5SAndroid Build Coastguard Worker }
326*8975f5c5SAndroid Build Coastguard Worker 
getImageActualFormat() const327*8975f5c5SAndroid Build Coastguard Worker const angle::Format &RenderTargetVk::getImageActualFormat() const
328*8975f5c5SAndroid Build Coastguard Worker {
329*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
330*8975f5c5SAndroid Build Coastguard Worker     return mImage->getActualFormat();
331*8975f5c5SAndroid Build Coastguard Worker }
332*8975f5c5SAndroid Build Coastguard Worker 
getImageIntendedFormat() const333*8975f5c5SAndroid Build Coastguard Worker const angle::Format &RenderTargetVk::getImageIntendedFormat() const
334*8975f5c5SAndroid Build Coastguard Worker {
335*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
336*8975f5c5SAndroid Build Coastguard Worker     return mImage->getIntendedFormat();
337*8975f5c5SAndroid Build Coastguard Worker }
338*8975f5c5SAndroid Build Coastguard Worker 
getExtents() const339*8975f5c5SAndroid Build Coastguard Worker gl::Extents RenderTargetVk::getExtents() const
340*8975f5c5SAndroid Build Coastguard Worker {
341*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
342*8975f5c5SAndroid Build Coastguard Worker     vk::LevelIndex levelVk = mImage->toVkLevel(mLevelIndexGL);
343*8975f5c5SAndroid Build Coastguard Worker     return mImage->getLevelExtents2D(levelVk);
344*8975f5c5SAndroid Build Coastguard Worker }
345*8975f5c5SAndroid Build Coastguard Worker 
getRotatedExtents() const346*8975f5c5SAndroid Build Coastguard Worker gl::Extents RenderTargetVk::getRotatedExtents() const
347*8975f5c5SAndroid Build Coastguard Worker {
348*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid());
349*8975f5c5SAndroid Build Coastguard Worker     vk::LevelIndex levelVk = mImage->toVkLevel(mLevelIndexGL);
350*8975f5c5SAndroid Build Coastguard Worker     return mImage->getRotatedLevelExtents2D(levelVk);
351*8975f5c5SAndroid Build Coastguard Worker }
352*8975f5c5SAndroid Build Coastguard Worker 
getLevelIndexForImage(const vk::ImageHelper & image) const353*8975f5c5SAndroid Build Coastguard Worker gl::LevelIndex RenderTargetVk::getLevelIndexForImage(const vk::ImageHelper &image) const
354*8975f5c5SAndroid Build Coastguard Worker {
355*8975f5c5SAndroid Build Coastguard Worker     return (getOwnerOfData()->getImageSerial() == image.getImageSerial()) ? mLevelIndexGL
356*8975f5c5SAndroid Build Coastguard Worker                                                                           : gl::LevelIndex(0);
357*8975f5c5SAndroid Build Coastguard Worker }
358*8975f5c5SAndroid Build Coastguard Worker 
updateSwapchainImage(vk::ImageHelper * image,vk::ImageViewHelper * imageViews,vk::ImageHelper * resolveImage,vk::ImageViewHelper * resolveImageViews)359*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image,
360*8975f5c5SAndroid Build Coastguard Worker                                           vk::ImageViewHelper *imageViews,
361*8975f5c5SAndroid Build Coastguard Worker                                           vk::ImageHelper *resolveImage,
362*8975f5c5SAndroid Build Coastguard Worker                                           vk::ImageViewHelper *resolveImageViews)
363*8975f5c5SAndroid Build Coastguard Worker {
364*8975f5c5SAndroid Build Coastguard Worker     ASSERT(image && image->valid() && imageViews);
365*8975f5c5SAndroid Build Coastguard Worker     mImage             = image;
366*8975f5c5SAndroid Build Coastguard Worker     mImageViews        = imageViews;
367*8975f5c5SAndroid Build Coastguard Worker     mResolveImage      = resolveImage;
368*8975f5c5SAndroid Build Coastguard Worker     mResolveImageViews = resolveImageViews;
369*8975f5c5SAndroid Build Coastguard Worker }
370*8975f5c5SAndroid Build Coastguard Worker 
getImageForCopy() const371*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper &RenderTargetVk::getImageForCopy() const
372*8975f5c5SAndroid Build Coastguard Worker {
373*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid() && (mResolveImage == nullptr || mResolveImage->valid()));
374*8975f5c5SAndroid Build Coastguard Worker     return *getOwnerOfData();
375*8975f5c5SAndroid Build Coastguard Worker }
376*8975f5c5SAndroid Build Coastguard Worker 
getImageForWrite() const377*8975f5c5SAndroid Build Coastguard Worker vk::ImageHelper &RenderTargetVk::getImageForWrite() const
378*8975f5c5SAndroid Build Coastguard Worker {
379*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage && mImage->valid() && (mResolveImage == nullptr || mResolveImage->valid()));
380*8975f5c5SAndroid Build Coastguard Worker     return *getOwnerOfData();
381*8975f5c5SAndroid Build Coastguard Worker }
382*8975f5c5SAndroid Build Coastguard Worker 
flushStagedUpdates(ContextVk * contextVk,vk::ClearValuesArray * deferredClears,uint32_t deferredClearIndex,uint32_t framebufferLayerCount)383*8975f5c5SAndroid Build Coastguard Worker angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk,
384*8975f5c5SAndroid Build Coastguard Worker                                                  vk::ClearValuesArray *deferredClears,
385*8975f5c5SAndroid Build Coastguard Worker                                                  uint32_t deferredClearIndex,
386*8975f5c5SAndroid Build Coastguard Worker                                                  uint32_t framebufferLayerCount)
387*8975f5c5SAndroid Build Coastguard Worker {
388*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mImage->valid() && (!isResolveImageOwnerOfData() || mResolveImage->valid()));
389*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebufferLayerCount != 0);
390*8975f5c5SAndroid Build Coastguard Worker 
391*8975f5c5SAndroid Build Coastguard Worker     // It's impossible to defer clears to slices of a 3D images, as the clear applies to all the
392*8975f5c5SAndroid Build Coastguard Worker     // slices, while deferred clears only clear a single slice (where the framebuffer is attached).
393*8975f5c5SAndroid Build Coastguard Worker     // Additionally, the layer index for 3D textures is always zero according to Vulkan.
394*8975f5c5SAndroid Build Coastguard Worker     uint32_t layerIndex = mLayerIndex;
395*8975f5c5SAndroid Build Coastguard Worker     if (mImage->getType() == VK_IMAGE_TYPE_3D)
396*8975f5c5SAndroid Build Coastguard Worker     {
397*8975f5c5SAndroid Build Coastguard Worker         layerIndex         = 0;
398*8975f5c5SAndroid Build Coastguard Worker         deferredClears     = nullptr;
399*8975f5c5SAndroid Build Coastguard Worker         deferredClearIndex = 0;
400*8975f5c5SAndroid Build Coastguard Worker     }
401*8975f5c5SAndroid Build Coastguard Worker 
402*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper *image = getOwnerOfData();
403*8975f5c5SAndroid Build Coastguard Worker 
404*8975f5c5SAndroid Build Coastguard Worker     // All updates should be staged on the image that owns the data as the source of truth.  With
405*8975f5c5SAndroid Build Coastguard Worker     // multisampled-render-to-texture framebuffers, that is the resolve image.  In that case, even
406*8975f5c5SAndroid Build Coastguard Worker     // though deferred clears set the loadOp of the transient multisampled image, the clears
407*8975f5c5SAndroid Build Coastguard Worker     // themselves are staged on the resolve image.  The |flushSingleSubresourceStagedUpdates| call
408*8975f5c5SAndroid Build Coastguard Worker     // below will either flush all staged updates to the resolve image, or if the only staged update
409*8975f5c5SAndroid Build Coastguard Worker     // is a clear, it will accumulate it in the |deferredClears| array.  Later, when the render pass
410*8975f5c5SAndroid Build Coastguard Worker     // is started, the deferred clears are applied to the transient multisampled image.
411*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!isResolveImageOwnerOfData() ||
412*8975f5c5SAndroid Build Coastguard Worker            !mImage->hasStagedUpdatesForSubresource(mLevelIndexGL, layerIndex, mLayerCount));
413*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isResolveImageOwnerOfData() || mResolveImage == nullptr ||
414*8975f5c5SAndroid Build Coastguard Worker            !mResolveImage->hasStagedUpdatesForSubresource(mLevelIndexGL, layerIndex, mLayerCount));
415*8975f5c5SAndroid Build Coastguard Worker 
416*8975f5c5SAndroid Build Coastguard Worker     if (!image->hasStagedUpdatesForSubresource(mLevelIndexGL, layerIndex, framebufferLayerCount))
417*8975f5c5SAndroid Build Coastguard Worker     {
418*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
419*8975f5c5SAndroid Build Coastguard Worker     }
420*8975f5c5SAndroid Build Coastguard Worker 
421*8975f5c5SAndroid Build Coastguard Worker     return image->flushSingleSubresourceStagedUpdates(contextVk, mLevelIndexGL, layerIndex,
422*8975f5c5SAndroid Build Coastguard Worker                                                       framebufferLayerCount, deferredClears,
423*8975f5c5SAndroid Build Coastguard Worker                                                       deferredClearIndex);
424*8975f5c5SAndroid Build Coastguard Worker }
425*8975f5c5SAndroid Build Coastguard Worker 
hasDefinedContent() const426*8975f5c5SAndroid Build Coastguard Worker bool RenderTargetVk::hasDefinedContent() const
427*8975f5c5SAndroid Build Coastguard Worker {
428*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper *image = getOwnerOfData();
429*8975f5c5SAndroid Build Coastguard Worker     return image->hasSubresourceDefinedContent(mLevelIndexGL, mLayerIndex, mLayerCount);
430*8975f5c5SAndroid Build Coastguard Worker }
431*8975f5c5SAndroid Build Coastguard Worker 
hasDefinedStencilContent() const432*8975f5c5SAndroid Build Coastguard Worker bool RenderTargetVk::hasDefinedStencilContent() const
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper *image = getOwnerOfData();
435*8975f5c5SAndroid Build Coastguard Worker     return image->hasSubresourceDefinedStencilContent(mLevelIndexGL, mLayerIndex, mLayerCount);
436*8975f5c5SAndroid Build Coastguard Worker }
437*8975f5c5SAndroid Build Coastguard Worker 
invalidateEntireContent(ContextVk * contextVk,bool * preferToKeepContentsDefinedOut)438*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::invalidateEntireContent(ContextVk *contextVk,
439*8975f5c5SAndroid Build Coastguard Worker                                              bool *preferToKeepContentsDefinedOut)
440*8975f5c5SAndroid Build Coastguard Worker {
441*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper *image = getOwnerOfData();
442*8975f5c5SAndroid Build Coastguard Worker     image->invalidateSubresourceContent(contextVk, mLevelIndexGL, mLayerIndex, mLayerCount,
443*8975f5c5SAndroid Build Coastguard Worker                                         preferToKeepContentsDefinedOut);
444*8975f5c5SAndroid Build Coastguard Worker }
445*8975f5c5SAndroid Build Coastguard Worker 
invalidateEntireStencilContent(ContextVk * contextVk,bool * preferToKeepContentsDefinedOut)446*8975f5c5SAndroid Build Coastguard Worker void RenderTargetVk::invalidateEntireStencilContent(ContextVk *contextVk,
447*8975f5c5SAndroid Build Coastguard Worker                                                     bool *preferToKeepContentsDefinedOut)
448*8975f5c5SAndroid Build Coastguard Worker {
449*8975f5c5SAndroid Build Coastguard Worker     vk::ImageHelper *image = getOwnerOfData();
450*8975f5c5SAndroid Build Coastguard Worker     image->invalidateSubresourceStencilContent(contextVk, mLevelIndexGL, mLayerIndex, mLayerCount,
451*8975f5c5SAndroid Build Coastguard Worker                                                preferToKeepContentsDefinedOut);
452*8975f5c5SAndroid Build Coastguard Worker }
453*8975f5c5SAndroid Build Coastguard Worker 
getImageIndexForClear(uint32_t layerCount) const454*8975f5c5SAndroid Build Coastguard Worker gl::ImageIndex RenderTargetVk::getImageIndexForClear(uint32_t layerCount) const
455*8975f5c5SAndroid Build Coastguard Worker {
456*8975f5c5SAndroid Build Coastguard Worker     // Determine the GL type from the Vk Image properties.
457*8975f5c5SAndroid Build Coastguard Worker     if (mImage->getType() == VK_IMAGE_TYPE_3D || mImage->getLayerCount() > 1)
458*8975f5c5SAndroid Build Coastguard Worker     {
459*8975f5c5SAndroid Build Coastguard Worker         // This is used for the sake of staging clears.  The depth slices of the 3D image are
460*8975f5c5SAndroid Build Coastguard Worker         // threated as layers for this purpose.
461*8975f5c5SAndroid Build Coastguard Worker         //
462*8975f5c5SAndroid Build Coastguard Worker         // We also don't need to distinguish 2D array and cube.
463*8975f5c5SAndroid Build Coastguard Worker         return gl::ImageIndex::Make2DArrayRange(mLevelIndexGL.get(), mLayerIndex, layerCount);
464*8975f5c5SAndroid Build Coastguard Worker     }
465*8975f5c5SAndroid Build Coastguard Worker 
466*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mLayerIndex == 0);
467*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mLayerCount == 1);
468*8975f5c5SAndroid Build Coastguard Worker     ASSERT(layerCount == 1);
469*8975f5c5SAndroid Build Coastguard Worker     return gl::ImageIndex::Make2D(mLevelIndexGL.get());
470*8975f5c5SAndroid Build Coastguard Worker }
471*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
472