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/renderer/FramebufferImpl.h" 14 #include "libANGLE/renderer/RenderTargetCache.h" 15 #include "libANGLE/renderer/vulkan/BufferVk.h" 16 #include "libANGLE/renderer/vulkan/ResourceVk.h" 17 #include "libANGLE/renderer/vulkan/UtilsVk.h" 18 #include "libANGLE/renderer/vulkan/vk_cache_utils.h" 19 20 namespace rx 21 { 22 class RendererVk; 23 class RenderTargetVk; 24 class WindowSurfaceVk; 25 26 class FramebufferVk : public FramebufferImpl 27 { 28 public: 29 // Factory methods so we don't have to use constructors with overloads. 30 static FramebufferVk *CreateUserFBO(RendererVk *renderer, const gl::FramebufferState &state); 31 32 // The passed-in SurfaceVK must be destroyed after this FBO is destroyed. Our Surface code is 33 // ref-counted on the number of 'current' contexts, so we shouldn't get any dangling surface 34 // references. See Surface::setIsCurrent(bool). 35 static FramebufferVk *CreateDefaultFBO(RendererVk *renderer, 36 const gl::FramebufferState &state, 37 WindowSurfaceVk *backbuffer); 38 39 ~FramebufferVk() override; 40 void destroy(const gl::Context *context) override; 41 42 angle::Result discard(const gl::Context *context, 43 size_t count, 44 const GLenum *attachments) override; 45 angle::Result invalidate(const gl::Context *context, 46 size_t count, 47 const GLenum *attachments) override; 48 angle::Result invalidateSub(const gl::Context *context, 49 size_t count, 50 const GLenum *attachments, 51 const gl::Rectangle &area) override; 52 53 angle::Result clear(const gl::Context *context, GLbitfield mask) override; 54 angle::Result clearBufferfv(const gl::Context *context, 55 GLenum buffer, 56 GLint drawbuffer, 57 const GLfloat *values) override; 58 angle::Result clearBufferuiv(const gl::Context *context, 59 GLenum buffer, 60 GLint drawbuffer, 61 const GLuint *values) override; 62 angle::Result clearBufferiv(const gl::Context *context, 63 GLenum buffer, 64 GLint drawbuffer, 65 const GLint *values) override; 66 angle::Result clearBufferfi(const gl::Context *context, 67 GLenum buffer, 68 GLint drawbuffer, 69 GLfloat depth, 70 GLint stencil) override; 71 72 const gl::InternalFormat &getImplementationColorReadFormat( 73 const gl::Context *context) const override; 74 angle::Result readPixels(const gl::Context *context, 75 const gl::Rectangle &area, 76 GLenum format, 77 GLenum type, 78 void *pixels) override; 79 80 angle::Result blit(const gl::Context *context, 81 const gl::Rectangle &sourceArea, 82 const gl::Rectangle &destArea, 83 GLbitfield mask, 84 GLenum filter) override; 85 86 bool checkStatus(const gl::Context *context) const override; 87 88 angle::Result syncState(const gl::Context *context, 89 GLenum binding, 90 const gl::Framebuffer::DirtyBits &dirtyBits) override; 91 92 angle::Result getSamplePosition(const gl::Context *context, 93 size_t index, 94 GLfloat *xy) const override; 95 RenderTargetVk *getDepthStencilRenderTarget() const; 96 97 // Internal helper function for readPixels operations. 98 angle::Result readPixelsImpl(ContextVk *contextVk, 99 const gl::Rectangle &area, 100 const PackPixelsParams &packPixelsParams, 101 VkImageAspectFlagBits copyAspectFlags, 102 RenderTargetVk *renderTarget, 103 void *pixels); 104 105 gl::Extents getReadImageExtents() const; 106 gl::Rectangle getCompleteRenderArea() const; 107 gl::Rectangle getScissoredRenderArea(ContextVk *contextVk) const; 108 109 const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const; 110 RenderTargetVk *getColorDrawRenderTarget(size_t colorIndex) const; 111 RenderTargetVk *getColorReadRenderTarget() const; 112 113 angle::Result startNewRenderPass(ContextVk *context, 114 const gl::Rectangle &renderArea, 115 vk::CommandBuffer **commandBufferOut); 116 117 RenderTargetVk *getFirstRenderTarget() const; 118 GLint getSamples() const; 119 getRenderPassDesc()120 const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; } getFramebufferDesc()121 const vk::FramebufferDesc &getFramebufferDesc() const { return mCurrentFramebufferDesc; } 122 // We only support depth/stencil packed format and depthstencil attachment always follow all 123 // color attachments getDepthStencilAttachmentIndexVk()124 size_t getDepthStencilAttachmentIndexVk() const 125 { 126 return getState().getEnabledDrawBuffers().count(); 127 } 128 129 private: 130 FramebufferVk(RendererVk *renderer, 131 const gl::FramebufferState &state, 132 WindowSurfaceVk *backbuffer); 133 134 // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'. 135 angle::Result blitWithCommand(ContextVk *contextVk, 136 const gl::Rectangle &sourceArea, 137 const gl::Rectangle &destArea, 138 RenderTargetVk *readRenderTarget, 139 RenderTargetVk *drawRenderTarget, 140 GLenum filter, 141 bool colorBlit, 142 bool depthBlit, 143 bool stencilBlit, 144 bool flipX, 145 bool flipY); 146 147 // Resolve color with vkCmdResolveImage 148 angle::Result resolveColorWithCommand(ContextVk *contextVk, 149 const UtilsVk::BlitResolveParameters ¶ms, 150 vk::ImageHelper *srcImage); 151 152 angle::Result getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut); 153 154 angle::Result clearImpl(const gl::Context *context, 155 gl::DrawBufferMask clearColorBuffers, 156 bool clearDepth, 157 bool clearStencil, 158 const VkClearColorValue &clearColorValue, 159 const VkClearDepthStencilValue &clearDepthStencilValue); 160 angle::Result clearWithDraw(ContextVk *contextVk, 161 const gl::Rectangle &clearArea, 162 gl::DrawBufferMask clearColorBuffers, 163 bool clearStencil, 164 VkColorComponentFlags colorMaskFlags, 165 uint8_t stencilMask, 166 const VkClearColorValue &clearColorValue, 167 uint8_t clearStencilValue); 168 void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); 169 void updateRenderPassDesc(); 170 angle::Result updateColorAttachment(const gl::Context *context, size_t colorIndex); 171 angle::Result invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments); 172 // Release all FramebufferVk objects in the cache and clear cache 173 void clearCache(ContextVk *contextVk); 174 void updateDepthStencilAttachmentSerial(ContextVk *contextVk); 175 176 RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const; 177 VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const; 178 179 WindowSurfaceVk *mBackbuffer; 180 181 vk::RenderPassDesc mRenderPassDesc; 182 vk::FramebufferHelper *mFramebuffer; 183 RenderTargetCache<RenderTargetVk> mRenderTargetCache; 184 185 // These two variables are used to quickly compute if we need to do a masked clear. If a color 186 // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see 187 // if the masked out channel is present in any of the attachments. 188 VkColorComponentFlags mActiveColorComponents; 189 gl::DrawBufferMask mActiveColorComponentMasksForClear[4]; 190 vk::DynamicBuffer mReadPixelBuffer; 191 192 // When we draw to the framebuffer, and the real format has an alpha channel but the format of 193 // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will 194 // contain the mask to apply to the alpha channel when drawing. 195 gl::DrawBufferMask mEmulatedAlphaAttachmentMask; 196 197 vk::FramebufferDesc mCurrentFramebufferDesc; 198 std::unordered_map<vk::FramebufferDesc, vk::FramebufferHelper> mFramebufferCache; 199 bool mSupportDepthStencilFeedbackLoops; 200 }; 201 } // namespace rx 202 203 #endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 204