blob: c4b850354d58ba084328efe536fbb122ed2334b5 [file] [log] [blame]
/*
* 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