mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-05 22:23:29 +00:00
Metal: Implement the backend connection and adapter.
BUG=dawn:29 Change-Id: Idaca7d2f8ac52d5f46d8030571b5e2da3a573a97 Reviewed-on: https://dawn-review.googlesource.com/c/3940 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
a27bdb4a5e
commit
978fa65a2c
2
BUILD.gn
2
BUILD.gn
@ -568,6 +568,8 @@ source_set("libdawn_native_sources") {
|
|||||||
"IOKit.framework",
|
"IOKit.framework",
|
||||||
]
|
]
|
||||||
sources += [
|
sources += [
|
||||||
|
"src/dawn_native/metal/BackendMTL.h",
|
||||||
|
"src/dawn_native/metal/BackendMTL.mm",
|
||||||
"src/dawn_native/metal/BufferMTL.h",
|
"src/dawn_native/metal/BufferMTL.h",
|
||||||
"src/dawn_native/metal/BufferMTL.mm",
|
"src/dawn_native/metal/BufferMTL.mm",
|
||||||
"src/dawn_native/metal/CommandBufferMTL.h",
|
"src/dawn_native/metal/CommandBufferMTL.h",
|
||||||
|
31
src/dawn_native/metal/BackendMTL.h
Normal file
31
src/dawn_native/metal/BackendMTL.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2019 The Dawn Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef DAWNNATIVE_METAL_BACKENDMTL_H_
|
||||||
|
#define DAWNNATIVE_METAL_BACKENDMTL_H_
|
||||||
|
|
||||||
|
#include "dawn_native/BackendConnection.h"
|
||||||
|
|
||||||
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
|
class Backend : public BackendConnection {
|
||||||
|
public:
|
||||||
|
Backend(InstanceBase* instance);
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}} // namespace dawn_native::metal
|
||||||
|
|
||||||
|
#endif // DAWNNATIVE_METAL_BACKENDMTL_H_
|
161
src/dawn_native/metal/BackendMTL.mm
Normal file
161
src/dawn_native/metal/BackendMTL.mm
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
// Copyright 2019 The Dawn Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "dawn_native/metal/BackendMTL.h"
|
||||||
|
|
||||||
|
#include "dawn_native/MetalBackend.h"
|
||||||
|
#include "dawn_native/metal/DeviceMTL.h"
|
||||||
|
|
||||||
|
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||||
|
|
||||||
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Since CGDisplayIOServicePort was deprecated in macOS 10.9, we need create
|
||||||
|
// an alternative function for getting I/O service port from current display.
|
||||||
|
io_service_t GetDisplayIOServicePort() {
|
||||||
|
// The matching service port (or 0 if none can be found)
|
||||||
|
io_service_t servicePort = 0;
|
||||||
|
|
||||||
|
// Create matching dictionary for display service
|
||||||
|
CFMutableDictionaryRef matchingDict = IOServiceMatching("IODisplayConnect");
|
||||||
|
if (matchingDict == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_iterator_t iter;
|
||||||
|
// IOServiceGetMatchingServices look up the default master ports that match a
|
||||||
|
// matching dictionary, and will consume the reference on the matching dictionary,
|
||||||
|
// so we don't need to release the dictionary, but the iterator handle should
|
||||||
|
// be released when its iteration is finished.
|
||||||
|
if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter) !=
|
||||||
|
kIOReturnSuccess) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vendor number and product number of current main display
|
||||||
|
const uint32_t displayVendorNumber = CGDisplayVendorNumber(kCGDirectMainDisplay);
|
||||||
|
const uint32_t displayProductNumber = CGDisplayModelNumber(kCGDirectMainDisplay);
|
||||||
|
|
||||||
|
io_service_t serv;
|
||||||
|
while ((serv = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
|
||||||
|
CFDictionaryRef displayInfo =
|
||||||
|
IODisplayCreateInfoDictionary(serv, kIODisplayOnlyPreferredName);
|
||||||
|
|
||||||
|
CFNumberRef vendorIDRef, productIDRef;
|
||||||
|
Boolean success;
|
||||||
|
// The ownership of CF object follows the 'Get Rule', we don't need to
|
||||||
|
// release these values
|
||||||
|
success = CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplayVendorID),
|
||||||
|
(const void**)&vendorIDRef);
|
||||||
|
success &= CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplayProductID),
|
||||||
|
(const void**)&productIDRef);
|
||||||
|
if (success) {
|
||||||
|
CFIndex vendorID = 0, productID = 0;
|
||||||
|
CFNumberGetValue(vendorIDRef, kCFNumberSInt32Type, &vendorID);
|
||||||
|
CFNumberGetValue(productIDRef, kCFNumberSInt32Type, &productID);
|
||||||
|
|
||||||
|
if (vendorID == displayVendorNumber && productID == displayProductNumber) {
|
||||||
|
// Check if vendor id and product id match with current display's
|
||||||
|
// If it does, we find the desired service port
|
||||||
|
servicePort = serv;
|
||||||
|
CFRelease(displayInfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(displayInfo);
|
||||||
|
IOObjectRelease(serv);
|
||||||
|
}
|
||||||
|
IOObjectRelease(iter);
|
||||||
|
return servicePort;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get integer property from registry entry.
|
||||||
|
uint32_t GetEntryProperty(io_registry_entry_t entry, CFStringRef name) {
|
||||||
|
uint32_t value = 0;
|
||||||
|
|
||||||
|
// Recursively search registry entry and its parents for property name
|
||||||
|
// The data should release with CFRelease
|
||||||
|
CFDataRef data = static_cast<CFDataRef>(IORegistryEntrySearchCFProperty(
|
||||||
|
entry, kIOServicePlane, name, kCFAllocatorDefault,
|
||||||
|
kIORegistryIterateRecursively | kIORegistryIterateParents));
|
||||||
|
|
||||||
|
if (data != nullptr) {
|
||||||
|
const uint32_t* valuePtr =
|
||||||
|
reinterpret_cast<const uint32_t*>(CFDataGetBytePtr(data));
|
||||||
|
if (valuePtr) {
|
||||||
|
value = *valuePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
// The Metal backend's Adapter.
|
||||||
|
|
||||||
|
class Adapter : public AdapterBase {
|
||||||
|
public:
|
||||||
|
Adapter(InstanceBase* instance, id<MTLDevice> device)
|
||||||
|
: AdapterBase(instance, BackendType::Metal), mDevice([device retain]) {
|
||||||
|
mPCIInfo.name = std::string([mDevice.name UTF8String]);
|
||||||
|
// Gather the PCI device and vendor IDs based on which device is rendering to the
|
||||||
|
// main display. This is obviously wrong for systems with multiple devices.
|
||||||
|
// TODO(cwallez@chromium.org): Once Chromium has the macOS 10.13 SDK rolled, we
|
||||||
|
// should use MTLDevice.registryID to gather the information.
|
||||||
|
io_registry_entry_t entry = GetDisplayIOServicePort();
|
||||||
|
if (entry != IO_OBJECT_NULL) {
|
||||||
|
mPCIInfo.vendorId = GetEntryProperty(entry, CFSTR("vendor-id"));
|
||||||
|
mPCIInfo.deviceId = GetEntryProperty(entry, CFSTR("device-id"));
|
||||||
|
IOObjectRelease(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Adapter() override {
|
||||||
|
[mDevice release];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ResultOrError<DeviceBase*> CreateDeviceImpl() override {
|
||||||
|
return {new Device(this, mDevice)};
|
||||||
|
}
|
||||||
|
|
||||||
|
id<MTLDevice> mDevice = nil;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implementation of the Metal backend's BackendConnection
|
||||||
|
|
||||||
|
Backend::Backend(InstanceBase* instance) : BackendConnection(instance, BackendType::Metal) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<AdapterBase>> Backend::DiscoverDefaultAdapters() {
|
||||||
|
NSArray<id<MTLDevice>>* devices = MTLCopyAllDevices();
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<AdapterBase>> adapters;
|
||||||
|
for (id<MTLDevice> device in devices) {
|
||||||
|
adapters.push_back(std::make_unique<Adapter>(GetInstance(), device));
|
||||||
|
}
|
||||||
|
|
||||||
|
[devices release];
|
||||||
|
return adapters;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendConnection* Connect(InstanceBase* instance) {
|
||||||
|
return new Backend(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
}} // namespace dawn_native::metal
|
@ -34,7 +34,7 @@ namespace dawn_native { namespace metal {
|
|||||||
|
|
||||||
class Device : public DeviceBase {
|
class Device : public DeviceBase {
|
||||||
public:
|
public:
|
||||||
Device();
|
Device(AdapterBase* adapter, id<MTLDevice> mtlDevice);
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||||
@ -47,8 +47,6 @@ namespace dawn_native { namespace metal {
|
|||||||
Serial GetLastSubmittedCommandSerial() const final override;
|
Serial GetLastSubmittedCommandSerial() const final override;
|
||||||
void TickImpl() override;
|
void TickImpl() override;
|
||||||
|
|
||||||
const dawn_native::PCIInfo& GetPCIInfo() const override;
|
|
||||||
|
|
||||||
id<MTLDevice> GetMTLDevice();
|
id<MTLDevice> GetMTLDevice();
|
||||||
|
|
||||||
id<MTLCommandBuffer> GetPendingCommandBuffer();
|
id<MTLCommandBuffer> GetPendingCommandBuffer();
|
||||||
@ -85,7 +83,6 @@ namespace dawn_native { namespace metal {
|
|||||||
ResultOrError<TextureViewBase*> CreateTextureViewImpl(
|
ResultOrError<TextureViewBase*> CreateTextureViewImpl(
|
||||||
TextureBase* texture,
|
TextureBase* texture,
|
||||||
const TextureViewDescriptor* descriptor) override;
|
const TextureViewDescriptor* descriptor) override;
|
||||||
void CollectPCIInfo();
|
|
||||||
|
|
||||||
void OnCompletedHandler();
|
void OnCompletedHandler();
|
||||||
|
|
||||||
@ -97,8 +94,6 @@ namespace dawn_native { namespace metal {
|
|||||||
Serial mCompletedSerial = 0;
|
Serial mCompletedSerial = 0;
|
||||||
Serial mLastSubmittedSerial = 0;
|
Serial mLastSubmittedSerial = 0;
|
||||||
id<MTLCommandBuffer> mPendingCommands = nil;
|
id<MTLCommandBuffer> mPendingCommands = nil;
|
||||||
|
|
||||||
dawn_native::PCIInfo mPCIInfo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // namespace dawn_native::metal
|
}} // namespace dawn_native::metal
|
||||||
|
@ -32,110 +32,15 @@
|
|||||||
#include "dawn_native/metal/SwapChainMTL.h"
|
#include "dawn_native/metal/SwapChainMTL.h"
|
||||||
#include "dawn_native/metal/TextureMTL.h"
|
#include "dawn_native/metal/TextureMTL.h"
|
||||||
|
|
||||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
namespace dawn_native { namespace metal {
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
namespace {
|
Device::Device(AdapterBase* adapter, id<MTLDevice> mtlDevice)
|
||||||
// Since CGDisplayIOServicePort was deprecated in macOS 10.9, we need create
|
: DeviceBase(adapter),
|
||||||
// an alternative function for getting I/O service port from current display.
|
mMtlDevice([mtlDevice retain]),
|
||||||
io_service_t GetDisplayIOServicePort() {
|
|
||||||
// The matching service port (or 0 if none can be found)
|
|
||||||
io_service_t servicePort = 0;
|
|
||||||
|
|
||||||
// Create matching dictionary for display service
|
|
||||||
CFMutableDictionaryRef matchingDict = IOServiceMatching("IODisplayConnect");
|
|
||||||
if (matchingDict == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
io_iterator_t iter;
|
|
||||||
// IOServiceGetMatchingServices look up the default master ports that match a
|
|
||||||
// matching dictionary, and will consume the reference on the matching dictionary,
|
|
||||||
// so we don't need to release the dictionary, but the iterator handle should
|
|
||||||
// be released when its iteration is finished.
|
|
||||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter) !=
|
|
||||||
kIOReturnSuccess) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vendor number and product number of current main display
|
|
||||||
const uint32_t displayVendorNumber = CGDisplayVendorNumber(kCGDirectMainDisplay);
|
|
||||||
const uint32_t displayProductNumber = CGDisplayModelNumber(kCGDirectMainDisplay);
|
|
||||||
|
|
||||||
io_service_t serv;
|
|
||||||
while ((serv = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
|
|
||||||
CFDictionaryRef displayInfo =
|
|
||||||
IODisplayCreateInfoDictionary(serv, kIODisplayOnlyPreferredName);
|
|
||||||
|
|
||||||
CFNumberRef vendorIDRef, productIDRef;
|
|
||||||
Boolean success;
|
|
||||||
// The ownership of CF object follows the 'Get Rule', we don't need to
|
|
||||||
// release these values
|
|
||||||
success = CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplayVendorID),
|
|
||||||
(const void**)&vendorIDRef);
|
|
||||||
success &= CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplayProductID),
|
|
||||||
(const void**)&productIDRef);
|
|
||||||
if (success) {
|
|
||||||
CFIndex vendorID = 0, productID = 0;
|
|
||||||
CFNumberGetValue(vendorIDRef, kCFNumberSInt32Type, &vendorID);
|
|
||||||
CFNumberGetValue(productIDRef, kCFNumberSInt32Type, &productID);
|
|
||||||
|
|
||||||
if (vendorID == displayVendorNumber && productID == displayProductNumber) {
|
|
||||||
// Check if vendor id and product id match with current display's
|
|
||||||
// If it does, we find the desired service port
|
|
||||||
servicePort = serv;
|
|
||||||
CFRelease(displayInfo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CFRelease(displayInfo);
|
|
||||||
IOObjectRelease(serv);
|
|
||||||
}
|
|
||||||
IOObjectRelease(iter);
|
|
||||||
return servicePort;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get integer property from registry entry.
|
|
||||||
uint32_t GetEntryProperty(io_registry_entry_t entry, CFStringRef name) {
|
|
||||||
uint32_t value = 0;
|
|
||||||
|
|
||||||
// Recursively search registry entry and its parents for property name
|
|
||||||
// The data should release with CFRelease
|
|
||||||
CFDataRef data = static_cast<CFDataRef>(IORegistryEntrySearchCFProperty(
|
|
||||||
entry, kIOServicePlane, name, kCFAllocatorDefault,
|
|
||||||
kIORegistryIterateRecursively | kIORegistryIterateParents));
|
|
||||||
|
|
||||||
if (data != nullptr) {
|
|
||||||
const uint32_t* valuePtr =
|
|
||||||
reinterpret_cast<const uint32_t*>(CFDataGetBytePtr(data));
|
|
||||||
if (valuePtr) {
|
|
||||||
value = *valuePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFRelease(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
BackendConnection* Connect(InstanceBase* instance) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Device
|
|
||||||
|
|
||||||
Device::Device()
|
|
||||||
: DeviceBase(nullptr),
|
|
||||||
mMtlDevice(MTLCreateSystemDefaultDevice()),
|
|
||||||
mMapTracker(new MapRequestTracker(this)),
|
mMapTracker(new MapRequestTracker(this)),
|
||||||
mResourceUploader(new ResourceUploader(this)) {
|
mResourceUploader(new ResourceUploader(this)) {
|
||||||
[mMtlDevice retain];
|
[mMtlDevice retain];
|
||||||
mCommandQueue = [mMtlDevice newCommandQueue];
|
mCommandQueue = [mMtlDevice newCommandQueue];
|
||||||
CollectPCIInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device() {
|
Device::~Device() {
|
||||||
@ -155,11 +60,11 @@ namespace dawn_native { namespace metal {
|
|||||||
mMapTracker = nullptr;
|
mMapTracker = nullptr;
|
||||||
mResourceUploader = nullptr;
|
mResourceUploader = nullptr;
|
||||||
|
|
||||||
[mMtlDevice release];
|
|
||||||
mMtlDevice = nil;
|
|
||||||
|
|
||||||
[mCommandQueue release];
|
[mCommandQueue release];
|
||||||
mCommandQueue = nil;
|
mCommandQueue = nil;
|
||||||
|
|
||||||
|
[mMtlDevice release];
|
||||||
|
mMtlDevice = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
ResultOrError<BindGroupBase*> Device::CreateBindGroupImpl(
|
||||||
@ -243,10 +148,6 @@ namespace dawn_native { namespace metal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dawn_native::PCIInfo& Device::GetPCIInfo() const {
|
|
||||||
return mPCIInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
id<MTLDevice> Device::GetMTLDevice() {
|
id<MTLDevice> Device::GetMTLDevice() {
|
||||||
return mMtlDevice;
|
return mMtlDevice;
|
||||||
}
|
}
|
||||||
@ -287,17 +188,6 @@ namespace dawn_native { namespace metal {
|
|||||||
return mResourceUploader.get();
|
return mResourceUploader.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::CollectPCIInfo() {
|
|
||||||
io_registry_entry_t entry = GetDisplayIOServicePort();
|
|
||||||
if (entry != IO_OBJECT_NULL) {
|
|
||||||
mPCIInfo.vendorId = GetEntryProperty(entry, CFSTR("vendor-id"));
|
|
||||||
mPCIInfo.deviceId = GetEntryProperty(entry, CFSTR("device-id"));
|
|
||||||
IOObjectRelease(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
mPCIInfo.name = std::string([mMtlDevice.name UTF8String]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultOrError<std::unique_ptr<StagingBufferBase>> Device::CreateStagingBuffer(size_t size) {
|
ResultOrError<std::unique_ptr<StagingBufferBase>> Device::CreateStagingBuffer(size_t size) {
|
||||||
return DAWN_UNIMPLEMENTED_ERROR("Device unable to create staging buffer.");
|
return DAWN_UNIMPLEMENTED_ERROR("Device unable to create staging buffer.");
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
|
|
||||||
namespace dawn_native { namespace metal {
|
namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
dawnDevice CreateDevice() {
|
|
||||||
return reinterpret_cast<dawnDevice>(new Device());
|
|
||||||
}
|
|
||||||
|
|
||||||
id<MTLDevice> GetMetalDevice(dawnDevice cDevice) {
|
id<MTLDevice> GetMetalDevice(dawnDevice cDevice) {
|
||||||
Device* device = reinterpret_cast<Device*>(cDevice);
|
Device* device = reinterpret_cast<Device*>(cDevice);
|
||||||
return device->GetMTLDevice();
|
return device->GetMTLDevice();
|
||||||
|
@ -15,15 +15,12 @@
|
|||||||
#ifndef DAWNNATIVE_METALBACKEND_H_
|
#ifndef DAWNNATIVE_METALBACKEND_H_
|
||||||
#define DAWNNATIVE_METALBACKEND_H_
|
#define DAWNNATIVE_METALBACKEND_H_
|
||||||
|
|
||||||
#include <dawn/dawn.h>
|
|
||||||
#include <dawn/dawn_wsi.h>
|
#include <dawn/dawn_wsi.h>
|
||||||
#include <dawn_native/dawn_native_export.h>
|
#include <dawn_native/DawnNative.h>
|
||||||
|
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
|
||||||
|
|
||||||
namespace dawn_native { namespace metal {
|
namespace dawn_native { namespace metal {
|
||||||
DAWN_NATIVE_EXPORT dawnDevice CreateDevice();
|
|
||||||
DAWN_NATIVE_EXPORT id<MTLDevice> GetMetalDevice(dawnDevice device);
|
DAWN_NATIVE_EXPORT id<MTLDevice> GetMetalDevice(dawnDevice device);
|
||||||
}} // namespace dawn_native::metal
|
}} // namespace dawn_native::metal
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
#include "GLFW/glfw3native.h"
|
#include "GLFW/glfw3native.h"
|
||||||
|
|
||||||
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
class SwapChainImplMTL {
|
class SwapChainImplMTL {
|
||||||
public:
|
public:
|
||||||
@ -113,9 +115,21 @@ namespace utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dawnDevice CreateDevice() override {
|
dawnDevice CreateDevice() override {
|
||||||
dawnDevice device = dawn_native::metal::CreateDevice();
|
// Make an instance and find a Metal adapter
|
||||||
mMetalDevice = dawn_native::metal::GetMetalDevice(device);
|
mInstance = std::make_unique<dawn_native::Instance>();
|
||||||
return device;
|
mInstance->DiscoverDefaultAdapters();
|
||||||
|
|
||||||
|
std::vector<dawn_native::Adapter> adapters = mInstance->GetAdapters();
|
||||||
|
for (dawn_native::Adapter adapter : adapters) {
|
||||||
|
if (adapter.GetBackendType() == dawn_native::BackendType::Metal) {
|
||||||
|
dawnDevice device = adapter.CreateDevice();
|
||||||
|
mMetalDevice = dawn_native::metal::GetMetalDevice(device);
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UNREACHABLE();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t GetSwapChainImplementation() override {
|
uint64_t GetSwapChainImplementation() override {
|
||||||
@ -131,6 +145,7 @@ namespace utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<dawn_native::Instance> mInstance;
|
||||||
id<MTLDevice> mMetalDevice = nil;
|
id<MTLDevice> mMetalDevice = nil;
|
||||||
dawnSwapChainImplementation mSwapchainImpl = {};
|
dawnSwapChainImplementation mSwapchainImpl = {};
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user