// Copyright 2018 The Dawn Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef DAWNNATIVE_VULKAN_DEVICEVK_H_ #define DAWNNATIVE_VULKAN_DEVICEVK_H_ #include "dawn_native/dawn_platform.h" #include "common/Serial.h" #include "common/SerialQueue.h" #include "dawn_native/Device.h" #include "dawn_native/vulkan/CommandRecordingContext.h" #include "dawn_native/vulkan/Forward.h" #include "dawn_native/vulkan/VulkanFunctions.h" #include "dawn_native/vulkan/VulkanInfo.h" #include "dawn_native/vulkan/external_memory/MemoryService.h" #include "dawn_native/vulkan/external_semaphore/SemaphoreService.h" #include #include namespace dawn_native { namespace vulkan { class Adapter; class BufferUploader; struct ExternalImageDescriptor; class FencedDeleter; class MapRequestTracker; class MemoryAllocator; class RenderPassCache; class Device : public DeviceBase { public: Device(Adapter* adapter, const DeviceDescriptor* descriptor); ~Device(); MaybeError Initialize(); // Contains all the Vulkan entry points, vkDoFoo is called via device->fn.DoFoo. const VulkanFunctions fn; VkInstance GetVkInstance() const; const VulkanDeviceInfo& GetDeviceInfo() const; VkDevice GetVkDevice() const; uint32_t GetGraphicsQueueFamily() const; VkQueue GetQueue() const; BufferUploader* GetBufferUploader() const; FencedDeleter* GetFencedDeleter() const; MapRequestTracker* GetMapRequestTracker() const; MemoryAllocator* GetMemoryAllocator() const; RenderPassCache* GetRenderPassCache() const; VkCommandBuffer GetPendingCommandBuffer(); CommandRecordingContext* GetPendingRecordingContext(); Serial GetPendingCommandSerial() const override; void SubmitPendingCommands(); TextureBase* CreateTextureWrappingVulkanImage( const ExternalImageDescriptor* descriptor, ExternalMemoryHandle memoryHandle, const std::vector& waitHandles); MaybeError SignalAndExportExternalTexture(Texture* texture, ExternalSemaphoreHandle* outHandle); // Dawn API CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder, const CommandBufferDescriptor* descriptor) override; Serial GetCompletedCommandSerial() const final override; Serial GetLastSubmittedCommandSerial() const final override; void TickImpl() override; ResultOrError> CreateStagingBuffer(size_t size) override; MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, uint64_t sourceOffset, BufferBase* destination, uint64_t destinationOffset, uint64_t size) override; private: ResultOrError CreateBindGroupImpl( const BindGroupDescriptor* descriptor) override; ResultOrError CreateBindGroupLayoutImpl( const BindGroupLayoutDescriptor* descriptor) override; ResultOrError CreateBufferImpl(const BufferDescriptor* descriptor) override; ResultOrError CreateComputePipelineImpl( const ComputePipelineDescriptor* descriptor) override; ResultOrError CreatePipelineLayoutImpl( const PipelineLayoutDescriptor* descriptor) override; ResultOrError CreateQueueImpl() override; ResultOrError CreateRenderPipelineImpl( const RenderPipelineDescriptor* descriptor) override; ResultOrError CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError CreateShaderModuleImpl( const ShaderModuleDescriptor* descriptor) override; ResultOrError CreateSwapChainImpl( const SwapChainDescriptor* descriptor) override; ResultOrError CreateTextureImpl(const TextureDescriptor* descriptor) override; ResultOrError CreateTextureViewImpl( TextureBase* texture, const TextureViewDescriptor* descriptor) override; ResultOrError CreateDevice(VkPhysicalDevice physicalDevice); void GatherQueueFromDevice(); // To make it easier to use fn it is a public const member. However // the Device is allowed to mutate them through these private methods. VulkanFunctions* GetMutableFunctions(); VulkanDeviceInfo mDeviceInfo = {}; VkDevice mVkDevice = VK_NULL_HANDLE; uint32_t mQueueFamily = 0; VkQueue mQueue = VK_NULL_HANDLE; std::unique_ptr mDeleter; std::unique_ptr mMapRequestTracker; std::unique_ptr mMemoryAllocator; std::unique_ptr mRenderPassCache; std::unique_ptr mExternalMemoryService; std::unique_ptr mExternalSemaphoreService; VkFence GetUnusedFence(); void CheckPassedFences(); // We track which operations are in flight on the GPU with an increasing serial. // This works only because we have a single queue. Each submit to a queue is associated // to a serial and a fence, such that when the fence is "ready" we know the operations // have finished. std::queue> mFencesInFlight; std::vector mUnusedFences; Serial mCompletedSerial = 0; Serial mLastSubmittedSerial = 0; struct CommandPoolAndBuffer { VkCommandPool pool = VK_NULL_HANDLE; VkCommandBuffer commandBuffer = VK_NULL_HANDLE; }; CommandPoolAndBuffer GetUnusedCommands(); void RecycleCompletedCommands(); void FreeCommands(CommandPoolAndBuffer* commands); SerialQueue mCommandsInFlight; std::vector mUnusedCommands; CommandPoolAndBuffer mPendingCommands; CommandRecordingContext mRecordingContext; MaybeError ImportExternalImage(const ExternalImageDescriptor* descriptor, ExternalMemoryHandle memoryHandle, const std::vector& waitHandles, VkSemaphore* outSignalSemaphore, VkDeviceMemory* outAllocation, std::vector* outWaitSemaphores); }; }} // namespace dawn_native::vulkan #endif // DAWNNATIVE_VULKAN_DEVICEVK_H_