Implement Direct3D semaphores

Change-Id: Iadfa14965bbe11cfea556ade5d46e264f0ace61a
Bug: skia:9935
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/298752
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Jim Van Verth 2020-06-25 13:10:29 -04:00 committed by Skia Commit-Bot
parent 7e16715806
commit c1a67b5b15
11 changed files with 229 additions and 9 deletions

View File

@ -4,6 +4,13 @@ This file includes a list of high level updates for each milestone release.
* * *
Milestone 86
------------
* Enable BackendSemaphores for the Direct3D backend.
https://review.skia.org/298752
* * *
Milestone 85
------------

View File

@ -35,6 +35,7 @@ skia_gpu_sources = [
"$_src/gpu/GrAuditTrail.cpp",
"$_src/gpu/GrAuditTrail.h",
"$_src/gpu/GrAutoLocaleSetter.h",
"$_src/gpu/GrBackendSemaphore.cpp",
"$_src/gpu/GrBackendSurface.cpp",
"$_src/gpu/GrBackendSurfaceMutableStateImpl.h",
"$_src/gpu/GrBackendTextureImageGenerator.cpp",
@ -783,6 +784,8 @@ skia_direct3d_sources = [
"$_src/gpu/d3d/GrD3DResourceState.h",
"$_src/gpu/d3d/GrD3DRootSignature.cpp",
"$_src/gpu/d3d/GrD3DRootSignature.h",
"$_src/gpu/d3d/GrD3DSemaphore.cpp",
"$_src/gpu/d3d/GrD3DSemaphore.h",
"$_src/gpu/d3d/GrD3DStencilAttachment.cpp",
"$_src/gpu/d3d/GrD3DStencilAttachment.h",
"$_src/gpu/d3d/GrD3DTexture.cpp",

View File

@ -13,6 +13,9 @@
#include "include/gpu/gl/GrGLTypes.h"
#include "include/gpu/mtl/GrMtlTypes.h"
#include "include/gpu/vk/GrVkTypes.h"
#ifdef SK_DIRECT3D
#include "include/gpu/d3d/GrD3DTypesMinimal.h"
#endif
/**
* Wrapper class for passing into and receiving data from Ganesh about a backend semaphore object.
@ -23,6 +26,14 @@ public:
// until either initGL or initVulkan are called which will set the appropriate GrBackend.
GrBackendSemaphore() : fBackend(GrBackendApi::kOpenGL), fGLSync(0), fIsInitialized(false) {}
#ifdef SK_DIRECT3D
// We only need to specify these if Direct3D is enabled, because it requires special copy
// characteristics.
~GrBackendSemaphore();
GrBackendSemaphore(const GrBackendSemaphore&);
GrBackendSemaphore& operator=(const GrBackendSemaphore&);
#endif
void initGL(GrGLsync sync) {
fBackend = GrBackendApi::kOpenGL;
fGLSync = sync;
@ -52,6 +63,14 @@ public:
#endif
}
#ifdef SK_DIRECT3D
void initDirect3D(const GrD3DFenceInfo& info) {
fBackend = GrBackendApi::kDirect3D;
this->assignD3DFenceInfo(info);
fIsInitialized = true;
}
#endif
bool isInitialized() const { return fIsInitialized; }
GrGLsync glSync() const {
@ -82,12 +101,23 @@ public:
return fMtlValue;
}
#ifdef SK_DIRECT3D
bool getD3DFenceInfo(GrD3DFenceInfo* outInfo) const;
#endif
private:
#ifdef SK_DIRECT3D
void assignD3DFenceInfo(const GrD3DFenceInfo& info);
#endif
GrBackendApi fBackend;
union {
GrGLsync fGLSync;
VkSemaphore fVkSemaphore;
GrMTLHandle fMtlEvent; // Expected to be an id<MTLEvent>
#ifdef SK_DIRECT3D
GrD3DFenceInfo* fD3DFenceInfo;
#endif
};
uint64_t fMtlValue;
bool fIsInitialized;

View File

@ -198,4 +198,14 @@ struct GrD3DTextureResourceInfo {
#endif
};
struct GrD3DFenceInfo {
GrD3DFenceInfo()
: fFence(nullptr)
, fValue(0) {
}
gr_cp<ID3D12Fence> fFence;
uint64_t fValue; // signal value for the fence
};
#endif

View File

@ -19,5 +19,6 @@
struct ID3D12Resource;
typedef int GrD3DResourceStateEnum;
struct GrD3DTextureResourceInfo;
struct GrD3DFenceInfo;
#endif

View File

@ -0,0 +1,73 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/gpu/GrBackendSemaphore.h"
#ifdef SK_DIRECT3D
#include "include/gpu/d3d/GrD3DTypes.h"
GrBackendSemaphore::~GrBackendSemaphore() {
if (fIsInitialized && GrBackendApi::kDirect3D == fBackend) {
delete fD3DFenceInfo;
fD3DFenceInfo = nullptr;
fIsInitialized = false;
}
}
void GrBackendSemaphore::assignD3DFenceInfo(const GrD3DFenceInfo& info) {
SkASSERT(GrBackendApi::kDirect3D == fBackend);
if (fIsInitialized) {
*fD3DFenceInfo = info;
} else {
fD3DFenceInfo = new GrD3DFenceInfo(info);
}
}
bool GrBackendSemaphore::getD3DFenceInfo(GrD3DFenceInfo* outInfo) const {
if (fIsInitialized && GrBackendApi::kDirect3D == fBackend) {
*outInfo = *fD3DFenceInfo;
return true;
}
return false;
}
GrBackendSemaphore::GrBackendSemaphore(const GrBackendSemaphore& that) {
fIsInitialized = false;
*this = that;
}
GrBackendSemaphore& GrBackendSemaphore::operator=(const GrBackendSemaphore& that) {
SkASSERT(!fIsInitialized || fBackend == that.fBackend);
fBackend = that.fBackend;
switch (that.fBackend) {
#ifdef SK_GL
case GrBackendApi::kOpenGL:
fGLSync = that.fGLSync;
break;
#endif
#ifdef SK_VULKAN
case GrBackendApi::kVulkan:
fVkSemaphore = that.fVkSemaphore;
break;
#endif
#ifdef SK_METAL
case GrBackendApi::kMetal:
fMtlEvent = that.fMtlEvent;
fMtlValue = that.fMtlValue;
break;
#endif
case GrBackendApi::kDirect3D:
this->assignD3DFenceInfo(*that.fD3DFenceInfo);
break;
default:
SK_ABORT("Unknown GrBackend");
}
fIsInitialized = true;
return *this;
}
#endif // SK_DIRECT3D

View File

@ -34,8 +34,8 @@ GrD3DCaps::GrD3DCaps(const GrContextOptions& contextOptions, IDXGIAdapter1* adap
fOversizedStencilSupport = false; //TODO: figure this out
fDrawInstancedSupport = true;
fSemaphoreSupport = true;
// TODO: implement these
fSemaphoreSupport = false;
fFenceSyncSupport = false;
fCrossContextTextureSupport = false;
fHalfFloatVertexAttributeSupport = false;

View File

@ -17,6 +17,7 @@
#include "src/gpu/d3d/GrD3DBuffer.h"
#include "src/gpu/d3d/GrD3DCaps.h"
#include "src/gpu/d3d/GrD3DOpsRenderPass.h"
#include "src/gpu/d3d/GrD3DSemaphore.h"
#include "src/gpu/d3d/GrD3DStencilAttachment.h"
#include "src/gpu/d3d/GrD3DTexture.h"
#include "src/gpu/d3d/GrD3DTextureRenderTarget.h"
@ -1211,3 +1212,30 @@ bool GrD3DGpu::onSubmitToGpu(bool syncCpu) {
return this->submitDirectCommandList(SyncQueue::kSkip);
}
}
std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT GrD3DGpu::makeSemaphore(bool) {
return GrD3DSemaphore::Make(this);
}
std::unique_ptr<GrSemaphore> GrD3DGpu::wrapBackendSemaphore(
const GrBackendSemaphore& semaphore,
GrResourceProvider::SemaphoreWrapType,
GrWrapOwnership) {
SkASSERT(this->caps()->semaphoreSupport());
GrD3DFenceInfo fenceInfo;
if (!semaphore.getD3DFenceInfo(&fenceInfo)) {
return nullptr;
}
return GrD3DSemaphore::MakeWrapped(fenceInfo);
}
void GrD3DGpu::insertSemaphore(GrSemaphore* semaphore) {
GrD3DSemaphore* d3dSem = static_cast<GrD3DSemaphore*>(semaphore);
// TODO: Do we need to track the lifetime of this? How do we know it's done?
fQueue->Signal(d3dSem->fence(), d3dSem->value());
}
void GrD3DGpu::waitSemaphore(GrSemaphore* semaphore) {
GrD3DSemaphore* d3dSem = static_cast<GrD3DSemaphore*>(semaphore);
// TODO: Do we need to track the lifetime of this?
fQueue->Wait(d3dSem->fence(), d3dSem->value());
}

View File

@ -88,17 +88,13 @@ public:
bool waitFence(GrFence) override { return true; }
void deleteFence(GrFence) const override {}
std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override {
return nullptr;
}
std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
std::unique_ptr<GrSemaphore> wrapBackendSemaphore(
const GrBackendSemaphore& semaphore,
GrResourceProvider::SemaphoreWrapType wrapType,
GrWrapOwnership ownership) override {
return nullptr;
}
void insertSemaphore(GrSemaphore* semaphore) override {}
void waitSemaphore(GrSemaphore* semaphore) override {}
GrWrapOwnership ownership) override;
void insertSemaphore(GrSemaphore* semaphore) override;
void waitSemaphore(GrSemaphore* semaphore) override;
std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override {
return nullptr;
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/d3d/GrD3DSemaphore.h"
#include "src/gpu/d3d/GrD3DGpu.h"
std::unique_ptr<GrD3DSemaphore> GrD3DSemaphore::Make(GrD3DGpu* gpu) {
GrD3DFenceInfo fenceInfo;
gpu->device()->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fenceInfo.fFence));
fenceInfo.fValue = 1;
return std::unique_ptr<GrD3DSemaphore>(new GrD3DSemaphore(fenceInfo));
}
std::unique_ptr<GrD3DSemaphore> GrD3DSemaphore::MakeWrapped(const GrD3DFenceInfo& fenceInfo) {
return std::unique_ptr<GrD3DSemaphore>(new GrD3DSemaphore(fenceInfo));
}
GrD3DSemaphore::GrD3DSemaphore(const GrD3DFenceInfo& fenceInfo) : fFenceInfo(fenceInfo) {}
GrBackendSemaphore GrD3DSemaphore::backendSemaphore() const {
GrBackendSemaphore backendSemaphore;
backendSemaphore.initDirect3D(fFenceInfo);
return backendSemaphore;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrMtlSemaphore_DEFINED
#define GrMtlSemaphore_DEFINED
#include "include/gpu/GrBackendSemaphore.h"
#include "include/gpu/d3d/GrD3DTypes.h"
#include "include/private/GrTypesPriv.h"
#include "src/gpu/GrSemaphore.h"
class GrD3DGpu;
class GrD3DSemaphore : public GrSemaphore {
public:
static std::unique_ptr<GrD3DSemaphore> Make(GrD3DGpu* gpu);
static std::unique_ptr<GrD3DSemaphore> MakeWrapped(const GrD3DFenceInfo&);
~GrD3DSemaphore() override {}
ID3D12Fence* fence() const { return fFenceInfo.fFence.get(); }
uint64_t value() const { return fFenceInfo.fValue; }
GrBackendSemaphore backendSemaphore() const override;
private:
GrD3DSemaphore(const GrD3DFenceInfo&);
void setIsOwned() override {}
GrD3DFenceInfo fFenceInfo;
typedef GrSemaphore INHERITED;
};
#endif