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 struct Format; 23 class FramebufferHelper; 24 class ImageHelper; 25 class ImageView; 26 class Resource; 27 class RenderPassDesc; 28 } // namespace vk 29 30 class ContextVk; 31 class TextureVk; 32 33 enum class RenderTargetTransience 34 { 35 // Regular render targets that load and store from the image. 36 Default, 37 // Multisampled-render-to-texture textures, where the implicit multisampled image is transient, 38 // but the resolved image is persistent. 39 MultisampledTransient, 40 // Multisampled-render-to-texture depth/stencil textures. 41 EntirelyTransient, 42 }; 43 44 // This is a very light-weight class that does not own to the resources it points to. 45 // It's meant only to copy across some information from a FramebufferAttachment to the 46 // business rendering logic. It stores Images and ImageViews by pointer for performance. 47 class RenderTargetVk final : public FramebufferAttachmentRenderTarget 48 { 49 public: 50 RenderTargetVk(); 51 ~RenderTargetVk() override; 52 53 // Used in std::vector initialization. 54 RenderTargetVk(RenderTargetVk &&other); 55 56 void init(vk::ImageHelper *image, 57 vk::ImageViewHelper *imageViews, 58 vk::ImageHelper *resolveImage, 59 vk::ImageViewHelper *resolveImageViews, 60 gl::LevelIndex levelIndexGL, 61 uint32_t layerIndex, 62 uint32_t layerCount, 63 RenderTargetTransience transience); 64 void reset(); 65 66 vk::ImageOrBufferViewSubresourceSerial getDrawSubresourceSerial() const; 67 vk::ImageOrBufferViewSubresourceSerial getResolveSubresourceSerial() const; 68 69 // Note: RenderTargets should be called in order, with the depth/stencil onRender last. 70 void onColorDraw(ContextVk *contextVk, 71 uint32_t framebufferLayerCount, 72 vk::PackedAttachmentIndex index); 73 void onColorResolve(ContextVk *contextVk, uint32_t framebufferLayerCount); 74 void onDepthStencilDraw(ContextVk *contextVk, uint32_t framebufferLayerCount); 75 76 vk::ImageHelper &getImageForRenderPass(); 77 const vk::ImageHelper &getImageForRenderPass() const; 78 79 vk::ImageHelper &getResolveImageForRenderPass(); 80 const vk::ImageHelper &getResolveImageForRenderPass() const; 81 82 vk::ImageHelper &getImageForCopy() const; 83 vk::ImageHelper &getImageForWrite() const; 84 85 // For cube maps we use single-level single-layer 2D array views. 86 angle::Result getImageView(ContextVk *contextVk, const vk::ImageView **imageViewOut) const; 87 angle::Result getImageViewWithColorspace(ContextVk *contextVk, 88 gl::SrgbWriteControlMode srgbWriteContrlMode, 89 const vk::ImageView **imageViewOut) const; 90 angle::Result getResolveImageView(ContextVk *contextVk, 91 const vk::ImageView **imageViewOut) const; 92 93 // For 3D textures, the 2D view created for render target is invalid to read from. The 94 // following will return a view to the whole image (for all types, including 3D and 2DArray). 95 angle::Result getAndRetainCopyImageView(ContextVk *contextVk, 96 const vk::ImageView **imageViewOut) const; 97 98 const vk::Format &getImageFormat() const; 99 gl::Extents getExtents() const; 100 gl::Extents getRotatedExtents() const; getLevelIndex()101 gl::LevelIndex getLevelIndex() const { return mLevelIndexGL; } getLayerIndex()102 uint32_t getLayerIndex() const { return mLayerIndex; } getLayerCount()103 uint32_t getLayerCount() const { return mLayerCount; } 104 105 gl::ImageIndex getImageIndexForClear(uint32_t layerCount) const; 106 107 // Special mutator for Surface RenderTargets. Allows the Framebuffer to keep a single 108 // RenderTargetVk pointer. 109 void updateSwapchainImage(vk::ImageHelper *image, 110 vk::ImageViewHelper *imageViews, 111 vk::ImageHelper *resolveImage, 112 vk::ImageViewHelper *resolveImageViews); 113 114 angle::Result flushStagedUpdates(ContextVk *contextVk, 115 vk::ClearValuesArray *deferredClears, 116 uint32_t deferredClearIndex, 117 uint32_t framebufferLayerCount); 118 119 void retainImageViews(ContextVk *contextVk) const; 120 121 bool hasDefinedContent() const; 122 bool hasDefinedStencilContent() const; 123 // Mark content as undefined so that certain optimizations are possible such as using DONT_CARE 124 // as loadOp of the render target in the next renderpass. 125 void invalidateEntireContent(ContextVk *contextVk); 126 void invalidateEntireStencilContent(ContextVk *contextVk); 127 void restoreEntireContent(); 128 void restoreEntireStencilContent(); 129 130 // See the description of mTransience for details of how the following two can interact. hasResolveAttachment()131 bool hasResolveAttachment() const { return mResolveImage != nullptr && !isEntirelyTransient(); } isImageTransient()132 bool isImageTransient() const { return mTransience != RenderTargetTransience::Default; } isEntirelyTransient()133 bool isEntirelyTransient() const 134 { 135 return mTransience == RenderTargetTransience::EntirelyTransient; 136 } 137 138 private: 139 angle::Result getImageViewImpl(ContextVk *contextVk, 140 const vk::ImageHelper &image, 141 gl::SrgbWriteControlMode mode, 142 vk::ImageViewHelper *imageViews, 143 const vk::ImageView **imageViewOut) const; 144 145 vk::ImageOrBufferViewSubresourceSerial getSubresourceSerialImpl( 146 vk::ImageViewHelper *imageViews) const; 147 148 bool isResolveImageOwnerOfData() const; 149 vk::ImageHelper *getOwnerOfData() const; 150 151 // The color or depth/stencil attachment of the framebuffer and its view. 152 vk::ImageHelper *mImage; 153 vk::ImageViewHelper *mImageViews; 154 155 // If present, this is the corresponding resolve attachment and its view. This is used to 156 // implement GL_EXT_multisampled_render_to_texture, so while the rendering is done on mImage 157 // during the renderpass, the resolved image is the one that actually holds the data. This 158 // means that data uploads and blit are done on this image, copies are done out of this image 159 // etc. This means that if there is no clear, and hasDefined*Content(), the contents of 160 // mResolveImage must be copied to mImage since the loadOp of the attachment must be set to 161 // LOAD. 162 vk::ImageHelper *mResolveImage; 163 vk::ImageViewHelper *mResolveImageViews; 164 165 // Which subresource of the image is used as render target. For single-layer render targets, 166 // |mLayerIndex| will contain the layer index and |mLayerCount| will be 1. For layered render 167 // targets, |mLayerIndex| will be 0 and |mLayerCount| will be the number of layers in the image 168 // (or level depth, if image is 3D). Note that blit and other functions that read or write to 169 // the render target always use layer 0, so this works out for users of |getLayerIndex()|. 170 gl::LevelIndex mLevelIndexGL; 171 uint32_t mLayerIndex; 172 uint32_t mLayerCount; 173 174 // If resolve attachment exists, |mTransience| could be *Transient if the multisampled results 175 // need to be discarded. 176 // 177 // - GL_EXT_multisampled_render_to_texture[2]: this is |MultisampledTransient| for render 178 // targets created from color textures, as well as color or depth/stencil renderbuffers. 179 // - GL_EXT_multisampled_render_to_texture2: this is |EntirelyTransient| for depth/stencil 180 // textures per this extension, even though a resolve attachment is not even provided. 181 // 182 // Based on the above, we have: 183 // 184 // mResolveImage == nullptr 185 // Normal rendering 186 // Default No resolve 187 // storeOp = STORE 188 // Owner of data: mImage 189 // 190 // --------------------------------------------- 191 // 192 // mResolveImage != nullptr 193 // GL_EXT_multisampled_render_to_texture 194 // Multisampled Resolve 195 // Transient storeOp = DONT_CARE 196 // resolve storeOp = STORE 197 // Owner of data: mResolveImage 198 // 199 // --------------------------------------------- 200 // 201 // mResolveImage != nullptr 202 // GL_EXT_multisampled_render_to_texture2 203 // Entirely No Resolve 204 // Transient storeOp = DONT_CARE 205 // Owner of data: mResolveImage 206 // 207 // In the above, storeOp of the resolve attachment is always STORE. If |Default|, storeOp is 208 // affected by a framebuffer invalidate call. Note that even though |EntirelyTransient| has a 209 // resolve attachment, it is not used. The only purpose of |mResolveImage| is to store deferred 210 // clears. 211 RenderTargetTransience mTransience; 212 }; 213 214 // A vector of rendertargets 215 using RenderTargetVector = std::vector<RenderTargetVk>; 216 } // namespace rx 217 218 #endif // LIBANGLE_RENDERER_VULKAN_RENDERTARGETVK_H_ 219