| // Copyright 2017 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_NULL_DEVICENULL_H_ |
| #define DAWNNATIVE_NULL_DEVICENULL_H_ |
| |
| #include "dawn_native/Adapter.h" |
| #include "dawn_native/BindGroup.h" |
| #include "dawn_native/BindGroupLayout.h" |
| #include "dawn_native/Buffer.h" |
| #include "dawn_native/CommandBuffer.h" |
| #include "dawn_native/CommandEncoder.h" |
| #include "dawn_native/ComputePipeline.h" |
| #include "dawn_native/Device.h" |
| #include "dawn_native/PipelineLayout.h" |
| #include "dawn_native/QuerySet.h" |
| #include "dawn_native/Queue.h" |
| #include "dawn_native/RenderPipeline.h" |
| #include "dawn_native/RingBufferAllocator.h" |
| #include "dawn_native/Sampler.h" |
| #include "dawn_native/ShaderModule.h" |
| #include "dawn_native/StagingBuffer.h" |
| #include "dawn_native/SwapChain.h" |
| #include "dawn_native/Texture.h" |
| #include "dawn_native/ToBackend.h" |
| #include "dawn_native/dawn_platform.h" |
| |
| namespace dawn_native { namespace null { |
| |
| class Adapter; |
| class BindGroup; |
| using BindGroupLayout = BindGroupLayoutBase; |
| class Buffer; |
| class CommandBuffer; |
| using ComputePipeline = ComputePipelineBase; |
| class Device; |
| using PipelineLayout = PipelineLayoutBase; |
| class QuerySet; |
| class Queue; |
| using RenderPipeline = RenderPipelineBase; |
| using Sampler = SamplerBase; |
| class ShaderModule; |
| class SwapChain; |
| using Texture = TextureBase; |
| using TextureView = TextureViewBase; |
| |
| struct NullBackendTraits { |
| using AdapterType = Adapter; |
| using BindGroupType = BindGroup; |
| using BindGroupLayoutType = BindGroupLayout; |
| using BufferType = Buffer; |
| using CommandBufferType = CommandBuffer; |
| using ComputePipelineType = ComputePipeline; |
| using DeviceType = Device; |
| using PipelineLayoutType = PipelineLayout; |
| using QuerySetType = QuerySet; |
| using QueueType = Queue; |
| using RenderPipelineType = RenderPipeline; |
| using SamplerType = Sampler; |
| using ShaderModuleType = ShaderModule; |
| using SwapChainType = SwapChain; |
| using TextureType = Texture; |
| using TextureViewType = TextureView; |
| }; |
| |
| template <typename T> |
| auto ToBackend(T&& common) -> decltype(ToBackendBase<NullBackendTraits>(common)) { |
| return ToBackendBase<NullBackendTraits>(common); |
| } |
| |
| struct PendingOperation { |
| virtual ~PendingOperation() = default; |
| virtual void Execute() = 0; |
| }; |
| |
| class Device : public DeviceBase { |
| public: |
| static ResultOrError<Device*> Create(Adapter* adapter, const DeviceDescriptor* descriptor); |
| ~Device() override; |
| |
| MaybeError Initialize(); |
| |
| ResultOrError<Ref<CommandBufferBase>> CreateCommandBuffer( |
| CommandEncoder* encoder, |
| const CommandBufferDescriptor* descriptor) override; |
| |
| MaybeError TickImpl() override; |
| |
| void AddPendingOperation(std::unique_ptr<PendingOperation> operation); |
| MaybeError SubmitPendingOperations(); |
| |
| ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override; |
| MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, |
| uint64_t sourceOffset, |
| BufferBase* destination, |
| uint64_t destinationOffset, |
| uint64_t size) override; |
| MaybeError CopyFromStagingToTexture(const StagingBufferBase* source, |
| const TextureDataLayout& src, |
| TextureCopy* dst, |
| const Extent3D& copySizePixels) override; |
| |
| MaybeError IncrementMemoryUsage(uint64_t bytes); |
| void DecrementMemoryUsage(uint64_t bytes); |
| |
| uint32_t GetOptimalBytesPerRowAlignment() const override; |
| uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override; |
| |
| float GetTimestampPeriodInNS() const override; |
| |
| private: |
| using DeviceBase::DeviceBase; |
| |
| ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl( |
| const BindGroupDescriptor* descriptor) override; |
| ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl( |
| const BindGroupLayoutDescriptor* descriptor) override; |
| ResultOrError<Ref<BufferBase>> CreateBufferImpl( |
| const BufferDescriptor* descriptor) override; |
| ResultOrError<Ref<ComputePipelineBase>> CreateComputePipelineImpl( |
| const ComputePipelineDescriptor* descriptor) override; |
| ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutImpl( |
| const PipelineLayoutDescriptor* descriptor) override; |
| ResultOrError<Ref<QuerySetBase>> CreateQuerySetImpl( |
| const QuerySetDescriptor* descriptor) override; |
| ResultOrError<Ref<RenderPipelineBase>> CreateRenderPipelineImpl( |
| const RenderPipelineDescriptor* descriptor) override; |
| ResultOrError<Ref<SamplerBase>> CreateSamplerImpl( |
| const SamplerDescriptor* descriptor) override; |
| ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl( |
| const ShaderModuleDescriptor* descriptor, |
| ShaderModuleParseResult* parseResult) override; |
| ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl( |
| const SwapChainDescriptor* descriptor) override; |
| ResultOrError<Ref<NewSwapChainBase>> CreateSwapChainImpl( |
| Surface* surface, |
| NewSwapChainBase* previousSwapChain, |
| const SwapChainDescriptor* descriptor) override; |
| ResultOrError<Ref<TextureBase>> CreateTextureImpl( |
| const TextureDescriptor* descriptor) override; |
| ResultOrError<Ref<TextureViewBase>> CreateTextureViewImpl( |
| TextureBase* texture, |
| const TextureViewDescriptor* descriptor) override; |
| |
| ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials() override; |
| |
| void ShutDownImpl() override; |
| MaybeError WaitForIdleForDestruction() override; |
| |
| std::vector<std::unique_ptr<PendingOperation>> mPendingOperations; |
| |
| static constexpr uint64_t kMaxMemoryUsage = 512 * 1024 * 1024; |
| size_t mMemoryUsage = 0; |
| }; |
| |
| class Adapter : public AdapterBase { |
| public: |
| Adapter(InstanceBase* instance); |
| ~Adapter() override; |
| |
| // AdapterBase Implementation |
| bool SupportsExternalImages() const override; |
| |
| // Used for the tests that intend to use an adapter without all extensions enabled. |
| void SetSupportedExtensions(const std::vector<const char*>& requiredExtensions); |
| |
| private: |
| ResultOrError<DeviceBase*> CreateDeviceImpl(const DeviceDescriptor* descriptor) override; |
| }; |
| |
| // Helper class so |BindGroup| can allocate memory for its binding data, |
| // before calling the BindGroupBase base class constructor. |
| class BindGroupDataHolder { |
| protected: |
| explicit BindGroupDataHolder(size_t size); |
| ~BindGroupDataHolder(); |
| |
| void* mBindingDataAllocation; |
| }; |
| |
| // We don't have the complexity of placement-allocation of bind group data in |
| // the Null backend. This class, keeps the binding data in a separate allocation for simplicity. |
| class BindGroup final : private BindGroupDataHolder, public BindGroupBase { |
| public: |
| BindGroup(DeviceBase* device, const BindGroupDescriptor* descriptor); |
| |
| private: |
| ~BindGroup() override = default; |
| }; |
| |
| class Buffer final : public BufferBase { |
| public: |
| Buffer(Device* device, const BufferDescriptor* descriptor); |
| |
| void CopyFromStaging(StagingBufferBase* staging, |
| uint64_t sourceOffset, |
| uint64_t destinationOffset, |
| uint64_t size); |
| |
| void DoWriteBuffer(uint64_t bufferOffset, const void* data, size_t size); |
| |
| private: |
| ~Buffer() override; |
| MaybeError MapAsyncImpl(wgpu::MapMode mode, size_t offset, size_t size) override; |
| void UnmapImpl() override; |
| void DestroyImpl() override; |
| bool IsCPUWritableAtCreation() const override; |
| MaybeError MapAtCreationImpl() override; |
| void* GetMappedPointerImpl() override; |
| |
| std::unique_ptr<uint8_t[]> mBackingData; |
| }; |
| |
| class CommandBuffer final : public CommandBufferBase { |
| public: |
| CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor); |
| }; |
| |
| class QuerySet final : public QuerySetBase { |
| public: |
| QuerySet(Device* device, const QuerySetDescriptor* descriptor); |
| |
| private: |
| ~QuerySet() override; |
| |
| void DestroyImpl() override; |
| }; |
| |
| class Queue final : public QueueBase { |
| public: |
| Queue(Device* device); |
| |
| private: |
| ~Queue() override; |
| MaybeError SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) override; |
| MaybeError WriteBufferImpl(BufferBase* buffer, |
| uint64_t bufferOffset, |
| const void* data, |
| size_t size) override; |
| }; |
| |
| class ShaderModule final : public ShaderModuleBase { |
| public: |
| using ShaderModuleBase::ShaderModuleBase; |
| |
| MaybeError Initialize(ShaderModuleParseResult* parseResult); |
| }; |
| |
| class SwapChain final : public NewSwapChainBase { |
| public: |
| static ResultOrError<Ref<SwapChain>> Create(Device* device, |
| Surface* surface, |
| NewSwapChainBase* previousSwapChain, |
| const SwapChainDescriptor* descriptor); |
| ~SwapChain() override; |
| |
| private: |
| using NewSwapChainBase::NewSwapChainBase; |
| MaybeError Initialize(NewSwapChainBase* previousSwapChain); |
| |
| Ref<Texture> mTexture; |
| |
| MaybeError PresentImpl() override; |
| ResultOrError<TextureViewBase*> GetCurrentTextureViewImpl() override; |
| void DetachFromSurfaceImpl() override; |
| }; |
| |
| class OldSwapChain final : public OldSwapChainBase { |
| public: |
| OldSwapChain(Device* device, const SwapChainDescriptor* descriptor); |
| |
| protected: |
| ~OldSwapChain() override; |
| TextureBase* GetNextTextureImpl(const TextureDescriptor* descriptor) override; |
| MaybeError OnBeforePresent(TextureViewBase*) override; |
| }; |
| |
| class NativeSwapChainImpl { |
| public: |
| using WSIContext = struct {}; |
| void Init(WSIContext* context); |
| DawnSwapChainError Configure(WGPUTextureFormat format, |
| WGPUTextureUsage, |
| uint32_t width, |
| uint32_t height); |
| DawnSwapChainError GetNextTexture(DawnSwapChainNextTexture* nextTexture); |
| DawnSwapChainError Present(); |
| wgpu::TextureFormat GetPreferredFormat() const; |
| }; |
| |
| class StagingBuffer : public StagingBufferBase { |
| public: |
| StagingBuffer(size_t size, Device* device); |
| ~StagingBuffer() override; |
| MaybeError Initialize() override; |
| |
| private: |
| Device* mDevice; |
| std::unique_ptr<uint8_t[]> mBuffer; |
| }; |
| |
| }} // namespace dawn_native::null |
| |
| #endif // DAWNNATIVE_NULL_DEVICENULL_H_ |