Add GrMtlFrameBuffer.

Sets up creation of the framebuffer object from the current render
target and adds it to the OpsRenderPass.

Bug: skia:12186
Change-Id: I08984553bcef2afcf3003d3f59e40c2fa9e383a9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/430042
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2021-07-20 11:33:58 -04:00 committed by Skia Commit-Bot
parent 202ce887ec
commit 960a4f89bb
8 changed files with 145 additions and 6 deletions

View File

@ -776,6 +776,8 @@ skia_metal_sources = [
"$_src/gpu/mtl/GrMtlCppUtil.h", "$_src/gpu/mtl/GrMtlCppUtil.h",
"$_src/gpu/mtl/GrMtlDepthStencil.h", "$_src/gpu/mtl/GrMtlDepthStencil.h",
"$_src/gpu/mtl/GrMtlDepthStencil.mm", "$_src/gpu/mtl/GrMtlDepthStencil.mm",
"$_src/gpu/mtl/GrMtlFramebuffer.h",
"$_src/gpu/mtl/GrMtlFramebuffer.mm",
"$_src/gpu/mtl/GrMtlGpu.h", "$_src/gpu/mtl/GrMtlGpu.h",
"$_src/gpu/mtl/GrMtlGpu.mm", "$_src/gpu/mtl/GrMtlGpu.mm",
"$_src/gpu/mtl/GrMtlOpsRenderPass.h", "$_src/gpu/mtl/GrMtlOpsRenderPass.h",

View File

@ -0,0 +1,39 @@
/*
* Copyright 2021 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrMtlFramebuffer_DEFINED
#define GrMtlFramebuffer_DEFINED
#include "include/gpu/GrTypes.h"
#include "include/gpu/mtl/GrMtlTypes.h"
#include "include/private/GrTypesPriv.h"
class GrMtlAttachment;
class GrMtlFramebuffer : public SkRefCnt {
public:
static sk_sp<const GrMtlFramebuffer> Make(GrMtlAttachment* colorAttachment,
GrMtlAttachment* resolveAttachment,
GrMtlAttachment* stencilAttachment);
GrMtlAttachment* colorAttachment() { return fColorAttachment.get(); }
GrMtlAttachment* resolveAttachment() { return fResolveAttachment.get(); }
GrMtlAttachment* stencilAttachment() { return fStencilAttachment.get(); }
private:
GrMtlFramebuffer(sk_sp<GrMtlAttachment> colorAttachment,
sk_sp<GrMtlAttachment> resolveAttachment,
sk_sp<GrMtlAttachment> stencilAttachment);
~GrMtlFramebuffer() override {}
sk_sp<GrMtlAttachment> fColorAttachment;
sk_sp<GrMtlAttachment> fResolveAttachment;
sk_sp<GrMtlAttachment> fStencilAttachment;
};
#endif

View File

@ -0,0 +1,30 @@
/*
* Copyright 2021 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/mtl/GrMtlFramebuffer.h"
#include "src/gpu/mtl/GrMtlAttachment.h"
sk_sp<const GrMtlFramebuffer> GrMtlFramebuffer::Make(
GrMtlAttachment* colorAttachment,
GrMtlAttachment* resolveAttachment,
GrMtlAttachment* stencilAttachment) {
// At the very least we need a colorAttachment
SkASSERT(colorAttachment);
auto fb = new GrMtlFramebuffer(sk_ref_sp(colorAttachment), sk_ref_sp(resolveAttachment),
sk_ref_sp(stencilAttachment));
return sk_sp<const GrMtlFramebuffer>(fb);
}
GrMtlFramebuffer::GrMtlFramebuffer(sk_sp<GrMtlAttachment> colorAttachment,
sk_sp<GrMtlAttachment> resolveAttachment,
sk_sp<GrMtlAttachment> stencilAttachment)
: fColorAttachment(std::move(colorAttachment))
, fResolveAttachment(std::move(resolveAttachment))
, fStencilAttachment(std::move(stencilAttachment)) {
}

View File

@ -208,13 +208,30 @@ void GrMtlGpu::destroyResources() {
} }
GrOpsRenderPass* GrMtlGpu::onGetOpsRenderPass( GrOpsRenderPass* GrMtlGpu::onGetOpsRenderPass(
GrRenderTarget* renderTarget, bool /*useMSAASurface*/, GrAttachment*, GrRenderTarget* renderTarget, bool useMSAASurface, GrAttachment* stencil,
GrSurfaceOrigin origin, const SkIRect& bounds, GrSurfaceOrigin origin, const SkIRect& bounds,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo, const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo, const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrSurfaceProxy*, true>& sampledProxies, const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
GrXferBarrierFlags renderPassXferBarriers) { GrXferBarrierFlags renderPassXferBarriers) {
return new GrMtlOpsRenderPass(this, renderTarget, origin, colorInfo, stencilInfo); // For the given render target and requested render pass features we need to find a compatible
// framebuffer to use.
GrMtlRenderTarget* mtlRT = static_cast<GrMtlRenderTarget*>(renderTarget);
SkASSERT(!useMSAASurface ||
(renderTarget->numSamples() > 1));
// TODO: Make use of discardable MSAA
bool withResolve = false;
sk_sp<GrMtlFramebuffer> framebuffer =
sk_ref_sp(mtlRT->getFramebuffer(withResolve, SkToBool(stencil)));
if (!framebuffer) {
return nullptr;
}
return new GrMtlOpsRenderPass(this, renderTarget, std::move(framebuffer), origin, colorInfo,
stencilInfo);
} }
GrMtlCommandBuffer* GrMtlGpu::commandBuffer() { GrMtlCommandBuffer* GrMtlGpu::commandBuffer() {

View File

@ -16,14 +16,15 @@
typedef uint32_t GrColor; typedef uint32_t GrColor;
class GrMtlBuffer; class GrMtlBuffer;
class GrMtlFramebuffer;
class GrMtlPipelineState; class GrMtlPipelineState;
class GrMtlRenderCommandEncoder; class GrMtlRenderCommandEncoder;
class GrMtlRenderTarget; class GrMtlRenderTarget;
class GrMtlOpsRenderPass : public GrOpsRenderPass { class GrMtlOpsRenderPass : public GrOpsRenderPass {
public: public:
GrMtlOpsRenderPass(GrMtlGpu* gpu, GrRenderTarget* rt, GrSurfaceOrigin origin, GrMtlOpsRenderPass(GrMtlGpu* gpu, GrRenderTarget* rt, sk_sp<GrMtlFramebuffer>,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo, GrSurfaceOrigin origin, const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo); const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo);
~GrMtlOpsRenderPass() override; ~GrMtlOpsRenderPass() override;
@ -68,6 +69,7 @@ private:
GrMtlGpu* fGpu; GrMtlGpu* fGpu;
sk_sp<GrMtlFramebuffer> fFramebuffer;
GrMtlRenderCommandEncoder* fActiveRenderCmdEncoder; GrMtlRenderCommandEncoder* fActiveRenderCmdEncoder;
GrMtlPipelineState* fActivePipelineState = nullptr; GrMtlPipelineState* fActivePipelineState = nullptr;
MTLPrimitiveType fActivePrimitiveType; MTLPrimitiveType fActivePrimitiveType;

View File

@ -23,11 +23,13 @@
GR_NORETAIN_BEGIN GR_NORETAIN_BEGIN
GrMtlOpsRenderPass::GrMtlOpsRenderPass(GrMtlGpu* gpu, GrRenderTarget* rt, GrSurfaceOrigin origin, GrMtlOpsRenderPass::GrMtlOpsRenderPass(GrMtlGpu* gpu, GrRenderTarget* rt,
sk_sp<GrMtlFramebuffer> framebuffer, GrSurfaceOrigin origin,
const GrOpsRenderPass::LoadAndStoreInfo& colorInfo, const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo) const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo)
: INHERITED(rt, origin) : INHERITED(rt, origin)
, fGpu(gpu) { , fGpu(gpu)
, fFramebuffer(std::move(framebuffer)) {
this->setupRenderPass(colorInfo, stencilInfo); this->setupRenderPass(colorInfo, stencilInfo);
} }

View File

@ -13,6 +13,7 @@
#include "include/gpu/GrBackendSurface.h" #include "include/gpu/GrBackendSurface.h"
#include "src/gpu/GrGpu.h" #include "src/gpu/GrGpu.h"
#include "src/gpu/mtl/GrMtlAttachment.h" #include "src/gpu/mtl/GrMtlAttachment.h"
#include "src/gpu/mtl/GrMtlFramebuffer.h"
#import <Metal/Metal.h> #import <Metal/Metal.h>
@ -53,6 +54,9 @@ public:
GrBackendFormat backendFormat() const override; GrBackendFormat backendFormat() const override;
const GrMtlFramebuffer* getFramebuffer(bool withResolve,
bool withStencil);
protected: protected:
GrMtlRenderTarget(GrMtlGpu* gpu, GrMtlRenderTarget(GrMtlGpu* gpu,
SkISize, SkISize,
@ -81,6 +85,15 @@ private:
bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override; bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override;
// We can have a renderpass with and without resolve attachment or stencil attachment,
// both of these being completely orthogonal. Thus we have a total of 4 types of render passes.
// We then cache a framebuffer for each type of these render passes.
// TODO: add support for other flags if needed
static constexpr int kNumCachedFramebuffers = 4;
sk_sp<const GrMtlFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers];
using INHERITED = GrRenderTarget; using INHERITED = GrRenderTarget;
}; };

View File

@ -9,6 +9,7 @@
#include "src/gpu/GrDirectContextPriv.h" #include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrResourceProvider.h" #include "src/gpu/GrResourceProvider.h"
#include "src/gpu/mtl/GrMtlFramebuffer.h"
#include "src/gpu/mtl/GrMtlGpu.h" #include "src/gpu/mtl/GrMtlGpu.h"
#include "src/gpu/mtl/GrMtlUtil.h" #include "src/gpu/mtl/GrMtlUtil.h"
@ -104,6 +105,39 @@ GrBackendFormat GrMtlRenderTarget::backendFormat() const {
return GrBackendFormat::MakeMtl(fColorAttachment->mtlFormat()); return GrBackendFormat::MakeMtl(fColorAttachment->mtlFormat());
} }
static int renderpass_features_to_index(bool hasResolve, bool hasStencil) {
int index = 0;
if (hasResolve) {
index += 1;
}
if (hasStencil) {
index += 2;
}
return index;
}
const GrMtlFramebuffer* GrMtlRenderTarget::getFramebuffer(bool withResolve,
bool withStencil) {
int cacheIndex =
renderpass_features_to_index(withResolve, withStencil);
SkASSERT(cacheIndex < GrMtlRenderTarget::kNumCachedFramebuffers);
if (fCachedFramebuffers[cacheIndex]) {
return fCachedFramebuffers[cacheIndex].get();
}
GrMtlAttachment* resolve = withResolve ? this->resolveAttachment() : nullptr;
GrMtlAttachment* colorAttachment = this->colorAttachment();
// Stencil attachment view is stored in the base RT stencil attachment
GrMtlAttachment* stencil =
withStencil ? static_cast<GrMtlAttachment*>(this->getStencilAttachment())
: nullptr;
fCachedFramebuffers[cacheIndex] =
GrMtlFramebuffer::Make(colorAttachment, resolve, stencil);
return fCachedFramebuffers[cacheIndex].get();
}
GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const { GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const {
SkASSERT(!this->wasDestroyed()); SkASSERT(!this->wasDestroyed());
return static_cast<GrMtlGpu*>(this->getGpu()); return static_cast<GrMtlGpu*>(this->getGpu());