| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #include <functional> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #define VULKAN_HPP_NAMESPACE vkhpp |
| #define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 |
| #define VULKAN_HPP_ENABLE_DYNAMIC_LOADER_TOOL 1 |
| #define VULKAN_HPP_NO_CONSTRUCTORS |
| #define VULKAN_HPP_NO_EXCEPTIONS |
| #define VULKAN_HPP_ASSERT_ON_RESULT |
| #include <vulkan/vulkan_raii.hpp> |
| #include <vulkan/vulkan_to_string.hpp> |
| |
| #include "Expected.h" |
| |
| namespace gfxstream { |
| |
| #define VK_EXPECT(x) \ |
| ({ \ |
| auto expected = (x); \ |
| if (!expected.ok()) { \ |
| return gfxstream::unexpected(expected.error()); \ |
| }; \ |
| std::move(expected.value()); \ |
| }) |
| |
| #define VK_EXPECT_RESULT(x) \ |
| do { \ |
| vkhpp::Result result = (x); \ |
| if (result != vkhpp::Result::eSuccess) { \ |
| return gfxstream::unexpected(result); \ |
| } \ |
| } while (0); |
| |
| #define VK_EXPECT_RV(x) \ |
| ({ \ |
| auto vkhpp_rv = (x); \ |
| if (vkhpp_rv.result != vkhpp::Result::eSuccess) { \ |
| return gfxstream::unexpected(vkhpp_rv.result); \ |
| }; \ |
| std::move(vkhpp_rv.value); \ |
| }) |
| |
| #define VK_EXPECT_RV_OR_STRING(x) \ |
| ({ \ |
| auto vkhpp_rv = (x); \ |
| if (vkhpp_rv.result != vkhpp::Result::eSuccess) { \ |
| return gfxstream::unexpected( \ |
| std::string("Failed to " #x ": ") + \ |
| vkhpp::to_string(vkhpp_rv.result)); \ |
| }; \ |
| std::move(vkhpp_rv.value); \ |
| }) |
| |
| #define VK_TRY(x) \ |
| do { \ |
| vkhpp::Result result = (x); \ |
| if (result != vkhpp::Result::eSuccess) { \ |
| return result; \ |
| } \ |
| } while (0); |
| |
| #define VK_TRY_RV(x) \ |
| ({ \ |
| auto vkhpp_rv = (x); \ |
| if (vkhpp_rv.result != vkhpp::Result::eSuccess) { \ |
| return vkhpp_rv.result; \ |
| }; \ |
| std::move(vkhpp_rv.value); \ |
| }) |
| |
| class Vk { |
| public: |
| static gfxstream::expected<Vk, vkhpp::Result> Load( |
| const std::vector<std::string>& instance_extensions = {}, |
| const std::vector<std::string>& instance_layers = {}, |
| const std::vector<std::string>& device_extensions = {}); |
| |
| Vk(const Vk&) = delete; |
| Vk& operator=(const Vk&) = delete; |
| |
| Vk(Vk&&) = default; |
| Vk& operator=(Vk&&) = default; |
| |
| struct BufferWithMemory { |
| vkhpp::UniqueBuffer buffer; |
| vkhpp::UniqueDeviceMemory bufferMemory; |
| }; |
| gfxstream::expected<BufferWithMemory, vkhpp::Result> CreateBuffer( |
| vkhpp::DeviceSize buffer_size, |
| vkhpp::BufferUsageFlags buffer_usages, |
| vkhpp::MemoryPropertyFlags buffer_memory_properties); |
| gfxstream::expected<BufferWithMemory, vkhpp::Result> CreateBufferWithData( |
| vkhpp::DeviceSize buffer_size, |
| vkhpp::BufferUsageFlags buffer_usages, |
| vkhpp::MemoryPropertyFlags buffer_memory_properties, |
| const uint8_t* buffer_data); |
| |
| vkhpp::Result DoCommandsImmediate( |
| const std::function<vkhpp::Result(vkhpp::UniqueCommandBuffer&)>& func, |
| const std::vector<vkhpp::UniqueSemaphore>& semaphores_wait = {}, |
| const std::vector<vkhpp::UniqueSemaphore>& semaphores_signal = {}); |
| |
| struct ImageWithMemory { |
| vkhpp::UniqueImage image; |
| vkhpp::UniqueDeviceMemory imageMemory; |
| vkhpp::UniqueImageView imageView; |
| }; |
| gfxstream::expected<ImageWithMemory, vkhpp::Result> CreateImage( |
| uint32_t width, |
| uint32_t height, |
| vkhpp::Format format, |
| vkhpp::ImageUsageFlags usages, |
| vkhpp::MemoryPropertyFlags memory_properties, |
| vkhpp::ImageLayout returned_layout); |
| |
| gfxstream::expected<std::vector<uint8_t>, vkhpp::Result> DownloadImage( |
| uint32_t width, |
| uint32_t height, |
| const vkhpp::UniqueImage& image, |
| vkhpp::ImageLayout current_layout, |
| vkhpp::ImageLayout returned_layout); |
| |
| struct YuvImageWithMemory { |
| vkhpp::UniqueSamplerYcbcrConversion imageSamplerConversion; |
| vkhpp::UniqueSampler imageSampler; |
| vkhpp::UniqueDeviceMemory imageMemory; |
| vkhpp::UniqueImage image; |
| vkhpp::UniqueImageView imageView; |
| }; |
| gfxstream::expected<YuvImageWithMemory, vkhpp::Result> CreateYuvImage( |
| uint32_t width, |
| uint32_t height, |
| vkhpp::ImageUsageFlags usages, |
| vkhpp::MemoryPropertyFlags memory_properties, |
| vkhpp::ImageLayout returned_layout); |
| |
| vkhpp::Result LoadYuvImage(const vkhpp::UniqueImage& image, |
| uint32_t width, |
| uint32_t height, |
| const std::vector<uint8_t>& image_data_y, |
| const std::vector<uint8_t>& image_data_u, |
| const std::vector<uint8_t>& image_data_v, |
| vkhpp::ImageLayout current_layout, |
| vkhpp::ImageLayout returned_layout); |
| |
| struct FramebufferWithAttachments { |
| std::optional<ImageWithMemory> colorAttachment; |
| std::optional<ImageWithMemory> depthAttachment; |
| vkhpp::UniqueRenderPass renderpass; |
| vkhpp::UniqueFramebuffer framebuffer; |
| }; |
| gfxstream::expected<FramebufferWithAttachments, vkhpp::Result> CreateFramebuffer( |
| uint32_t width, |
| uint32_t height, |
| vkhpp::Format colorAttachmentFormat = vkhpp::Format::eUndefined, |
| vkhpp::Format depthAttachmentFormat = vkhpp::Format::eUndefined); |
| |
| vkhpp::Instance& instance() { return *mInstance; } |
| |
| vkhpp::Device& device() { return *mDevice; } |
| |
| private: |
| Vk(vkhpp::DynamicLoader loader, |
| vkhpp::UniqueInstance instance, |
| std::optional<vkhpp::UniqueDebugUtilsMessengerEXT> debug, |
| vkhpp::PhysicalDevice physical_device, |
| vkhpp::UniqueDevice device, |
| vkhpp::Queue queue, |
| uint32_t queue_family_index, |
| vkhpp::UniqueCommandPool command_pool, |
| vkhpp::UniqueBuffer stagingBuffer, |
| vkhpp::UniqueDeviceMemory stagingBufferMemory) |
| : mLoader(std::move(loader)), |
| mInstance(std::move(instance)), |
| mDebugMessenger(std::move(debug)), |
| mPhysicalDevice(std::move(physical_device)), |
| mDevice(std::move(device)), |
| mQueue(std::move(queue)), |
| mQueueFamilyIndex(queue_family_index), |
| mCommandPool(std::move(command_pool)), |
| mStagingBuffer(std::move(stagingBuffer)), |
| mStagingBufferMemory(std::move(stagingBufferMemory)) {} |
| |
| // Note: order is important for destruction. |
| vkhpp::DynamicLoader mLoader; |
| vkhpp::UniqueInstance mInstance; |
| std::optional<vkhpp::UniqueDebugUtilsMessengerEXT> mDebugMessenger; |
| vkhpp::PhysicalDevice mPhysicalDevice; |
| vkhpp::UniqueDevice mDevice; |
| vkhpp::Queue mQueue; |
| uint32_t mQueueFamilyIndex; |
| vkhpp::UniqueCommandPool mCommandPool; |
| static constexpr const VkDeviceSize kStagingBufferSize = 32 * 1024 * 1024; |
| vkhpp::UniqueBuffer mStagingBuffer; |
| vkhpp::UniqueDeviceMemory mStagingBufferMemory; |
| }; |
| |
| } // namespace cuttlefish |