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