1 // Copyright 2019 The SwiftShader Authors. All Rights Reserved. 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 #include <vulkan/vulkan_core.h> 16 17 #include <memory> 18 #include <vector> 19 20 class Driver; 21 22 // Device provides a wrapper around a VkDevice with a number of helper functions 23 // for common test operations. 24 class Device 25 { 26 public: 27 Device(); 28 ~Device(); 29 30 // CreateComputeDevice enumerates the physical devices, looking for a device 31 // that supports compute. 32 // If a compatible physical device is found, then a device is created and 33 // assigned to out. 34 // If a compatible physical device is not found, VK_SUCCESS will still be 35 // returned (as there was no Vulkan error), but calling Device::IsValid() 36 // on this device will return false. 37 static VkResult CreateComputeDevice( 38 const Driver *driver, VkInstance instance, std::unique_ptr<Device> &out); 39 40 // IsValid returns true if the Device is initialized and can be used. 41 bool IsValid() const; 42 43 // CreateBuffer creates a new buffer with the 44 // VK_BUFFER_USAGE_STORAGE_BUFFER_BIT usage, and 45 // VK_SHARING_MODE_EXCLUSIVE sharing mode. 46 VkResult CreateStorageBuffer(VkDeviceMemory memory, VkDeviceSize size, 47 VkDeviceSize offset, VkBuffer *out) const; 48 49 // DestroyBuffer destroys a VkBuffer. 50 void DestroyBuffer(VkBuffer buffer) const; 51 52 // CreateShaderModule creates a new shader module with the given SPIR-V 53 // code. 54 VkResult CreateShaderModule(const std::vector<uint32_t> &spirv, 55 VkShaderModule *out) const; 56 57 // DestroyShaderModule destroys a VkShaderModule. 58 void DestroyShaderModule(VkShaderModule shaderModule) const; 59 60 // CreateDescriptorSetLayout creates a new descriptor set layout with the 61 // given bindings. 62 VkResult CreateDescriptorSetLayout( 63 const std::vector<VkDescriptorSetLayoutBinding> &bindings, 64 VkDescriptorSetLayout *out) const; 65 66 // DestroyDescriptorSetLayout destroys a VkDescriptorSetLayout. 67 void DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout) const; 68 69 // CreatePipelineLayout creates a new single set descriptor set layout. 70 VkResult CreatePipelineLayout(VkDescriptorSetLayout layout, 71 VkPipelineLayout *out) const; 72 73 // DestroyPipelineLayout destroys a VkPipelineLayout. 74 void DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const; 75 76 // CreateComputePipeline creates a new compute pipeline with the entry point 77 // "main". 78 VkResult CreateComputePipeline(VkShaderModule module, 79 VkPipelineLayout pipelineLayout, 80 VkPipeline *out) const; 81 82 // DestroyPipeline destroys a graphics or compute pipeline. 83 void DestroyPipeline(VkPipeline pipeline) const; 84 85 // CreateStorageBufferDescriptorPool creates a new descriptor pool that can 86 // hold descriptorCount storage buffers. 87 VkResult CreateStorageBufferDescriptorPool(uint32_t descriptorCount, 88 VkDescriptorPool *out) const; 89 90 // DestroyDescriptorPool destroys the VkDescriptorPool. 91 void DestroyDescriptorPool(VkDescriptorPool descriptorPool) const; 92 93 // AllocateDescriptorSet allocates a single descriptor set with the given 94 // layout from pool. 95 VkResult AllocateDescriptorSet(VkDescriptorPool pool, 96 VkDescriptorSetLayout layout, 97 VkDescriptorSet *out) const; 98 99 // UpdateStorageBufferDescriptorSets updates the storage buffers in 100 // descriptorSet with the given list of VkDescriptorBufferInfos. 101 void UpdateStorageBufferDescriptorSets(VkDescriptorSet descriptorSet, 102 const std::vector<VkDescriptorBufferInfo> &bufferInfos) const; 103 104 // AllocateMemory allocates size bytes from a memory heap that has all the 105 // given flag bits set. 106 // If memory could not be allocated from any heap then 107 // VK_ERROR_OUT_OF_DEVICE_MEMORY is returned. 108 VkResult AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory *out) const; 109 110 // FreeMemory frees the VkDeviceMemory. 111 void FreeMemory(VkDeviceMemory memory) const; 112 113 // MapMemory wraps vkMapMemory, supplying the first VkDevice parameter. 114 VkResult MapMemory(VkDeviceMemory memory, VkDeviceSize offset, 115 VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const; 116 117 // UnmapMemory wraps vkUnmapMemory, supplying the first VkDevice parameter. 118 void UnmapMemory(VkDeviceMemory memory) const; 119 120 // CreateCommandPool creates a new command pool. 121 VkResult CreateCommandPool(VkCommandPool *out) const; 122 123 // DestroyCommandPool destroys a VkCommandPool. 124 void DestroyCommandPool(VkCommandPool commandPool) const; 125 126 // AllocateCommandBuffer creates a new command buffer with a primary level. 127 VkResult AllocateCommandBuffer(VkCommandPool pool, VkCommandBuffer *out) const; 128 129 // FreeCommandBuffer frees the VkCommandBuffer. 130 void FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer); 131 132 // BeginCommandBuffer begins writing to commandBuffer. 133 VkResult BeginCommandBuffer(VkCommandBufferUsageFlags usage, VkCommandBuffer commandBuffer) const; 134 135 // QueueSubmitAndWait submits the given command buffer and waits for it to 136 // complete. 137 VkResult QueueSubmitAndWait(VkCommandBuffer commandBuffer) const; 138 139 static VkResult GetPhysicalDevices( 140 const Driver *driver, VkInstance instance, 141 std::vector<VkPhysicalDevice> &out); 142 143 static int GetComputeQueueFamilyIndex( 144 const Driver *driver, VkPhysicalDevice device); 145 146 private: 147 Device(const Driver *driver, VkDevice device, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); 148 149 static std::vector<VkQueueFamilyProperties> 150 GetPhysicalDeviceQueueFamilyProperties( 151 const Driver *driver, VkPhysicalDevice device); 152 153 const Driver *driver; 154 VkDevice device; 155 VkPhysicalDevice physicalDevice; 156 uint32_t queueFamilyIndex; 157 }; 158