Start adding D3D backend
Bug: skia:
Change-Id: Id24ed653adb80fe9b2ad597a34e459eb91ca53ec
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271057
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index ab6e22a..0acc43e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -597,6 +597,16 @@
}
}
+ if (skia_use_direct3d) {
+ public_defines += [ "SK_DIRECT3D" ]
+ sources += skia_direct3d_sources
+ libs += [
+ "d3d12.lib",
+ "dxgi.lib",
+ "d3dcompiler.lib",
+ ]
+ }
+
cflags_objcc = []
if (skia_use_metal) {
public_defines += [ "SK_METAL" ]
@@ -1372,6 +1382,9 @@
if (skia_use_metal) {
sources += [ "tools/gpu/mtl/MtlTestContext.mm" ]
}
+ if (skia_use_direct3d) {
+ sources += [ "tools/gpu/d3d/D3DTestContext.cpp" ]
+ }
if (skia_use_dawn) {
public_deps += [ "//third_party/dawn:dawn_headers" ]
sources += [ "tools/gpu/dawn/DawnTestContext.cpp" ]
diff --git a/gn/gpu.gni b/gn/gpu.gni
index ecc0228..0d2e676 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -726,6 +726,9 @@
"$_src/gpu/vk/GrVkVertexBuffer.h",
]
+skia_direct3d_sources = [
+]
+
skia_dawn_sources = [
"$_include/gpu/dawn/GrDawnTypes.h",
"$_src/gpu/dawn/GrDawnBuffer.cpp",
diff --git a/gn/skia.gni b/gn/skia.gni
index 297317e..0fa96e3 100644
--- a/gn/skia.gni
+++ b/gn/skia.gni
@@ -38,6 +38,7 @@
skia_update_fuchsia_sdk = false
skia_use_angle = false
skia_use_dawn = false
+ skia_use_direct3d = false
skia_use_egl = false
skia_use_expat = true
skia_use_experimental_xform = false
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 12d8c5a..62e5c71 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -24,6 +24,7 @@
class GrClientMappedBufferManager;
class GrContextPriv;
class GrContextThreadSafeProxy;
+struct GrD3DBackendContext;
class GrFragmentProcessor;
struct GrGLInterface;
class GrGpu;
@@ -56,7 +57,7 @@
static sk_sp<GrContext> MakeGL();
/**
- * The Vulkan context (VkQueue, VkDevice, VkInstance) must be kept alive unitl the returned
+ * The Vulkan context (VkQueue, VkDevice, VkInstance) must be kept alive until the returned
* GrContext is first destroyed or abandoned.
*/
static sk_sp<GrContext> MakeVulkan(const GrVkBackendContext&, const GrContextOptions&);
@@ -73,6 +74,16 @@
static sk_sp<GrContext> MakeMetal(void* device, void* queue);
#endif
+#ifdef SK_DIRECT3D
+ /**
+ * Makes a GrContext which uses Direct3D as the backend. The Direct3D context
+ * must be kept alive until the returned GrContext is first destroyed or abandoned.
+ */
+ static sk_sp<GrContext> MakeDirect3D(const GrD3DBackendContext&,
+ const GrContextOptions& options);
+ static sk_sp<GrContext> MakeDirect3D(const GrD3DBackendContext&);
+#endif
+
#ifdef SK_DAWN
static sk_sp<GrContext> MakeDawn(const wgpu::Device& device, const GrContextOptions& options);
static sk_sp<GrContext> MakeDawn(const wgpu::Device& device);
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index c2ccbdb..e7d4f7e 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -133,10 +133,11 @@
* Possible 3D APIs that may be used by Ganesh.
*/
enum class GrBackendApi : unsigned {
- kMetal,
- kDawn,
kOpenGL,
kVulkan,
+ kMetal,
+ kDirect3D,
+ kDawn,
/**
* Mock is a backend that does not draw anything. It is used for unit tests
* and to measure CPU overhead.
diff --git a/include/gpu/d3d/GrD3DBackendContext.h b/include/gpu/d3d/GrD3DBackendContext.h
new file mode 100644
index 0000000..a433257
--- /dev/null
+++ b/include/gpu/d3d/GrD3DBackendContext.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrD3DBackendContext_DEFINED
+#define GrD3DBackendContext_DEFINED
+
+#include "include/core/SkRefCnt.h"
+
+// The BackendContext contains all of the base D3D objects needed by the GrD3DGpu. The assumption
+// is that the client will set these up and pass them to the GrD3DGpu constructor.
+struct SK_API GrD3DBackendContext {
+};
+
+#endif
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 3b11f4f..5a8ab5c 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -1172,11 +1172,12 @@
#if GR_TEST_UTILS || defined(SK_ENABLE_DUMP_GPU)
static constexpr const char* GrBackendApiToStr(GrBackendApi api) {
switch (api) {
- case GrBackendApi::kMetal: return "Metal";
- case GrBackendApi::kDawn: return "Dawn";
- case GrBackendApi::kOpenGL: return "OpenGL";
- case GrBackendApi::kVulkan: return "Vulkan";
- case GrBackendApi::kMock: return "Mock";
+ case GrBackendApi::kOpenGL: return "OpenGL";
+ case GrBackendApi::kVulkan: return "Vulkan";
+ case GrBackendApi::kMetal: return "Metal";
+ case GrBackendApi::kDirect3D: return "Direct3D";
+ case GrBackendApi::kDawn: return "Dawn";
+ case GrBackendApi::kMock: return "Mock";
}
SkUNREACHABLE;
}
diff --git a/src/gpu/GrBackendSurface.cpp b/src/gpu/GrBackendSurface.cpp
index 61f653c..5e267b4 100644
--- a/src/gpu/GrBackendSurface.cpp
+++ b/src/gpu/GrBackendSurface.cpp
@@ -49,6 +49,11 @@
fMtlFormat = that.fMtlFormat;
break;
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D:
+ //TODO fD3DFormat = that.fD3DFormat;
+ break;
+#endif
#ifdef SK_DAWN
case GrBackendApi::kDawn:
fDawnFormat = that.fDawnFormat;
@@ -293,6 +298,11 @@
str.append(GrMtlFormatToStr(fMtlFormat));
#endif
break;
+ case GrBackendApi::kDirect3D:
+#ifdef SK_DIRECT3D
+ //TODO str.append(GrD3DFormatToStr(fD3DFormat));
+#endif
+ break;
case GrBackendApi::kDawn:
#ifdef SK_DAWN
str.append(GrDawnFormatToStr(fDawnFormat));
@@ -450,6 +460,11 @@
fMtlInfo = that.fMtlInfo;
break;
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D:
+ // TODO fD3DInfo = that.fD3DInfo;
+ break;
+#endif
#ifdef SK_DAWN
case GrBackendApi::kDawn:
fDawnInfo = that.fDawnInfo;
@@ -573,6 +588,10 @@
case GrBackendApi::kMetal:
return this->fMtlInfo.fTexture == that.fMtlInfo.fTexture;
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D:
+ return false; //TODO
+#endif
case GrBackendApi::kMock:
return fMockInfo.id() == that.fMockInfo.id();
default:
@@ -599,11 +618,6 @@
return GrBackendFormat::MakeVk(info.fFormat);
}
#endif
-#ifdef SK_DAWN
- case GrBackendApi::kDawn: {
- return GrBackendFormat::MakeDawn(fDawnInfo.fFormat);
- }
-#endif
#ifdef SK_METAL
case GrBackendApi::kMetal: {
GrMtlTextureInfo mtlInfo;
@@ -611,6 +625,16 @@
return GrBackendFormat::MakeMtl(GrGetMTLPixelFormatFromMtlTextureInfo(mtlInfo));
}
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D: {
+ return GrBackendFormat(); // TODO
+ }
+#endif
+#ifdef SK_DAWN
+ case GrBackendApi::kDawn: {
+ return GrBackendFormat::MakeDawn(fDawnInfo.fFormat);
+ }
+#endif
case GrBackendApi::kMock:
return fMockInfo.getBackendFormat();
default:
@@ -646,6 +670,10 @@
case GrBackendApi::kMetal:
return t0.fMtlInfo == t1.fMtlInfo;
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D:
+ return false;
+#endif
#ifdef SK_DAWN
case GrBackendApi::kDawn:
return t0.fDawnInfo == t1.fDawnInfo;
@@ -795,16 +823,21 @@
fVkInfo.assign(that.fVkInfo, this->isValid());
break;
#endif
-#ifdef SK_DAWN
- case GrBackendApi::kDawn:
- fDawnInfo = that.fDawnInfo;
- break;
-#endif
#ifdef SK_METAL
case GrBackendApi::kMetal:
fMtlInfo = that.fMtlInfo;
break;
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D:
+ // TODO fD3DInfo = that.fD3DInfo;
+ break;
+#endif
+#ifdef SK_DAWN
+ case GrBackendApi::kDawn:
+ fDawnInfo = that.fDawnInfo;
+ break;
+#endif
case GrBackendApi::kMock:
fMockInfo = that.fMockInfo;
break;
@@ -898,6 +931,12 @@
return GrBackendFormat::MakeMtl(GrGetMTLPixelFormatFromMtlTextureInfo(mtlInfo));
}
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D: {
+ // TODO
+ return GrBackendFormat();
+ }
+#endif
#ifdef SK_DAWN
case GrBackendApi::kDawn: {
GrDawnRenderTargetInfo dawnInfo;
@@ -957,6 +996,10 @@
case GrBackendApi::kMetal:
return r0.fMtlInfo == r1.fMtlInfo;
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D:
+ return false; // TODO r0.fD3DInfo == r1.fD3DInfo;
+#endif
#ifdef SK_DAWN
case GrBackendApi::kDawn:
return r0.fDawnInfo == r1.fDawnInfo;
diff --git a/src/gpu/GrLegacyDirectContext.cpp b/src/gpu/GrLegacyDirectContext.cpp
index 04a40bb..31e2678 100644
--- a/src/gpu/GrLegacyDirectContext.cpp
+++ b/src/gpu/GrLegacyDirectContext.cpp
@@ -228,6 +228,29 @@
}
#endif
+#ifdef SK_DIRECT3D
+sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
+ GrContextOptions defaultOptions;
+ return MakeDirect3D(backendContext, defaultOptions);
+}
+
+sk_sp<GrContext> GrContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
+ const GrContextOptions& options) {
+ return nullptr;
+ //sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kDirect3D, options));
+
+ //context->fGpu = GrD3DGpu::Make(backendContext, options, context.get());
+ //if (!context->fGpu) {
+ // return nullptr;
+ //}
+
+ //if (!context->init(context->fGpu->refCaps())) {
+ // return nullptr;
+ //}
+ //return context;
+}
+#endif
+
#ifdef SK_DAWN
sk_sp<GrContext> GrContext::MakeDawn(const wgpu::Device& device) {
GrContextOptions defaultOptions;
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index a177089..7b4be8b 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -102,14 +102,6 @@
static bool isBGRA(const GrBackendFormat& format) {
switch (format.backend()) {
- case GrBackendApi::kMetal:
-#ifdef SK_METAL
- return GrMtlFormatIsBGRA(format.asMtlFormat());
-#else
- return false;
-#endif
- case GrBackendApi::kDawn:
- return false;
case GrBackendApi::kOpenGL:
#ifdef SK_GL
return format.asGLFormat() == GrGLFormat::kBGRA8;
@@ -125,6 +117,20 @@
return false;
#endif
}
+ case GrBackendApi::kMetal:
+#ifdef SK_METAL
+ return GrMtlFormatIsBGRA(format.asMtlFormat());
+#else
+ return false;
+#endif
+ case GrBackendApi::kDirect3D:
+#ifdef SK_DIRECT3D
+ return false; // TODO
+#else
+ return false;
+#endif
+ case GrBackendApi::kDawn:
+ return false;
case GrBackendApi::kMock: {
SkImage::CompressionType compression = format.asMockCompressionType();
if (compression != SkImage::CompressionType::kNone) {
@@ -139,10 +145,6 @@
static bool isRGB(const GrBackendFormat& format) {
switch (format.backend()) {
- case GrBackendApi::kMetal:
- return false; // Metal doesn't even pretend to support this
- case GrBackendApi::kDawn:
- return false;
case GrBackendApi::kOpenGL:
#ifdef SK_GL
return format.asGLFormat() == GrGLFormat::kRGB8;
@@ -158,6 +160,12 @@
return false;
#endif
}
+ case GrBackendApi::kMetal:
+ return false; // Metal doesn't even pretend to support this
+ case GrBackendApi::kDirect3D:
+ return false; // Not supported in Direct3D 12
+ case GrBackendApi::kDawn:
+ return false;
case GrBackendApi::kMock:
return false; // No GrColorType::kRGB_888
}
diff --git a/tools/gpu/GrContextFactory.cpp b/tools/gpu/GrContextFactory.cpp
index 4432c87..d89314e 100644
--- a/tools/gpu/GrContextFactory.cpp
+++ b/tools/gpu/GrContextFactory.cpp
@@ -13,7 +13,7 @@
#endif
#if SK_ANGLE
- #include "tools/gpu/gl/angle/GLTestContext_angle.h"
+#include "tools/gpu/gl/angle/GLTestContext_angle.h"
#endif
#include "tools/gpu/gl/command_buffer/GLTestContext_command_buffer.h"
#ifdef SK_VULKAN
@@ -22,6 +22,9 @@
#ifdef SK_METAL
#include "tools/gpu/mtl/MtlTestContext.h"
#endif
+#ifdef SK_DIRECT3D
+#include "tools/gpu/d3d/D3DTestContext.h"
+#endif
#ifdef SK_DAWN
#include "tools/gpu/dawn/DawnTestContext.h"
#endif
@@ -247,6 +250,18 @@
break;
}
#endif
+#ifdef SK_DIRECT3D
+ case GrBackendApi::kDirect3D: {
+ D3DTestContext* d3dSharedContext = masterContext
+ ? static_cast<D3DTestContext*>(masterContext->fTestContext) : nullptr;
+ SkASSERT(kDirect3D_ContextType == type);
+ testCtx.reset(CreatePlatformD3DTestContext(d3dSharedContext));
+ if (!testCtx) {
+ return ContextInfo();
+ }
+ break;
+ }
+#endif
#ifdef SK_DAWN
case GrBackendApi::kDawn: {
DawnTestContext* dawnSharedContext = masterContext
diff --git a/tools/gpu/GrContextFactory.h b/tools/gpu/GrContextFactory.h
index d1b7fd5..d46e1c1 100644
--- a/tools/gpu/GrContextFactory.h
+++ b/tools/gpu/GrContextFactory.h
@@ -41,6 +41,7 @@
kCommandBuffer_ContextType, //! Chromium command buffer OpenGL ES context.
kVulkan_ContextType, //! Vulkan
kMetal_ContextType, //! Metal
+ kDirect3D_ContextType, //! Direct3D 12
kDawn_ContextType, //! Dawn
kMock_ContextType, //! Mock context that does not draw.
kLastContextType = kMock_ContextType
@@ -72,6 +73,8 @@
return GrBackendApi::kVulkan;
case kMetal_ContextType:
return GrBackendApi::kMetal;
+ case kDirect3D_ContextType:
+ return GrBackendApi::kDirect3D;
case kDawn_ContextType:
return GrBackendApi::kDawn;
case kMock_ContextType:
@@ -103,6 +106,8 @@
return "Vulkan";
case kMetal_ContextType:
return "Metal";
+ case kDirect3D_ContextType:
+ return "Direct3D";
case kDawn_ContextType:
return "Dawn";
case kMock_ContextType:
diff --git a/tools/gpu/d3d/D3DTestContext.cpp b/tools/gpu/d3d/D3DTestContext.cpp
new file mode 100644
index 0000000..c72a6cb
--- /dev/null
+++ b/tools/gpu/d3d/D3DTestContext.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "tools/gpu/d3d/D3DTestContext.h"
+
+#ifdef SK_DIRECT3D
+
+#include "include/gpu/GrContext.h"
+
+namespace {
+
+// TODO: Implement D3DFenceSync
+
+class D3DTestContextImpl : public sk_gpu_test::D3DTestContext {
+public:
+ static D3DTestContext* Create(D3DTestContext* sharedContext) {
+ GrD3DBackendContext backendContext;
+ bool ownsContext;
+ if (sharedContext) {
+ // take from the given context
+ ownsContext = false;
+ } else {
+ // create our own
+ ownsContext = true;
+ }
+ return new D3DTestContextImpl(backendContext, ownsContext);
+ }
+
+ ~D3DTestContextImpl() override { this->teardown(); }
+
+ void testAbandon() override {}
+
+ // There is really nothing to here since we don't own any unqueued command buffers here.
+ void submit() override {}
+
+ void finish() override {}
+
+ sk_sp<GrContext> makeGrContext(const GrContextOptions& options) override {
+ return GrContext::MakeDirect3D(fD3D, options);
+ }
+
+protected:
+ void teardown() override {
+ INHERITED::teardown();
+ if (fOwnsContext) {
+ // delete all the D3D objects in the backend context
+ }
+ }
+
+private:
+ D3DTestContextImpl(const GrD3DBackendContext& backendContext, bool ownsContext)
+ : D3DTestContext(backendContext, ownsContext) {
+// TODO fFenceSync.reset(new D3DFenceSync(backendContext));
+ }
+
+ void onPlatformMakeNotCurrent() const override {}
+ void onPlatformMakeCurrent() const override {}
+ std::function<void()> onPlatformGetAutoContextRestore() const override { return nullptr; }
+ void onPlatformSwapBuffers() const override {}
+
+ typedef sk_gpu_test::D3DTestContext INHERITED;
+};
+} // anonymous namespace
+
+namespace sk_gpu_test {
+D3DTestContext* CreatePlatformD3DTestContext(D3DTestContext* sharedContext) {
+ return D3DTestContextImpl::Create(sharedContext);
+}
+} // namespace sk_gpu_test
+
+#endif
diff --git a/tools/gpu/d3d/D3DTestContext.h b/tools/gpu/d3d/D3DTestContext.h
new file mode 100644
index 0000000..c8b9c53
--- /dev/null
+++ b/tools/gpu/d3d/D3DTestContext.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef D3DTestContext_DEFINED
+#define D3DTestContext_DEFINED
+
+#include "tools/gpu/TestContext.h"
+
+#ifdef SK_DIRECT3D
+
+#include "include/gpu/d3d/GrD3DBackendContext.h"
+
+namespace sk_gpu_test {
+class D3DTestContext : public TestContext {
+public:
+ virtual GrBackendApi backend() override { return GrBackendApi::kDirect3D; }
+
+protected:
+ D3DTestContext(const GrD3DBackendContext& d3d, bool ownsContext)
+ : fD3D(d3d)
+ , fOwnsContext(ownsContext) {}
+
+ GrD3DBackendContext fD3D;
+ bool fOwnsContext;
+
+private:
+ typedef TestContext INHERITED;
+};
+
+/**
+ * Creates D3D context object bound to the native D3D library.
+ */
+D3DTestContext* CreatePlatformD3DTestContext(D3DTestContext*);
+
+} // namespace sk_gpu_test
+
+#endif
+
+#endif