Title: [290262] trunk/Source/WebGPU
Revision
290262
Author
mmaxfi...@apple.com
Date
2022-02-21 12:49:00 -0800 (Mon, 21 Feb 2022)

Log Message

[WebGPU] Tracer bullet part 8: Basic implementation of device creation routines
https://bugs.webkit.org/show_bug.cgi?id=236902

Reviewed by Dean Jackson.

This is a basic implementation of the Instance, Adapter, and Device methods. Device limits are not
implemented yet, so for now we claim every limits is 0.

* WebGPU/Adapter.mm:
(WebGPU::Adapter::Adapter):
(WebGPU::Adapter::enumerateFeatures):
(WebGPU::Adapter::getLimits):
(WebGPU::Adapter::getProperties):
(WebGPU::Adapter::hasFeature):
(WebGPU::deviceMeetsRequiredLimits):
(WebGPU::Adapter::requestDevice):
* WebGPU/Device.h:
* WebGPU/Device.mm:
(WebGPU::Device::create):
(WebGPU::Device::Device):
(WebGPU::Device::destroy):
(WebGPU::Device::enumerateFeatures):
(WebGPU::Device::getLimits):
(WebGPU::Device::getQueue):
(WebGPU::Device::hasFeature):
(WebGPU::Device::popErrorScope):
(WebGPU::Device::pushErrorScope):
(WebGPU::Device::setDeviceLostCallback):
(WebGPU::Device::setUncapturedErrorCallback):
(WebGPU::Device::setLabel):
* WebGPU/Instance.mm:
(WebGPU::sortedDevices):
(WebGPU::Instance::requestAdapter):

Modified Paths

Diff

Modified: trunk/Source/WebGPU/ChangeLog (290261 => 290262)


--- trunk/Source/WebGPU/ChangeLog	2022-02-21 20:42:43 UTC (rev 290261)
+++ trunk/Source/WebGPU/ChangeLog	2022-02-21 20:49:00 UTC (rev 290262)
@@ -1,5 +1,41 @@
 2022-02-21  Myles C. Maxfield  <mmaxfi...@apple.com>
 
+        [WebGPU] Tracer bullet part 8: Basic implementation of device creation routines
+        https://bugs.webkit.org/show_bug.cgi?id=236902
+
+        Reviewed by Dean Jackson.
+
+        This is a basic implementation of the Instance, Adapter, and Device methods. Device limits are not
+        implemented yet, so for now we claim every limits is 0.
+
+        * WebGPU/Adapter.mm:
+        (WebGPU::Adapter::Adapter):
+        (WebGPU::Adapter::enumerateFeatures):
+        (WebGPU::Adapter::getLimits):
+        (WebGPU::Adapter::getProperties):
+        (WebGPU::Adapter::hasFeature):
+        (WebGPU::deviceMeetsRequiredLimits):
+        (WebGPU::Adapter::requestDevice):
+        * WebGPU/Device.h:
+        * WebGPU/Device.mm:
+        (WebGPU::Device::create):
+        (WebGPU::Device::Device):
+        (WebGPU::Device::destroy):
+        (WebGPU::Device::enumerateFeatures):
+        (WebGPU::Device::getLimits):
+        (WebGPU::Device::getQueue):
+        (WebGPU::Device::hasFeature):
+        (WebGPU::Device::popErrorScope):
+        (WebGPU::Device::pushErrorScope):
+        (WebGPU::Device::setDeviceLostCallback):
+        (WebGPU::Device::setUncapturedErrorCallback):
+        (WebGPU::Device::setLabel):
+        * WebGPU/Instance.mm:
+        (WebGPU::sortedDevices):
+        (WebGPU::Instance::requestAdapter):
+
+2022-02-21  Myles C. Maxfield  <mmaxfi...@apple.com>
+
         [WebGPU] Tracer bullet part 7: Clean up includes a bit
         https://bugs.webkit.org/show_bug.cgi?id=236900
 

Modified: trunk/Source/WebGPU/WebGPU/Adapter.mm (290261 => 290262)


