First draft of Dawn backend: clears are working.
First draft of (mostly stubbed-out) GrDawnGpu. Skeletons of GrDawnCaps, GrDawnGpuCommandBuffer, GrDawnRenderTarget. First draft of DawnTestContext. First draft of psuedo-fences for Dawn, implemented with MapReadAsync. Change-Id: I443f3370522639e82f2fa0eebe6b206c372f13a4 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228137 Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
bd865e2703
commit
985741a554
5
BUILD.gn
5
BUILD.gn
@ -650,6 +650,7 @@ optional("gpu") {
|
||||
|
||||
if (skia_use_dawn) {
|
||||
public_defines += [ "SK_DAWN" ]
|
||||
sources += skia_dawn_sources
|
||||
public_deps += [
|
||||
"//third_party/dawn:dawn_headers",
|
||||
"//third_party/dawn:libdawn",
|
||||
@ -1566,6 +1567,10 @@ if (skia_enable_tools) {
|
||||
if (skia_use_metal) {
|
||||
sources += [ "tools/gpu/mtl/MtlTestContext.mm" ]
|
||||
}
|
||||
if (skia_use_dawn) {
|
||||
public_deps += [ "//third_party/dawn:dawn_headers" ]
|
||||
sources += [ "tools/gpu/dawn/DawnTestContext.cpp" ]
|
||||
}
|
||||
}
|
||||
|
||||
test_lib("flags") {
|
||||
|
13
gn/gpu.gni
13
gn/gpu.gni
@ -704,6 +704,19 @@ skia_vk_sources = [
|
||||
"$_src/gpu/vk/GrVkVertexBuffer.h",
|
||||
]
|
||||
|
||||
skia_dawn_sources = [
|
||||
"$_src/gpu/dawn/GrDawnCaps.cpp",
|
||||
"$_src/gpu/dawn/GrDawnCaps.h",
|
||||
"$_src/gpu/dawn/GrDawnGpu.cpp",
|
||||
"$_src/gpu/dawn/GrDawnGpu.h",
|
||||
"$_src/gpu/dawn/GrDawnGpuCommandBuffer.cpp",
|
||||
"$_src/gpu/dawn/GrDawnGpuCommandBuffer.h",
|
||||
"$_src/gpu/dawn/GrDawnRenderTarget.cpp",
|
||||
"$_src/gpu/dawn/GrDawnRenderTarget.h",
|
||||
"$_src/gpu/dawn/GrDawnUtil.cpp",
|
||||
"$_src/gpu/dawn/GrDawnUtil.h",
|
||||
]
|
||||
|
||||
skia_metal_sources = [
|
||||
"$_include/gpu/mtl/GrMtlTypes.h",
|
||||
"$_src/gpu/mtl/GrMtlBuffer.h",
|
||||
|
@ -15,9 +15,17 @@
|
||||
#include "include/private/GrGLTypesPriv.h"
|
||||
#include "include/private/GrVkTypesPriv.h"
|
||||
|
||||
#ifdef SK_DAWN
|
||||
#include "include/gpu/dawn/GrDawnTypes.h"
|
||||
#endif
|
||||
|
||||
class GrVkImageLayout;
|
||||
class GrGLTextureParameters;
|
||||
|
||||
#ifdef SK_DAWN
|
||||
#include "dawn/dawncpp.h"
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
#include "include/gpu/mtl/GrMtlTypes.h"
|
||||
#endif
|
||||
@ -60,6 +68,12 @@ public:
|
||||
// external format.
|
||||
static GrBackendFormat MakeVk(const GrVkYcbcrConversionInfo& ycbcrInfo);
|
||||
|
||||
#ifdef SK_DAWN
|
||||
static GrBackendFormat MakeDawn(dawn::TextureFormat format) {
|
||||
return GrBackendFormat(format);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
static GrBackendFormat MakeMtl(GrMTLPixelFormat format) {
|
||||
return GrBackendFormat(format);
|
||||
@ -87,6 +101,10 @@ public:
|
||||
|
||||
const GrVkYcbcrConversionInfo* getVkYcbcrConversionInfo() const;
|
||||
|
||||
#ifdef SK_DAWN
|
||||
const dawn::TextureFormat* getDawnFormat() const;
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
// If the backend API is Metal, this returns a pointer to a GrMTLPixelFormat. Otherwise
|
||||
// it returns nullptr
|
||||
@ -110,6 +128,10 @@ private:
|
||||
|
||||
GrBackendFormat(const VkFormat vkFormat, const GrVkYcbcrConversionInfo&);
|
||||
|
||||
#ifdef SK_DAWN
|
||||
GrBackendFormat(dawn::TextureFormat format);
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
GrBackendFormat(const GrMTLPixelFormat mtlFormat);
|
||||
#endif
|
||||
@ -125,6 +147,10 @@ private:
|
||||
VkFormat fFormat;
|
||||
GrVkYcbcrConversionInfo fYcbcrConversionInfo;
|
||||
} fVk;
|
||||
#ifdef SK_DAWN
|
||||
dawn::TextureFormat fDawnFormat;
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
GrMTLPixelFormat fMtlFormat;
|
||||
#endif
|
||||
@ -160,6 +186,12 @@ public:
|
||||
const GrMtlTextureInfo& mtlInfo);
|
||||
#endif
|
||||
|
||||
#ifdef SK_DAWN
|
||||
GrBackendTexture(int width,
|
||||
int height,
|
||||
const GrDawnImageInfo& dawnInfo);
|
||||
#endif
|
||||
|
||||
GrBackendTexture(int width,
|
||||
int height,
|
||||
GrMipMapped,
|
||||
@ -184,6 +216,12 @@ public:
|
||||
// externally to GrContext.
|
||||
void glTextureParametersModified();
|
||||
|
||||
#ifdef SK_DAWN
|
||||
// If the backend API is Dawn, copies a snapshot of the GrDawnImageInfo struct into the passed
|
||||
// in pointer and returns true. Otherwise returns false if the backend API is not Dawn.
|
||||
bool getDawnImageInfo(GrDawnImageInfo*) const;
|
||||
#endif
|
||||
|
||||
// If the backend API is Vulkan, copies a snapshot of the GrVkImageInfo struct into the passed
|
||||
// in pointer and returns true. This snapshot will set the fImageLayout to the current layout
|
||||
// state. Otherwise returns false if the backend API is not Vulkan.
|
||||
@ -239,6 +277,7 @@ private:
|
||||
friend class GrProxyProvider;
|
||||
friend class GrGpu;
|
||||
friend class GrGLGpu;
|
||||
friend class GrDawnGpu;
|
||||
friend class GrVkGpu;
|
||||
friend class GrMtlGpu;
|
||||
friend class PromiseImageHelper;
|
||||
@ -286,6 +325,9 @@ private:
|
||||
#ifdef SK_METAL
|
||||
GrMtlTextureInfo fMtlInfo;
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
GrDawnImageInfo fDawnInfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
class SK_API GrBackendRenderTarget {
|
||||
@ -300,6 +342,14 @@ public:
|
||||
int stencilBits,
|
||||
const GrGLFramebufferInfo& glInfo);
|
||||
|
||||
#ifdef SK_DAWN
|
||||
GrBackendRenderTarget(int width,
|
||||
int height,
|
||||
int sampleCnt,
|
||||
int stencilBits,
|
||||
const GrDawnImageInfo& dawnInfo);
|
||||
#endif
|
||||
|
||||
/** Deprecated, use version that does not take stencil bits. */
|
||||
GrBackendRenderTarget(int width,
|
||||
int height,
|
||||
@ -341,6 +391,12 @@ public:
|
||||
// in pointer and returns true. Otherwise returns false if the backend API is not GL.
|
||||
bool getGLFramebufferInfo(GrGLFramebufferInfo*) const;
|
||||
|
||||
#ifdef SK_DAWN
|
||||
// If the backend API is Dawn, copies a snapshot of the GrDawnImageInfo struct into the passed
|
||||
// in pointer and returns true. Otherwise returns false if the backend API is not Dawn.
|
||||
bool getDawnImageInfo(GrDawnImageInfo*) const;
|
||||
#endif
|
||||
|
||||
// If the backend API is Vulkan, copies a snapshot of the GrVkImageInfo struct into the passed
|
||||
// in pointer and returns true. This snapshot will set the fImageLayout to the current layout
|
||||
// state. Otherwise returns false if the backend API is not Vulkan.
|
||||
@ -387,6 +443,7 @@ private:
|
||||
friend class SkImage_Gpu;
|
||||
friend class GrGpu;
|
||||
friend class GrGLGpu;
|
||||
friend class GrDawnGpu;
|
||||
friend class GrProxyProvider;
|
||||
friend class GrVkGpu;
|
||||
friend class GrMtlGpu;
|
||||
@ -423,6 +480,9 @@ private:
|
||||
#ifdef SK_METAL
|
||||
GrMtlTextureInfo fMtlInfo;
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
GrDawnImageInfo fDawnInfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -70,6 +70,11 @@ public:
|
||||
static sk_sp<GrContext> MakeMetal(void* device, void* queue);
|
||||
#endif
|
||||
|
||||
#ifdef SK_DAWN
|
||||
static sk_sp<GrContext> MakeDawn(const dawn::Device& device, const GrContextOptions& options);
|
||||
static sk_sp<GrContext> MakeDawn(const dawn::Device& device);
|
||||
#endif
|
||||
|
||||
static sk_sp<GrContext> MakeMock(const GrMockOptions*, const GrContextOptions&);
|
||||
static sk_sp<GrContext> MakeMock(const GrMockOptions*);
|
||||
|
||||
|
@ -182,6 +182,7 @@ static inline constexpr size_t GrSizeAlignDown(size_t x, uint32_t alignment) {
|
||||
*/
|
||||
enum class GrBackendApi : unsigned {
|
||||
kMetal,
|
||||
kDawn,
|
||||
kOpenGL,
|
||||
kVulkan,
|
||||
/**
|
||||
|
40
include/gpu/dawn/GrDawnTypes.h
Normal file
40
include/gpu/dawn/GrDawnTypes.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrDawnTypes_DEFINED
|
||||
#define GrDawnTypes_DEFINED
|
||||
|
||||
#ifdef Always
|
||||
#undef Always
|
||||
#endif
|
||||
#include "dawn/dawncpp.h"
|
||||
|
||||
struct GrDawnImageInfo {
|
||||
dawn::Texture fTexture;
|
||||
dawn::TextureFormat fFormat;
|
||||
uint32_t fLevelCount;
|
||||
GrDawnImageInfo() : fTexture(nullptr), fFormat(), fLevelCount(0) {
|
||||
}
|
||||
GrDawnImageInfo(const GrDawnImageInfo& other)
|
||||
: fTexture(other.fTexture)
|
||||
, fFormat(other.fFormat)
|
||||
, fLevelCount(other.fLevelCount) {
|
||||
}
|
||||
GrDawnImageInfo& operator=(const GrDawnImageInfo& other) {
|
||||
fTexture = other.fTexture;
|
||||
fFormat = other.fFormat;
|
||||
fLevelCount = other.fLevelCount;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const GrDawnImageInfo& other) const {
|
||||
return fTexture.Get() == other.fTexture.Get() &&
|
||||
fFormat == other.fFormat &&
|
||||
fLevelCount == other.fLevelCount;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -251,6 +251,9 @@ BASE_SRCS_ALL = struct(
|
||||
# Currently exclude all vulkan specific files
|
||||
"src/gpu/vk/*",
|
||||
|
||||
# Currently exclude all Dawn-specific files
|
||||
"src/gpu/dawn/*",
|
||||
|
||||
# Defines main.
|
||||
"src/sksl/SkSLMain.cpp",
|
||||
|
||||
@ -517,6 +520,7 @@ DM_SRCS_ALL = struct(
|
||||
"tests/FontMgrFontConfigTest.cpp", # FontConfig-only.
|
||||
"tests/skia_test.cpp", # Old main.
|
||||
"tools/gpu/atlastext/*",
|
||||
"tools/gpu/dawn/*",
|
||||
"tools/gpu/gl/angle/*",
|
||||
"tools/gpu/gl/egl/*",
|
||||
"tools/gpu/gl/glx/*",
|
||||
|
@ -10,6 +10,11 @@
|
||||
|
||||
#include "src/gpu/gl/GrGLUtil.h"
|
||||
|
||||
#ifdef SK_DAWN
|
||||
#include "include/gpu/dawn/GrDawnTypes.h"
|
||||
#include "src/gpu/dawn/GrDawnUtil.h"
|
||||
#endif
|
||||
|
||||
#ifdef SK_VULKAN
|
||||
#include "include/gpu/vk/GrVkTypes.h"
|
||||
#include "src/gpu/vk/GrVkImageLayout.h"
|
||||
@ -43,6 +48,11 @@ GrBackendFormat::GrBackendFormat(const GrBackendFormat& that)
|
||||
case GrBackendApi::kMetal:
|
||||
fMtlFormat = that.fMtlFormat;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
case GrBackendApi::kDawn:
|
||||
fDawnFormat = that.fDawnFormat;
|
||||
break;
|
||||
#endif
|
||||
case GrBackendApi::kMock:
|
||||
fMockColorType = that.fMockColorType;
|
||||
@ -138,6 +148,22 @@ const GrVkYcbcrConversionInfo* GrBackendFormat::getVkYcbcrConversionInfo() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef SK_DAWN
|
||||
GrBackendFormat::GrBackendFormat(dawn::TextureFormat format)
|
||||
: fBackend(GrBackendApi::kDawn)
|
||||
, fValid(true)
|
||||
, fDawnFormat(format)
|
||||
, fTextureType(GrTextureType::k2D) {
|
||||
}
|
||||
|
||||
const dawn::TextureFormat* GrBackendFormat::getDawnFormat() const {
|
||||
if (this->isValid() && GrBackendApi::kDawn == fBackend) {
|
||||
return &fDawnFormat;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_METAL
|
||||
GrBackendFormat::GrBackendFormat(GrMTLPixelFormat mtlFormat)
|
||||
: fBackend(GrBackendApi::kMetal)
|
||||
@ -205,6 +231,11 @@ bool GrBackendFormat::operator==(const GrBackendFormat& that) const {
|
||||
#ifdef SK_METAL
|
||||
case GrBackendApi::kMetal:
|
||||
return fMtlFormat == that.fMtlFormat;
|
||||
#endif
|
||||
break;
|
||||
case GrBackendApi::kDawn:
|
||||
#ifdef SK_DAWN
|
||||
return fDawnFormat == that.fDawnFormat;
|
||||
#endif
|
||||
break;
|
||||
case GrBackendApi::kMock:
|
||||
@ -215,6 +246,19 @@ bool GrBackendFormat::operator==(const GrBackendFormat& that) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SK_DAWN
|
||||
GrBackendTexture::GrBackendTexture(int width,
|
||||
int height,
|
||||
const GrDawnImageInfo& dawnInfo)
|
||||
: fIsValid(true)
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fConfig(GrDawnFormatToPixelConfig(dawnInfo.fFormat))
|
||||
, fMipMapped(GrMipMapped(dawnInfo.fLevelCount > 1))
|
||||
, fBackend(GrBackendApi::kDawn)
|
||||
, fDawnInfo(dawnInfo) {}
|
||||
#endif
|
||||
|
||||
GrBackendTexture::GrBackendTexture(int width,
|
||||
int height,
|
||||
const GrVkImageInfo& vkInfo)
|
||||
@ -356,6 +400,11 @@ GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
|
||||
case GrBackendApi::kMetal:
|
||||
fMtlInfo = that.fMtlInfo;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
case GrBackendApi::kDawn:
|
||||
fDawnInfo = that.fDawnInfo;
|
||||
break;
|
||||
#endif
|
||||
case GrBackendApi::kMock:
|
||||
fMockInfo = that.fMockInfo;
|
||||
@ -367,6 +416,16 @@ GrBackendTexture& GrBackendTexture::operator=(const GrBackendTexture& that) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef SK_DAWN
|
||||
bool GrBackendTexture::getDawnImageInfo(GrDawnImageInfo* outInfo) const {
|
||||
if (this->isValid() && GrBackendApi::kDawn == fBackend) {
|
||||
*outInfo = fDawnInfo;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GrBackendTexture::getVkImageInfo(GrVkImageInfo* outInfo) const {
|
||||
#ifdef SK_VULKAN
|
||||
if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
|
||||
@ -484,6 +543,11 @@ GrBackendFormat GrBackendTexture::getBackendFormat() const {
|
||||
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;
|
||||
@ -526,6 +590,10 @@ bool GrBackendTexture::TestingOnly_Equals(const GrBackendTexture& t0, const GrBa
|
||||
#ifdef SK_METAL
|
||||
case GrBackendApi::kMetal:
|
||||
return t0.fMtlInfo == t1.fMtlInfo;
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
case GrBackendApi::kDawn:
|
||||
return t0.fDawnInfo == t1.fDawnInfo;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
@ -535,6 +603,22 @@ bool GrBackendTexture::TestingOnly_Equals(const GrBackendTexture& t0, const GrBa
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_DAWN
|
||||
GrBackendRenderTarget::GrBackendRenderTarget(int width,
|
||||
int height,
|
||||
int sampleCnt,
|
||||
int stencilBits,
|
||||
const GrDawnImageInfo& dawnInfo)
|
||||
: fIsValid(true)
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fSampleCnt(sampleCnt)
|
||||
, fStencilBits(stencilBits)
|
||||
, fConfig(GrDawnFormatToPixelConfig(dawnInfo.fFormat))
|
||||
, fBackend(GrBackendApi::kDawn)
|
||||
, fDawnInfo(dawnInfo) {}
|
||||
#endif
|
||||
|
||||
GrBackendRenderTarget::GrBackendRenderTarget(int width,
|
||||
int height,
|
||||
int sampleCnt,
|
||||
@ -670,6 +754,11 @@ GrBackendRenderTarget& GrBackendRenderTarget::operator=(const GrBackendRenderTar
|
||||
fVkInfo.assign(that.fVkInfo, this->isValid());
|
||||
#endif
|
||||
break;
|
||||
#ifdef SK_DAWN
|
||||
case GrBackendApi::kDawn:
|
||||
fDawnInfo = that.fDawnInfo;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SK_METAL
|
||||
case GrBackendApi::kMetal:
|
||||
fMtlInfo = that.fMtlInfo;
|
||||
@ -685,6 +774,16 @@ GrBackendRenderTarget& GrBackendRenderTarget::operator=(const GrBackendRenderTar
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef SK_DAWN
|
||||
bool GrBackendRenderTarget::getDawnImageInfo(GrDawnImageInfo* outInfo) const {
|
||||
if (this->isValid() && GrBackendApi::kDawn == fBackend) {
|
||||
*outInfo = fDawnInfo;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GrBackendRenderTarget::getVkImageInfo(GrVkImageInfo* outInfo) const {
|
||||
#ifdef SK_VULKAN
|
||||
if (this->isValid() && GrBackendApi::kVulkan == fBackend) {
|
||||
@ -801,6 +900,10 @@ bool GrBackendRenderTarget::TestingOnly_Equals(const GrBackendRenderTarget& r0,
|
||||
#ifdef SK_METAL
|
||||
case GrBackendApi::kMetal:
|
||||
return r0.fMtlInfo == r1.fMtlInfo;
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
case GrBackendApi::kDawn:
|
||||
return r0.fDawnInfo == r1.fDawnInfo;
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
|
@ -231,14 +231,16 @@ SkString GrContextPriv::dump() const {
|
||||
|
||||
static const char* kBackendStr[] = {
|
||||
"Metal",
|
||||
"Dawn",
|
||||
"OpenGL",
|
||||
"Vulkan",
|
||||
"Mock",
|
||||
};
|
||||
GR_STATIC_ASSERT(0 == (unsigned)GrBackendApi::kMetal);
|
||||
GR_STATIC_ASSERT(1 == (unsigned)GrBackendApi::kOpenGL);
|
||||
GR_STATIC_ASSERT(2 == (unsigned)GrBackendApi::kVulkan);
|
||||
GR_STATIC_ASSERT(3 == (unsigned)GrBackendApi::kMock);
|
||||
GR_STATIC_ASSERT(1 == (unsigned)GrBackendApi::kDawn);
|
||||
GR_STATIC_ASSERT(2 == (unsigned)GrBackendApi::kOpenGL);
|
||||
GR_STATIC_ASSERT(3 == (unsigned)GrBackendApi::kVulkan);
|
||||
GR_STATIC_ASSERT(4 == (unsigned)GrBackendApi::kMock);
|
||||
writer.appendString("backend", kBackendStr[(unsigned)fContext->backend()]);
|
||||
|
||||
writer.appendName("caps");
|
||||
|
@ -23,6 +23,9 @@
|
||||
#ifdef SK_VULKAN
|
||||
#include "src/gpu/vk/GrVkGpu.h"
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
#include "dawn/GrDawnGpu.h"
|
||||
#endif
|
||||
|
||||
#ifdef SK_DISABLE_REDUCE_OPLIST_SPLITTING
|
||||
static const bool kDefaultReduceOpListSplitting = false;
|
||||
@ -218,3 +221,23 @@ sk_sp<GrContext> GrContext::MakeMetal(void* device, void* queue, const GrContext
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SK_DAWN
|
||||
sk_sp<GrContext> GrContext::MakeDawn(const dawn::Device& device) {
|
||||
GrContextOptions defaultOptions;
|
||||
return MakeDawn(device, defaultOptions);
|
||||
}
|
||||
|
||||
sk_sp<GrContext> GrContext::MakeDawn(const dawn::Device& device, const GrContextOptions& options) {
|
||||
sk_sp<GrContext> context(new GrLegacyDirectContext(GrBackendApi::kDawn, options));
|
||||
|
||||
context->fGpu = GrDawnGpu::Make(device, options, context.get());
|
||||
if (!context->fGpu) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!context->init(context->fGpu->refCaps(), nullptr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
#endif
|
||||
|
179
src/gpu/dawn/GrDawnCaps.cpp
Normal file
179
src/gpu/dawn/GrDawnCaps.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrDawnCaps.h"
|
||||
|
||||
GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(contextOptions) {
|
||||
fBufferMapThreshold = SK_MaxS32; // FIXME: get this from Dawn?
|
||||
fShaderCaps.reset(new GrShaderCaps(contextOptions));
|
||||
fMaxTextureSize = 2048;
|
||||
fPerformPartialClearsAsDraws = true;
|
||||
}
|
||||
|
||||
bool GrDawnCaps::isFormatSRGB(const GrBackendFormat& format) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrDawnCaps::isConfigTexturable(GrPixelConfig config) const {
|
||||
switch (config) {
|
||||
case kRGBA_8888_GrPixelConfig:
|
||||
case kBGRA_8888_GrPixelConfig:
|
||||
case kAlpha_8_GrPixelConfig:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GrPixelConfig GrDawnCaps::onGetConfigFromBackendFormat(const GrBackendFormat& format,
|
||||
GrColorType colorType) const {
|
||||
dawn::TextureFormat textureFormat = *format.getDawnFormat();
|
||||
switch (colorType) {
|
||||
case GrColorType::kUnknown:
|
||||
return kUnknown_GrPixelConfig;
|
||||
case GrColorType::kAlpha_8:
|
||||
if (dawn::TextureFormat::R8Unorm == textureFormat) {
|
||||
return kAlpha_8_as_Red_GrPixelConfig;
|
||||
}
|
||||
break;
|
||||
case GrColorType::kRGBA_8888:
|
||||
if (dawn::TextureFormat::R8G8B8A8Unorm == textureFormat) {
|
||||
return kRGBA_8888_GrPixelConfig;
|
||||
}
|
||||
break;
|
||||
case GrColorType::kRGB_888x:
|
||||
break;
|
||||
case GrColorType::kBGRA_8888:
|
||||
if (dawn::TextureFormat::B8G8R8A8Unorm == textureFormat) {
|
||||
return kBGRA_8888_GrPixelConfig;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kUnknown_GrPixelConfig;
|
||||
}
|
||||
|
||||
GrPixelConfig GrDawnCaps::getYUVAConfigFromBackendFormat(const GrBackendFormat& backendFormat)
|
||||
const {
|
||||
const dawn::TextureFormat* format = backendFormat.getDawnFormat();
|
||||
if (!format) {
|
||||
return kUnknown_GrPixelConfig;
|
||||
}
|
||||
switch (*format) {
|
||||
case dawn::TextureFormat::R8Unorm:
|
||||
return kAlpha_8_as_Red_GrPixelConfig;
|
||||
break;
|
||||
case dawn::TextureFormat::R8G8B8A8Unorm:
|
||||
return kRGBA_8888_GrPixelConfig;
|
||||
break;
|
||||
case dawn::TextureFormat::B8G8R8A8Unorm:
|
||||
return kBGRA_8888_GrPixelConfig;
|
||||
break;
|
||||
default:
|
||||
return kUnknown_GrPixelConfig;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t GrDawnCaps::onTransferFromOffsetAlignment(GrColorType bufferColorType) const {
|
||||
if (bufferColorType == GrColorType::kRGB_888x) {
|
||||
return false;
|
||||
}
|
||||
size_t bpp = GrColorTypeBytesPerPixel(bufferColorType);
|
||||
switch (bpp & 0b11) {
|
||||
case 0: return bpp;
|
||||
case 2: return 2 * bpp;
|
||||
default: return 4 * bpp;
|
||||
}
|
||||
}
|
||||
|
||||
static GrSwizzle get_swizzle(const GrBackendFormat& format, GrColorType colorType,
|
||||
bool forOutput) {
|
||||
SkASSERT(format.getDawnFormat());
|
||||
|
||||
switch (colorType) {
|
||||
case GrColorType::kAlpha_8: // fall through
|
||||
case GrColorType::kAlpha_F16:
|
||||
if (forOutput) {
|
||||
return GrSwizzle::AAAA();
|
||||
} else {
|
||||
return GrSwizzle::RRRR();
|
||||
}
|
||||
case GrColorType::kGray_8:
|
||||
if (!forOutput) {
|
||||
return GrSwizzle::RRRA();
|
||||
}
|
||||
break;
|
||||
case GrColorType::kRGB_888x:
|
||||
if (!forOutput) {
|
||||
return GrSwizzle::RGB1();
|
||||
}
|
||||
default:
|
||||
return GrSwizzle::RGBA();
|
||||
}
|
||||
return GrSwizzle::RGBA();
|
||||
}
|
||||
|
||||
bool GrDawnCaps::isFormatTexturable(GrColorType ct, const GrBackendFormat& format) const {
|
||||
GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this->isConfigTexturable(config);
|
||||
}
|
||||
|
||||
bool GrDawnCaps::isFormatCopyable(GrColorType ct, const GrBackendFormat& format) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
int GrDawnCaps::getRenderTargetSampleCount(int requestedCount, GrColorType ct,
|
||||
const GrBackendFormat& format) const {
|
||||
GrPixelConfig config = this->getConfigFromBackendFormat(format, ct);
|
||||
if (kUnknown_GrPixelConfig == config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this->getRenderTargetSampleCount(requestedCount, config);
|
||||
}
|
||||
|
||||
GrBackendFormat GrDawnCaps::getBackendFormatFromColorType(GrColorType ct) const {
|
||||
GrPixelConfig config = GrColorTypeToPixelConfig(ct);
|
||||
if (config == kUnknown_GrPixelConfig) {
|
||||
return GrBackendFormat();
|
||||
}
|
||||
dawn::TextureFormat format;
|
||||
if (!GrPixelConfigToDawnFormat(config, &format)) {
|
||||
return GrBackendFormat();
|
||||
}
|
||||
return GrBackendFormat::MakeDawn(format);
|
||||
}
|
||||
|
||||
GrBackendFormat GrDawnCaps::getBackendFormatFromCompressionType(SkImage::CompressionType type) const
|
||||
{
|
||||
return GrBackendFormat();
|
||||
}
|
||||
|
||||
GrSwizzle GrDawnCaps::getTextureSwizzle(const GrBackendFormat& format, GrColorType colorType) const
|
||||
{
|
||||
return get_swizzle(format, colorType, false);
|
||||
}
|
||||
|
||||
bool GrDawnCaps::canClearTextureOnCreation() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
GrSwizzle GrDawnCaps::getOutputSwizzle(const GrBackendFormat& format, GrColorType colorType) const
|
||||
{
|
||||
return get_swizzle(format, colorType, true);
|
||||
}
|
||||
|
||||
bool GrDawnCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
|
||||
const GrBackendFormat& format) const {
|
||||
return true;
|
||||
}
|
90
src/gpu/dawn/GrDawnCaps.h
Normal file
90
src/gpu/dawn/GrDawnCaps.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrDawnCaps_DEFINED
|
||||
#define GrDawnCaps_DEFINED
|
||||
|
||||
#include "src/gpu/GrCaps.h"
|
||||
#include "include/gpu/GrContextOptions.h"
|
||||
#include "src/gpu/dawn/GrDawnUtil.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
|
||||
class GrDawnCaps : public GrCaps {
|
||||
public:
|
||||
GrDawnCaps(const GrContextOptions& contextOptions);
|
||||
|
||||
bool isFormatSRGB(const GrBackendFormat& format) const override;
|
||||
bool isFormatTexturable(GrColorType, const GrBackendFormat& format) const override;
|
||||
bool isFormatCopyable(GrColorType, const GrBackendFormat& format) const override;
|
||||
|
||||
bool isConfigTexturable(GrPixelConfig config) const override;
|
||||
|
||||
bool isConfigCopyable(GrPixelConfig config) const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint) const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
|
||||
bool* rectsMustMatch, bool* disallowSubrect) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&, GrColorType) const
|
||||
override {
|
||||
return GrPixelConfig::kUnknown_GrPixelConfig;
|
||||
}
|
||||
|
||||
GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat&, GrColorType) const override;
|
||||
|
||||
GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat&) const override;
|
||||
|
||||
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override {
|
||||
return SurfaceReadPixelsSupport::kSupported;
|
||||
}
|
||||
|
||||
bool onSurfaceSupportsWritePixels(const GrSurface* surface) const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
int getRenderTargetSampleCount(int requestedCount, GrColorType,
|
||||
const GrBackendFormat&) const override;
|
||||
|
||||
int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override {
|
||||
return this->isConfigTexturable(config) ? 1 : 0;
|
||||
}
|
||||
|
||||
int maxRenderTargetSampleCount(GrColorType ct,
|
||||
const GrBackendFormat& format) const override {
|
||||
return this->maxRenderTargetSampleCount(this->getConfigFromBackendFormat(format, ct));
|
||||
}
|
||||
|
||||
int maxRenderTargetSampleCount(GrPixelConfig config) const override {
|
||||
return this->isConfigTexturable(config) ? 1 : 0;
|
||||
}
|
||||
|
||||
GrBackendFormat getBackendFormatFromColorType(GrColorType ct) const override;
|
||||
|
||||
GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
|
||||
|
||||
bool canClearTextureOnCreation() const override;
|
||||
|
||||
GrSwizzle getTextureSwizzle(const GrBackendFormat&, GrColorType) const override;
|
||||
|
||||
GrSwizzle getOutputSwizzle(const GrBackendFormat&, GrColorType) const override;
|
||||
|
||||
size_t onTransferFromOffsetAlignment(GrColorType bufferColorType) const override;
|
||||
|
||||
bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
|
||||
|
||||
typedef GrCaps INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
258
src/gpu/dawn/GrDawnGpu.cpp
Normal file
258
src/gpu/dawn/GrDawnGpu.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrDawnGpu.h"
|
||||
|
||||
#include "include/gpu/GrBackendSemaphore.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "include/gpu/GrContextOptions.h"
|
||||
#include "src/gpu/GrGeometryProcessor.h"
|
||||
#include "src/gpu/GrGpuResourceCacheAccess.h"
|
||||
#include "src/gpu/GrMesh.h"
|
||||
#include "src/gpu/dawn/GrDawnCaps.h"
|
||||
#include "src/gpu/dawn/GrDawnRenderTarget.h"
|
||||
#include "src/gpu/dawn/GrDawnGpuCommandBuffer.h"
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/GrSemaphore.h"
|
||||
#include "src/gpu/GrTexturePriv.h"
|
||||
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
|
||||
#if !defined(SK_BUILD_FOR_WIN)
|
||||
#include <unistd.h>
|
||||
#endif // !defined(SK_BUILD_FOR_WIN)
|
||||
|
||||
sk_sp<GrGpu> GrDawnGpu::Make(const dawn::Device& device,
|
||||
const GrContextOptions& options, GrContext* context) {
|
||||
if (!device) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sk_sp<GrGpu>(new GrDawnGpu(context, options, device));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrDawnGpu::GrDawnGpu(GrContext* context, const GrContextOptions& options,
|
||||
const dawn::Device& device)
|
||||
: INHERITED(context)
|
||||
, fDevice(device)
|
||||
, fQueue(device.CreateQueue())
|
||||
, fCompiler(new SkSL::Compiler()) {
|
||||
fCaps.reset(new GrDawnCaps(options));
|
||||
}
|
||||
|
||||
GrDawnGpu::~GrDawnGpu() {
|
||||
}
|
||||
|
||||
|
||||
void GrDawnGpu::disconnect(DisconnectType type) {
|
||||
INHERITED::disconnect(type);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrGpuRTCommandBuffer* GrDawnGpu::getCommandBuffer(
|
||||
GrRenderTarget* rt, GrSurfaceOrigin origin, const SkRect& bounds,
|
||||
const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
|
||||
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
|
||||
fCachedRTCommandBuffer.reset(
|
||||
new GrDawnGpuRTCommandBuffer(this, rt, origin, colorInfo, stencilInfo));
|
||||
return fCachedRTCommandBuffer.get();
|
||||
}
|
||||
|
||||
GrGpuTextureCommandBuffer* GrDawnGpu::getCommandBuffer(GrTexture* texture,
|
||||
GrSurfaceOrigin origin) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
sk_sp<GrGpuBuffer> GrDawnGpu::onCreateBuffer(size_t size, GrGpuBufferType type,
|
||||
GrAccessPattern accessPattern, const void* data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool GrDawnGpu::onWritePixels(GrSurface* surface,
|
||||
int left, int top, int width, int height,
|
||||
GrColorType colorType,
|
||||
const GrMipLevel texels[], int mipLevelCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrDawnGpu::onTransferPixelsTo(GrTexture* texture,
|
||||
int left, int top, int width, int height,
|
||||
GrColorType colorType, GrGpuBuffer* transferBuffer,
|
||||
size_t bufferOffset, size_t rowBytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrDawnGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
|
||||
GrColorType, GrGpuBuffer* transferBuffer, size_t offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
sk_sp<GrTexture> GrDawnGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
|
||||
const GrMipLevel texels[], int mipLevelCount) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrTexture> GrDawnGpu::onCreateCompressedTexture(int width, int height,
|
||||
SkImage::CompressionType, SkBudgeted,
|
||||
const void* data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrTexture> GrDawnGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
|
||||
GrWrapOwnership ownership,
|
||||
GrWrapCacheable cacheable,
|
||||
GrIOType) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrTexture> GrDawnGpu::onWrapRenderableBackendTexture(const GrBackendTexture& tex,
|
||||
int sampleCnt, GrColorType,
|
||||
GrWrapOwnership,
|
||||
GrWrapCacheable cacheable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrRenderTarget> GrDawnGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrRenderTarget> GrDawnGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTexture& tex,
|
||||
int sampleCnt) {
|
||||
GrDawnImageInfo info;
|
||||
if (!tex.getDawnImageInfo(&info)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!info.fTexture) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrSurfaceDesc desc;
|
||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
desc.fWidth = tex.width();
|
||||
desc.fHeight = tex.height();
|
||||
desc.fConfig = tex.config();
|
||||
desc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, tex.config());
|
||||
if (desc.fSampleCnt < 1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrDawnRenderTarget> tgt = GrDawnRenderTarget::MakeWrapped(this, desc, info);
|
||||
return tgt;
|
||||
}
|
||||
|
||||
GrStencilAttachment* GrDawnGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
|
||||
int width,
|
||||
int height,
|
||||
int numStencilSamples) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrBackendTexture GrDawnGpu::createBackendTexture(int width, int height,
|
||||
const GrBackendFormat& format,
|
||||
GrMipMapped mipMapped,
|
||||
GrRenderable renderable,
|
||||
const void* pixels,
|
||||
size_t rowBytes,
|
||||
const SkColor4f* color,
|
||||
GrProtected isProtected) {
|
||||
return GrBackendTexture();
|
||||
}
|
||||
|
||||
void GrDawnGpu::deleteBackendTexture(const GrBackendTexture& tex) {
|
||||
}
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
bool GrDawnGpu::isTestingOnlyBackendTexture(const GrBackendTexture& tex) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrBackendRenderTarget GrDawnGpu::createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) {
|
||||
return GrBackendRenderTarget();
|
||||
}
|
||||
|
||||
void GrDawnGpu::deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) {
|
||||
}
|
||||
|
||||
void GrDawnGpu::testingOnly_flushGpuAndSync() {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void GrDawnGpu::onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access,
|
||||
const GrFlushInfo& info, const GrPrepareForExternalIORequests&) {
|
||||
}
|
||||
|
||||
bool GrDawnGpu::onCopySurface(GrSurface* dst,
|
||||
GrSurface* src,
|
||||
const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint,
|
||||
bool canDiscardOutsideDstRect) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrDawnGpu::onReadPixels(GrSurface* surface,
|
||||
int left, int top, int width, int height,
|
||||
GrColorType colorType,
|
||||
void* buffer,
|
||||
size_t rowBytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrDawnGpu::onRegenerateMipMapLevels(GrTexture*) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GrDawnGpu::submit(GrGpuCommandBuffer* buffer) {
|
||||
if (auto buf = static_cast<GrDawnGpuRTCommandBuffer*>(buffer->asRTCommandBuffer())) {
|
||||
buf->submit();
|
||||
}
|
||||
}
|
||||
|
||||
GrFence SK_WARN_UNUSED_RESULT GrDawnGpu::insertFence() {
|
||||
return GrFence();
|
||||
}
|
||||
|
||||
bool GrDawnGpu::waitFence(GrFence fence, uint64_t timeout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GrDawnGpu::deleteFence(GrFence fence) const {
|
||||
}
|
||||
|
||||
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrDawnGpu::makeSemaphore(bool isOwned) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrSemaphore> GrDawnGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
|
||||
GrResourceProvider::SemaphoreWrapType wrapType,
|
||||
GrWrapOwnership ownership) {
|
||||
SkASSERT(!"unimplemented");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GrDawnGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore) {
|
||||
SkASSERT(!"unimplemented");
|
||||
}
|
||||
|
||||
void GrDawnGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
|
||||
SkASSERT(!"unimplemented");
|
||||
}
|
||||
|
||||
void GrDawnGpu::checkFinishProcs() {
|
||||
SkASSERT(!"unimplemented");
|
||||
}
|
||||
|
||||
sk_sp<GrSemaphore> GrDawnGpu::prepareTextureForCrossContextUsage(GrTexture* texture) {
|
||||
return nullptr;
|
||||
}
|
147
src/gpu/dawn/GrDawnGpu.h
Normal file
147
src/gpu/dawn/GrDawnGpu.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrDawnGpu_DEFINED
|
||||
#define GrDawnGpu_DEFINED
|
||||
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "dawn/dawncpp.h"
|
||||
|
||||
class GrPipeline;
|
||||
class GrDawnGpuRTCommandBuffer;
|
||||
|
||||
namespace SkSL {
|
||||
class Compiler;
|
||||
}
|
||||
|
||||
class GrDawnGpu : public GrGpu {
|
||||
public:
|
||||
static sk_sp<GrGpu> Make(const dawn::Device& device, const GrContextOptions&, GrContext*);
|
||||
GrDawnGpu(GrContext* context, const GrContextOptions& options, const dawn::Device& device);
|
||||
|
||||
~GrDawnGpu() override;
|
||||
|
||||
void disconnect(DisconnectType) override;
|
||||
|
||||
const dawn::Device& device() const { return fDevice; }
|
||||
const dawn::Queue& queue() const { return fQueue; }
|
||||
|
||||
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
|
||||
|
||||
GrBackendTexture createBackendTexture(int w, int h,
|
||||
const GrBackendFormat &,
|
||||
GrMipMapped,
|
||||
GrRenderable,
|
||||
const void* pixels,
|
||||
size_t rowBytes,
|
||||
const SkColor4f* color,
|
||||
GrProtected isProtected) override;
|
||||
void deleteBackendTexture(const GrBackendTexture&) override;
|
||||
#if GR_TEST_UTILS
|
||||
bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
|
||||
|
||||
GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
|
||||
void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
|
||||
|
||||
void testingOnly_flushGpuAndSync() override;
|
||||
#endif
|
||||
|
||||
GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
|
||||
int width,
|
||||
int height,
|
||||
int numStencilSamples) override;
|
||||
|
||||
GrGpuRTCommandBuffer* getCommandBuffer(
|
||||
GrRenderTarget*, GrSurfaceOrigin, const SkRect& bounds,
|
||||
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
|
||||
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
|
||||
|
||||
GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
|
||||
|
||||
SkSL::Compiler* shaderCompiler() const {
|
||||
return fCompiler.get();
|
||||
}
|
||||
|
||||
void submit(GrGpuCommandBuffer* cb) override;
|
||||
GrFence SK_WARN_UNUSED_RESULT insertFence() override;
|
||||
bool waitFence(GrFence, uint64_t timeout) override;
|
||||
void deleteFence(GrFence) const override;
|
||||
|
||||
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned = true) override;
|
||||
sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
|
||||
GrResourceProvider::SemaphoreWrapType wrapType,
|
||||
GrWrapOwnership ownership) override;
|
||||
void insertSemaphore(sk_sp<GrSemaphore> semaphore) override;
|
||||
void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
|
||||
void checkFinishProcs() override;
|
||||
|
||||
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
|
||||
|
||||
private:
|
||||
void onResetContext(uint32_t resetBits) override {}
|
||||
|
||||
virtual void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) override {}
|
||||
|
||||
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
|
||||
const GrMipLevel texels[], int mipLevelCount) override;
|
||||
|
||||
sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, SkImage::CompressionType,
|
||||
SkBudgeted, const void* data) override;
|
||||
|
||||
sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership,
|
||||
GrWrapCacheable, GrIOType) override;
|
||||
sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt,
|
||||
GrColorType, GrWrapOwnership,
|
||||
GrWrapCacheable) override;
|
||||
sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
|
||||
|
||||
sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
|
||||
int sampleCnt) override;
|
||||
|
||||
sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType type, GrAccessPattern,
|
||||
const void* data) override;
|
||||
|
||||
bool onReadPixels(GrSurface* surface,
|
||||
int left, int top, int width, int height,
|
||||
GrColorType, void* buffer, size_t rowBytes) override;
|
||||
|
||||
bool onWritePixels(GrSurface* surface,
|
||||
int left, int top, int width, int height,
|
||||
GrColorType, const GrMipLevel texels[], int mipLevelCount) override;
|
||||
|
||||
bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
|
||||
GrColorType colorType, GrGpuBuffer* transferBuffer,
|
||||
size_t offset, size_t rowBytes) override;
|
||||
|
||||
bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
|
||||
GrColorType, GrGpuBuffer* transferBuffer, size_t offset) override;
|
||||
|
||||
void onResolveRenderTarget(GrRenderTarget* target) override {
|
||||
}
|
||||
|
||||
bool onRegenerateMipMapLevels(GrTexture*) override;
|
||||
|
||||
bool onCopySurface(GrSurface* dst, GrSurface* src,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint,
|
||||
bool canDiscardOutsideDstRect) override;
|
||||
|
||||
void onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access,
|
||||
const GrFlushInfo& info, const GrPrepareForExternalIORequests&) override;
|
||||
|
||||
dawn::Device fDevice;
|
||||
dawn::Queue fQueue; // Must be Graphics queue
|
||||
|
||||
// Compiler used for compiling sksl into spirv. We only want to create the compiler once since
|
||||
// there is significant overhead to the first compile of any compiler.
|
||||
std::unique_ptr<SkSL::Compiler> fCompiler;
|
||||
|
||||
std::unique_ptr<GrDawnGpuRTCommandBuffer> fCachedRTCommandBuffer;
|
||||
|
||||
typedef GrGpu INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
152
src/gpu/dawn/GrDawnGpuCommandBuffer.cpp
Normal file
152
src/gpu/dawn/GrDawnGpuCommandBuffer.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrDawnGpuCommandBuffer.h"
|
||||
|
||||
#include "src/gpu/GrFixedClip.h"
|
||||
#include "src/gpu/GrMesh.h"
|
||||
#include "src/gpu/GrOpFlushState.h"
|
||||
#include "src/gpu/GrPipeline.h"
|
||||
#include "src/gpu/GrRenderTargetPriv.h"
|
||||
#include "src/gpu/GrTexturePriv.h"
|
||||
#include "src/gpu/dawn/GrDawnGpu.h"
|
||||
#include "src/gpu/dawn/GrDawnRenderTarget.h"
|
||||
#include "include/core/SkRect.h"
|
||||
|
||||
void GrDawnGpuTextureCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint) {
|
||||
}
|
||||
|
||||
void GrDawnGpuTextureCommandBuffer::insertEventMarker(const char* msg) {
|
||||
}
|
||||
|
||||
void GrDawnGpuTextureCommandBuffer::submit() {
|
||||
for (int i = 0; i < fCopies.count(); ++i) {
|
||||
CopyInfo& copyInfo = fCopies[i];
|
||||
fGpu->copySurface(fTexture, copyInfo.fSrc, copyInfo.fSrcRect, copyInfo.fDstPoint);
|
||||
}
|
||||
}
|
||||
|
||||
GrDawnGpuTextureCommandBuffer::~GrDawnGpuTextureCommandBuffer() {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
dawn::LoadOp to_dawn_load_op(GrLoadOp loadOp) {
|
||||
switch (loadOp) {
|
||||
case GrLoadOp::kLoad:
|
||||
return dawn::LoadOp::Load;
|
||||
case GrLoadOp::kClear:
|
||||
return dawn::LoadOp::Clear;
|
||||
case GrLoadOp::kDiscard:
|
||||
default:
|
||||
SK_ABORT("Invalid LoadOp");
|
||||
return dawn::LoadOp::Load;
|
||||
}
|
||||
}
|
||||
|
||||
GrDawnGpuRTCommandBuffer::GrDawnGpuRTCommandBuffer(GrDawnGpu* gpu,
|
||||
GrRenderTarget* rt, GrSurfaceOrigin origin,
|
||||
const LoadAndStoreInfo& colorInfo,
|
||||
const StencilLoadAndStoreInfo& stencilInfo)
|
||||
: INHERITED(rt, origin)
|
||||
, fGpu(gpu) {
|
||||
this->init();
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::init() {
|
||||
}
|
||||
|
||||
|
||||
GrDawnGpuRTCommandBuffer::~GrDawnGpuRTCommandBuffer() {
|
||||
}
|
||||
|
||||
GrGpu* GrDawnGpuRTCommandBuffer::gpu() { return fGpu; }
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::end() {
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::submit() {
|
||||
if (fCommandBuffer) {
|
||||
fGpu->queue().Submit(1, &fCommandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::insertEventMarker(const char* msg) {
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
|
||||
GrGpuBuffer* transferBuffer, size_t offset) {
|
||||
fGpu->transferPixelsFrom(fRenderTarget, srcRect.fLeft, srcRect.fTop, srcRect.width(),
|
||||
srcRect.height(), bufferColorType, transferBuffer, offset);
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::inlineUpload(GrOpFlushState* state,
|
||||
GrDeferredTextureUploadFn& upload) {
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::copy(GrSurface* src, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::bindGeometry(const GrBuffer* indexBuffer,
|
||||
const GrBuffer* vertexBuffer,
|
||||
const GrBuffer* instanceBuffer) {
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
const GrMesh meshes[],
|
||||
int meshCount,
|
||||
const SkRect& bounds) {
|
||||
if (!meshCount) {
|
||||
return;
|
||||
}
|
||||
GrFragmentProcessor::Iter iter(pipeline);
|
||||
|
||||
for (int i = 0; i < meshCount; ++i) {
|
||||
const GrMesh& mesh = meshes[i];
|
||||
mesh.sendToGpu(this);
|
||||
}
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,
|
||||
const GrBuffer* vertexBuffer,
|
||||
int vertexCount,
|
||||
int baseVertex,
|
||||
const GrBuffer* instanceBuffer,
|
||||
int instanceCount,
|
||||
int baseInstance) {
|
||||
this->bindGeometry(nullptr, vertexBuffer, instanceBuffer);
|
||||
fGpu->stats()->incNumDraws();
|
||||
}
|
||||
|
||||
void GrDawnGpuRTCommandBuffer::sendIndexedInstancedMeshToGpu(GrPrimitiveType,
|
||||
const GrBuffer* indexBuffer,
|
||||
int indexCount,
|
||||
int baseIndex,
|
||||
const GrBuffer* vertexBuffer,
|
||||
int baseVertex,
|
||||
const GrBuffer* instanceBuffer,
|
||||
int instanceCount,
|
||||
int baseInstance,
|
||||
GrPrimitiveRestart restart) {
|
||||
this->bindGeometry(indexBuffer, vertexBuffer, instanceBuffer);
|
||||
fGpu->stats()->incNumDraws();
|
||||
}
|
||||
|
148
src/gpu/dawn/GrDawnGpuCommandBuffer.h
Normal file
148
src/gpu/dawn/GrDawnGpuCommandBuffer.h
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrDawnGpuCommandBuffer_DEFINED
|
||||
#define GrDawnGpuCommandBuffer_DEFINED
|
||||
|
||||
#include "src/gpu/GrGpuCommandBuffer.h"
|
||||
|
||||
#include "src/gpu/GrColor.h"
|
||||
#include "src/gpu/GrMesh.h"
|
||||
#include "include/gpu/GrTypes.h"
|
||||
#include "dawn/dawncpp.h"
|
||||
|
||||
class GrDawnGpu;
|
||||
class GrDawnRenderTarget;
|
||||
|
||||
class GrDawnGpuTextureCommandBuffer : public GrGpuTextureCommandBuffer {
|
||||
public:
|
||||
GrDawnGpuTextureCommandBuffer(GrDawnGpu* gpu, GrTexture* texture, GrSurfaceOrigin origin)
|
||||
: INHERITED(texture, origin)
|
||||
, fGpu(gpu) {
|
||||
}
|
||||
|
||||
~GrDawnGpuTextureCommandBuffer() override;
|
||||
|
||||
void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
|
||||
|
||||
void insertEventMarker(const char*) override;
|
||||
|
||||
private:
|
||||
void submit();
|
||||
|
||||
struct CopyInfo {
|
||||
CopyInfo(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint)
|
||||
: fSrc(src), fSrcOrigin(srcOrigin), fSrcRect(srcRect), fDstPoint(dstPoint) {}
|
||||
|
||||
GrSurface* fSrc;
|
||||
GrSurfaceOrigin fSrcOrigin;
|
||||
SkIRect fSrcRect;
|
||||
SkIPoint fDstPoint;
|
||||
};
|
||||
|
||||
GrDawnGpu* fGpu;
|
||||
SkTArray<CopyInfo> fCopies;
|
||||
|
||||
typedef GrGpuTextureCommandBuffer INHERITED;
|
||||
};
|
||||
|
||||
class GrDawnGpuRTCommandBuffer : public GrGpuRTCommandBuffer, private GrMesh::SendToGpuImpl {
|
||||
public:
|
||||
GrDawnGpuRTCommandBuffer(GrDawnGpu*, GrRenderTarget*, GrSurfaceOrigin,
|
||||
const LoadAndStoreInfo&,
|
||||
const StencilLoadAndStoreInfo&);
|
||||
|
||||
~GrDawnGpuRTCommandBuffer() override;
|
||||
|
||||
void begin() override { }
|
||||
void end() override;
|
||||
|
||||
void transferFrom(const SkIRect& srcRect, GrColorType bufferColorType,
|
||||
GrGpuBuffer* transferBuffer, size_t offset) override;
|
||||
void insertEventMarker(const char*) override;
|
||||
|
||||
void inlineUpload(GrOpFlushState* state, GrDeferredTextureUploadFn& upload) override;
|
||||
|
||||
void copy(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
|
||||
|
||||
void submit();
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
||||
GrGpu* gpu() override;
|
||||
|
||||
// Bind vertex and index buffers
|
||||
void bindGeometry(const GrBuffer* indexBuffer,
|
||||
const GrBuffer* vertexBuffer,
|
||||
const GrBuffer* instanceBuffer);
|
||||
|
||||
void onDraw(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
|
||||
const GrMesh mesh[],
|
||||
int meshCount,
|
||||
const SkRect& bounds) override;
|
||||
|
||||
void sendMeshToGpu(GrPrimitiveType primType, const GrBuffer* vertexBuffer, int vertexCount,
|
||||
int baseVertex) final {
|
||||
this->sendInstancedMeshToGpu(primType, vertexBuffer, vertexCount, baseVertex,
|
||||
nullptr, 1, 0);
|
||||
}
|
||||
|
||||
void sendIndexedMeshToGpu(GrPrimitiveType primType,
|
||||
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
uint16_t /*minIndexValue*/, uint16_t /*maxIndexValue*/,
|
||||
const GrBuffer* vertexBuffer, int baseVertex,
|
||||
GrPrimitiveRestart restart) final {
|
||||
this->sendIndexedInstancedMeshToGpu(primType, indexBuffer, indexCount, baseIndex,
|
||||
vertexBuffer, baseVertex, nullptr, 1, 0, restart);
|
||||
}
|
||||
|
||||
void sendInstancedMeshToGpu(GrPrimitiveType,
|
||||
const GrBuffer* vertexBuffer, int vertexCount, int baseVertex,
|
||||
const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance) final;
|
||||
|
||||
void sendIndexedInstancedMeshToGpu(GrPrimitiveType,
|
||||
const GrBuffer* indexBuffer, int indexCount, int baseIndex,
|
||||
const GrBuffer* vertexBuffer, int baseVertex,
|
||||
const GrBuffer* instanceBuffer, int instanceCount,
|
||||
int baseInstance, GrPrimitiveRestart) final;
|
||||
|
||||
void onClear(const GrFixedClip&, const SkPMColor4f& color) override;
|
||||
|
||||
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override;
|
||||
|
||||
struct InlineUploadInfo {
|
||||
InlineUploadInfo(GrOpFlushState* state, const GrDeferredTextureUploadFn& upload)
|
||||
: fFlushState(state), fUpload(upload) {}
|
||||
|
||||
GrOpFlushState* fFlushState;
|
||||
GrDeferredTextureUploadFn fUpload;
|
||||
};
|
||||
|
||||
struct CopyInfo {
|
||||
CopyInfo(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint)
|
||||
: fSrc(src), fSrcOrigin(srcOrigin), fSrcRect(srcRect), fDstPoint(dstPoint) {}
|
||||
|
||||
GrSurface* fSrc;
|
||||
GrSurfaceOrigin fSrcOrigin;
|
||||
SkIRect fSrcRect;
|
||||
SkIPoint fDstPoint;
|
||||
};
|
||||
|
||||
dawn::CommandBuffer fCommandBuffer;
|
||||
GrDawnGpu* fGpu;
|
||||
|
||||
typedef GrGpuRTCommandBuffer INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
64
src/gpu/dawn/GrDawnRenderTarget.cpp
Normal file
64
src/gpu/dawn/GrDawnRenderTarget.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrDawnRenderTarget.h"
|
||||
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "src/gpu/dawn/GrDawnGpu.h"
|
||||
#include "src/gpu/dawn/GrDawnUtil.h"
|
||||
|
||||
GrDawnRenderTarget::GrDawnRenderTarget(GrDawnGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrDawnImageInfo& info,
|
||||
GrBackendObjectOwnership ownership)
|
||||
: GrSurface(gpu, desc)
|
||||
, GrRenderTarget(gpu, desc)
|
||||
, fInfo(info) {
|
||||
this->registerWithCacheWrapped(GrWrapCacheable::kNo);
|
||||
}
|
||||
|
||||
GrDawnRenderTarget*
|
||||
GrDawnRenderTarget::Create(GrDawnGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrDawnImageInfo& info,
|
||||
GrBackendObjectOwnership ownership) {
|
||||
SkASSERT(1 == info.fLevelCount);
|
||||
return new GrDawnRenderTarget(gpu, desc, info, ownership);
|
||||
}
|
||||
|
||||
sk_sp<GrDawnRenderTarget>
|
||||
GrDawnRenderTarget::MakeWrapped(GrDawnGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrDawnImageInfo& info) {
|
||||
return sk_sp<GrDawnRenderTarget>(
|
||||
GrDawnRenderTarget::Create(gpu, desc, info,
|
||||
GrBackendObjectOwnership::kBorrowed));
|
||||
}
|
||||
|
||||
bool GrDawnRenderTarget::completeStencilAttachment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
GrDawnRenderTarget::~GrDawnRenderTarget() {
|
||||
}
|
||||
|
||||
void GrDawnRenderTarget::onRelease() {
|
||||
INHERITED::onRelease();
|
||||
}
|
||||
|
||||
void GrDawnRenderTarget::onAbandon() {
|
||||
INHERITED::onAbandon();
|
||||
}
|
||||
|
||||
GrBackendRenderTarget GrDawnRenderTarget::getBackendRenderTarget() const {
|
||||
return GrBackendRenderTarget(this->width(), this->height(), this->numSamples(),
|
||||
this->numSamples(), fInfo);
|
||||
}
|
||||
|
||||
GrBackendFormat GrDawnRenderTarget::backendFormat() const {
|
||||
return GrBackendFormat::MakeDawn(fInfo.fFormat);
|
||||
}
|
67
src/gpu/dawn/GrDawnRenderTarget.h
Normal file
67
src/gpu/dawn/GrDawnRenderTarget.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GrDawnRenderTarget_DEFINED
|
||||
#define GrDawnRenderTarget_DEFINED
|
||||
|
||||
#include "include/gpu/dawn/GrDawnTypes.h"
|
||||
#include "include/gpu/GrRenderTarget.h"
|
||||
|
||||
class GrDawnGpu;
|
||||
|
||||
class GrDawnRenderTarget: public GrRenderTarget {
|
||||
public:
|
||||
static sk_sp<GrDawnRenderTarget> MakeWrapped(GrDawnGpu*, const GrSurfaceDesc&,
|
||||
const GrDawnImageInfo&);
|
||||
|
||||
~GrDawnRenderTarget() override;
|
||||
|
||||
// override of GrRenderTarget
|
||||
ResolveType getResolveType() const override {
|
||||
if (this->numSamples() > 1) {
|
||||
return kCanResolve_ResolveType;
|
||||
}
|
||||
return kAutoResolves_ResolveType;
|
||||
}
|
||||
|
||||
bool canAttemptStencilAttachment() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
GrBackendRenderTarget getBackendRenderTarget() const override;
|
||||
GrBackendFormat backendFormat() const override;
|
||||
|
||||
protected:
|
||||
GrDawnRenderTarget(GrDawnGpu* gpu,
|
||||
const GrSurfaceDesc& desc,
|
||||
const GrDawnImageInfo& info,
|
||||
GrBackendObjectOwnership);
|
||||
|
||||
GrDawnGpu* getDawnGpu() const;
|
||||
|
||||
void onAbandon() override;
|
||||
void onRelease() override;
|
||||
void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) override {}
|
||||
|
||||
// This accounts for the texture's memory and any MSAA renderbuffer's memory.
|
||||
size_t onGpuMemorySize() const override {
|
||||
// The plus 1 is to account for the resolve texture or if not using msaa the RT itself
|
||||
int numSamples = this->numSamples() + 1;
|
||||
return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
|
||||
numSamples, GrMipMapped::kNo);
|
||||
}
|
||||
|
||||
static GrDawnRenderTarget* Create(GrDawnGpu*, const GrSurfaceDesc&,
|
||||
const GrDawnImageInfo&, GrBackendObjectOwnership);
|
||||
|
||||
bool completeStencilAttachment() override;
|
||||
GrDawnImageInfo fInfo;
|
||||
typedef GrRenderTarget INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
42
src/gpu/dawn/GrDawnUtil.cpp
Normal file
42
src/gpu/dawn/GrDawnUtil.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrDawnUtil.h"
|
||||
|
||||
GrPixelConfig GrDawnFormatToPixelConfig(dawn::TextureFormat format) {
|
||||
switch (format) {
|
||||
case dawn::TextureFormat::R8G8B8A8Unorm:
|
||||
return kRGBA_8888_GrPixelConfig;
|
||||
case dawn::TextureFormat::B8G8R8A8Unorm:
|
||||
return kBGRA_8888_GrPixelConfig;
|
||||
case dawn::TextureFormat::R8Unorm:
|
||||
return kAlpha_8_GrPixelConfig;
|
||||
case dawn::TextureFormat::D32FloatS8Uint:
|
||||
default:
|
||||
SkASSERT(false);
|
||||
return kRGBA_8888_GrPixelConfig;
|
||||
}
|
||||
}
|
||||
|
||||
bool GrPixelConfigToDawnFormat(GrPixelConfig config, dawn::TextureFormat* format) {
|
||||
switch (config) {
|
||||
case kRGBA_8888_GrPixelConfig:
|
||||
case kRGBA_4444_GrPixelConfig:
|
||||
case kRGB_565_GrPixelConfig:
|
||||
case kGray_8_GrPixelConfig:
|
||||
*format = dawn::TextureFormat::R8G8B8A8Unorm;
|
||||
return true;
|
||||
case kBGRA_8888_GrPixelConfig:
|
||||
*format = dawn::TextureFormat::B8G8R8A8Unorm;
|
||||
return true;
|
||||
case kAlpha_8_GrPixelConfig:
|
||||
*format = dawn::TextureFormat::R8Unorm;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
17
src/gpu/dawn/GrDawnUtil.h
Normal file
17
src/gpu/dawn/GrDawnUtil.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrDawnUtil_DEFINED
|
||||
#define GrDawnUtil_DEFINED
|
||||
|
||||
#include "include/private/GrTypesPriv.h"
|
||||
#include "dawn/dawncpp.h"
|
||||
|
||||
GrPixelConfig GrDawnFormatToPixelConfig(dawn::TextureFormat format);
|
||||
bool GrPixelConfigToDawnFormat(GrPixelConfig config, dawn::TextureFormat* format);
|
||||
|
||||
#endif // GrDawnUtil_DEFINED
|
@ -82,6 +82,9 @@ static const struct {
|
||||
{ "angle_gl_es3_msaa8", "gpu", "api=angle_gl_es3,samples=8" },
|
||||
{ "commandbuffer", "gpu", "api=commandbuffer" },
|
||||
{ "mock", "gpu", "api=mock" },
|
||||
#ifdef SK_DAWN
|
||||
{ "dawn", "gpu", "api=dawn" },
|
||||
#endif
|
||||
#ifdef SK_VULKAN
|
||||
{ "vk", "gpu", "api=vulkan" },
|
||||
{ "vknostencils", "gpu", "api=vulkan,stencils=false" },
|
||||
@ -267,6 +270,12 @@ static bool parse_option_gpu_api(const SkString& value,
|
||||
*outContextType = GrContextFactory::kMetal_ContextType;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
if (value.equals("dawn")) {
|
||||
*outContextType = GrContextFactory::kDawn_ContextType;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -20,6 +20,9 @@
|
||||
#ifdef SK_METAL
|
||||
#include "tools/gpu/mtl/MtlTestContext.h"
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
#include "tools/gpu/dawn/DawnTestContext.h"
|
||||
#endif
|
||||
#include "src/gpu/GrCaps.h"
|
||||
#include "src/gpu/gl/GrGLGpu.h"
|
||||
#include "tools/gpu/mock/MockTestContext.h"
|
||||
@ -229,6 +232,17 @@ ContextInfo GrContextFactory::getContextInfoInternal(ContextType type, ContextOv
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef SK_DAWN
|
||||
case GrBackendApi::kDawn: {
|
||||
DawnTestContext* dawnSharedContext = masterContext
|
||||
? static_cast<DawnTestContext*>(masterContext->fTestContext) : nullptr;
|
||||
testCtx.reset(CreatePlatformDawnTestContext(dawnSharedContext));
|
||||
if (!testCtx) {
|
||||
return ContextInfo();
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case GrBackendApi::kMock: {
|
||||
TestContext* sharedContext = masterContext ? masterContext->fTestContext : nullptr;
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
kCommandBuffer_ContextType, //! Chromium command buffer OpenGL ES context.
|
||||
kVulkan_ContextType, //! Vulkan
|
||||
kMetal_ContextType, //! Metal
|
||||
kDawn_ContextType, //! Dawn
|
||||
kMock_ContextType, //! Mock context that does not draw.
|
||||
kLastContextType = kMock_ContextType
|
||||
};
|
||||
@ -71,6 +72,8 @@ public:
|
||||
return GrBackendApi::kVulkan;
|
||||
case kMetal_ContextType:
|
||||
return GrBackendApi::kMetal;
|
||||
case kDawn_ContextType:
|
||||
return GrBackendApi::kDawn;
|
||||
case kMock_ContextType:
|
||||
return GrBackendApi::kMock;
|
||||
default:
|
||||
@ -100,6 +103,8 @@ public:
|
||||
return "Vulkan";
|
||||
case kMetal_ContextType:
|
||||
return "Metal";
|
||||
case kDawn_ContextType:
|
||||
return "Dawn";
|
||||
case kMock_ContextType:
|
||||
return "Mock";
|
||||
}
|
||||
|
250
tools/gpu/dawn/DawnTestContext.cpp
Normal file
250
tools/gpu/dawn/DawnTestContext.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "dawn/dawncpp.h"
|
||||
#include "dawn_native/DawnNative.h"
|
||||
#include "DawnTestContext.h"
|
||||
|
||||
#ifdef SK_BUILD_FOR_UNIX
|
||||
#include "GL/glx.h"
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define USE_OPENGL_BACKEND 0
|
||||
|
||||
#ifdef SK_DAWN
|
||||
#include "dawn/dawn.h"
|
||||
#include "include/gpu/GrContext.h"
|
||||
#include "tools/AutoreleasePool.h"
|
||||
#if USE_OPENGL_BACKEND
|
||||
#include "dawn_native/OpenGLBackend.h"
|
||||
#endif
|
||||
|
||||
#if defined(SK_BUILD_FOR_MAC) && USE_OPENGL_BACKEND
|
||||
#include <dlfcn.h>
|
||||
static void* getProcAddressMacOS(const char* procName) {
|
||||
return dlsym(RTLD_DEFAULT, procName);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
class ProcGetter {
|
||||
public:
|
||||
typedef void(*Proc)();
|
||||
|
||||
ProcGetter()
|
||||
: fModule(LoadLibraryA("opengl32.dll")) {
|
||||
SkASSERT(!fInstance);
|
||||
fInstance = this;
|
||||
}
|
||||
|
||||
~ProcGetter() {
|
||||
if (fModule) {
|
||||
FreeLibrary(fModule);
|
||||
}
|
||||
fInstance = nullptr;
|
||||
}
|
||||
|
||||
static void* getProcAddress(const char* name) {
|
||||
return fInstance->getProc(name);
|
||||
}
|
||||
|
||||
private:
|
||||
Proc getProc(const char* name) {
|
||||
PROC proc;
|
||||
if (proc = GetProcAddress(fModule, name)) {
|
||||
return (Proc) proc;
|
||||
}
|
||||
if (proc = wglGetProcAddress(name)) {
|
||||
return (Proc) proc;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HMODULE fModule;
|
||||
static ProcGetter* fInstance;
|
||||
};
|
||||
|
||||
ProcGetter* ProcGetter::fInstance;
|
||||
#endif
|
||||
|
||||
class DawnFence {
|
||||
public:
|
||||
DawnFence(const dawn::Device& device, const dawn::Buffer& buffer)
|
||||
: fDevice(device), fBuffer(buffer), fCalled(false) {
|
||||
fBuffer.MapReadAsync(callback, this);
|
||||
}
|
||||
|
||||
bool wait() {
|
||||
while (!fCalled) {
|
||||
fDevice.Tick();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
~DawnFence() {
|
||||
}
|
||||
|
||||
static void callback(DawnBufferMapAsyncStatus status, const void* data, uint64_t dataLength,
|
||||
void* userData) {
|
||||
DawnFence* fence = static_cast<DawnFence*>(userData);
|
||||
fence->fCalled = true;
|
||||
}
|
||||
dawn::Buffer buffer() { return fBuffer; }
|
||||
|
||||
private:
|
||||
dawn::Device fDevice;
|
||||
dawn::Buffer fBuffer;
|
||||
bool fCalled;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements sk_gpu_test::FenceSync for Dawn.
|
||||
*/
|
||||
class DawnFenceSync : public sk_gpu_test::FenceSync {
|
||||
public:
|
||||
DawnFenceSync(dawn::Device device) : fDevice(device) {
|
||||
}
|
||||
|
||||
~DawnFenceSync() override {
|
||||
}
|
||||
|
||||
sk_gpu_test::PlatformFence SK_WARN_UNUSED_RESULT insertFence() const override {
|
||||
dawn::Buffer buffer;
|
||||
if (fBuffers.empty()) {
|
||||
dawn::BufferDescriptor desc;
|
||||
desc.usage = dawn::BufferUsageBit::MapRead | dawn::BufferUsageBit::TransferDst;
|
||||
desc.size = 1;
|
||||
buffer = fDevice.CreateBuffer(&desc);
|
||||
} else {
|
||||
buffer = fBuffers.back();
|
||||
fBuffers.pop_back();
|
||||
}
|
||||
DawnFence* fence = new DawnFence(fDevice, buffer);
|
||||
return reinterpret_cast<sk_gpu_test::PlatformFence>(fence);
|
||||
}
|
||||
|
||||
bool waitFence(sk_gpu_test::PlatformFence opaqueFence) const override {
|
||||
fAutoreleasePool.drain();
|
||||
DawnFence* fence = reinterpret_cast<DawnFence*>(opaqueFence);
|
||||
return fence->wait();
|
||||
}
|
||||
|
||||
void deleteFence(sk_gpu_test::PlatformFence opaqueFence) const override {
|
||||
DawnFence* fence = reinterpret_cast<DawnFence*>(opaqueFence);
|
||||
fBuffers.push_back(fence->buffer());
|
||||
delete fence;
|
||||
}
|
||||
|
||||
private:
|
||||
dawn::Device fDevice;
|
||||
mutable std::vector<dawn::Buffer> fBuffers;
|
||||
mutable AutoreleasePool fAutoreleasePool;
|
||||
typedef sk_gpu_test::FenceSync INHERITED;
|
||||
};
|
||||
|
||||
class DawnTestContextImpl : public sk_gpu_test::DawnTestContext {
|
||||
public:
|
||||
static dawn::Device createDevice(const dawn_native::Instance& instance,
|
||||
dawn_native::BackendType type) {
|
||||
DawnProcTable backendProcs = dawn_native::GetProcs();
|
||||
dawnSetProcs(&backendProcs);
|
||||
|
||||
std::vector<dawn_native::Adapter> adapters = instance.GetAdapters();
|
||||
for (dawn_native::Adapter adapter : adapters) {
|
||||
if (adapter.GetBackendType() == type) {
|
||||
return adapter.CreateDevice();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static DawnTestContext* Create(DawnTestContext* sharedContext) {
|
||||
std::unique_ptr<dawn_native::Instance> instance = std::make_unique<dawn_native::Instance>();
|
||||
dawn::Device device;
|
||||
if (sharedContext) {
|
||||
device = sharedContext->getDevice();
|
||||
} else {
|
||||
dawn_native::BackendType type;
|
||||
#if USE_OPENGL_BACKEND
|
||||
dawn_native::opengl::AdapterDiscoveryOptions adapterOptions;
|
||||
adapterOptions.getProc = reinterpret_cast<void*(*)(const char*)>(
|
||||
#if defined(SK_BUILD_FOR_UNIX)
|
||||
glXGetProcAddress
|
||||
#elif defined(SK_BUILD_FOR_MAC)
|
||||
getProcAddressMacOS
|
||||
#elif defined(SK_BUILD_FOR_WIN)
|
||||
ProcGetter::getProcAddress
|
||||
#endif
|
||||
);
|
||||
instance->DiscoverAdapters(&adapterOptions);
|
||||
type = dawn_native::BackendType::OpenGL;
|
||||
#else
|
||||
instance->DiscoverDefaultAdapters();
|
||||
#if defined(SK_BUILD_FOR_MAC)
|
||||
type = dawn_native::BackendType::Metal;
|
||||
#elif defined(SK_BUILD_FOR_WIN)
|
||||
type = dawn_native::BackendType::D3D12;
|
||||
#elif defined(SK_BUILD_FOR_UNIX)
|
||||
type = dawn_native::BackendType::Vulkan;
|
||||
#endif
|
||||
#endif
|
||||
device = createDevice(*instance, type);
|
||||
}
|
||||
if (!device) {
|
||||
return nullptr;
|
||||
}
|
||||
return new DawnTestContextImpl(std::move(instance), device);
|
||||
}
|
||||
|
||||
~DawnTestContextImpl() 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::MakeDawn(fDevice, options);
|
||||
}
|
||||
|
||||
protected:
|
||||
void teardown() override {
|
||||
INHERITED::teardown();
|
||||
}
|
||||
|
||||
private:
|
||||
DawnTestContextImpl(std::unique_ptr<dawn_native::Instance> instance,
|
||||
const dawn::Device& device)
|
||||
: DawnTestContext(device)
|
||||
, fInstance(std::move(instance)) {
|
||||
fFenceSync.reset(new DawnFenceSync(fDevice));
|
||||
}
|
||||
|
||||
void onPlatformMakeCurrent() const override {}
|
||||
std::function<void()> onPlatformGetAutoContextRestore() const override { return nullptr; }
|
||||
void onPlatformSwapBuffers() const override {}
|
||||
std::unique_ptr<dawn_native::Instance> fInstance;
|
||||
|
||||
typedef sk_gpu_test::DawnTestContext INHERITED;
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
namespace sk_gpu_test {
|
||||
DawnTestContext* CreatePlatformDawnTestContext(DawnTestContext* sharedContext) {
|
||||
return DawnTestContextImpl::Create(sharedContext);
|
||||
}
|
||||
} // namespace sk_gpu_test
|
||||
|
||||
#endif
|
42
tools/gpu/dawn/DawnTestContext.h
Normal file
42
tools/gpu/dawn/DawnTestContext.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef DawnTestContext_DEFINED
|
||||
#define DawnTestContext_DEFINED
|
||||
|
||||
#include "tools/gpu/TestContext.h"
|
||||
|
||||
#ifdef SK_DAWN
|
||||
|
||||
namespace sk_gpu_test {
|
||||
class DawnTestContext : public TestContext {
|
||||
public:
|
||||
virtual GrBackend backend() override { return GrBackendApi::kDawn; }
|
||||
|
||||
const dawn::Device& getDevice() {
|
||||
return fDevice;
|
||||
}
|
||||
|
||||
protected:
|
||||
DawnTestContext(const dawn::Device& device) : fDevice(device) {}
|
||||
|
||||
dawn::Device fDevice;
|
||||
|
||||
private:
|
||||
typedef TestContext INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates Dawn context object bound to the Dawn library.
|
||||
*/
|
||||
DawnTestContext* CreatePlatformDawnTestContext(DawnTestContext*);
|
||||
|
||||
} // namespace sk_gpu_test
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -9,6 +9,10 @@
|
||||
#ifndef WindowContextFactory_unix_DEFINED
|
||||
#define WindowContextFactory_unix_DEFINED
|
||||
|
||||
// dawncpp.h and X.h don't get along. Include this first, before X11 defines None, Success etc.
|
||||
#ifdef SK_DAWN
|
||||
#include "dawn/dawncpp.h"
|
||||
#endif
|
||||
#include <X11/Xlib.h>
|
||||
#include <GL/glx.h>
|
||||
typedef Window XWindow;
|
||||
|
Loading…
Reference in New Issue
Block a user