Hash :
c759b8b4
Author :
Date :
2019-01-03T15:16:50
Vulkan: More Vertex Array optimizations. Inlines a number of Vulkan vertex array methods. Also changes the way vertex buffers are bound. Note that Vulkan doesn't support NULL buffer bindings. Thus we create an emulated NULL buffer to work around the problem of having gaps in the bound vertex buffers. This allows us to use a single bind call for ranges of vertex buffers even when there are gaps. Also changes how vertex array dirty bits are reset. Instead of calling memset to clear the affected buffers we pass a mutable pointer to the Vertex Array sync state. This allows us to only reset the dirty bits that we sync. This saves on the memory clearing time. Improves perf by about 10% in the Vulkan VBO state change test. Bug: angleproject:3014 Change-Id: Ib7b742dff7897fc891606a652ea0b64255a24c86 Reviewed-on: https://chromium-review.googlesource.com/c/1390360 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// FramebufferVk.h:
// Defines the class interface for FramebufferVk, implementing FramebufferImpl.
//
#ifndef LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
#define LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
#include "libANGLE/renderer/FramebufferImpl.h"
#include "libANGLE/renderer/RenderTargetCache.h"
#include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/vk_cache_utils.h"
namespace rx
{
class RendererVk;
class RenderTargetVk;
class WindowSurfaceVk;
class FramebufferVk : public FramebufferImpl
{
public:
// Factory methods so we don't have to use constructors with overloads.
static FramebufferVk *CreateUserFBO(RendererVk *renderer, const gl::FramebufferState &state);
// The passed-in SurfaceVK must be destroyed after this FBO is destroyed. Our Surface code is
// ref-counted on the number of 'current' contexts, so we shouldn't get any dangling surface
// references. See Surface::setIsCurrent(bool).
static FramebufferVk *CreateDefaultFBO(RendererVk *renderer,
const gl::FramebufferState &state,
WindowSurfaceVk *backbuffer);
~FramebufferVk() override;
void destroy(const gl::Context *context) override;
angle::Result discard(const gl::Context *context,
size_t count,
const GLenum *attachments) override;
angle::Result invalidate(const gl::Context *context,
size_t count,
const GLenum *attachments) override;
angle::Result invalidateSub(const gl::Context *context,
size_t count,
const GLenum *attachments,
const gl::Rectangle &area) override;
angle::Result clear(const gl::Context *context, GLbitfield mask) override;
angle::Result clearBufferfv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values) override;
angle::Result clearBufferuiv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLuint *values) override;
angle::Result clearBufferiv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLint *values) override;
angle::Result clearBufferfi(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil) override;
GLenum getImplementationColorReadFormat(const gl::Context *context) const override;
GLenum getImplementationColorReadType(const gl::Context *context) const override;
angle::Result readPixels(const gl::Context *context,
const gl::Rectangle &area,
GLenum format,
GLenum type,
void *pixels) override;
angle::Result blit(const gl::Context *context,
const gl::Rectangle &sourceArea,
const gl::Rectangle &destArea,
GLbitfield mask,
GLenum filter) override;
bool checkStatus(const gl::Context *context) const override;
angle::Result syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
angle::Result getSamplePosition(const gl::Context *context,
size_t index,
GLfloat *xy) const override;
RenderTargetVk *getDepthStencilRenderTarget() const;
// Internal helper function for readPixels operations.
angle::Result readPixelsImpl(ContextVk *contextVk,
const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams,
VkImageAspectFlagBits copyAspectFlags,
RenderTargetVk *renderTarget,
void *pixels);
const gl::Extents &getReadImageExtents() const;
const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const;
RenderTargetVk *getColorReadRenderTarget() const;
// This will clear the current write operation if it is complete.
bool appendToStartedRenderPass(Serial currentQueueSerial, vk::CommandBuffer **commandBufferOut)
{
return mFramebuffer.appendToStartedRenderPass(currentQueueSerial, commandBufferOut);
}
vk::FramebufferHelper *getFramebuffer() { return &mFramebuffer; }
angle::Result startNewRenderPass(ContextVk *context, vk::CommandBuffer **commandBufferOut);
RenderTargetVk *getFirstRenderTarget() const;
GLint getSamples() const;
const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; }
private:
FramebufferVk(RendererVk *renderer,
const gl::FramebufferState &state,
WindowSurfaceVk *backbuffer);
// Helper for appendToStarted/else startNewRenderPass.
angle::Result getCommandBufferForDraw(ContextVk *contextVk,
vk::CommandBuffer **commandBufferOut,
vk::RecordingMode *modeOut);
// The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'.
angle::Result blitWithCommand(ContextVk *contextVk,
const gl::Rectangle &readRectIn,
const gl::Rectangle &drawRectIn,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget,
GLenum filter,
bool colorBlit,
bool depthBlit,
bool stencilBlit,
bool flipSource,
bool flipDest);
// Note that 'copyArea' must be clipped to the scissor and FBO. The clipping is done in 'blit'.
angle::Result blitWithCopy(ContextVk *contextVk,
const gl::Rectangle ©Area,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget,
bool blitDepthBuffer,
bool blitStencilBuffer);
angle::Result blitWithReadback(ContextVk *contextVk,
const gl::Rectangle ©Area,
VkImageAspectFlagBits aspect,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget);
angle::Result getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut);
angle::Result clearWithClearAttachments(ContextVk *contextVk,
bool clearColor,
bool clearDepth,
bool clearStencil,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithDraw(ContextVk *contextVk, VkColorComponentFlags colorMaskFlags);
void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
void updateRenderPassDesc();
WindowSurfaceVk *mBackbuffer;
vk::RenderPassDesc mRenderPassDesc;
vk::FramebufferHelper mFramebuffer;
RenderTargetCache<RenderTargetVk> mRenderTargetCache;
// These two variables are used to quickly compute if we need to do a masked clear. If a color
// channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see
// if the masked out channel is present in any of the attachments.
VkColorComponentFlags mActiveColorComponents;
gl::DrawBufferMask mActiveColorComponentMasksForClear[4];
vk::DynamicBuffer mReadPixelBuffer;
vk::DynamicBuffer mBlitPixelBuffer;
// When we draw to the framebuffer, and the real format has an alpha channel but the format of
// the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
// contain the mask to apply to the alpha channel when drawing.
gl::DrawBufferMask mEmulatedAlphaAttachmentMask;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_