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 // FramebufferVk.h: 7 // Defines the class interface for FramebufferVk, implementing FramebufferImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 12 13 #include "libANGLE/angletypes.h" 14 #include "libANGLE/renderer/FramebufferImpl.h" 15 #include "libANGLE/renderer/RenderTargetCache.h" 16 #include "libANGLE/renderer/vulkan/BufferVk.h" 17 #include "libANGLE/renderer/vulkan/ResourceVk.h" 18 #include "libANGLE/renderer/vulkan/SurfaceVk.h" 19 #include "libANGLE/renderer/vulkan/UtilsVk.h" 20 #include "libANGLE/renderer/vulkan/vk_cache_utils.h" 21 #include "libANGLE/renderer/vulkan/vk_helpers.h" 22 23 namespace rx 24 { 25 class RendererVk; 26 class RenderTargetVk; 27 class WindowSurfaceVk; 28 29 class FramebufferVk : public FramebufferImpl 30 { 31 public: 32 FramebufferVk(RendererVk *renderer, const gl::FramebufferState &state); 33 ~FramebufferVk() override; 34 void destroy(const gl::Context *context) override; 35 36 angle::Result discard(const gl::Context *context, 37 size_t count, 38 const GLenum *attachments) override; 39 angle::Result invalidate(const gl::Context *context, 40 size_t count, 41 const GLenum *attachments) override; 42 angle::Result invalidateSub(const gl::Context *context, 43 size_t count, 44 const GLenum *attachments, 45 const gl::Rectangle &area) override; 46 47 angle::Result clear(const gl::Context *context, GLbitfield mask) override; 48 angle::Result clearBufferfv(const gl::Context *context, 49 GLenum buffer, 50 GLint drawbuffer, 51 const GLfloat *values) override; 52 angle::Result clearBufferuiv(const gl::Context *context, 53 GLenum buffer, 54 GLint drawbuffer, 55 const GLuint *values) override; 56 angle::Result clearBufferiv(const gl::Context *context, 57 GLenum buffer, 58 GLint drawbuffer, 59 const GLint *values) override; 60 angle::Result clearBufferfi(const gl::Context *context, 61 GLenum buffer, 62 GLint drawbuffer, 63 GLfloat depth, 64 GLint stencil) override; 65 66 const gl::InternalFormat &getImplementationColorReadFormat( 67 const gl::Context *context) const override; 68 angle::Result readPixels(const gl::Context *context, 69 const gl::Rectangle &area, 70 GLenum format, 71 GLenum type, 72 const gl::PixelPackState &pack, 73 gl::Buffer *packBuffer, 74 void *pixels) override; 75 76 angle::Result blit(const gl::Context *context, 77 const gl::Rectangle &sourceArea, 78 const gl::Rectangle &destArea, 79 GLbitfield mask, 80 GLenum filter) override; 81 82 gl::FramebufferStatus checkStatus(const gl::Context *context) const override; 83 84 angle::Result syncState(const gl::Context *context, 85 GLenum binding, 86 const gl::Framebuffer::DirtyBits &dirtyBits, 87 gl::Command command) override; 88 89 angle::Result getSamplePosition(const gl::Context *context, 90 size_t index, 91 GLfloat *xy) const override; 92 RenderTargetVk *getDepthStencilRenderTarget() const; 93 94 // Internal helper function for readPixels operations. 95 angle::Result readPixelsImpl(ContextVk *contextVk, 96 const gl::Rectangle &area, 97 const PackPixelsParams &packPixelsParams, 98 VkImageAspectFlagBits copyAspectFlags, 99 RenderTargetVk *renderTarget, 100 void *pixels); 101 102 gl::Extents getReadImageExtents() const; 103 gl::Rectangle getNonRotatedCompleteRenderArea() const; 104 gl::Rectangle getRotatedCompleteRenderArea(ContextVk *contextVk) const; 105 gl::Rectangle getRotatedScissoredRenderArea(ContextVk *contextVk) const; 106 // Returns render area with deferred clears in consideration. When deferred clear is used 107 // in the render pass, the render area must cover the whole framebuffer. 108 gl::Rectangle getRenderArea(ContextVk *contextVk) const; 109 110 const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const; 111 RenderTargetVk *getColorDrawRenderTarget(size_t colorIndexGL) const; 112 RenderTargetVk *getColorReadRenderTarget() const; 113 114 angle::Result startNewRenderPass(ContextVk *contextVk, 115 const gl::Rectangle &renderArea, 116 vk::RenderPassCommandBuffer **commandBufferOut, 117 bool *renderPassDescChangedOut); 118 119 GLint getSamples() const; 120 getRenderPassDesc()121 const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; } 122 123 void updateColorResolveAttachment( 124 uint32_t colorIndexGL, 125 vk::ImageOrBufferViewSubresourceSerial resolveImageViewSerial); 126 127 angle::Result getFramebuffer(ContextVk *contextVk, 128 vk::MaybeImagelessFramebuffer *framebufferOut, 129 RenderTargetVk *resolveRenderTargetIn, 130 const vk::ImageView *resolveImageViewIn, 131 const SwapchainResolveMode swapchainResolveMode); 132 hasDeferredClears()133 bool hasDeferredClears() const { return !mDeferredClears.empty(); } 134 angle::Result flushDeferredClears(ContextVk *contextVk); 135 136 void switchToFramebufferFetchMode(ContextVk *contextVk, bool hasFramebufferFetch); 137 138 bool updateLegacyDither(ContextVk *contextVk); 139 140 void removeColorResolveAttachment(uint32_t colorIndexGL); 141 setBackbuffer(WindowSurfaceVk * backbuffer)142 void setBackbuffer(WindowSurfaceVk *backbuffer) { mBackbuffer = backbuffer; } getBackbuffer()143 WindowSurfaceVk *getBackbuffer() const { return mBackbuffer; } 144 145 void releaseCurrentFramebuffer(ContextVk *contextVk); 146 getLastRenderPassQueueSerial()147 const QueueSerial &getLastRenderPassQueueSerial() const { return mLastRenderPassQueueSerial; } 148 hasAnyExternalAttachments()149 bool hasAnyExternalAttachments() const { return mIsExternalColorAttachments.any(); } 150 hasFrontBufferUsage()151 bool hasFrontBufferUsage() const 152 { 153 return (mAttachmentHasFrontBufferUsage & mState.getColorAttachmentsMask()).any(); 154 } 155 156 enum class RenderTargetImage 157 { 158 AttachmentImage, 159 ResolveImage 160 }; 161 162 struct RenderTargetInfo 163 { RenderTargetInfoRenderTargetInfo164 RenderTargetInfo() 165 : renderTarget(nullptr), renderTargetImage(RenderTargetImage::AttachmentImage) 166 {} RenderTargetInfoRenderTargetInfo167 RenderTargetInfo(RenderTargetVk *renderTarget, RenderTargetImage renderTargetImage) 168 : renderTarget(renderTarget), renderTargetImage(renderTargetImage) 169 {} 170 RenderTargetVk *renderTarget; 171 RenderTargetImage renderTargetImage; 172 }; 173 174 angle::Result getAttachmentsAndRenderTargets( 175 ContextVk *contextVk, 176 const vk::ImageView *resolveImageViewIn, 177 RenderTargetVk *resolveRenderTargetIn, 178 vk::FramebufferAttachmentsVector<VkImageView> *attachments, 179 vk::FramebufferAttachmentsVector<RenderTargetInfo> *renderTargetsInfoOut); 180 181 private: 182 enum class ClearWithCommand 183 { 184 Always, 185 OptimizeWithLoadOp, 186 }; 187 188 // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'. 189 angle::Result blitWithCommand(ContextVk *contextVk, 190 const gl::Rectangle &sourceArea, 191 const gl::Rectangle &destArea, 192 RenderTargetVk *readRenderTarget, 193 RenderTargetVk *drawRenderTarget, 194 GLenum filter, 195 bool colorBlit, 196 bool depthBlit, 197 bool stencilBlit, 198 bool flipX, 199 bool flipY); 200 201 // Resolve color with subpass attachment 202 angle::Result resolveColorWithSubpass(ContextVk *contextVk, 203 const UtilsVk::BlitResolveParameters ¶ms); 204 205 // Resolve color with vkCmdResolveImage 206 angle::Result resolveColorWithCommand(ContextVk *contextVk, 207 const UtilsVk::BlitResolveParameters ¶ms, 208 vk::ImageHelper *srcImage); 209 210 angle::Result clearImpl(const gl::Context *context, 211 gl::DrawBufferMask clearColorBuffers, 212 bool clearDepth, 213 bool clearStencil, 214 const VkClearColorValue &clearColorValue, 215 const VkClearDepthStencilValue &clearDepthStencilValue); 216 217 void mergeClearsWithDeferredClears(gl::DrawBufferMask clearColorBuffers, 218 bool clearDepth, 219 bool clearStencil, 220 const VkClearColorValue &clearColorValue, 221 const VkClearDepthStencilValue &clearDepthStencilValue); 222 angle::Result clearWithDraw(ContextVk *contextVk, 223 const gl::Rectangle &clearArea, 224 gl::DrawBufferMask clearColorBuffers, 225 bool clearDepth, 226 bool clearStencil, 227 gl::BlendStateExt::ColorMaskStorage::Type colorMasks, 228 uint8_t stencilMask, 229 const VkClearColorValue &clearColorValue, 230 const VkClearDepthStencilValue &clearDepthStencilValue); 231 void redeferClears(ContextVk *contextVk); 232 void redeferClearsForReadFramebuffer(ContextVk *contextVk); 233 void redeferClearsImpl(ContextVk *contextVk); 234 void clearWithCommand(ContextVk *contextVk, 235 const gl::Rectangle &scissoredRenderArea, 236 ClearWithCommand behavior, 237 vk::ClearValuesArray *clears); 238 void clearWithLoadOp(ContextVk *contextVk); 239 void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); 240 void updateRenderPassDesc(ContextVk *contextVk); 241 angle::Result updateColorAttachment(const gl::Context *context, uint32_t colorIndex); 242 angle::Result updateDepthStencilAttachment(const gl::Context *context); 243 void updateDepthStencilAttachmentSerial(ContextVk *contextVk); 244 angle::Result flushColorAttachmentUpdates(const gl::Context *context, 245 bool deferClears, 246 uint32_t colorIndex); 247 angle::Result flushDepthStencilAttachmentUpdates(const gl::Context *context, bool deferClears); 248 angle::Result invalidateImpl(ContextVk *contextVk, 249 size_t count, 250 const GLenum *attachments, 251 bool isSubInvalidate, 252 const gl::Rectangle &invalidateArea); 253 254 RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const; 255 VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const; 256 257 VkClearValue getCorrectedColorClearValue(size_t colorIndexGL, 258 const VkClearColorValue &clearColor) const; 259 260 void updateLayerCount(); 261 262 void insertCache(ContextVk *contextVk, 263 const vk::FramebufferDesc &desc, 264 vk::FramebufferHelper &&newFramebuffer); 265 266 WindowSurfaceVk *mBackbuffer; 267 268 vk::RenderPassDesc mRenderPassDesc; 269 RenderTargetCache<RenderTargetVk> mRenderTargetCache; 270 271 // This variable is used to quickly compute if we need to do a masked clear. If a color 272 // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see 273 // if the masked out channel is present in any of the attachments. 274 gl::BlendStateExt::ColorMaskStorage::Type mActiveColorComponentMasksForClear; 275 276 // When we draw to the framebuffer, and the real format has an alpha channel but the format of 277 // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will 278 // contain the mask to apply to the alpha channel when drawing. 279 gl::DrawBufferMask mEmulatedAlphaAttachmentMask; 280 281 // mCurrentFramebufferDesc is used to detect framebuffer changes using its serials. Therefore, 282 // it must be maintained even when using the imageless framebuffer extension. 283 vk::FramebufferDesc mCurrentFramebufferDesc; 284 285 // The framebuffer cache actually owns the Framebuffer object and manages its lifetime. We just 286 // store the current VkFramebuffer handle here that associated with mCurrentFramebufferDesc. 287 vk::Framebuffer mCurrentFramebuffer; 288 289 vk::ClearValuesArray mDeferredClears; 290 291 // Whether any of the color attachments are an external image such as dmabuf, AHB etc. In such 292 // cases, some optimizations are disabled such as deferred clears because the results need to be 293 // made externally available. 294 gl::DrawBufferMask mIsExternalColorAttachments; 295 gl::DrawBufferMask mAttachmentHasFrontBufferUsage; 296 297 bool mIsCurrentFramebufferCached; 298 299 // Serial of the render pass this framebuffer has opened, if any. 300 QueueSerial mLastRenderPassQueueSerial; 301 }; 302 } // namespace rx 303 304 #endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 305