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; getDepthStencilRenderTarget()91 RenderTargetVk *getDepthStencilRenderTarget() const 92 { 93 return mRenderTargetCache.getDepthStencil(); 94 } 95 96 // Internal helper function for readPixels operations. 97 angle::Result readPixelsImpl(ContextVk *contextVk, 98 const gl::Rectangle &area, 99 const PackPixelsParams &packPixelsParams, 100 VkImageAspectFlagBits copyAspectFlags, 101 RenderTargetVk *renderTarget, 102 void *pixels); 103 104 gl::Extents getReadImageExtents() const; 105 // Return the framebuffer's non-rotated render area. This is a gl::Rectangle that is based on 106 // the dimensions of the framebuffer, IS NOT rotated, and IS NOT y-flipped getNonRotatedCompleteRenderArea()107 gl::Rectangle getNonRotatedCompleteRenderArea() const 108 { 109 const gl::Box &dimensions = mState.getDimensions(); 110 return gl::Rectangle(0, 0, dimensions.width, dimensions.height); 111 } 112 gl::Rectangle getRotatedCompleteRenderArea(ContextVk *contextVk) const; 113 gl::Rectangle getRotatedScissoredRenderArea(ContextVk *contextVk) const; 114 // Returns render area with deferred clears in consideration. When deferred clear is used 115 // in the render pass, the render area must cover the whole framebuffer. 116 gl::Rectangle getRenderArea(ContextVk *contextVk) const; getLayerCount()117 uint32_t getLayerCount() const { return mCurrentFramebufferDesc.getLayerCount(); } 118 119 const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const; 120 RenderTargetVk *getColorDrawRenderTarget(size_t colorIndexGL) const; 121 RenderTargetVk *getColorReadRenderTarget() const; 122 123 angle::Result startNewRenderPass(ContextVk *contextVk, 124 const gl::Rectangle &renderArea, 125 vk::RenderPassCommandBuffer **commandBufferOut, 126 bool *renderPassDescChangedOut); 127 128 GLint getSamples() const; 129 getRenderPassDesc()130 const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; } 131 132 angle::Result getFramebuffer(ContextVk *contextVk, vk::RenderPassFramebuffer *framebufferOut); 133 hasDeferredClears()134 bool hasDeferredClears() const { return !mDeferredClears.empty(); } hasDeferredDepthClear()135 bool hasDeferredDepthClear() const { return mDeferredClears.testDepth(); } hasDeferredStencilClear()136 bool hasDeferredStencilClear() const { return mDeferredClears.testStencil(); } 137 angle::Result flushDepthStencilDeferredClear(ContextVk *contextVk, 138 VkImageAspectFlagBits aspect); 139 140 void switchToColorFramebufferFetchMode(ContextVk *contextVk, bool hasColorFramebufferFetch); 141 142 bool updateLegacyDither(ContextVk *contextVk); 143 setBackbuffer(WindowSurfaceVk * backbuffer)144 void setBackbuffer(WindowSurfaceVk *backbuffer) { mBackbuffer = backbuffer; } getBackbuffer()145 WindowSurfaceVk *getBackbuffer() const { return mBackbuffer; } 146 147 void releaseCurrentFramebuffer(ContextVk *contextVk); 148 getLastRenderPassQueueSerial()149 const QueueSerial &getLastRenderPassQueueSerial() const { return mLastRenderPassQueueSerial; } 150 hasAnyExternalAttachments()151 bool hasAnyExternalAttachments() const { return mIsExternalColorAttachments.any(); } 152 hasFrontBufferUsage()153 bool hasFrontBufferUsage() const 154 { 155 return (mAttachmentHasFrontBufferUsage & mState.getColorAttachmentsMask()).any(); 156 } 157 isFoveationEnabled()158 bool isFoveationEnabled() { return mFoveationState.isFoveated(); } 159 160 private: 161 enum class ClearWithCommand 162 { 163 Always, 164 OptimizeWithLoadOp, 165 }; 166 167 enum class RenderTargetImage 168 { 169 Attachment, 170 Resolve, 171 FragmentShadingRate, 172 }; 173 174 struct RenderTargetInfo 175 { RenderTargetInfoRenderTargetInfo176 RenderTargetInfo() : renderTarget(nullptr), renderTargetImage(RenderTargetImage::Attachment) 177 {} RenderTargetInfoRenderTargetInfo178 RenderTargetInfo(RenderTargetVk *renderTarget, RenderTargetImage renderTargetImage) 179 : renderTarget(renderTarget), renderTargetImage(renderTargetImage) 180 {} 181 RenderTargetVk *renderTarget; 182 RenderTargetImage renderTargetImage; 183 }; 184 185 // Returns the attachments to be used to create a framebuffer. The views returned in 186 // |unpackedAttachments| are not necessarily packed, but the render targets in 187 // |packedRenderTargetsInfoOut| are. In particular, the resolve attachment views need to stay 188 // sparse to be placed in |RenderPassFramebuffer|, but the calling function will have to pack 189 // them to match the render buffers before creating a framebuffer. 190 angle::Result getAttachmentsAndRenderTargets( 191 vk::ErrorContext *context, 192 vk::FramebufferAttachmentsVector<VkImageView> *unpackedAttachments, 193 vk::FramebufferAttachmentsVector<RenderTargetInfo> *packedRenderTargetsInfoOut); 194 195 angle::Result createNewFramebuffer( 196 ContextVk *contextVk, 197 uint32_t framebufferWidth, 198 const uint32_t framebufferHeight, 199 const uint32_t framebufferLayers, 200 const vk::FramebufferAttachmentsVector<VkImageView> &unpackedAttachments, 201 const vk::FramebufferAttachmentsVector<RenderTargetInfo> &renderTargetsInfo); 202 203 // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'. 204 angle::Result blitWithCommand(ContextVk *contextVk, 205 const gl::Rectangle &sourceArea, 206 const gl::Rectangle &destArea, 207 RenderTargetVk *readRenderTarget, 208 RenderTargetVk *drawRenderTarget, 209 GLenum filter, 210 bool colorBlit, 211 bool depthBlit, 212 bool stencilBlit, 213 bool flipX, 214 bool flipY); 215 216 // Resolve color with subpass attachment 217 angle::Result resolveColorWithSubpass(ContextVk *contextVk, 218 const UtilsVk::BlitResolveParameters ¶ms); 219 220 // Resolve depth/stencil with subpass attachment 221 angle::Result resolveDepthStencilWithSubpass(ContextVk *contextVk, 222 const UtilsVk::BlitResolveParameters ¶ms, 223 VkImageAspectFlags aspects); 224 225 // Resolve color with vkCmdResolveImage 226 angle::Result resolveColorWithCommand(ContextVk *contextVk, 227 const UtilsVk::BlitResolveParameters ¶ms, 228 vk::ImageHelper *srcImage); 229 230 angle::Result clearImpl(const gl::Context *context, 231 gl::DrawBufferMask clearColorBuffers, 232 bool clearDepth, 233 bool clearStencil, 234 const VkClearColorValue &clearColorValue, 235 const VkClearDepthStencilValue &clearDepthStencilValue); 236 237 void mergeClearsWithDeferredClears( 238 gl::DrawBufferMask clearColorBuffers, 239 bool clearDepth, 240 bool clearStencil, 241 const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues, 242 const VkClearDepthStencilValue &clearDepthStencilValue); 243 angle::Result clearWithDraw(ContextVk *contextVk, 244 const gl::Rectangle &clearArea, 245 gl::DrawBufferMask clearColorBuffers, 246 bool clearDepth, 247 bool clearStencil, 248 gl::BlendStateExt::ColorMaskStorage::Type colorMasks, 249 uint8_t stencilMask, 250 const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues, 251 const VkClearDepthStencilValue &clearDepthStencilValue); 252 void restageDeferredClears(ContextVk *contextVk); 253 void restageDeferredClearsForReadFramebuffer(ContextVk *contextVk); 254 void restageDeferredClearsImpl(ContextVk *contextVk); 255 angle::Result flushDeferredClears(ContextVk *contextVk); 256 void clearWithCommand(ContextVk *contextVk, 257 const gl::Rectangle &scissoredRenderArea, 258 ClearWithCommand behavior, 259 vk::ClearValuesArray *clears); 260 void clearWithLoadOp(ContextVk *contextVk); 261 void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); 262 void updateRenderPassDesc(ContextVk *contextVk); 263 angle::Result updateColorAttachment(const gl::Context *context, uint32_t colorIndex); 264 void updateColorAttachmentColorspace(gl::SrgbWriteControlMode srgbWriteControlMode); 265 angle::Result updateDepthStencilAttachment(const gl::Context *context); 266 void updateDepthStencilAttachmentSerial(ContextVk *contextVk); 267 angle::Result flushColorAttachmentUpdates(const gl::Context *context, 268 bool deferClears, 269 uint32_t colorIndex); 270 angle::Result flushDepthStencilAttachmentUpdates(const gl::Context *context, bool deferClears); 271 angle::Result invalidateImpl(ContextVk *contextVk, 272 size_t count, 273 const GLenum *attachments, 274 bool isSubInvalidate, 275 const gl::Rectangle &invalidateArea); 276 277 RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const; 278 VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const; 279 280 VkClearValue getCorrectedColorClearValue(size_t colorIndexGL, 281 const VkClearColorValue &clearColor) const; 282 283 void updateLayerCount(); 284 285 angle::Result ensureFragmentShadingRateImageAndViewInitialized( 286 ContextVk *contextVk, 287 const uint32_t fragmentShadingRateAttachmentWidth, 288 const uint32_t fragmentShadingRateAttachmentHeight); 289 angle::Result generateFragmentShadingRateWithCPU( 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 generateFragmentShadingRateWithCompute( 299 ContextVk *contextVk, 300 const uint32_t fragmentShadingRateWidth, 301 const uint32_t fragmentShadingRateHeight, 302 const uint32_t fragmentShadingRateBlockWidth, 303 const uint32_t fragmentShadingRateBlockHeight, 304 const uint32_t foveatedAttachmentWidth, 305 const uint32_t foveatedAttachmentHeight, 306 const std::vector<gl::FocalPoint> &activeFocalPoints); 307 angle::Result updateFragmentShadingRateAttachment(ContextVk *contextVk, 308 const gl::FoveationState &foveationState, 309 const gl::Extents &foveatedAttachmentSize); 310 angle::Result updateFoveationState(ContextVk *contextVk, 311 const gl::FoveationState &newFoveationState, 312 const gl::Extents &foveatedAttachmentSize); 313 314 void insertCache(ContextVk *contextVk, 315 const vk::FramebufferDesc &desc, 316 vk::FramebufferHelper &&newFramebuffer); 317 318 WindowSurfaceVk *mBackbuffer; 319 320 vk::RenderPassDesc mRenderPassDesc; 321 RenderTargetCache<RenderTargetVk> mRenderTargetCache; 322 323 // This variable is used to quickly compute if we need to do a masked clear. If a color 324 // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see 325 // if the masked out channel is present in any of the attachments. 326 gl::BlendStateExt::ColorMaskStorage::Type mActiveColorComponentMasksForClear; 327 328 // When we draw to the framebuffer, and the real format has an alpha channel but the format of 329 // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will 330 // contain the mask to apply to the alpha channel when drawing. 331 gl::DrawBufferMask mEmulatedAlphaAttachmentMask; 332 333 // mCurrentFramebufferDesc is used to detect framebuffer changes using its serials. Therefore, 334 // it must be maintained even when using the imageless framebuffer extension. 335 vk::FramebufferDesc mCurrentFramebufferDesc; 336 337 // The framebuffer cache actually owns the Framebuffer object and manages its lifetime. We just 338 // store the current VkFramebuffer handle here that associated with mCurrentFramebufferDesc. 339 vk::Framebuffer mCurrentFramebuffer; 340 341 vk::ClearValuesArray mDeferredClears; 342 343 // Whether any of the color attachments are an external image such as dmabuf, AHB etc. In such 344 // cases, some optimizations are disabled such as deferred clears because the results need to be 345 // made externally available. 346 gl::DrawBufferMask mIsExternalColorAttachments; 347 gl::DrawBufferMask mAttachmentHasFrontBufferUsage; 348 349 bool mIsCurrentFramebufferCached; 350 bool mIsYUVResolve; 351 352 gl::FoveationState mFoveationState; 353 vk::ImageHelper mFragmentShadingRateImage; 354 vk::ImageViewHelper mFragmentShadingRateImageView; 355 356 // Serial of the render pass this framebuffer has opened, if any. 357 QueueSerial mLastRenderPassQueueSerial; 358 }; 359 } // namespace rx 360 361 #endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 362