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:
parent
202ce887ec
commit
960a4f89bb
@ -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",
|
||||||
|
39
src/gpu/mtl/GrMtlFramebuffer.h
Normal file
39
src/gpu/mtl/GrMtlFramebuffer.h
Normal 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
|
30
src/gpu/mtl/GrMtlFramebuffer.mm
Normal file
30
src/gpu/mtl/GrMtlFramebuffer.mm
Normal 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)) {
|
||||||
|
}
|
@ -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() {
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
Loading…
Reference in New Issue
Block a user