--- trunk/Source/WebGPU/WebGPU/Adapter.mm	2022-02-21 20:42:43 UTC (rev 290261)
+++ trunk/Source/WebGPU/WebGPU/Adapter.mm	2022-02-21 20:49:00 UTC (rev 290262)
@@ -34,38 +34,95 @@
 Adapter::Adapter(id <MTLDevice> device)
     : m_device(device)
 {
-    UNUSED_VARIABLE(m_device);
 }
 
 Adapter::~Adapter() = default;
 
-size_t Adapter::enumerateFeatures(WGPUFeatureName* features)
+size_t Adapter::enumerateFeatures(WGPUFeatureName*)
 {
-    UNUSED_PARAM(features);
+    // We support no optional features right now.
     return 0;
 }
 
 bool Adapter::getLimits(WGPUSupportedLimits* limits)
 {
-    UNUSED_PARAM(limits);
+    if (limits->nextInChain != nullptr)
+        return false;
+
+    // FIXME: Implement this.
+    limits->limits = { };
     return true;
 }
 
 void Adapter::getProperties(WGPUAdapterProperties* properties)
 {
-    UNUSED_PARAM(properties);
+    // FIXME: What should the vendorID and deviceID be?
+    properties->vendorID = 0;
+    properties->deviceID = 0;
+    properties->name = m_device.name.UTF8String;
+    properties->driverDescription = "";
+    properties->adapterType = m_device.hasUnifiedMemory ? WGPUAdapterType_IntegratedGPU : WGPUAdapterType_DiscreteGPU;
+    properties->backendType = WGPUBackendType_Metal;
 }
 
-bool Adapter::hasFeature(WGPUFeatureName feature)
+bool Adapter::hasFeature(WGPUFeatureName)
 {
-    UNUSED_PARAM(feature);
+    // We support no optional features right now.
     return false;
 }
 
+static bool deviceMeetsRequiredLimits(id <MTLDevice>, const WGPURequiredLimits& requiredLimits)
+{
+    // FIXME: Implement this.
+    return !requiredLimits.nextInChain
+        && !requiredLimits.limits.maxTextureDimension1D
+        && !requiredLimits.limits.maxTextureDimension2D
+        && !requiredLimits.limits.maxTextureDimension3D
+        && !requiredLimits.limits.maxTextureArrayLayers
+        && !requiredLimits.limits.maxBindGroups
+        && !requiredLimits.limits.maxDynamicUniformBuffersPerPipelineLayout
+        && !requiredLimits.limits.maxDynamicStorageBuffersPerPipelineLayout
+        && !requiredLimits.limits.maxSampledTexturesPerShaderStage
+        && !requiredLimits.limits.maxSamplersPerShaderStage
+        && !requiredLimits.limits.maxStorageBuffersPerShaderStage
+        && !requiredLimits.limits.maxStorageTexturesPerShaderStage
+        && !requiredLimits.limits.maxUniformBuffersPerShaderStage
+        && !requiredLimits.limits.maxUniformBufferBindingSize
+        && !requiredLimits.limits.maxStorageBufferBindingSize
+        && !requiredLimits.limits.minUniformBufferOffsetAlignment
+        && !requiredLimits.limits.minStorageBufferOffsetAlignment
+        && !requiredLimits.limits.maxVertexBuffers
+        && !requiredLimits.limits.maxVertexAttributes
+        && !requiredLimits.limits.maxVertexBufferArrayStride
+        && !requiredLimits.limits.maxInterStageShaderComponents
+        && !requiredLimits.limits.maxComputeWorkgroupStorageSize
+        && !requiredLimits.limits.maxComputeInvocationsPerWorkgroup
+        && !requiredLimits.limits.maxComputeWorkgroupSizeX
+        && !requiredLimits.limits.maxComputeWorkgroupSizeY
+        && !requiredLimits.limits.maxComputeWorkgroupSizeZ
+        && !requiredLimits.limits.maxComputeWorkgroupsPerDimension;
+}
+
 void Adapter::requestDevice(const WGPUDeviceDescriptor* descriptor, WTF::Function<void(WGPURequestDeviceStatus, RefPtr<Device>&&, const char*)>&& callback)
 {
-    UNUSED_PARAM(descriptor);
-    UNUSED_PARAM(callback);
+    if (descriptor->nextInChain) {
+        callback(WGPURequestDeviceStatus_Error, nullptr, "Unknown descriptor type");
+        return;
+    }
+
+    if (descriptor->requiredFeaturesCount) {
+        callback(WGPURequestDeviceStatus_Error, nullptr, "Device does not support requested features");
+        return;
+    }
+
+    if (descriptor->requiredLimits && !deviceMeetsRequiredLimits(m_device, *descriptor->requiredLimits)) {
+        callback(WGPURequestDeviceStatus_Error, nullptr, "Device does not support requested limits");
+        return;
+    }
+
+    // See the comment in Device::setLabel() about why we're not setting the label here.
+
+    callback(WGPURequestDeviceStatus_Success, Device::create(m_device), nullptr);
 }
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/Device.h (290261 => 290262)


