Add Instance and CreateInstance to webgpu.h

This is the first step in making the API before WGPUDevice creation
match webgpu.h and is necessary to implement WGPUSwapChain.

BUG=dawn:269

Change-Id: If92ced42d7683d79e67c02738949ff8b483d22c4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14061
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Corentin Wallez 2020-01-10 13:06:48 +00:00 committed by Commit Bot service account
parent e6441b604f
commit 5fc2c82c11
14 changed files with 97 additions and 17 deletions

View File

@ -738,6 +738,14 @@
{"value": 1, "name": "uint32"} {"value": 1, "name": "uint32"}
] ]
}, },
"instance": {
"category": "object"
},
"instance descriptor": {
"category": "structure",
"extensible": true,
"members": []
},
"vertex attribute descriptor": { "vertex attribute descriptor": {
"category": "structure", "category": "structure",
"extensible": false, "extensible": false,

View File

@ -92,6 +92,12 @@ namespace dawn_native {
static constexpr size_t sProcMapSize = sizeof(sProcMap) / sizeof(sProcMap[0]); static constexpr size_t sProcMapSize = sizeof(sProcMap) / sizeof(sProcMap[0]);
} }
WGPUInstance NativeCreateInstance(WGPUInstanceDescriptor const* cDescriptor) {
const dawn_native::InstanceDescriptor* descriptor =
reinterpret_cast<const dawn_native::InstanceDescriptor*>(cDescriptor);
return reinterpret_cast<WGPUInstance>(InstanceBase::Create(descriptor));
}
WGPUProc NativeGetProcAddress(WGPUDevice, const char* procName) { WGPUProc NativeGetProcAddress(WGPUDevice, const char* procName) {
if (procName == nullptr) { if (procName == nullptr) {
return nullptr; return nullptr;
@ -107,10 +113,15 @@ namespace dawn_native {
return entry->proc; return entry->proc;
} }
// Special case the two free-standing functions of the API.
if (strcmp(procName, "wgpuGetProcAddress") == 0) { if (strcmp(procName, "wgpuGetProcAddress") == 0) {
return reinterpret_cast<WGPUProc>(NativeGetProcAddress); return reinterpret_cast<WGPUProc>(NativeGetProcAddress);
} }
if (strcmp(procName, "wgpuCreateInstance") == 0) {
return reinterpret_cast<WGPUProc>(NativeCreateInstance);
}
return nullptr; return nullptr;
} }
@ -126,6 +137,7 @@ namespace dawn_native {
DawnProcTable GetProcsAutogen() { DawnProcTable GetProcsAutogen() {
DawnProcTable table; DawnProcTable table;
table.getProcAddress = NativeGetProcAddress; table.getProcAddress = NativeGetProcAddress;
table.createInstance = NativeCreateInstance;
{% for type in by_category["object"] %} {% for type in by_category["object"] %}
{% for method in c_methods(type) %} {% for method in c_methods(type) %}
table.{{as_varName(type.name, method.name)}} = Native{{as_MethodSuffix(type.name, method.name)}}; table.{{as_varName(type.name, method.name)}} = Native{{as_MethodSuffix(type.name, method.name)}};

View File

@ -26,6 +26,10 @@ void dawnProcSetProcs(const DawnProcTable* procs_) {
} }
} }
WGPUInstance wgpuCreateInstance(WGPUInstanceDescriptor const * descriptor) {
return procs.createInstance(descriptor);
}
WGPUProc wgpuGetProcAddress(WGPUDevice device, const char* procName) { WGPUProc wgpuGetProcAddress(WGPUDevice device, const char* procName) {
return procs.getProcAddress(device, procName); return procs.getProcAddress(device, procName);
} }

View File

@ -19,6 +19,7 @@
typedef struct DawnProcTable { typedef struct DawnProcTable {
WGPUProcGetProcAddress getProcAddress; WGPUProcGetProcAddress getProcAddress;
WGPUProcCreateInstance createInstance;
{% for type in by_category["object"] %} {% for type in by_category["object"] %}
{% for method in c_methods(type) %} {% for method in c_methods(type) %}

View File

@ -94,6 +94,11 @@ namespace dawn_wire { namespace client {
{% endfor %} {% endfor %}
namespace { namespace {
WGPUInstance ClientCreateInstance(WGPUInstanceDescriptor const* descriptor) {
UNREACHABLE();
return nullptr;
}
struct ProcEntry { struct ProcEntry {
WGPUProc proc; WGPUProc proc;
const char* name; const char* name;
@ -121,10 +126,15 @@ namespace dawn_wire { namespace client {
return entry->proc; return entry->proc;
} }
// Special case the two free-standing functions of the API.
if (strcmp(procName, "wgpuGetProcAddress") == 0) { if (strcmp(procName, "wgpuGetProcAddress") == 0) {
return reinterpret_cast<WGPUProc>(ClientGetProcAddress); return reinterpret_cast<WGPUProc>(ClientGetProcAddress);
} }
if (strcmp(procName, "wgpuCreateInstance") == 0) {
return reinterpret_cast<WGPUProc>(ClientCreateInstance);
}
return nullptr; return nullptr;
} }
@ -145,6 +155,7 @@ namespace dawn_wire { namespace client {
DawnProcTable GetProcs() { DawnProcTable GetProcs() {
DawnProcTable table; DawnProcTable table;
table.getProcAddress = ClientGetProcAddress; table.getProcAddress = ClientGetProcAddress;
table.createInstance = ClientCreateInstance;
{% for type in by_category["object"] %} {% for type in by_category["object"] %}
{% for method in c_methods(type) %} {% for method in c_methods(type) %}
{% set suffix = as_MethodSuffix(type.name, method.name) %} {% set suffix = as_MethodSuffix(type.name, method.name) %}

View File

@ -101,6 +101,7 @@ typedef void (*WGPUProc)();
#if !defined(WGPU_SKIP_PROCS) #if !defined(WGPU_SKIP_PROCS)
typedef WGPUInstance (*WGPUProcCreateInstance)(WGPUInstanceDescriptor const * descriptor);
typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procName); typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procName);
{% for type in by_category["object"] if len(c_methods(type)) > 0 %} {% for type in by_category["object"] if len(c_methods(type)) > 0 %}
@ -119,6 +120,7 @@ typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procN
#if !defined(WGPU_SKIP_DECLARATIONS) #if !defined(WGPU_SKIP_DECLARATIONS)
WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPUInstanceDescriptor const * descriptor);
WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName); WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName);
{% for type in by_category["object"] if len(c_methods(type)) > 0 %} {% for type in by_category["object"] if len(c_methods(type)) > 0 %}

View File

@ -125,6 +125,12 @@ namespace wgpu {
{% endfor %} {% endfor %}
Instance CreateInstance(const InstanceDescriptor* descriptor) {
const WGPUInstanceDescriptor* cDescriptor =
reinterpret_cast<const WGPUInstanceDescriptor*>(descriptor);
return Instance::Acquire(wgpuCreateInstance(cDescriptor));
}
Proc GetProcAddress(Device const& device, const char* procName) { Proc GetProcAddress(Device const& device, const char* procName) {
return reinterpret_cast<Proc>(wgpuGetProcAddress(device.Get(), procName)); return reinterpret_cast<Proc>(wgpuGetProcAddress(device.Get(), procName));
} }

View File

@ -183,6 +183,7 @@ namespace wgpu {
{% endfor %} {% endfor %}
Instance CreateInstance(InstanceDescriptor const * descriptor = nullptr);
Proc GetProcAddress(Device const& device, const char* procName); Proc GetProcAddress(Device const& device, const char* procName);
{% for type in by_category["structure"] %} {% for type in by_category["structure"] %}

View File

@ -80,13 +80,15 @@ namespace dawn_native {
// Instance // Instance
Instance::Instance() : mImpl(new InstanceBase()) { Instance::Instance() : mImpl(InstanceBase::Create()) {
} }
Instance::~Instance() { Instance::~Instance() {
delete mImpl; if (mImpl != nullptr) {
mImpl->Release();
mImpl = nullptr; mImpl = nullptr;
} }
}
void Instance::DiscoverDefaultAdapters() { void Instance::DiscoverDefaultAdapters() {
mImpl->DiscoverDefaultAdapters(); mImpl->DiscoverDefaultAdapters();
@ -121,6 +123,10 @@ namespace dawn_native {
mImpl->SetPlatform(platform); mImpl->SetPlatform(platform);
} }
WGPUInstance Instance::Get() const {
return reinterpret_cast<WGPUInstance>(mImpl);
}
size_t GetLazyClearCountForTesting(WGPUDevice device) { size_t GetLazyClearCountForTesting(WGPUDevice device) {
dawn_native::DeviceBase* deviceBase = reinterpret_cast<dawn_native::DeviceBase*>(device); dawn_native::DeviceBase* deviceBase = reinterpret_cast<dawn_native::DeviceBase*>(device);
return deviceBase->GetLazyClearCountForTesting(); return deviceBase->GetLazyClearCountForTesting();

View File

@ -50,6 +50,19 @@ namespace dawn_native {
// InstanceBase // InstanceBase
// static
InstanceBase* InstanceBase::Create(const InstanceDescriptor* descriptor) {
Ref<InstanceBase> instance = AcquireRef(new InstanceBase);
if (!instance->Initialize(descriptor)) {
return nullptr;
}
return instance.Detach();
}
bool InstanceBase::Initialize(const InstanceDescriptor*) {
return true;
}
void InstanceBase::DiscoverDefaultAdapters() { void InstanceBase::DiscoverDefaultAdapters() {
EnsureBackendConnections(); EnsureBackendConnections();

View File

@ -18,7 +18,9 @@
#include "dawn_native/Adapter.h" #include "dawn_native/Adapter.h"
#include "dawn_native/BackendConnection.h" #include "dawn_native/BackendConnection.h"
#include "dawn_native/Extensions.h" #include "dawn_native/Extensions.h"
#include "dawn_native/RefCounted.h"
#include "dawn_native/Toggles.h" #include "dawn_native/Toggles.h"
#include "dawn_native/dawn_platform.h"
#include <array> #include <array>
#include <memory> #include <memory>
@ -29,13 +31,9 @@ namespace dawn_native {
// This is called InstanceBase for consistency across the frontend, even if the backends don't // This is called InstanceBase for consistency across the frontend, even if the backends don't
// specialize this class. // specialize this class.
class InstanceBase final { class InstanceBase final : public RefCounted {
public: public:
InstanceBase() = default; static InstanceBase* Create(const InstanceDescriptor* descriptor = nullptr);
~InstanceBase() = default;
InstanceBase(const InstanceBase& other) = delete;
InstanceBase& operator=(const InstanceBase& other) = delete;
void DiscoverDefaultAdapters(); void DiscoverDefaultAdapters();
bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options); bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
@ -67,6 +65,14 @@ namespace dawn_native {
dawn_platform::Platform* GetPlatform() const; dawn_platform::Platform* GetPlatform() const;
private: private:
InstanceBase() = default;
~InstanceBase() = default;
InstanceBase(const InstanceBase& other) = delete;
InstanceBase& operator=(const InstanceBase& other) = delete;
bool Initialize(const InstanceDescriptor* descriptor);
// Lazily creates connections to all backends that have been compiled. // Lazily creates connections to all backends that have been compiled.
void EnsureBackendConnections(); void EnsureBackendConnections();

View File

@ -146,6 +146,9 @@ namespace dawn_native {
void SetPlatform(dawn_platform::Platform* platform); void SetPlatform(dawn_platform::Platform* platform);
// Returns the underlying WGPUInstance object.
WGPUInstance Get() const;
private: private:
InstanceBase* mImpl = nullptr; InstanceBase* mImpl = nullptr;
}; };

View File

@ -20,7 +20,10 @@
class ExtensionTests : public testing::Test { class ExtensionTests : public testing::Test {
public: public:
ExtensionTests() : testing::Test(), mInstanceBase(), mAdapterBase(&mInstanceBase) { ExtensionTests()
: testing::Test(),
mInstanceBase(dawn_native::InstanceBase::Create()),
mAdapterBase(mInstanceBase.Get()) {
} }
std::vector<const char*> GetAllExtensionNames() { std::vector<const char*> GetAllExtensionNames() {
@ -35,7 +38,7 @@ class ExtensionTests : public testing::Test {
static_cast<size_t>(dawn_native::Extension::EnumCount); static_cast<size_t>(dawn_native::Extension::EnumCount);
protected: protected:
dawn_native::InstanceBase mInstanceBase; dawn_native::Ref<dawn_native::InstanceBase> mInstanceBase;
dawn_native::null::Adapter mAdapterBase; dawn_native::null::Adapter mAdapterBase;
}; };

View File

@ -51,8 +51,8 @@ namespace {
public: public:
GetProcAddressTests() GetProcAddressTests()
: testing::TestWithParam<DawnFlavor>(), : testing::TestWithParam<DawnFlavor>(),
mNativeInstance(), mNativeInstance(dawn_native::InstanceBase::Create()),
mNativeAdapter(&mNativeInstance) { mNativeAdapter(mNativeInstance.Get()) {
} }
void SetUp() override { void SetUp() override {
@ -90,7 +90,7 @@ namespace {
} }
protected: protected:
dawn_native::InstanceBase mNativeInstance; dawn_native::Ref<dawn_native::InstanceBase> mNativeInstance;
dawn_native::null::Adapter mNativeAdapter; dawn_native::null::Adapter mNativeAdapter;
std::unique_ptr<utils::TerribleCommandBuffer> mC2sBuf; std::unique_ptr<utils::TerribleCommandBuffer> mC2sBuf;
@ -136,13 +136,17 @@ namespace {
ASSERT_EQ(mProcs.getProcAddress(mDevice.Get(), "0"), nullptr); ASSERT_EQ(mProcs.getProcAddress(mDevice.Get(), "0"), nullptr);
} }
// Test that GetProcAddress supports itself: it is handled specially because it is a // Test that GetProcAddress supports freestanding function that are handled specially
// freestanding function and not a method on an object. TEST_P(GetProcAddressTests, FreeStandingFunctions) {
TEST_P(GetProcAddressTests, GetProcAddressItself) {
ASSERT_EQ(mProcs.getProcAddress(nullptr, "wgpuGetProcAddress"), ASSERT_EQ(mProcs.getProcAddress(nullptr, "wgpuGetProcAddress"),
reinterpret_cast<WGPUProc>(mProcs.getProcAddress)); reinterpret_cast<WGPUProc>(mProcs.getProcAddress));
ASSERT_EQ(mProcs.getProcAddress(mDevice.Get(), "wgpuGetProcAddress"), ASSERT_EQ(mProcs.getProcAddress(mDevice.Get(), "wgpuGetProcAddress"),
reinterpret_cast<WGPUProc>(mProcs.getProcAddress)); reinterpret_cast<WGPUProc>(mProcs.getProcAddress));
ASSERT_EQ(mProcs.getProcAddress(nullptr, "wgpuCreateInstance"),
reinterpret_cast<WGPUProc>(mProcs.createInstance));
ASSERT_EQ(mProcs.getProcAddress(mDevice.Get(), "wgpuCreateInstance"),
reinterpret_cast<WGPUProc>(mProcs.createInstance));
} }
INSTANTIATE_TEST_SUITE_P(, INSTANTIATE_TEST_SUITE_P(,