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