--- trunk/Source/WebGPU/WebGPU/Device.h	2022-02-21 20:42:43 UTC (rev 290261)
+++ trunk/Source/WebGPU/WebGPU/Device.h	2022-02-21 20:49:00 UTC (rev 290262)
@@ -83,9 +83,10 @@
     void setLabel(const char*);
 
 private:
-    Device(id <MTLDevice>);
+    Device(id <MTLDevice>, Ref<Queue>&&);
 
     id <MTLDevice> m_device { nil };
+    Ref<Queue> m_defaultQueue;
 };
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/Device.mm (290261 => 290262)


--- trunk/Source/WebGPU/WebGPU/Device.mm	2022-02-21 20:42:43 UTC (rev 290261)
+++ trunk/Source/WebGPU/WebGPU/Device.mm	2022-02-21 20:49:00 UTC (rev 290262)
@@ -47,13 +47,18 @@
 
 RefPtr<Device> Device::create(id <MTLDevice> device)
 {
-    return adoptRef(*new Device(device));
+    id <MTLCommandQueue> commandQueue = [device newCommandQueue];
+    if (!commandQueue)
+        return nullptr;
+    auto queue = Queue::create(commandQueue);
+
+    return adoptRef(*new Device(device, WTFMove(queue)));
 }
 
-Device::Device(id <MTLDevice> device)
+Device::Device(id <MTLDevice> device, Ref<Queue>&& queue)
     : m_device(device)
+    , m_defaultQueue(WTFMove(queue))
 {
-    UNUSED_VARIABLE(m_device);
 }
 
 Device::~Device() = default;
@@ -60,33 +65,39 @@
 
 void Device::destroy()
 {
+    // FIXME: Implement this.
 }
 
-size_t Device::enumerateFeatures(WGPUFeatureName* features)
+size_t Device::enumerateFeatures(WGPUFeatureName*)
 {
-    UNUSED_PARAM(features);
+    // We support no optional features right now.
     return 0;
 }
 
 bool Device::getLimits(WGPUSupportedLimits* limits)
 {
-    UNUSED_PARAM(limits);
-    return false;
+    if (limits->nextInChain != nullptr)
+        return false;
+
+    // FIXME: Implement this.
+    limits->limits = { };
+    return true;
 }
 
 RefPtr<Queue> Device::getQueue()
 {
-    return Queue::create(nil);
+    return m_defaultQueue.copyRef();
 }
 
-bool Device::hasFeature(WGPUFeatureName feature)
+bool Device::hasFeature(WGPUFeatureName)
 {
-    UNUSED_PARAM(feature);
+    // We support no optional features right now.
     return false;
 }
 
 bool Device::popErrorScope(WTF::Function<void(WGPUErrorType, const char*)>&& callback)
 {
+    // FIXME: Implement this.
     UNUSED_PARAM(callback);
     return false;
 }
@@ -93,22 +104,25 @@
 
 void Device::pushErrorScope(WGPUErrorFilter filter)
 {
+    // FIXME: Implement this.
     UNUSED_PARAM(filter);
 }
 
 void Device::setDeviceLostCallback(WTF::Function<void(WGPUDeviceLostReason, const char*)>&& callback)
 {
+    // FIXME: Implement this.
     UNUSED_PARAM(callback);
 }
 
 void Device::setUncapturedErrorCallback(WTF::Function<void(WGPUErrorType, const char*)>&& callback)
 {
+    // FIXME: Implement this.
     UNUSED_PARAM(callback);
 }
 
