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/CommandGraph.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 GLenum getImplementationColorReadFormat(const gl::Context *context) const override; 73 GLenum getImplementationColorReadType(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 const gl::Framebuffer::DirtyBits &dirtyBits) override; 90 91 angle::Result getSamplePosition(const gl::Context *context, 92 size_t index, 93 GLfloat *xy) const override; 94 RenderTargetVk *getDepthStencilRenderTarget() const; 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 gl::Rectangle getCompleteRenderArea() const; 106 gl::Rectangle getScissoredRenderArea(ContextVk *contextVk) const; 107 108 void onScissorChange(ContextVk *contextVk); 109 110 const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const; 111 RenderTargetVk *getColorReadRenderTarget() const; 112 113 // This will clear the current write operation if it is complete. appendToStartedRenderPass(Serial currentQueueSerial,const gl::Rectangle & renderArea,vk::CommandBuffer ** commandBufferOut)114 bool appendToStartedRenderPass(Serial currentQueueSerial, 115 const gl::Rectangle &renderArea, 116 vk::CommandBuffer **commandBufferOut) 117 { 118 return mFramebuffer.appendToStartedRenderPass(currentQueueSerial, renderArea, 119 commandBufferOut); 120 } 121 getFramebuffer()122 vk::FramebufferHelper *getFramebuffer() { return &mFramebuffer; } 123 124 angle::Result startNewRenderPass(ContextVk *context, 125 const gl::Rectangle &renderArea, 126 vk::CommandBuffer **commandBufferOut); 127 128 RenderTargetVk *getFirstRenderTarget() const; 129 GLint getSamples() const; 130 getRenderPassDesc()131 const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; } 132 133 private: 134 FramebufferVk(RendererVk *renderer, 135 const gl::FramebufferState &state, 136 WindowSurfaceVk *backbuffer); 137 138 // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'. 139 angle::Result blitWithCommand(ContextVk *contextVk, 140 const gl::Rectangle &sourceArea, 141 const gl::Rectangle &destArea, 142 RenderTargetVk *readRenderTarget, 143 RenderTargetVk *drawRenderTarget, 144 GLenum filter, 145 bool colorBlit, 146 bool depthBlit, 147 bool stencilBlit, 148 bool flipX, 149 bool flipY); 150 151 // Resolve color with vkCmdResolveImage 152 angle::Result resolveColorWithCommand(ContextVk *contextVk, 153 const UtilsVk::BlitResolveParameters ¶ms, 154 vk::ImageHelper *srcImage); 155 156 angle::Result getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut); 157 158 angle::Result clearImpl(const gl::Context *context, 159 gl::DrawBufferMask clearColorBuffers, 160 bool clearDepth, 161 bool clearStencil, 162 const VkClearColorValue &clearColorValue, 163 const VkClearDepthStencilValue &clearDepthStencilValue); 164 angle::Result clearWithRenderPassOp(ContextVk *contextVk, 165 const gl::Rectangle &clearArea, 166 gl::DrawBufferMask clearColorBuffers, 167 bool clearDepth, 168 bool clearStencil, 169 const VkClearColorValue &clearColorValue, 170 const VkClearDepthStencilValue &clearDepthStencilValue); 171 angle::Result clearWithDraw(ContextVk *contextVk, 172 const gl::Rectangle &clearArea, 173 gl::DrawBufferMask clearColorBuffers, 174 bool clearStencil, 175 VkColorComponentFlags colorMaskFlags, 176 uint8_t stencilMask, 177 const VkClearColorValue &clearColorValue, 178 uint8_t clearStencilValue); 179 void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a); 180 void updateRenderPassDesc(); 181 angle::Result updateColorAttachment(const gl::Context *context, size_t colorIndex); 182 void invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments); 183 184 WindowSurfaceVk *mBackbuffer; 185 186 vk::RenderPassDesc mRenderPassDesc; 187 vk::FramebufferHelper mFramebuffer; 188 RenderTargetCache<RenderTargetVk> mRenderTargetCache; 189 190 // These two variables are used to quickly compute if we need to do a masked clear. If a color 191 // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see 192 // if the masked out channel is present in any of the attachments. 193 VkColorComponentFlags mActiveColorComponents; 194 gl::DrawBufferMask mActiveColorComponentMasksForClear[4]; 195 vk::DynamicBuffer mReadPixelBuffer; 196 197 // When we draw to the framebuffer, and the real format has an alpha channel but the format of 198 // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will 199 // contain the mask to apply to the alpha channel when drawing. 200 gl::DrawBufferMask mEmulatedAlphaAttachmentMask; 201 }; 202 } // namespace rx 203 204 #endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_ 205