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/SurfaceVk.h" 18 #include "libANGLE/renderer/vulkan/UtilsVk.h" 19 #include "libANGLE/renderer/vulkan/vk_cache_utils.h" 20 #include "libANGLE/renderer/vulkan/vk_helpers.h" 21 #include "libANGLE/renderer/vulkan/vk_resource.h" 22 23 namespace rx 24 { 25 class RenderTargetVk; 26 class WindowSurfaceVk; 27 28 class FramebufferVk : public FramebufferImpl 29 { 30 public: 31 FramebufferVk(vk::Renderer *renderer, const gl::FramebufferState &state); 32 ~FramebufferVk() override; 33 void destroy(const gl::Context *context) override; 34 35 angle::Result discard(const gl::Context *context, 36 size_t count, 37 const GLenum *attachments) override; 38 angle::Result invalidate(const gl::Context *context, 39 size_t count, 40 const GLenum *attachments) override; 41 angle::Result invalidateSub(const gl::Context *context, 42 size_t count, 43 const GLenum *attachments, 44 const gl::Rectangle &area) override; 45 46 angle::Result clear(const gl::Context *context, GLbitfield mask) override; 47 angle::Result clearBufferfv(const gl::Context *context, 48 GLenum buffer, 49 GLint drawbuffer, 50 const GLfloat *values) override; 51 angle::Result clearBufferuiv(const gl::Context *context, 52 GLenum buffer, 53 GLint drawbuffer, 54 const GLuint *values) override; 55 angle::Result clearBufferiv(const gl::Context *context, 56 GLenum buffer, 57 GLint drawbuffer, 58 const GLint *values) override; 59 angle::Result clearBufferfi(const gl::Context *context, 60 GLenum buffer, 61 GLint drawbuffer, 62 GLfloat depth, 63 GLint stencil) override; 64 65 const gl::InternalFormat &getImplementationColorReadFormat( 66 const gl::Context *context) const override; 67 angle::Result readPixels(const gl::Context *context, 68 const gl::Rectangle &area, 69 GLenum format, 70 GLenum type, 71 const gl::PixelPackState &pack, 72 gl::Buffer *packBuffer, 73 void *pixels) override; 74 75 angle::Result blit(const gl::Context *context, 76 const gl::Rectangle &sourceArea, 77 const gl::Rectangle &destArea, 78 GLbitfield mask, 79 GLenum filter) override; 80 81 gl::FramebufferStatus checkStatus(const gl::Context *context) const override; 82 83 angle::Result syncState(const gl::Context *context, 84 GLenum binding, 85 const gl::Framebuffer::DirtyBits &dirtyBits, 86 gl::Command command) override; 87 88 angle::Result getSamplePosition(const gl::Context *context, 89 size_t index, 90 GLfloat *xy) const override; 91 RenderTargetVk *getDepthStencilRenderTarget() const; 92 93 // Internal helper function for readPixels operations. 94 angle::Result readPixelsImpl(ContextVk *contextVk, 95 const gl::Rectangle &area, 96 const PackPixelsParams &packPixelsParams, 97 VkImageAspectFlagBits copyAspectFlags, 98 RenderTargetVk *renderTarget, 99 void *pixels); 100 101 gl::Extents getReadImageExtents() const; 102 gl::Rectangle getNonRotatedCompleteRenderArea() const; 103 gl::Rectangle getRotatedCompleteRenderArea(ContextVk *contextVk) const; 104 gl::Rectangle getRotatedScissoredRenderArea(ContextVk *contextVk) const; 105 // Returns render area with deferred clears in consideration. When deferred clear is used 106 // in the render pass, the render area must cover the whole framebuffer. 107 gl::Rectangle getRenderArea(ContextVk *contextVk) const; getLayerCount()108 uint32_t getLayerCount() const { return mCurrentFramebufferDesc.getLayerCount(); } 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 angle::Result getFramebuffer(ContextVk *contextVk, vk::RenderPassFramebuffer *framebufferOut); 124 hasDeferredClears()125 bool hasDeferredClears() const { return !mDeferredClears.empty(); } hasDeferredDepthClear()126 bool hasDeferredDepthClear() const { return mDeferredClears.testDepth(); } hasDeferredStencilClear()127 bool hasDeferredStencilClear() const { return mDeferredClears.testStencil(); } 128 angle::Result flushDepthStencilDeferredClear(ContextVk *contextVk, 129 VkImageAspectFlagBits aspect); 130 131 void switchToColorFramebufferFetchMode(ContextVk *contextVk, bool hasColorFramebufferFetch); 132 133 bool updateLegacyDither(ContextVk *contextVk); 134 setBackbuffer(WindowSurfaceVk * backbuffer)135 void setBackbuffer(WindowSurfaceVk *backbuffer) { mBackbuffer = backbuffer; } getBackbuffer()136 WindowSurfaceVk *getBackbuffer() const { return mBackbuffer; } 137 138 void releaseCurrentFramebuffer(ContextVk *contextVk); 139 getLastRenderPassQueueSerial()140 const QueueSerial &getLastRenderPassQueueSerial() const { return mLastRenderPassQueueSerial; } 141 hasAnyExternalAttachments()142 bool hasAnyExternalAttachments() const { return mIsExternalColorAttachments.any(); } 143 hasFrontBufferUsage()144 bool hasFrontBufferUsage() const 145 { 146 return (mAttachmentHasFrontBufferUsage & mState.getColorAttachmentsMask()).any(); 147 } 148 isFoveationEnabled()149 bool isFoveationEnabled() { return mFoveationState.isFoveated(); } 150 151 private: 152 enum class ClearWithCommand 153 { 154 Always, 155 OptimizeWithLoadOp, 156 }; 157 158 enum class RenderTargetImage 159 { 160 Attachment, 161 Resolve, 162 FragmentShadingRate, 163 }; 164 165 struct RenderTargetInfo 166 { RenderTargetInfoRenderTargetInfo167 RenderTargetInfo() : renderTarget(nullptr), renderTargetImage(RenderTargetImage::Attachment) 168 {} RenderTargetInfoRenderTargetInfo169 RenderTargetInfo(RenderTargetVk *renderTarget, RenderTargetImage renderTargetImage) 170 : renderTarget(renderTarget), renderTargetImage(renderTargetImage) 171 {} 172 RenderTargetVk *renderTarget; 173 RenderTargetImage renderTargetImage; 174 }; 175 176 // Returns the attachments to be used to create a framebuffer. The views returned in 177 // |unpackedAttachments| are not necessarily packed, but the render targets in 178 // |packedRenderTargetsInfoOut| are. In particular, the resolve attachment views need to stay 179 // sparse to be placed in |RenderPassFramebuffer|, but the calling function will have to pack 180 // them to match the render buffers before creating a framebuffer. 181 angle::Result getAttachmentsAndRenderTargets( 182 vk::Context *context, 183 vk::FramebufferAttachmentsVector<VkImageView> *unpackedAttachments, 184 vk::FramebufferAttachmentsVector<RenderTargetInfo> *packedRenderTargetsInfoOut); 185 186 angle::Result createNewFramebuffer( 187 ContextVk *contextVk, 188 uint32_t framebufferWidth, 189 const uint32_t framebufferHeight, 190 const uint32_t framebufferLayers, 191 const vk::FramebufferAttachmentsVector<VkImageView> &unpackedAttachments, 192 const vk::FramebufferAttachmentsVector<RenderTargetInfo> &renderTargetsInfo); 193 194 // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'. 195 angle::Result blitWithCommand(ContextVk *contextVk, 196 const gl::Rectangle &sourceArea, 197 const gl::Rectangle &destArea, 198 RenderTargetVk *readRenderTarget, 199 RenderTargetVk *drawRenderTarget, 200 GLenum filter, 201 bool colorBlit, 202 bool depthBlit, 203 bool stencilBlit, 204 bool flipX, 205 bool flipY); 206 207 // Resolve color with subpass attachment 208 angle::Result resolveColorWithSubpass(ContextVk *contextVk, 209 const UtilsVk::BlitResolveParameters ¶ms); 210 211 // Resolve depth/stencil with subpass attachment 212 angle::Result resolveDepthStencilWithSubpass(ContextVk *contextVk, 213 const UtilsVk::BlitResolveParameters ¶ms, 214 VkImageAspectFlags aspects); 215 216 // Resolve color with vkCmdResolveImage 217 angle::Result resolveColorWithCommand(ContextVk *contextVk, 218 const UtilsVk::BlitResolveParameters ¶ms, 219 vk::ImageHelper *srcImage); 220 221 angle::Result clearImpl(const gl::Context *context, 222 gl::DrawBufferMask clearColorBuffers, 223 bool clearDepth, 224 bool clearStencil, 225 const VkClearColorValue &clearColorValue, 226 const VkClearDepthStencilValue &clearDepthStencilValue); 227 228 void mergeClearsWithDeferredClears( 229 gl::DrawBufferMask clearColorBuffers, 230 bool clearDepth, 231 bool clearStencil, 232 const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues, 233 const VkClearDepthStencilValue &clearDepthStencilValue); 234 angle::Result clearWithDraw(ContextVk *contextVk, 235 const gl::Rectangle &clearArea, 236 gl::DrawBufferMask clearColorBuffers, 237 bool clearDepth, 238 bool clearStencil, 239 gl::BlendStateExt::ColorMaskStorage::Type colorMasks, 240 uint8_t stencilMask, 241 const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues, 242 const VkClearDepthStencilValue &clearDepthStencilValue); 243 void restageDeferredClears(ContextVk *contextVk); 244 void restageDeferredClearsForReadFramebuffer(ContextVk *contextVk); 245 void restageDeferredClearsImpl(ContextVk *contextVk); 246 angle::Result flushDeferredClears(ContextVk *contextVk); 247 void clearWithCommand(ContextVk *contextVk, 248 const gl::Rectangle &scissoredRenderArea, 249 ClearWithCommand behavior, 250 vk::ClearValuesArray *clears); 251 void clearWithLoadOp(ContextVk *contextVk); 252 void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); 253 void updateRenderPassDesc(ContextVk *contextVk); 254 angle::Result updateColorAttachment(const gl::Context *context, uint32_t colorIndex); 255 void updateColorAttachmentColorspace(gl::SrgbWriteControlMode srgbWriteControlMode); 256 angle::Result updateDepthStencilAttachment(const gl::Context *context); 257 void updateDepthStencilAttachmentSerial(ContextVk *contextVk); 258 angle::Result flushColorAttachmentUpdates(const gl::Context *context, 259 bool deferClears, 260 uint32_t colorIndex); 261 angle::Result flushDepthStencilAttachmentUpdates(const gl::Context *context, bool deferClears); 262 angle::Result invalidateImpl(ContextVk *contextVk, 263 size_t count, 264 const GLenum *attachments, 265 bool isSubInvalidate, 266 const gl::Rectangle &invalidateArea); 267 268 RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const; 269 VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const; 270 271 VkClearValue getCorrectedColorClearValue(size_t colorIndexGL, 272 const VkClearColorValue &clearColor) const; 273 274 void updateLayerCount(); 275 276 angle::Result ensureFragmentShadingRateImageAndViewInitialized( 277 ContextVk *contextVk, 278 const uint32_t fragmentShadingRateAttachmentWidth, 279 const uint32_t fragmentShadingRateAttachmentHeight); 280 angle::Result generateFragmentShadingRateWithCPU( 281 ContextVk *contextVk, 282 const uint32_t fragmentShadingRateWidth, 283 const uint32_t fragmentShadingRateHeight, 284 const uint32_t fragmentShadingRateBlockWidth, 285 const uint32_t fragmentShadingRateBlockHeight, 286 const uint32_t foveatedAttachmentWidth, 287 const uint32_t foveatedAttachmentHeight, 288 const std::vector<gl::FocalPoint> &activeFocalPoints); 289 angle::Result generateFragmentShadingRateWithCompute( 290 ContextVk *contextVk, 291 const uint32_t fragmentShadingRateWidth, 292 const uint32_t fragmentShadingRateHeight, 293 const uint32_t fragmentShadingRateBlockWidth, 294 const uint32_t fragmentShadingRateBlockHeight, 295 const uint32_t foveatedAttachmentWidth, 296 const uint32_t foveatedAttachmentHeight, 297 const std::vector<gl::FocalPoint> &activeFocalPoints); 298 angle::Result updateFragmentShadingRateAttachment(ContextVk *contextVk, 299 const gl::FoveationState &foveationState, 300 const gl::Extents &foveatedAttachmentSize); 301 angle::Result updateFoveationState(ContextVk *contextVk, 302 const gl::FoveationState &newFoveationState, 303 const gl::Extents &foveatedAttachmentSize); 304 305 void insertCache(ContextVk *contextVk, 306 const vk::FramebufferDesc &desc, 307 vk::FramebufferHelper &&newFramebuffer); 308 309 WindowSurfaceVk *mBackbuffer; 310 311 vk::RenderPassDesc mRenderPassDesc; 312 RenderTargetCache<RenderTargetVk> mRenderTargetCache; 313 314 // This variable is used to quickly compute if we need to do a masked clear. If a color 315 // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see 316 // if the masked out channel is present in any of the attachments. 317 gl::BlendStateExt::ColorMaskStorage::Type mActiveColorComponentMasksForClear; 318 319 // When we draw to the framebuffer, and the real format has an alpha channel but the format of 320 // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will 321 // contain the mask to apply to the alpha channel when drawing. 322 gl::DrawBufferMask mEmulatedAlphaAttachmentMask; 323 324 // mCurrentFramebufferDesc is used to detect framebuffer changes using its serials. Therefore, 325 // it must be maintained even when using the imageless framebuffer extension. 326 vk::FramebufferDesc mCurrentFramebufferDesc; 327 328 // The framebuffer cache actually owns the Framebuffer object and manages its lifetime. We just 329 // store the current VkFramebuffer handle here that associated with mCurrentFramebufferDesc. 330 vk::Framebuffer mCurrentFramebuffer; 331 332 vk::ClearValuesArray mDeferredClears; 333 334 // Whether any of the color attachments are an external image such as dmabuf, AHB etc. In such 335 // cases, some optimizations are disabled such as deferred clears because the results need to be 336 // made externally available. 337 gl::DrawBufferMask mIsExternalColorAttachments; 338 gl::DrawBufferMask mAttachmentHasFrontBufferUsage; 339 340 bool mIsCurrentFramebufferCached; 341 bool mIsYUVResolve; 342 343 gl::FoveationState mFoveationState; 344 vk::ImageHelper mFragmentShadingRateImage; 345 vk::ImageViewHelper mFragmentShadingRateImageView; 346 347 // Serial of the render pass this framebuffer has opened, if any. 348 QueueSerial mLastRenderPassQueueSerial; 349 }; 350 } // namespace rx 351 352 #endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 353