-void Device::setLabel(const char* label)
+void Device::setLabel(const char*)
 {
-    UNUSED_PARAM(label);
+    // Because MTLDevices are process-global, we can't set the label on it, because 2 contexts' labels would fight each other.
 }
 
 } // namespace WebGPU

Modified: trunk/Source/WebGPU/WebGPU/Instance.mm (290261 => 290262)


--- trunk/Source/WebGPU/WebGPU/Instance.mm	2022-02-21 20:42:43 UTC (rev 290261)
+++ trunk/Source/WebGPU/WebGPU/Instance.mm	2022-02-21 20:49:00 UTC (rev 290262)
@@ -74,11 +74,74 @@
     } while (result);
 }
 
+static NSArray<id <MTLDevice>> *sortedDevices(NSArray<id <MTLDevice>> *devices, WGPUPowerPreference powerPreference)
+{
+    switch (powerPreference) {
+    case WGPUPowerPreference_Undefined:
+        return devices;
+    case WGPUPowerPreference_LowPower:
+        return [devices sortedArrayWithOptions:NSSortStable usingComparator:^NSComparisonResult (id <MTLDevice> obj1, id <MTLDevice> obj2)
+        {
+            if (obj1.lowPower == obj2.lowPower)
+                return NSOrderedSame;
+            if (obj1.lowPower)
+                return NSOrderedAscending;
+            return NSOrderedDescending;
+        }];
+    case WGPUPowerPreference_HighPerformance:
+        return [devices sortedArrayWithOptions:NSSortStable usingComparator:^NSComparisonResult (id <MTLDevice> obj1, id <MTLDevice> obj2)
+        {
+            if (obj1.lowPower == obj2.lowPower)
+                return NSOrderedSame;
+            if (obj1.lowPower)
+                return NSOrderedDescending;
+            return NSOrderedAscending;
+        }];
+    default:
+        return nil;
+    }
+}
+
 void Instance::requestAdapter(const WGPURequestAdapterOptions* options, WTF::Function<void(WGPURequestAdapterStatus, RefPtr<Adapter>&&, const char*)>&& callback)
 {
-    UNUSED_PARAM(options);
-    UNUSED_PARAM(callback);
-    callback(WGPURequestAdapterStatus_Unavailable, Adapter::create(nil), "Adapter");
+#if PLATFORM(MAC) || PLATFORM(MACCATALYST)
+    NSArray<id <MTLDevice>> *devices = MTLCopyAllDevices();
+#else
+    NSArray<id <MTLDevice>> *devices = [NSArray array];
+    if (id <MTLDevice> device = MTLCreateSystemDefaultDevice())
+        [devices append:device];
+#endif
+
+    // FIXME: Deal with options->compatibleSurface.
+
+    auto sortedDevices = WebGPU::sortedDevices(devices, options->powerPreference);
+
+    if (options->nextInChain) {
+        callback(WGPURequestAdapterStatus_Error, nullptr, "Unknown descriptor type");
+        return;
+    }
+
+    if (options->forceFallbackAdapter) {
+        callback(WGPURequestAdapterStatus_Unavailable, nullptr, "No adapters present");
+        return;
+    }
+
+    if (!sortedDevices) {
+        callback(WGPURequestAdapterStatus_Error, nullptr, "Unknown power preference");
+        return;
+    }
+
+    if (!sortedDevices.count) {
+        callback(WGPURequestAdapterStatus_Unavailable, nullptr, "No adapters present");
+        return;
+    }
+
+    if (!sortedDevices[0]) {
+        callback(WGPURequestAdapterStatus_Error, nullptr, "Adapter is internally null");
+        return;
+    }
+
+    callback(WGPURequestAdapterStatus_Success, Adapter::create(sortedDevices[0]), nullptr);
 }
 
 } // namespace WebGPU
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to