Commit 22ebce39 authored by Erich Gubler's avatar Erich Gubler
Browse files

Bug 1653164: feat(webgpu): show `wgpu*` fields for WebGPU adapters in...

Bug 1653164: feat(webgpu): show `wgpu*` fields for WebGPU adapters in `about:support` r=webgpu-reviewers,webidl,saschanaz,jgilbert

Differential Revision: https://phabricator.services.mozilla.com/D177402
parent 99bc4b23
Loading
Loading
Loading
Loading
+81 −12
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/WebGPUBinding.h"
#include "Adapter.h"

@@ -22,6 +23,73 @@ bool AdapterInfo::WrapObject(JSContext* const cx,
  return dom::GPUAdapterInfo_Binding::Wrap(cx, this, givenProto, reflector);
}

void AdapterInfo::GetWgpuName(nsString& s) const {
  s = mAboutSupportInfo->name;
}

size_t AdapterInfo::WgpuVendor() const { return mAboutSupportInfo->vendor; }

size_t AdapterInfo::WgpuDevice() const { return mAboutSupportInfo->device; }

void AdapterInfo::GetWgpuDeviceType(nsString& s) const {
  switch (mAboutSupportInfo->device_type) {
    case ffi::WGPUDeviceType_Cpu:
      s.AssignLiteral("Cpu");
      return;
    case ffi::WGPUDeviceType_DiscreteGpu:
      s.AssignLiteral("DiscreteGpu");
      return;
    case ffi::WGPUDeviceType_IntegratedGpu:
      s.AssignLiteral("IntegratedGpu");
      return;
    case ffi::WGPUDeviceType_VirtualGpu:
      s.AssignLiteral("VirtualGpu");
      return;
    case ffi::WGPUDeviceType_Other:
      s.AssignLiteral("Other");
      return;
    case ffi::WGPUDeviceType_Sentinel:
      break;
  }
  MOZ_CRASH("Bad `ffi::WGPUDeviceType`");
}

void AdapterInfo::GetWgpuDriver(nsString& s) const {
  s = mAboutSupportInfo->driver;
}

void AdapterInfo::GetWgpuDriverInfo(nsString& s) const {
  s = mAboutSupportInfo->driver_info;
}

void AdapterInfo::GetWgpuBackend(nsString& s) const {
  switch (mAboutSupportInfo->backend) {
    case ffi::WGPUBackend_Empty:
      s.AssignLiteral("Empty");
      return;
    case ffi::WGPUBackend_Vulkan:
      s.AssignLiteral("Vulkan");
      return;
    case ffi::WGPUBackend_Metal:
      s.AssignLiteral("Metal");
      return;
    case ffi::WGPUBackend_Dx12:
      s.AssignLiteral("Dx12");
      return;
    case ffi::WGPUBackend_Dx11:
      s.AssignLiteral("Dx11");
      return;
    case ffi::WGPUBackend_Gl:
      s.AssignLiteral("Gl");
      return;
    case ffi::WGPUBackend_BrowserWebGpu:  // This should never happen, because
                                          // we _are_ the browser.
    case ffi::WGPUBackend_Sentinel:
      break;
  }
  MOZ_CRASH("Bad `ffi::WGPUBackend`");
}

// -

GPU_IMPL_CYCLE_COLLECTION(Adapter, mParent, mBridge, mFeatures, mLimits)
@@ -51,29 +119,29 @@ Maybe<uint32_t> Adapter::MakeFeatureBits(
}

