• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // RenderTargetVk:
7 //   Wrapper around a Vulkan renderable resource, using an ImageView.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_RENDERTARGETVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_RENDERTARGETVK_H_
12 
13 #include "common/vulkan/vk_headers.h"
14 #include "libANGLE/FramebufferAttachment.h"
15 #include "libANGLE/renderer/renderer_utils.h"
16 #include "libANGLE/renderer/vulkan/vk_helpers.h"
17 
18 namespace rx
19 {
20 namespace vk
21 {
22 class FramebufferHelper;
23 class ImageHelper;
24 class ImageView;
25 class Resource;
26 class RenderPassDesc;
27 }  // namespace vk
28 
29 class ContextVk;
30 class TextureVk;
31 
32 enum class RenderTargetTransience
33 {
34     // Regular render targets that load and store from the image.
35     Default,
36     // Multisampled-render-to-texture textures, where the implicit multisampled image is transient,
37     // but the resolved image is persistent.
38     MultisampledTransient,
39     // Renderable YUV textures, where the color attachment (if it exists at all) is transient,
40     // but the resolved image is persistent.
41     YuvResolveTransient,
42     // Multisampled-render-to-texture depth/stencil textures.
43     EntirelyTransient,
44 };
45 
46 // This is a very light-weight class that does not own to the resources it points to.
47 // It's meant only to copy across some information from a FramebufferAttachment to the
48 // business rendering logic. It stores Images and ImageViews by pointer for performance.
49 class RenderTargetVk final : public FramebufferAttachmentRenderTarget
50 {
51   public:
52     RenderTargetVk();
53     ~RenderTargetVk() override;
54 
55     // Used in std::vector initialization.
56     RenderTargetVk(RenderTargetVk &&other);
57 
58     void init(vk::ImageHelper *image,
59               vk::ImageViewHelper *imageViews,
60               vk::ImageHelper *resolveImage,
61               vk::ImageViewHelper *resolveImageViews,
62               UniqueSerial imageSiblingSerial,
63               gl::LevelIndex levelIndexGL,
64               uint32_t layerIndex,
65               uint32_t layerCount,
66               RenderTargetTransience transience);
67 
68     vk::ImageOrBufferViewSubresourceSerial getDrawSubresourceSerial() const;
69     vk::ImageOrBufferViewSubresourceSerial getResolveSubresourceSerial() const;
70 
71     // Note: RenderTargets should be called in order, with the depth/stencil onRender last.
72     void onColorDraw(ContextVk *contextVk,
73                      uint32_t framebufferLayerCount,
74                      vk::PackedAttachmentIndex index);
75     void onColorResolve(ContextVk *contextVk, uint32_t framebufferLayerCount);
76     void onDepthStencilDraw(ContextVk *contextVk, uint32_t framebufferLayerCount);
77     void onDepthStencilResolve(ContextVk *contextVk, uint32_t framebufferLayerCount);
78 
79     vk::ImageHelper &getImageForRenderPass();
80     const vk::ImageHelper &getImageForRenderPass() const;
81 
82     vk::ImageHelper &getResolveImageForRenderPass();
83     const vk::ImageHelper &getResolveImageForRenderPass() const;
84 
85     vk::ImageHelper &getImageForCopy() const;
86     vk::ImageHelper &getImageForWrite() const;
87 
88     // For cube maps we use single-level single-layer 2D array views.
89     angle::Result getImageView(vk::Context *context, const vk::ImageView **imageViewOut) const;
90     angle::Result getImageViewWithColorspace(vk::Context *context,
91                                              gl::SrgbWriteControlMode srgbWriteContrlMode,
92                                              const vk::ImageView **imageViewOut) const;
93     angle::Result getResolveImageView(vk::Context *context,
94                                       const vk::ImageView **imageViewOut) const;
95 
96     // For 3D textures, the 2D view created for render target is invalid to read from.  The
97     // following will return a view to the whole image (for all types, including 3D and 2DArray).
98     angle::Result getCopyImageView(vk::Context *context, const vk::ImageView **imageViewOut) const;
99 
100     angle::FormatID getImageActualFormatID() const;
101     const angle::Format &getImageActualFormat() const;
102     angle::FormatID getImageIntendedFormatID() const;
103     const angle::Format &getImageIntendedFormat() const;
104 
105     gl::Extents getExtents() const;
106     gl::Extents getRotatedExtents() const;
getLevelIndex()107     gl::LevelIndex getLevelIndex() const { return mLevelIndexGL; }
108     gl::LevelIndex getLevelIndexForImage(const vk::ImageHelper &image) const;
getLayerIndex()109     uint32_t getLayerIndex() const { return mLayerIndex; }
getLayerCount()110     uint32_t getLayerCount() const { return mLayerCount; }
is3DImage()111     bool is3DImage() const { return getOwnerOfData()->getType() == VK_IMAGE_TYPE_3D; }
112 
113     gl::ImageIndex getImageIndexForClear(uint32_t layerCount) const;
114 
115     // Special mutator for Surface RenderTargets. Allows the Framebuffer to keep a single
116     // RenderTargetVk pointer.
117     void updateSwapchainImage(vk::ImageHelper *image,
118                               vk::ImageViewHelper *imageViews,
119                               vk::ImageHelper *resolveImage,
120                               vk::ImageViewHelper *resolveImageViews);
121 
122     angle::Result flushStagedUpdates(ContextVk *contextVk,
123                                      vk::ClearValuesArray *deferredClears,
124                                      uint32_t deferredClearIndex,
125                                      uint32_t framebufferLayerCount);
126 
127     bool hasDefinedContent() const;
128     bool hasDefinedStencilContent() const;
129     // Mark content as undefined so that certain optimizations are possible such as using DONT_CARE
130     // as loadOp of the render target in the next renderpass.  If |preferToKeepContentsDefinedOut|
131     // is set to true, it's preferred to ignore the invalidation due to image format and device
132     // architecture properties.
133     void invalidateEntireContent(ContextVk *contextVk, bool *preferToKeepContentsDefinedOut);
134     void invalidateEntireStencilContent(ContextVk *contextVk, bool *preferToKeepContentsDefinedOut);
135 
136     // See the description of mTransience for details of how the following two can interact.
hasResolveAttachment()137     bool hasResolveAttachment() const { return mResolveImage != nullptr && !isEntirelyTransient(); }
isImageTransient()138     bool isImageTransient() const { return mTransience != RenderTargetTransience::Default; }
isEntirelyTransient()139     bool isEntirelyTransient() const
140     {
141         return mTransience == RenderTargetTransience::EntirelyTransient;
142     }
isYuvResolve()143     bool isYuvResolve() const
144     {
145         return mResolveImage != nullptr ? mResolveImage->isYuvResolve() : false;
146     }
147 
onNewFramebuffer(const vk::SharedFramebufferCacheKey & sharedFramebufferCacheKey)148     void onNewFramebuffer(const vk::SharedFramebufferCacheKey &sharedFramebufferCacheKey)
149     {
150         ASSERT(!mFramebufferCacheManager.containsKey(sharedFramebufferCacheKey));
151         mFramebufferCacheManager.addKey(sharedFramebufferCacheKey);
152     }
release(ContextVk * contextVk)153     void release(ContextVk *contextVk) { mFramebufferCacheManager.releaseKeys(contextVk); }
destroy(vk::Renderer * renderer)154     void destroy(vk::Renderer *renderer) { mFramebufferCacheManager.destroyKeys(renderer); }
155 
156   private:
157     void reset();
158 
159     angle::Result getImageViewImpl(vk::Context *context,
160                                    const vk::ImageHelper &image,
161                                    gl::SrgbWriteControlMode mode,
162                                    vk::ImageViewHelper *imageViews,
163                                    const vk::ImageView **imageViewOut) const;
164 
165     vk::ImageOrBufferViewSubresourceSerial getSubresourceSerialImpl(
166         vk::ImageViewHelper *imageViews) const;
167 
168     bool isResolveImageOwnerOfData() const;
169     vk::ImageHelper *getOwnerOfData() const;
170 
171     // The color or depth/stencil attachment of the framebuffer and its view.
172     vk::ImageHelper *mImage;
173     vk::ImageViewHelper *mImageViews;
174 
175     // If present, this is the corresponding resolve attachment and its view.  This is used to
176     // implement GL_EXT_multisampled_render_to_texture, so while the rendering is done on mImage
177     // during the renderpass, the resolved image is the one that actually holds the data.  This
178     // means that data uploads and blit are done on this image, copies are done out of this image
179     // etc.  This means that if there is no clear, and hasDefined*Content(), the contents of
180     // mResolveImage must be copied to mImage since the loadOp of the attachment must be set to
181     // LOAD.
182     vk::ImageHelper *mResolveImage;
183     vk::ImageViewHelper *mResolveImageViews;
184 
185     UniqueSerial mImageSiblingSerial;
186 
187     // Which subresource of the image is used as render target.
188     //
189     // |mLevelIndexGL| applies to the level index of mImage unless there is a resolve attachment,
190     // in which case |mLevelIndexGL| applies to the mResolveImage since mImage is always
191     // single-level.
192     //
193     // For single-layer render targets, |mLayerIndex| will contain the layer index and |mLayerCount|
194     // will be 1.  For layered render targets, |mLayerIndex| will be 0 and |mLayerCount| will be the
195     // number of layers in the image (or level depth, if image is 3D).  Note that blit and other
196     // functions that read or write to the render target always use layer 0, so this works out for
197     // users of |getLayerIndex()|.
198     gl::LevelIndex mLevelIndexGL;
199     uint32_t mLayerIndex;
200     uint32_t mLayerCount;
201 
202     // If resolve attachment exists, |mTransience| could be *Transient if the multisampled results
203     // need to be discarded.
204     //
205     // - GL_EXT_multisampled_render_to_texture[2]: this is |MultisampledTransient| for render
206     //   targets created from color textures, as well as color or depth/stencil renderbuffers.
207     // - GL_EXT_multisampled_render_to_texture2: this is |EntirelyTransient| for depth/stencil
208     //   textures per this extension, even though a resolve attachment is not even provided.
209     //
210     // Based on the above, we have:
211     //
212     //                     mResolveImage == nullptr
213     //                        Normal rendering
214     // Default                   No resolve
215     //                         storeOp = STORE
216     //                      Owner of data: mImage
217     //
218     //      ---------------------------------------------
219     //
220     //                     mResolveImage != nullptr
221     //               GL_EXT_multisampled_render_to_texture
222     // Multisampled               Resolve
223     // Transient             storeOp = DONT_CARE
224     //                     resolve storeOp = STORE
225     //                   Owner of data: mResolveImage
226     //
227     //      ---------------------------------------------
228     //
229     //                     mResolveImage != nullptr
230     //               GL_EXT_multisampled_render_to_texture2
231     // Entirely                  No Resolve
232     // Transient             storeOp = DONT_CARE
233     //                   Owner of data: mResolveImage
234     //
235     // In the above, storeOp of the resolve attachment is always STORE.  If |Default|, storeOp is
236     // affected by a framebuffer invalidate call.  Note that even though |EntirelyTransient| has a
237     // resolve attachment, it is not used.  The only purpose of |mResolveImage| is to store deferred
238     // clears.
239     RenderTargetTransience mTransience;
240 
241     // Track references to the cached Framebuffer object that created out of this object
242     vk::FramebufferCacheManager mFramebufferCacheManager;
243 };
244 
245 // A vector of rendertargets
246 using RenderTargetVector = std::vector<RenderTargetVk>;
247 }  // namespace rx
248 
249 #endif  // LIBANGLE_RENDERER_VULKAN_RENDERTARGETVK_H_
250