// Copyright 2019 The SwiftShader Authors. All Rights Reserved. // // 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. #include #include #include class Driver; // Device provides a wrapper around a VkDevice with a number of helper functions // for common test operations. class Device { public: Device(); ~Device(); // CreateComputeDevice enumerates the physical devices, looking for a device // that supports compute. // If a compatible physical device is found, then a device is created and // assigned to out. // If a compatible physical device is not found, VK_SUCCESS will still be // returned (as there was no Vulkan error), but calling Device::IsValid() // on this device will return false. static VkResult CreateComputeDevice( Driver const *driver, VkInstance instance, std::unique_ptr &out); // IsValid returns true if the Device is initialized and can be used. bool IsValid() const; // CreateBuffer creates a new buffer with the // VK_BUFFER_USAGE_STORAGE_BUFFER_BIT usage, and // VK_SHARING_MODE_EXCLUSIVE sharing mode. VkResult CreateStorageBuffer(VkDeviceMemory memory, VkDeviceSize size, VkDeviceSize offset, VkBuffer *out) const; // DestroyBuffer destroys a VkBuffer. void DestroyBuffer(VkBuffer buffer) const; // CreateShaderModule creates a new shader module with the given SPIR-V // code. VkResult CreateShaderModule(const std::vector &spirv, VkShaderModule *out) const; // DestroyShaderModule destroys a VkShaderModule. void DestroyShaderModule(VkShaderModule shaderModule) const; // CreateDescriptorSetLayout creates a new descriptor set layout with the // given bindings. VkResult CreateDescriptorSetLayout( const std::vector &bindings, VkDescriptorSetLayout *out) const; // DestroyDescriptorSetLayout destroys a VkDescriptorSetLayout. void DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout) const; // CreatePipelineLayout creates a new single set descriptor set layout. VkResult CreatePipelineLayout(VkDescriptorSetLayout layout, VkPipelineLayout *out) const; // DestroyPipelineLayout destroys a VkPipelineLayout. void DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const; // CreateComputePipeline creates a new compute pipeline with the entry point // "main". VkResult CreateComputePipeline(VkShaderModule module, VkPipelineLayout pipelineLayout, VkPipeline *out) const; // DestroyPipeline destroys a graphics or compute pipeline. void DestroyPipeline(VkPipeline pipeline) const; // CreateStorageBufferDescriptorPool creates a new descriptor pool that can // hold descriptorCount storage buffers. VkResult CreateStorageBufferDescriptorPool(uint32_t descriptorCount, VkDescriptorPool *out) const; // DestroyDescriptorPool destroys the VkDescriptorPool. void DestroyDescriptorPool(VkDescriptorPool descriptorPool) const; // AllocateDescriptorSet allocates a single descriptor set with the given // layout from pool. VkResult AllocateDescriptorSet(VkDescriptorPool pool, VkDescriptorSetLayout layout, VkDescriptorSet *out) const; // UpdateStorageBufferDescriptorSets updates the storage buffers in // descriptorSet with the given list of VkDescriptorBufferInfos. void UpdateStorageBufferDescriptorSets(VkDescriptorSet descriptorSet, const std::vector &bufferInfos) const; // AllocateMemory allocates size bytes from a memory heap that has all the // given flag bits set. // If memory could not be allocated from any heap then // VK_ERROR_OUT_OF_DEVICE_MEMORY is returned. VkResult AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory *out) const; // FreeMemory frees the VkDeviceMemory. void FreeMemory(VkDeviceMemory memory) const; // MapMemory wraps vkMapMemory, supplying the first VkDevice parameter. VkResult MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const; // UnmapMemory wraps vkUnmapMemory, supplying the first VkDevice parameter. void UnmapMemory(VkDeviceMemory memory) const; // CreateCommandPool creates a new command pool. VkResult CreateCommandPool(VkCommandPool *out) const; // DestroyCommandPool destroys a VkCommandPool. void DestroyCommandPool(VkCommandPool commandPool) const; // AllocateCommandBuffer creates a new command buffer with a primary level. VkResult AllocateCommandBuffer(VkCommandPool pool, VkCommandBuffer *out) const; // FreeCommandBuffer frees the VkCommandBuffer. void FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer); // BeginCommandBuffer begins writing to commandBuffer. VkResult BeginCommandBuffer(VkCommandBufferUsageFlags usage, VkCommandBuffer commandBuffer) const; // QueueSubmitAndWait submits the given command buffer and waits for it to // complete. VkResult QueueSubmitAndWait(VkCommandBuffer commandBuffer) const; static VkResult GetPhysicalDevices( Driver const *driver, VkInstance instance, std::vector &out); static int GetComputeQueueFamilyIndex( Driver const *driver, VkPhysicalDevice device); private: Device(Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); static std::vector GetPhysicalDeviceQueueFamilyProperties( Driver const *driver, VkPhysicalDevice device); Driver const *driver; VkDevice device; VkPhysicalDevice physicalDevice; uint32_t queueFamilyIndex; };