Adapter::Adapter(Instance* const aParent, WebGPUChild* const aBridge,
                 const ffi::WGPUAdapterInformation& aInfo)
                 const std::shared_ptr<ffi::WGPUAdapterInformation>& aInfo)
    : ChildOf(aParent),
      mBridge(aBridge),
      mId(aInfo.id),
      mId(aInfo->id),
      mFeatures(new SupportedFeatures(this)),
      mLimits(
          new SupportedLimits(this, MakeUnique<ffi::WGPULimits>(aInfo.limits))),
      mIsFallbackAdapter(aInfo.ty == ffi::WGPUDeviceType_Cpu) {
      mLimits(new SupportedLimits(this,
                                  MakeUnique<ffi::WGPULimits>(aInfo->limits))),
      mInfo(aInfo) {
  ErrorResult result;  // TODO: should this come from outside
  // This list needs to match `AdapterRequestDevice`
  if (aInfo.features & WGPUFeatures_DEPTH_CLIP_CONTROL) {
  if (aInfo->features & WGPUFeatures_DEPTH_CLIP_CONTROL) {
    dom::GPUSupportedFeatures_Binding::SetlikeHelpers::Add(
        mFeatures, u"depth-clip-control"_ns, result);
  }
  if (aInfo.features & WGPUFeatures_TEXTURE_COMPRESSION_BC) {
  if (aInfo->features & WGPUFeatures_TEXTURE_COMPRESSION_BC) {
    dom::GPUSupportedFeatures_Binding::SetlikeHelpers::Add(
        mFeatures, u"texture-compression-bc"_ns, result);
  }
  if (aInfo.features & WGPUFeatures_INDIRECT_FIRST_INSTANCE) {
  if (aInfo->features & WGPUFeatures_INDIRECT_FIRST_INSTANCE) {
    dom::GPUSupportedFeatures_Binding::SetlikeHelpers::Add(
        mFeatures, u"indirect-first-instance"_ns, result);
  }
  if (aInfo.features & WGPUFeatures_DEPTH32FLOAT_STENCIL8) {
  if (aInfo->features & WGPUFeatures_DEPTH32FLOAT_STENCIL8) {
    dom::GPUSupportedFeatures_Binding::SetlikeHelpers::Add(
        mFeatures, u"depth32float-stencil8"_ns, result);
  }
@@ -90,6 +158,9 @@ void Adapter::Cleanup() {

const RefPtr<SupportedFeatures>& Adapter::Features() const { return mFeatures; }
const RefPtr<SupportedLimits>& Adapter::Limits() const { return mLimits; }
bool Adapter::IsFallbackAdapter() const {
  return mInfo->device_type == ffi::WGPUDeviceType::WGPUDeviceType_Cpu;
}

already_AddRefed<dom::Promise> Adapter::RequestDevice(
    const dom::GPUDeviceDescriptor& aDesc, ErrorResult& aRv) {
@@ -152,9 +223,7 @@ already_AddRefed<dom::Promise> Adapter::RequestAdapterInfo(
  RefPtr<dom::Promise> promise = dom::Promise::Create(GetParentObject(), aRv);
  if (!promise) return nullptr;

  auto rai = UniquePtr<AdapterInfo>{new AdapterInfo};
  // E.g. rai.mDevice = SanitizeRenderer(deviceName);

  auto rai = UniquePtr<AdapterInfo>{new AdapterInfo(mInfo)};
  promise->MaybeResolve(std::move(rai));
  return promise.forget();
}
+26 −12
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ struct GPUDeviceDescriptor;
struct GPUExtensions;
struct GPUFeatures;
enum class GPUFeatureName : uint8_t;
enum class WgpuBackend : uint8_t;
enum class WgpuDeviceType : uint8_t;
template <typename T>
class Sequence;
}  // namespace dom
@@ -35,16 +37,27 @@ struct WGPUAdapterInformation;
}  // namespace ffi

class AdapterInfo final : public dom::NonRefcountedDOMObject {
 public:
  nsString mVendor;
  nsString mArchitecture;
  nsString mDevice;
  nsString mDescription;
 private:
  const std::shared_ptr<ffi::WGPUAdapterInformation> mAboutSupportInfo;

  void GetVendor(nsString& s) const { s = mVendor; }
  void GetArchitecture(nsString& s) const { s = mArchitecture; }
  void GetDevice(nsString& s) const { s = mDevice; }
  void GetDescription(nsString& s) const { s = mDescription; }
 public:
  AdapterInfo(
      const std::shared_ptr<ffi::WGPUAdapterInformation>& aAboutSupportInfo)
      : mAboutSupportInfo(aAboutSupportInfo) {}

  void GetVendor(nsString& s) const { s = nsString(); }
  void GetArchitecture(nsString& s) const { s = nsString(); }
  void GetDevice(nsString& s) const { s = nsString(); }
  void GetDescription(nsString& s) const { s = nsString(); }

  // Non-standard field getters; see also TODO BUGZILLA LINK
  void GetWgpuName(nsString&) const;
  size_t WgpuVendor() const;
  size_t WgpuDevice() const;
  void GetWgpuDeviceType(nsString&) const;
  void GetWgpuDriver(nsString&) const;
  void GetWgpuDriverInfo(nsString&) const;
  void GetWgpuBackend(nsString&) const;

  bool WrapObject(JSContext*, JS::Handle<JSObject*>,
                  JS::MutableHandle<JSObject*>);
@@ -69,14 +82,15 @@ class Adapter final : public ObjectBase, public ChildOf<Instance> {
  // to unlink them in CC unlink.
  RefPtr<SupportedFeatures> mFeatures;
  RefPtr<SupportedLimits> mLimits;
  const bool mIsFallbackAdapter = false;

  const std::shared_ptr<ffi::WGPUAdapterInformation> mInfo;

 public:
  Adapter(Instance* const aParent, WebGPUChild* const aBridge,
          const ffi::WGPUAdapterInformation& aInfo);
          const std::shared_ptr<ffi::WGPUAdapterInformation>& aInfo);
  const RefPtr<SupportedFeatures>& Features() const;
  const RefPtr<SupportedLimits>& Limits() const;
  bool IsFallbackAdapter() const { return mIsFallbackAdapter; }
  bool IsFallbackAdapter() const;

  already_AddRefed<dom::Promise> RequestDevice(
      const dom::GPUDeviceDescriptor& aDesc, ErrorResult& aRv);
+3 −3
Original line number Diff line number Diff line
@@ -92,9 +92,9 @@ already_AddRefed<dom::Promise> Instance::RequestAdapter(
  bridge->InstanceRequestAdapter(aOptions)->Then(
      GetCurrentSerialEventTarget(), __func__,
      [promise, instance, bridge](ipc::ByteBuf aInfoBuf) {
        ffi::WGPUAdapterInformation info = {};
        ffi::wgpu_client_adapter_extract_info(ToFFI(&aInfoBuf), &info);
        MOZ_ASSERT(info.id != 0);
        auto info = std::make_shared<ffi::WGPUAdapterInformation>();
        ffi::wgpu_client_adapter_extract_info(ToFFI(&aInfoBuf), info.get());
        MOZ_ASSERT(info->id != 0);
        RefPtr<Adapter> adapter = new Adapter(instance, bridge, info);
        promise->MaybeResolve(adapter);
      },
+9 −0
Original line number Diff line number Diff line
@@ -89,6 +89,15 @@ interface GPUAdapterInfo {
    readonly attribute DOMString architecture;
    readonly attribute DOMString device;
    readonly attribute DOMString description;

    // Non-standard; see <https://bugzilla.mozilla.org/show_bug.cgi?id=1831994>.
    [ChromeOnly] readonly attribute DOMString wgpuName;
    [ChromeOnly] readonly attribute unsigned long wgpuVendor;
    [ChromeOnly] readonly attribute unsigned long wgpuDevice;
    [ChromeOnly] readonly attribute DOMString wgpuDeviceType;
    [ChromeOnly] readonly attribute DOMString wgpuDriver;
    [ChromeOnly] readonly attribute DOMString wgpuDriverInfo;
    [ChromeOnly] readonly attribute DOMString wgpuBackend;
};

[Pref="dom.webgpu.enabled",
+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ include = ["BufferUsages"]
"nsCString" = "nsCString"
"nsAString" = "nsAString"
"nsACString" = "nsACString"
"nsStringRepr" = "nsString"
"BufferDescriptor______nsACString" = "WGPUBufferDescriptor"
"CommandBufferDescriptor______nsACString" = "WGPUCommandBufferDescriptor"
"CommandEncoderDescriptor______nsACString" = "WGPUCommandEncoderDescriptor"
@@ -61,6 +62,7 @@ include = ["BufferUsages"]
# This one does not work for some reason.
"WGPUTextureDescriptor______nsACString__FfiSlice_TextureFormat" = "WGPUTextureDescriptor"
"SamplerDescriptor______nsACString" = "WGPUSamplerDescriptor"
"AdapterInformation_nsString" = "WGPUAdapterInformation"

[parse]
parse_deps = true
Loading