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