• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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_VULKAN_DEVICEVK_H_
16 #define DAWNNATIVE_VULKAN_DEVICEVK_H_
17 
18 #include "dawn_native/dawn_platform.h"
19 
20 #include "common/SerialQueue.h"
21 #include "dawn_native/Commands.h"
22 #include "dawn_native/Device.h"
23 #include "dawn_native/vulkan/CommandRecordingContext.h"
24 #include "dawn_native/vulkan/DescriptorSetAllocator.h"
25 #include "dawn_native/vulkan/Forward.h"
26 #include "dawn_native/vulkan/VulkanFunctions.h"
27 #include "dawn_native/vulkan/VulkanInfo.h"
28 
29 #include "dawn_native/vulkan/external_memory/MemoryService.h"
30 #include "dawn_native/vulkan/external_semaphore/SemaphoreService.h"
31 
32 #include <memory>
33 #include <queue>
34 
35 namespace dawn_native { namespace vulkan {
36 
37     class Adapter;
38     class BindGroupLayout;
39     class BufferUploader;
40     class FencedDeleter;
41     class RenderPassCache;
42     class ResourceMemoryAllocator;
43 
44     class Device final : public DeviceBase {
45       public:
46         static ResultOrError<Device*> Create(Adapter* adapter,
47                                              const DawnDeviceDescriptor* descriptor);
48         ~Device() override;
49 
50         MaybeError Initialize();
51 
52         // Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo.
53         const VulkanFunctions fn;
54 
55         VkInstance GetVkInstance() const;
56         const VulkanDeviceInfo& GetDeviceInfo() const;
57         const VulkanGlobalInfo& GetGlobalInfo() const;
58         VkDevice GetVkDevice() const;
59         uint32_t GetGraphicsQueueFamily() const;
60         VkQueue GetQueue() const;
61 
62         FencedDeleter* GetFencedDeleter() const;
63         RenderPassCache* GetRenderPassCache() const;
64         ResourceMemoryAllocator* GetResourceMemoryAllocator() const;
65 
66         CommandRecordingContext* GetPendingRecordingContext();
67         MaybeError SubmitPendingCommands();
68 
69         void EnqueueDeferredDeallocation(DescriptorSetAllocator* allocator);
70 
71         // Dawn Native API
72 
73         TextureBase* CreateTextureWrappingVulkanImage(
74             const ExternalImageDescriptorVk* descriptor,
75             ExternalMemoryHandle memoryHandle,
76             const std::vector<ExternalSemaphoreHandle>& waitHandles);
77         bool SignalAndExportExternalTexture(Texture* texture,
78                                             VkImageLayout desiredLayout,
79                                             ExternalImageExportInfoVk* info,
80                                             std::vector<ExternalSemaphoreHandle>* semaphoreHandle);
81 
82         ResultOrError<Ref<CommandBufferBase>> CreateCommandBuffer(
83             CommandEncoder* encoder,
84             const CommandBufferDescriptor* descriptor) override;
85 
86         MaybeError TickImpl() override;
87 
88         ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
89         MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
90                                            uint64_t sourceOffset,
91                                            BufferBase* destination,
92                                            uint64_t destinationOffset,
93                                            uint64_t size) override;
94         MaybeError CopyFromStagingToTexture(const StagingBufferBase* source,
95                                             const TextureDataLayout& src,
96                                             TextureCopy* dst,
97                                             const Extent3D& copySizePixels) override;
98 
99         // Return the fixed subgroup size to use for compute shaders on this device or 0 if none
100         // needs to be set.
101         uint32_t GetComputeSubgroupSize() const;
102 
103         uint32_t GetOptimalBytesPerRowAlignment() const override;
104         uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override;
105 
106         float GetTimestampPeriodInNS() const override;
107 
108       private:
109         Device(Adapter* adapter, const DawnDeviceDescriptor* descriptor);
110 
111         ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl(
112             const BindGroupDescriptor* descriptor) override;
113         ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl(
114             const BindGroupLayoutDescriptor* descriptor,
115             PipelineCompatibilityToken pipelineCompatibilityToken) override;
116         ResultOrError<Ref<BufferBase>> CreateBufferImpl(
117             const BufferDescriptor* descriptor) override;
118         ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutImpl(
119             const PipelineLayoutDescriptor* descriptor) override;
120         ResultOrError<Ref<QuerySetBase>> CreateQuerySetImpl(
121             const QuerySetDescriptor* descriptor) override;
122         ResultOrError<Ref<SamplerBase>> CreateSamplerImpl(
123             const SamplerDescriptor* descriptor) override;
124         ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl(
125             const ShaderModuleDescriptor* descriptor,
126             ShaderModuleParseResult* parseResult) override;
127         ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl(
128             const SwapChainDescriptor* descriptor) override;
129         ResultOrError<Ref<NewSwapChainBase>> CreateSwapChainImpl(
130             Surface* surface,
131             NewSwapChainBase* previousSwapChain,
132             const SwapChainDescriptor* descriptor) override;
133         ResultOrError<Ref<TextureBase>> CreateTextureImpl(
134             const TextureDescriptor* descriptor) override;
135         ResultOrError<Ref<TextureViewBase>> CreateTextureViewImpl(
136             TextureBase* texture,
137             const TextureViewDescriptor* descriptor) override;
138         Ref<ComputePipelineBase> CreateUninitializedComputePipelineImpl(
139             const ComputePipelineDescriptor* descriptor) override;
140         Ref<RenderPipelineBase> CreateUninitializedRenderPipelineImpl(
141             const RenderPipelineDescriptor* descriptor) override;
142         void InitializeComputePipelineAsyncImpl(Ref<ComputePipelineBase> computePipeline,
143                                                 WGPUCreateComputePipelineAsyncCallback callback,
144                                                 void* userdata) override;
145         void InitializeRenderPipelineAsyncImpl(Ref<RenderPipelineBase> renderPipeline,
146                                                WGPUCreateRenderPipelineAsyncCallback callback,
147                                                void* userdata) override;
148 
149         ResultOrError<VulkanDeviceKnobs> CreateDevice(VkPhysicalDevice physicalDevice);
150         void GatherQueueFromDevice();
151 
152         uint32_t FindComputeSubgroupSize() const;
153         void InitTogglesFromDriver();
154         void ApplyDepth24PlusS8Toggle();
155 
156         void DestroyImpl() override;
157         MaybeError WaitForIdleForDestruction() override;
158 
159         // To make it easier to use fn it is a public const member. However
160         // the Device is allowed to mutate them through these private methods.
161         VulkanFunctions* GetMutableFunctions();
162 
163         VulkanDeviceInfo mDeviceInfo = {};
164         VkDevice mVkDevice = VK_NULL_HANDLE;
165         uint32_t mQueueFamily = 0;
166         VkQueue mQueue = VK_NULL_HANDLE;
167         uint32_t mComputeSubgroupSize = 0;
168 
169         SerialQueue<ExecutionSerial, Ref<DescriptorSetAllocator>>
170             mDescriptorAllocatorsPendingDeallocation;
171         std::unique_ptr<FencedDeleter> mDeleter;
172         std::unique_ptr<ResourceMemoryAllocator> mResourceMemoryAllocator;
173         std::unique_ptr<RenderPassCache> mRenderPassCache;
174 
175         std::unique_ptr<external_memory::Service> mExternalMemoryService;
176         std::unique_ptr<external_semaphore::Service> mExternalSemaphoreService;
177 
178         ResultOrError<VkFence> GetUnusedFence();
179         ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials() override;
180 
181         // We track which operations are in flight on the GPU with an increasing serial.
182         // This works only because we have a single queue. Each submit to a queue is associated
183         // to a serial and a fence, such that when the fence is "ready" we know the operations
184         // have finished.
185         std::queue<std::pair<VkFence, ExecutionSerial>> mFencesInFlight;
186         // Fences in the unused list aren't reset yet.
187         std::vector<VkFence> mUnusedFences;
188 
189         MaybeError PrepareRecordingContext();
190         void RecycleCompletedCommands();
191 
192         struct CommandPoolAndBuffer {
193             VkCommandPool pool = VK_NULL_HANDLE;
194             VkCommandBuffer commandBuffer = VK_NULL_HANDLE;
195         };
196         SerialQueue<ExecutionSerial, CommandPoolAndBuffer> mCommandsInFlight;
197         // Command pools in the unused list haven't been reset yet.
198         std::vector<CommandPoolAndBuffer> mUnusedCommands;
199         // There is always a valid recording context stored in mRecordingContext
200         CommandRecordingContext mRecordingContext;
201 
202         MaybeError ImportExternalImage(const ExternalImageDescriptorVk* descriptor,
203                                        ExternalMemoryHandle memoryHandle,
204                                        VkImage image,
205                                        const std::vector<ExternalSemaphoreHandle>& waitHandles,
206                                        VkSemaphore* outSignalSemaphore,
207                                        VkDeviceMemory* outAllocation,
208                                        std::vector<VkSemaphore>* outWaitSemaphores);
209     };
210 
211 }}  // namespace dawn_native::vulkan
212 
213 #endif  // DAWNNATIVE_VULKAN_DEVICEVK_H_
214