• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef DAWNNATIVE_NULL_DEVICENULL_H_
16 #define DAWNNATIVE_NULL_DEVICENULL_H_
17 
18 #include "dawn_native/Adapter.h"
19 #include "dawn_native/BindGroup.h"
20 #include "dawn_native/BindGroupLayout.h"
21 #include "dawn_native/Buffer.h"
22 #include "dawn_native/CommandBuffer.h"
23 #include "dawn_native/CommandEncoder.h"
24 #include "dawn_native/ComputePipeline.h"
25 #include "dawn_native/Device.h"
26 #include "dawn_native/PipelineLayout.h"
27 #include "dawn_native/QuerySet.h"
28 #include "dawn_native/Queue.h"
29 #include "dawn_native/RenderPipeline.h"
30 #include "dawn_native/RingBufferAllocator.h"
31 #include "dawn_native/Sampler.h"
32 #include "dawn_native/ShaderModule.h"
33 #include "dawn_native/StagingBuffer.h"
34 #include "dawn_native/SwapChain.h"
35 #include "dawn_native/Texture.h"
36 #include "dawn_native/ToBackend.h"
37 #include "dawn_native/dawn_platform.h"
38 
39 namespace dawn_native { namespace null {
40 
41     class Adapter;
42     class BindGroup;
43     class BindGroupLayout;
44     class Buffer;
45     class CommandBuffer;
46     class ComputePipeline;
47     class Device;
48     using PipelineLayout = PipelineLayoutBase;
49     class QuerySet;
50     class Queue;
51     class RenderPipeline;
52     using Sampler = SamplerBase;
53     class ShaderModule;
54     class SwapChain;
55     using Texture = TextureBase;
56     using TextureView = TextureViewBase;
57 
58     struct NullBackendTraits {
59         using AdapterType = Adapter;
60         using BindGroupType = BindGroup;
61         using BindGroupLayoutType = BindGroupLayout;
62         using BufferType = Buffer;
63         using CommandBufferType = CommandBuffer;
64         using ComputePipelineType = ComputePipeline;
65         using DeviceType = Device;
66         using PipelineLayoutType = PipelineLayout;
67         using QuerySetType = QuerySet;
68         using QueueType = Queue;
69         using RenderPipelineType = RenderPipeline;
70         using SamplerType = Sampler;
71         using ShaderModuleType = ShaderModule;
72         using SwapChainType = SwapChain;
73         using TextureType = Texture;
74         using TextureViewType = TextureView;
75     };
76 
77     template <typename T>
78     auto ToBackend(T&& common) -> decltype(ToBackendBase<NullBackendTraits>(common)) {
79         return ToBackendBase<NullBackendTraits>(common);
80     }
81 
82     struct PendingOperation {
83         virtual ~PendingOperation() = default;
84         virtual void Execute() = 0;
85     };
86 
87     class Device final : public DeviceBase {
88       public:
89         static ResultOrError<Device*> Create(Adapter* adapter,
90                                              const DawnDeviceDescriptor* descriptor);
91         ~Device() override;
92 
93         MaybeError Initialize();
94 
95         ResultOrError<Ref<CommandBufferBase>> CreateCommandBuffer(
96             CommandEncoder* encoder,
97             const CommandBufferDescriptor* descriptor) override;
98 
99         MaybeError TickImpl() override;
100 
101         void AddPendingOperation(std::unique_ptr<PendingOperation> operation);
102         MaybeError SubmitPendingOperations();
103 
104         ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
105         MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
106                                            uint64_t sourceOffset,
107                                            BufferBase* destination,
108                                            uint64_t destinationOffset,
109                                            uint64_t size) override;
110         MaybeError CopyFromStagingToTexture(const StagingBufferBase* source,
111                                             const TextureDataLayout& src,
112                                             TextureCopy* dst,
113                                             const Extent3D& copySizePixels) override;
114 
115         MaybeError IncrementMemoryUsage(uint64_t bytes);
116         void DecrementMemoryUsage(uint64_t bytes);
117 
118         uint32_t GetOptimalBytesPerRowAlignment() const override;
119         uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override;
120 
121         float GetTimestampPeriodInNS() const override;
122 
123       private:
124         using DeviceBase::DeviceBase;
125 
126         ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
127             const BindGroupDescriptor* descriptor) override;
128         ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
129             const BindGroupLayoutDescriptor* descriptor,
130             PipelineCompatibilityToken pipelineCompatibilityToken) override;
131         ResultOrError<Ref<BufferBase>> CreateBufferImpl(
132             const BufferDescriptor* descriptor) override;
133         Ref<ComputePipelineBase> CreateUninitializedComputePipelineImpl(
134             const ComputePipelineDescriptor* descriptor) override;
135         ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutImpl(
136             const PipelineLayoutDescriptor* descriptor) override;
137         ResultOrError<Ref<QuerySetBase>> CreateQuerySetImpl(
138             const QuerySetDescriptor* descriptor) override;
139         Ref<RenderPipelineBase> CreateUninitializedRenderPipelineImpl(
140             const RenderPipelineDescriptor* descriptor) override;
141         ResultOrError<Ref<SamplerBase>> CreateSamplerImpl(
142             const SamplerDescriptor* descriptor) override;
143         ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
144             const ShaderModuleDescriptor* descriptor,
145             ShaderModuleParseResult* parseResult) override;
146         ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
147             const SwapChainDescriptor* descriptor) override;
148         ResultOrError<Ref<NewSwapChainBase>> CreateSwapChainImpl(
149             Surface* surface,
150             NewSwapChainBase* previousSwapChain,
151             const SwapChainDescriptor* descriptor) override;
152         ResultOrError<Ref<TextureBase>> CreateTextureImpl(
153             const TextureDescriptor* descriptor) override;
154         ResultOrError<Ref<TextureViewBase>> CreateTextureViewImpl(
155             TextureBase* texture,
156             const TextureViewDescriptor* descriptor) override;
157 
158         ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials() override;
159 
160         void DestroyImpl() override;
161         MaybeError WaitForIdleForDestruction() override;
162 
163         std::vector<std::unique_ptr<PendingOperation>> mPendingOperations;
164 
165         static constexpr uint64_t kMaxMemoryUsage = 512 * 1024 * 1024;
166         size_t mMemoryUsage = 0;
167     };
168 
169     class Adapter : public AdapterBase {
170       public:
171         Adapter(InstanceBase* instance);
172         ~Adapter() override;
173 
174         // AdapterBase Implementation
175         bool SupportsExternalImages() const override;
176 
177         // Used for the tests that intend to use an adapter without all features enabled.
178         void SetSupportedFeatures(const std::vector<const char*>& requiredFeatures);
179 
180       private:
181         MaybeError InitializeImpl() override;
182         MaybeError InitializeSupportedFeaturesImpl() override;
183         MaybeError InitializeSupportedLimitsImpl(CombinedLimits* limits) override;
184 
185         ResultOrError<DeviceBase*> CreateDeviceImpl(
186             const DawnDeviceDescriptor* descriptor) override;
187     };
188 
189     // Helper class so |BindGroup| can allocate memory for its binding data,
190     // before calling the BindGroupBase base class constructor.
191     class BindGroupDataHolder {
192       protected:
193         explicit BindGroupDataHolder(size_t size);
194         ~BindGroupDataHolder();
195 
196         void* mBindingDataAllocation;
197     };
198 
199     // We don't have the complexity of placement-allocation of bind group data in
200     // the Null backend. This class, keeps the binding data in a separate allocation for simplicity.
201     class BindGroup final : private BindGroupDataHolder, public BindGroupBase {
202       public:
203         BindGroup(DeviceBase* device, const BindGroupDescriptor* descriptor);
204 
205       private:
206         ~BindGroup() override = default;
207     };
208 
209     class BindGroupLayout final : public BindGroupLayoutBase {
210       public:
211         BindGroupLayout(DeviceBase* device,
212                         const BindGroupLayoutDescriptor* descriptor,
213                         PipelineCompatibilityToken pipelineCompatibilityToken);
214 
215       private:
216         ~BindGroupLayout() override = default;
217     };
218 
219     class Buffer final : public BufferBase {
220       public:
221         Buffer(Device* device, const BufferDescriptor* descriptor);
222 
223         void CopyFromStaging(StagingBufferBase* staging,
224                              uint64_t sourceOffset,
225                              uint64_t destinationOffset,
226                              uint64_t size);
227 
228         void DoWriteBuffer(uint64_t bufferOffset, const void* data, size_t size);
229 
230       private:
231         MaybeError MapAsyncImpl(wgpu::MapMode mode, size_t offset, size_t size) override;
232         void UnmapImpl() override;
233         void DestroyImpl() override;
234         bool IsCPUWritableAtCreation() const override;
235         MaybeError MapAtCreationImpl() override;
236         void* GetMappedPointerImpl() override;
237 
238         std::unique_ptr<uint8_t[]> mBackingData;
239     };
240 
241     class CommandBuffer final : public CommandBufferBase {
242       public:
243         CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor);
244     };
245 
246     class QuerySet final : public QuerySetBase {
247       public:
248         QuerySet(Device* device, const QuerySetDescriptor* descriptor);
249     };
250 
251     class Queue final : public QueueBase {
252       public:
253         Queue(Device* device);
254 
255       private:
256         ~Queue() override;
257         MaybeError SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) override;
258         MaybeError WriteBufferImpl(BufferBase* buffer,
259                                    uint64_t bufferOffset,
260                                    const void* data,
261                                    size_t size) override;
262     };
263 
264     class ComputePipeline final : public ComputePipelineBase {
265       public:
266         using ComputePipelineBase::ComputePipelineBase;
267 
268         MaybeError Initialize() override;
269     };
270 
271     class RenderPipeline final : public RenderPipelineBase {
272       public:
273         using RenderPipelineBase::RenderPipelineBase;
274 
275         MaybeError Initialize() override;
276     };
277 
278     class ShaderModule final : public ShaderModuleBase {
279       public:
280         using ShaderModuleBase::ShaderModuleBase;
281 
282         MaybeError Initialize(ShaderModuleParseResult* parseResult);
283     };
284 
285     class SwapChain final : public NewSwapChainBase {
286       public:
287         static ResultOrError<Ref<SwapChain>> Create(Device* device,
288                                                     Surface* surface,
289                                                     NewSwapChainBase* previousSwapChain,
290                                                     const SwapChainDescriptor* descriptor);
291         ~SwapChain() override;
292 
293       private:
294         using NewSwapChainBase::NewSwapChainBase;
295         MaybeError Initialize(NewSwapChainBase* previousSwapChain);
296 
297         Ref<Texture> mTexture;
298 
299         MaybeError PresentImpl() override;
300         ResultOrError<TextureViewBase*> GetCurrentTextureViewImpl() override;
301         void DetachFromSurfaceImpl() override;
302     };
303 
304     class OldSwapChain final : public OldSwapChainBase {
305       public:
306         OldSwapChain(Device* device, const SwapChainDescriptor* descriptor);
307 
308       protected:
309         ~OldSwapChain() override;
310         TextureBase* GetNextTextureImpl(const TextureDescriptor* descriptor) override;
311         MaybeError OnBeforePresent(TextureViewBase*) override;
312     };
313 
314     class NativeSwapChainImpl {
315       public:
316         using WSIContext = struct {};
317         void Init(WSIContext* context);
318         DawnSwapChainError Configure(WGPUTextureFormat format,
319                                      WGPUTextureUsage,
320                                      uint32_t width,
321                                      uint32_t height);
322         DawnSwapChainError GetNextTexture(DawnSwapChainNextTexture* nextTexture);
323         DawnSwapChainError Present();
324         wgpu::TextureFormat GetPreferredFormat() const;
325     };
326 
327     class StagingBuffer : public StagingBufferBase {
328       public:
329         StagingBuffer(size_t size, Device* device);
330         ~StagingBuffer() override;
331         MaybeError Initialize() override;
332 
333       private:
334         Device* mDevice;
335         std::unique_ptr<uint8_t[]> mBuffer;
336     };
337 
338 }}  // namespace dawn_native::null
339 
340 #endif  // DAWNNATIVE_NULL_DEVICENULL_H_
341