• 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_DEVICE_H_
16 #define DAWNNATIVE_DEVICE_H_
17 
18 #include "common/Serial.h"
19 #include "dawn_native/Error.h"
20 #include "dawn_native/Format.h"
21 #include "dawn_native/Forward.h"
22 #include "dawn_native/ObjectBase.h"
23 #include "dawn_native/Toggles.h"
24 
25 #include "dawn_native/DawnNative.h"
26 #include "dawn_native/dawn_platform.h"
27 
28 #include <memory>
29 
30 namespace dawn_native {
31 
32     using ErrorCallback = void (*)(const char* errorMessage, void* userData);
33 
34     class AdapterBase;
35     class FenceSignalTracker;
36     class DynamicUploader;
37     class StagingBufferBase;
38 
39     class DeviceBase {
40       public:
41         DeviceBase(AdapterBase* adapter, const DeviceDescriptor* descriptor);
42         virtual ~DeviceBase();
43 
44         void HandleError(const char* message);
45 
ConsumedError(MaybeError maybeError)46         bool ConsumedError(MaybeError maybeError) {
47             if (DAWN_UNLIKELY(maybeError.IsError())) {
48                 ConsumeError(maybeError.AcquireError());
49                 return true;
50             }
51             return false;
52         }
53 
54         MaybeError ValidateObject(const ObjectBase* object) const;
55 
56         AdapterBase* GetAdapter() const;
57 
58         FenceSignalTracker* GetFenceSignalTracker() const;
59 
60         // Returns the Format corresponding to the dawn::TextureFormat or an error if the format
61         // isn't a valid dawn::TextureFormat or isn't supported by this device.
62         // The pointer returned has the same lifetime as the device.
63         ResultOrError<const Format*> GetInternalFormat(dawn::TextureFormat format) const;
64 
65         // Returns the Format corresponding to the dawn::TextureFormat and assumes the format is
66         // valid and supported.
67         // The reference returned has the same lifetime as the device.
68         const Format& GetValidInternalFormat(dawn::TextureFormat format) const;
69 
70         virtual CommandBufferBase* CreateCommandBuffer(
71             CommandEncoderBase* encoder,
72             const CommandBufferDescriptor* descriptor) = 0;
73 
74         virtual Serial GetCompletedCommandSerial() const = 0;
75         virtual Serial GetLastSubmittedCommandSerial() const = 0;
76         virtual Serial GetPendingCommandSerial() const = 0;
77         virtual void TickImpl() = 0;
78 
79         // Many Dawn objects are completely immutable once created which means that if two
80         // creations are given the same arguments, they can return the same object. Reusing
81         // objects will help make comparisons between objects by a single pointer comparison.
82         //
83         // Technically no object is immutable as they have a reference count, and an
84         // application with reference-counting issues could "see" that objects are reused.
85         // This is solved by automatic-reference counting, and also the fact that when using
86         // the client-server wire every creation will get a different proxy object, with a
87         // different reference count.
88         //
89         // When trying to create an object, we give both the descriptor and an example of what
90         // the created object will be, the "blueprint". The blueprint is just a FooBase object
91         // instead of a backend Foo object. If the blueprint doesn't match an object in the
92         // cache, then the descriptor is used to make a new object.
93         ResultOrError<BindGroupLayoutBase*> GetOrCreateBindGroupLayout(
94             const BindGroupLayoutDescriptor* descriptor);
95         void UncacheBindGroupLayout(BindGroupLayoutBase* obj);
96 
97         ResultOrError<ComputePipelineBase*> GetOrCreateComputePipeline(
98             const ComputePipelineDescriptor* descriptor);
99         void UncacheComputePipeline(ComputePipelineBase* obj);
100 
101         ResultOrError<PipelineLayoutBase*> GetOrCreatePipelineLayout(
102             const PipelineLayoutDescriptor* descriptor);
103         void UncachePipelineLayout(PipelineLayoutBase* obj);
104 
105         ResultOrError<RenderPipelineBase*> GetOrCreateRenderPipeline(
106             const RenderPipelineDescriptor* descriptor);
107         void UncacheRenderPipeline(RenderPipelineBase* obj);
108 
109         ResultOrError<SamplerBase*> GetOrCreateSampler(const SamplerDescriptor* descriptor);
110         void UncacheSampler(SamplerBase* obj);
111 
112         ResultOrError<ShaderModuleBase*> GetOrCreateShaderModule(
113             const ShaderModuleDescriptor* descriptor);
114         void UncacheShaderModule(ShaderModuleBase* obj);
115 
116         // Dawn API
117         BindGroupBase* CreateBindGroup(const BindGroupDescriptor* descriptor);
118         BindGroupLayoutBase* CreateBindGroupLayout(const BindGroupLayoutDescriptor* descriptor);
119         BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
120         DawnCreateBufferMappedResult CreateBufferMapped(const BufferDescriptor* descriptor);
121         void CreateBufferMappedAsync(const BufferDescriptor* descriptor,
122                                      dawn::BufferCreateMappedCallback callback,
123                                      void* userdata);
124         CommandEncoderBase* CreateCommandEncoder(const CommandEncoderDescriptor* descriptor);
125         ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
126         PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
127         QueueBase* CreateQueue();
128         RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor);
129         SamplerBase* CreateSampler(const SamplerDescriptor* descriptor);
130         ShaderModuleBase* CreateShaderModule(const ShaderModuleDescriptor* descriptor);
131         SwapChainBase* CreateSwapChain(const SwapChainDescriptor* descriptor);
132         TextureBase* CreateTexture(const TextureDescriptor* descriptor);
133         TextureViewBase* CreateTextureView(TextureBase* texture,
134                                            const TextureViewDescriptor* descriptor);
135 
136         void Tick();
137 
138         void SetErrorCallback(dawn::DeviceErrorCallback callback, void* userdata);
139         void Reference();
140         void Release();
141 
142         virtual ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(
143             size_t size) = 0;
144         virtual MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
145                                                    uint64_t sourceOffset,
146                                                    BufferBase* destination,
147                                                    uint64_t destinationOffset,
148                                                    uint64_t size) = 0;
149 
150         ResultOrError<DynamicUploader*> GetDynamicUploader() const;
151 
152         std::vector<const char*> GetTogglesUsed() const;
153         bool IsToggleEnabled(Toggle toggle) const;
154 
155       protected:
156         void SetToggle(Toggle toggle, bool isEnabled);
157         void ApplyToggleOverrides(const DeviceDescriptor* deviceDescriptor);
158 
159         std::unique_ptr<DynamicUploader> mDynamicUploader;
160 
161       private:
162         virtual ResultOrError<BindGroupBase*> CreateBindGroupImpl(
163             const BindGroupDescriptor* descriptor) = 0;
164         virtual ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
165             const BindGroupLayoutDescriptor* descriptor) = 0;
166         virtual ResultOrError<BufferBase*> CreateBufferImpl(const BufferDescriptor* descriptor) = 0;
167         virtual ResultOrError<ComputePipelineBase*> CreateComputePipelineImpl(
168             const ComputePipelineDescriptor* descriptor) = 0;
169         virtual ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
170             const PipelineLayoutDescriptor* descriptor) = 0;
171         virtual ResultOrError<QueueBase*> CreateQueueImpl() = 0;
172         virtual ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
173             const RenderPipelineDescriptor* descriptor) = 0;
174         virtual ResultOrError<SamplerBase*> CreateSamplerImpl(
175             const SamplerDescriptor* descriptor) = 0;
176         virtual ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
177             const ShaderModuleDescriptor* descriptor) = 0;
178         virtual ResultOrError<SwapChainBase*> CreateSwapChainImpl(
179             const SwapChainDescriptor* descriptor) = 0;
180         virtual ResultOrError<TextureBase*> CreateTextureImpl(
181             const TextureDescriptor* descriptor) = 0;
182         virtual ResultOrError<TextureViewBase*> CreateTextureViewImpl(
183             TextureBase* texture,
184             const TextureViewDescriptor* descriptor) = 0;
185 
186         MaybeError CreateBindGroupInternal(BindGroupBase** result,
187                                            const BindGroupDescriptor* descriptor);
188         MaybeError CreateBindGroupLayoutInternal(BindGroupLayoutBase** result,
189                                                  const BindGroupLayoutDescriptor* descriptor);
190         MaybeError CreateBufferInternal(BufferBase** result, const BufferDescriptor* descriptor);
191         MaybeError CreateComputePipelineInternal(ComputePipelineBase** result,
192                                                  const ComputePipelineDescriptor* descriptor);
193         MaybeError CreatePipelineLayoutInternal(PipelineLayoutBase** result,
194                                                 const PipelineLayoutDescriptor* descriptor);
195         MaybeError CreateQueueInternal(QueueBase** result);
196         MaybeError CreateRenderPipelineInternal(RenderPipelineBase** result,
197                                                 const RenderPipelineDescriptor* descriptor);
198         MaybeError CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor);
199         MaybeError CreateShaderModuleInternal(ShaderModuleBase** result,
200                                               const ShaderModuleDescriptor* descriptor);
201         MaybeError CreateSwapChainInternal(SwapChainBase** result,
202                                            const SwapChainDescriptor* descriptor);
203         MaybeError CreateTextureInternal(TextureBase** result, const TextureDescriptor* descriptor);
204         MaybeError CreateTextureViewInternal(TextureViewBase** result,
205                                              TextureBase* texture,
206                                              const TextureViewDescriptor* descriptor);
207 
208         void ConsumeError(ErrorData* error);
209         void SetDefaultToggles();
210 
211         AdapterBase* mAdapter = nullptr;
212 
213         // The object caches aren't exposed in the header as they would require a lot of
214         // additional includes.
215         struct Caches;
216         std::unique_ptr<Caches> mCaches;
217 
218         struct DeferredCreateBufferMappedAsync {
219             dawn::BufferCreateMappedCallback callback;
220             DawnBufferMapAsyncStatus status;
221             DawnCreateBufferMappedResult result;
222             void* userdata;
223         };
224 
225         std::unique_ptr<FenceSignalTracker> mFenceSignalTracker;
226         std::vector<DeferredCreateBufferMappedAsync> mDeferredCreateBufferMappedAsyncResults;
227 
228         dawn::DeviceErrorCallback mErrorCallback = nullptr;
229         void* mErrorUserdata = 0;
230         uint32_t mRefCount = 1;
231 
232         FormatTable mFormatTable;
233 
234         TogglesSet mTogglesSet;
235     };
236 
237 }  // namespace dawn_native
238 
239 #endif  // DAWNNATIVE_DEVICE_H_
240