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