text: // Copyright 2018 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 INCLUDE_DAWN_NATIVE_DAWNNATIVE_H_
  #define INCLUDE_DAWN_NATIVE_DAWNNATIVE_H_
  
  #include <string>
  #include <vector>
  
  #include "dawn/dawn_proc_table.h"
  #include "dawn/native/dawn_native_export.h"
  #include "dawn/webgpu.h"
  
  namespace dawn::platform {
  class Platform;
  }  // namespace dawn::platform
  
  namespace wgpu {
  struct AdapterProperties;
  struct DeviceDescriptor;
  }  // namespace wgpu
  
  namespace dawn::native {
  
  class InstanceBase;
  class AdapterBase;
  
  // An optional parameter of Adapter::CreateDevice() to send additional information when creating
  // a Device. For example, we can use it to enable a workaround, optimization or feature.
  struct DAWN_NATIVE_EXPORT DawnDeviceDescriptor {
      std::vector<const char*> requiredFeatures;
      std::vector<const char*> forceEnabledToggles;
      std::vector<const char*> forceDisabledToggles;
  
      const WGPURequiredLimits* requiredLimits = nullptr;
  };
  
  // A struct to record the information of a toggle. A toggle is a code path in Dawn device that
  // can be manually configured to run or not outside Dawn, including workarounds, special
  // features and optimizations.
  struct ToggleInfo {
      const char* name;
      const char* description;
      const char* url;
  };
  
  // A struct to record the information of a feature. A feature is a GPU feature that is not
  // required to be supported by all Dawn backends and can only be used when it is enabled on the
  // creation of device.
  using FeatureInfo = ToggleInfo;
  
  // An adapter is an object that represent on possibility of creating devices in the system.
  // Most of the time it will represent a combination of a physical GPU and an API. Not that the
  // same GPU can be represented by multiple adapters but on different APIs.
  //
  // The underlying Dawn adapter is owned by the Dawn instance so this class is not RAII but just
  // a reference to an underlying adapter.
  class DAWN_NATIVE_EXPORT Adapter {
    public:
      Adapter();
      // NOLINTNEXTLINE(runtime/explicit)
      Adapter(AdapterBase* impl);
      ~Adapter();
  
      Adapter(const Adapter& other);
      Adapter& operator=(const Adapter& other);
  
      // Essentially webgpu.h's wgpuAdapterGetProperties while we don't have WGPUAdapter in
      // dawn.json
      void GetProperties(wgpu::AdapterProperties* properties) const;
      void GetProperties(WGPUAdapterProperties* properties) const;
  
      std::vector<const char*> GetSupportedExtensions() const;
      std::vector<const char*> GetSupportedFeatures() const;
      WGPUDeviceProperties GetAdapterProperties() const;
      bool GetLimits(WGPUSupportedLimits* limits) const;
  
      void SetUseTieredLimits(bool useTieredLimits);
  
      // Check that the Adapter is able to support importing external images. This is necessary
      // to implement the swapchain and interop APIs in Chromium.
      bool SupportsExternalImages() const;
  
      explicit operator bool() const;
  
      // Create a device on this adapter. On an error, nullptr is returned.
      WGPUDevice CreateDevice(const DawnDeviceDescriptor* deviceDescriptor);
      WGPUDevice CreateDevice(const wgpu::DeviceDescriptor* deviceDescriptor);
      WGPUDevice CreateDevice(const WGPUDeviceDescriptor* deviceDescriptor = nullptr);
  
      void RequestDevice(const DawnDeviceDescriptor* descriptor,
                         WGPURequestDeviceCallback callback,
                         void* userdata);
      void RequestDevice(const wgpu::DeviceDescriptor* descriptor,
                         WGPURequestDeviceCallback callback,
                         void* userdata);
      void RequestDevice(const WGPUDeviceDescriptor* descriptor,
                         WGPURequestDeviceCallback callback,
                         void* userdata);
  
      // Returns the underlying WGPUAdapter object.
      WGPUAdapter Get() const;
  
      // Reset the backend device object for testing purposes.
      void ResetInternalDeviceForTesting();
  
    private:
      AdapterBase* mImpl = nullptr;
  };
  
  // Base class for options passed to Instance::DiscoverAdapters.
  struct DAWN_NATIVE_EXPORT AdapterDiscoveryOptionsBase {
    public:
      const WGPUBackendType backendType;
  
    protected:
      explicit AdapterDiscoveryOptionsBase(WGPUBackendType type);
  };
  
  enum BackendValidationLevel { Full, Partial, Disabled };
  
  // Represents a connection to dawn_native and is used for dependency injection, discovering
  // system adapters and injecting custom adapters (like a Swiftshader Vulkan adapter).
  //
  // This is an RAII class for Dawn instances and also controls the lifetime of all adapters
  // for this instance.
  class DAWN_NATIVE_EXPORT Instance {
    public:
      explicit Instance(const WGPUInstanceDescriptor* desc = nullptr);
      ~Instance();
  
      Instance(const Instance& other) = delete;
      Instance& operator=(const Instance& other) = delete;
  
      // Gather all adapters in the system that can be accessed with no special options. These
      // adapters will later be returned by GetAdapters.
      void DiscoverDefaultAdapters();
  
      // Adds adapters that can be discovered with the options provided (like a getProcAddress).
      // The backend is chosen based on the type of the options used. Returns true on success.
      bool DiscoverAdapters(const AdapterDiscoveryOptionsBase* options);
  
      // Returns all the adapters that the instance knows about.
      std::vector<Adapter> GetAdapters() const;
  
      const ToggleInfo* GetToggleInfo(const char* toggleName);
      const FeatureInfo* GetFeatureInfo(WGPUFeatureName feature);
  
      // Enables backend validation layers
      void EnableBackendValidation(bool enableBackendValidation);
      void SetBackendValidationLevel(BackendValidationLevel validationLevel);
  
      // Enable debug capture on Dawn startup
      void EnableBeginCaptureOnStartup(bool beginCaptureOnStartup);
  
      // TODO(dawn:1374) Deprecate this once it is passed via the descriptor.
      void SetPlatform(dawn::platform::Platform* platform);
  
      // Returns the underlying WGPUInstance object.
      WGPUInstance Get() const;
  
    private:
      InstanceBase* mImpl = nullptr;
  };
  
  // Backend-agnostic API for dawn_native
  DAWN_NATIVE_EXPORT const DawnProcTable& GetProcs();
  
  // Query the names of all the toggles that are enabled in device
  DAWN_NATIVE_EXPORT std::vector<const char*> GetTogglesUsed(WGPUDevice device);
  
  // Backdoor to get the number of lazy clears for testing
  DAWN_NATIVE_EXPORT size_t GetLazyClearCountForTesting(WGPUDevice device);
  
  // Backdoor to get the number of deprecation warnings for testing
  DAWN_NATIVE_EXPORT size_t GetDeprecationWarningCountForTesting(WGPUDevice device);
  
  //  Query if texture has been initialized
  DAWN_NATIVE_EXPORT bool IsTextureSubresourceInitialized(
      WGPUTexture texture,
      uint32_t baseMipLevel,
      uint32_t levelCount,
      uint32_t baseArrayLayer,
      uint32_t layerCount,
      WGPUTextureAspect aspect = WGPUTextureAspect_All);
  
  // Backdoor to get the order of the ProcMap for testing
  DAWN_NATIVE_EXPORT std::vector<const char*> GetProcMapNamesForTesting();
  
  DAWN_NATIVE_EXPORT bool DeviceTick(WGPUDevice device);
  
  // ErrorInjector functions used for testing only. Defined in dawn_native/ErrorInjector.cpp
  DAWN_NATIVE_EXPORT void EnableErrorInjector();
  DAWN_NATIVE_EXPORT void DisableErrorInjector();
  DAWN_NATIVE_EXPORT void ClearErrorInjector();
  DAWN_NATIVE_EXPORT uint64_t AcquireErrorInjectorCallCount();
  DAWN_NATIVE_EXPORT void InjectErrorAt(uint64_t index);
  
  // The different types of external images
  enum ExternalImageType {
      OpaqueFD,
      DmaBuf,
      IOSurface,
      DXGISharedHandle,
      EGLImage,
  };
  
  // Common properties of external images
  struct DAWN_NATIVE_EXPORT ExternalImageDescriptor {
    public:
      const WGPUTextureDescriptor* cTextureDescriptor;  // Must match image creation params
      bool isInitialized;  // Whether the texture is initialized on import
      ExternalImageType GetType() const;
  
    protected:
      explicit ExternalImageDescriptor(ExternalImageType type);
  
    private:
      ExternalImageType mType;
  };
  
  struct DAWN_NATIVE_EXPORT ExternalImageAccessDescriptor {
    public:
      bool isInitialized;  // Whether the texture is initialized on import
      WGPUTextureUsageFlags usage;
  };
  
  struct DAWN_NATIVE_EXPORT ExternalImageExportInfo {
    public:
      bool isInitialized;  // Whether the texture is initialized after export
      ExternalImageType GetType() const;
  
    protected:
      explicit ExternalImageExportInfo(ExternalImageType type);
  
    private:
      ExternalImageType mType;
  };
  
  DAWN_NATIVE_EXPORT const char* GetObjectLabelForTesting(void* objectHandle);
  
  DAWN_NATIVE_EXPORT uint64_t GetAllocatedSizeForTesting(WGPUBuffer buffer);
  
  DAWN_NATIVE_EXPORT bool BindGroupLayoutBindingsEqualForTesting(WGPUBindGroupLayout a,
                                                                 WGPUBindGroupLayout b);
  
  }  // namespace dawn::native
  
  // TODO(dawn:824): Remove once the deprecation period is passed.
  namespace dawn_native = dawn::native;
  
  #endif  // INCLUDE_DAWN_NATIVE_DAWNNATIVE_H_
  