blob: c2371787d149fd396d519c9788feb524c04cd856 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_H_
#define SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_H_
#include <unordered_map>
#include <vector>
#include <vulkan/vk_layer.h>
#include <vulkan/vulkan.h>
#include "platform_event.h"
struct VkLayerDispatchTable_;
using VkLayerDispatchTable = struct VkLayerDispatchTable_;
struct VkLayerInstanceDispatchTable_;
using VkLayerInstanceDispatchTable = struct VkLayerInstanceDispatchTable_;
struct LayerData {
VkInstance instance = VK_NULL_HANDLE;
uint32_t instance_version = VK_API_VERSION_1_0;
std::unique_ptr<VkLayerDispatchTable> device_dispatch_table;
std::unique_ptr<VkLayerInstanceDispatchTable> instance_dispatch_table;
std::unordered_map<VkDebugUtilsMessengerEXT, VkDebugUtilsMessengerCreateInfoEXT> debug_callbacks;
PFN_vkSetDeviceLoaderData fpSetDeviceLoaderData = nullptr;
};
struct DeviceData {
bool protected_memory_supported = false;
};
namespace image_pipe_swapchain {
struct SupportedImageProperties {
std::vector<VkSurfaceFormatKHR> formats;
};
// An abstract surface that must implement CreateImage, RemoveImage, and
// PresentImage.
class ImagePipeSurface {
public:
struct ImageInfo {
VkImage image{};
VkDeviceMemory memory{};
uint32_t image_id{};
};
ImagePipeSurface() {}
virtual ~ImagePipeSurface() = default;
VkFlags SupportedUsage() {
return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT;
}
virtual bool Init() { return true; }
virtual bool CanPresentPendingImage() { return true; }
virtual bool GetSize(uint32_t* width_out, uint32_t* height_out) { return false; }
virtual bool IsLost() { return false; }
// Adds an image resource to image pipe.
virtual bool CreateImage(VkDevice device, VkLayerDispatchTable* pDisp, VkFormat format,
VkImageUsageFlags usage, VkSwapchainCreateFlagsKHR swapchain_flags,
VkExtent2D extent, uint32_t image_count,
const VkAllocationCallbacks* pAllocator,
std::vector<ImageInfo>* image_info_out) = 0;
// Removes an image resource from the pipe.
virtual void RemoveImage(uint32_t image_id) = 0;
// Enqueues the specified image for presentation.
virtual void PresentImage(uint32_t image_id,
std::vector<std::unique_ptr<PlatformEvent>> acquire_fences,
std::vector<std::unique_ptr<PlatformEvent>> release_fences,
VkQueue queue) = 0;
#if defined(VK_USE_PLATFORM_FUCHSIA)
virtual bool OnCreateSurface(VkInstance instance, VkLayerInstanceDispatchTable* dispatch_table,
const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return true;
}
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
virtual bool OnCreateSurface(VkInstance instance, VkLayerInstanceDispatchTable* dispatch_table,
const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return true;
}
#endif
virtual void OnDestroySurface(VkInstance instance, VkLayerInstanceDispatchTable* dispatch_table,
const VkAllocationCallbacks* pAllocator) {}
virtual bool OnCreateSwapchain(VkDevice device, LayerData* device_layer_data,
const VkSwapchainCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
return true;
}
virtual void OnDestroySwapchain(VkDevice device, const VkAllocationCallbacks* pAllocator) {}
virtual SupportedImageProperties& GetSupportedImageProperties() = 0;
virtual VkResult GetPresentModes(VkPhysicalDevice physicalDevice,
VkLayerInstanceDispatchTable* dispatch_table, uint32_t* pCount,
VkPresentModeKHR* pPresentModes) {
constexpr int kPresentModeCount = 1;
constexpr VkPresentModeKHR kPresentModes[kPresentModeCount] = {VK_PRESENT_MODE_FIFO_KHR};
if (!pPresentModes) {
*pCount = kPresentModeCount;
return VK_SUCCESS;
}
VkResult result = VK_SUCCESS;
if (*pCount < kPresentModeCount) {
result = VK_INCOMPLETE;
} else {
*pCount = kPresentModeCount;
}
memcpy(pPresentModes, kPresentModes, (*pCount) * sizeof(VkPresentModeKHR));
return result;
}
protected:
uint32_t next_image_id() {
if (++next_image_id_ == 0) {
++next_image_id_;
}
return next_image_id_;
}
private:
uint32_t next_image_id_ = UINT32_MAX - 1; // Exercise rollover
};
} // namespace image_pipe_swapchain
#endif // SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_H_