mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-04 06:06:17 +00:00
c/main: Refactor vk_swapchain into comp_target_swapchain
This commit is contained in:
parent
6260248d20
commit
e8360c013d
|
@ -23,10 +23,9 @@ set(MAIN_SOURCE_FILES
|
|||
main/comp_shaders.c
|
||||
main/comp_swapchain.c
|
||||
main/comp_target.h
|
||||
main/comp_vk_swapchain.c
|
||||
main/comp_vk_swapchain.h
|
||||
main/comp_target_swapchain.c
|
||||
main/comp_target_swapchain.h
|
||||
main/comp_window.h
|
||||
main/comp_window_target.c
|
||||
main/comp_layer.h
|
||||
main/comp_layer.c
|
||||
main/comp_layer_renderer.h
|
||||
|
|
508
src/xrt/compositor/main/comp_target_swapchain.c
Normal file
508
src/xrt/compositor/main/comp_target_swapchain.c
Normal file
|
@ -0,0 +1,508 @@
|
|||
// Copyright 2019-2020, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Target Vulkan swapchain code.
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util/u_misc.h"
|
||||
|
||||
#include "comp_target_swapchain.h"
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Types, defines and data.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* These formats will be 'preferred' - in future we may wish to give preference
|
||||
* to higher bit depths if they are available, but most display devices we are
|
||||
* interested in should support one these.
|
||||
*/
|
||||
static VkFormat preferred_color_formats[] = {
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_FORMAT_B8G8R8A8_UNORM,
|
||||
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Pre declare functions.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
comp_target_swapchain_create_image_views(struct comp_target_swapchain *cts);
|
||||
|
||||
static void
|
||||
comp_target_swapchain_destroy_image_views(struct comp_target_swapchain *cts);
|
||||
|
||||
static void
|
||||
comp_target_swapchain_destroy_old(struct comp_target_swapchain *cts,
|
||||
VkSwapchainKHR old);
|
||||
|
||||
static VkExtent2D
|
||||
comp_target_swapchain_select_extent(struct comp_target_swapchain *cts,
|
||||
VkSurfaceCapabilitiesKHR caps,
|
||||
uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
static bool
|
||||
_find_surface_format(struct comp_target_swapchain *cts,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceFormatKHR *format);
|
||||
|
||||
static bool
|
||||
_check_surface_present_mode(struct vk_bundle *vk,
|
||||
VkSurfaceKHR surface,
|
||||
VkPresentModeKHR present_mode);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions!
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
comp_target_swapchain_create_images(struct comp_target *ct,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
VkFormat color_format,
|
||||
VkColorSpaceKHR color_space,
|
||||
VkPresentModeKHR present_mode)
|
||||
{
|
||||
struct comp_target_swapchain *cts = (struct comp_target_swapchain *)ct;
|
||||
VkBool32 supported;
|
||||
VkResult ret;
|
||||
|
||||
// Free old image views.
|
||||
comp_target_swapchain_destroy_image_views(cts);
|
||||
|
||||
VkSwapchainKHR old_swapchain_handle = cts->swapchain.handle;
|
||||
|
||||
cts->base.num_images = 0;
|
||||
cts->swapchain.handle = VK_NULL_HANDLE;
|
||||
cts->present_mode = present_mode;
|
||||
cts->preferred.color_format = color_format;
|
||||
cts->preferred.color_space = color_space;
|
||||
|
||||
|
||||
// Sanity check.
|
||||
cts->vk->vkGetPhysicalDeviceSurfaceSupportKHR(
|
||||
cts->vk->physical_device, 0, cts->surface.handle, &supported);
|
||||
if (!supported) {
|
||||
VK_ERROR(cts->vk,
|
||||
"vkGetPhysicalDeviceSurfaceSupportKHR: "
|
||||
"surface not supported!");
|
||||
}
|
||||
|
||||
// More sanity checks.
|
||||
if (!_check_surface_present_mode(cts->vk, cts->surface.handle,
|
||||
cts->present_mode)) {
|
||||
// Free old.
|
||||
comp_target_swapchain_destroy_old(cts, old_swapchain_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the correct format.
|
||||
if (!_find_surface_format(cts, cts->surface.handle,
|
||||
&cts->surface.format)) {
|
||||
// Free old.
|
||||
comp_target_swapchain_destroy_old(cts, old_swapchain_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the caps first.
|
||||
VkSurfaceCapabilitiesKHR surface_caps;
|
||||
ret = cts->vk->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
cts->vk->physical_device, cts->surface.handle, &surface_caps);
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(cts->vk,
|
||||
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR: %s",
|
||||
vk_result_string(ret));
|
||||
|
||||
// Free old.
|
||||
comp_target_swapchain_destroy_old(cts, old_swapchain_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the extents of the swapchain.
|
||||
VkExtent2D extent = comp_target_swapchain_select_extent(
|
||||
cts, surface_caps, width, height);
|
||||
|
||||
// Create the swapchain now.
|
||||
VkSwapchainCreateInfoKHR swapchain_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
.surface = cts->surface.handle,
|
||||
.minImageCount = surface_caps.minImageCount,
|
||||
.imageFormat = cts->surface.format.format,
|
||||
.imageColorSpace = cts->surface.format.colorSpace,
|
||||
.imageExtent =
|
||||
{
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
},
|
||||
.imageArrayLayers = 1,
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
.presentMode = cts->present_mode,
|
||||
.clipped = VK_TRUE,
|
||||
.oldSwapchain = old_swapchain_handle,
|
||||
};
|
||||
|
||||
ret = cts->vk->vkCreateSwapchainKHR(cts->vk->device, &swapchain_info,
|
||||
NULL, &cts->swapchain.handle);
|
||||
|
||||
// Always destroy the old.
|
||||
comp_target_swapchain_destroy_old(cts, old_swapchain_handle);
|
||||
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(cts->vk, "vkCreateSwapchainKHR: %s",
|
||||
vk_result_string(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set target info.
|
||||
*/
|
||||
|
||||
cts->base.width = extent.width;
|
||||
cts->base.height = extent.height;
|
||||
cts->base.format = cts->surface.format.format;
|
||||
|
||||
comp_target_swapchain_create_image_views(cts);
|
||||
}
|
||||
|
||||
static VkExtent2D
|
||||
comp_target_swapchain_select_extent(struct comp_target_swapchain *cts,
|
||||
VkSurfaceCapabilitiesKHR caps,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
// If width (and height) equals the special value 0xFFFFFFFF,
|
||||
// the size of the surface will be set by the swapchain
|
||||
if (caps.currentExtent.width == (uint32_t)-1) {
|
||||
VkExtent2D extent = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
return extent;
|
||||
}
|
||||
|
||||
if (caps.currentExtent.width != width ||
|
||||
caps.currentExtent.height != height) {
|
||||
VK_DEBUG(cts->vk,
|
||||
"Using swap chain extent dimensions %dx%d instead of "
|
||||
"requested %dx%d.",
|
||||
caps.currentExtent.width, caps.currentExtent.height,
|
||||
width, height);
|
||||
}
|
||||
|
||||
return caps.currentExtent;
|
||||
}
|
||||
|
||||
static void
|
||||
comp_target_swapchain_destroy_old(struct comp_target_swapchain *cts,
|
||||
VkSwapchainKHR old)
|
||||
{
|
||||
if (old != VK_NULL_HANDLE) {
|
||||
cts->vk->vkDestroySwapchainKHR(cts->vk->device, old, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult
|
||||
comp_target_swapchain_acquire_next_image(struct comp_target *ct,
|
||||
VkSemaphore semaphore,
|
||||
uint32_t *out_index)
|
||||
{
|
||||
struct comp_target_swapchain *cts = (struct comp_target_swapchain *)ct;
|
||||
|
||||
return cts->vk->vkAcquireNextImageKHR( //
|
||||
cts->vk->device, // device
|
||||
cts->swapchain.handle, // timeout
|
||||
UINT64_MAX, // timeout
|
||||
semaphore, // semaphore
|
||||
VK_NULL_HANDLE, // fence
|
||||
out_index); // pImageIndex
|
||||
}
|
||||
|
||||
VkResult
|
||||
comp_target_swapchain_present(struct comp_target *ct,
|
||||
VkQueue queue,
|
||||
uint32_t index,
|
||||
VkSemaphore semaphore)
|
||||
{
|
||||
struct comp_target_swapchain *cts = (struct comp_target_swapchain *)ct;
|
||||
|
||||
VkPresentInfoKHR presentInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &semaphore,
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &cts->swapchain.handle,
|
||||
.pImageIndices = &index,
|
||||
};
|
||||
|
||||
return cts->vk->vkQueuePresentKHR(queue, &presentInfo);
|
||||
}
|
||||
|
||||
static bool
|
||||
_find_surface_format(struct comp_target_swapchain *cts,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceFormatKHR *format)
|
||||
{
|
||||
uint32_t num_formats;
|
||||
VkSurfaceFormatKHR *formats = NULL;
|
||||
cts->vk->vkGetPhysicalDeviceSurfaceFormatsKHR(
|
||||
cts->vk->physical_device, surface, &num_formats, NULL);
|
||||
|
||||
if (num_formats != 0) {
|
||||
formats = U_TYPED_ARRAY_CALLOC(VkSurfaceFormatKHR, num_formats);
|
||||
cts->vk->vkGetPhysicalDeviceSurfaceFormatsKHR(
|
||||
cts->vk->physical_device, surface, &num_formats, formats);
|
||||
} else {
|
||||
VK_ERROR(cts->vk, "Could not enumerate surface formats.");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkSurfaceFormatKHR *formats_for_colorspace = NULL;
|
||||
formats_for_colorspace =
|
||||
U_TYPED_ARRAY_CALLOC(VkSurfaceFormatKHR, num_formats);
|
||||
|
||||
uint32_t num_formats_cs = 0;
|
||||
uint32_t num_pref_formats = ARRAY_SIZE(preferred_color_formats);
|
||||
|
||||
// Gather formats that match our color space, we will select
|
||||
// from these in preference to others.
|
||||
|
||||
for (uint32_t i = 0; i < num_formats; i++) {
|
||||
if (formats[i].colorSpace == cts->preferred.color_space) {
|
||||
formats_for_colorspace[num_formats_cs] = formats[i];
|
||||
num_formats_cs++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_formats_cs > 0) {
|
||||
// we have at least one format with our preferred colorspace
|
||||
// if we have one that is on our preferred formats list, use it
|
||||
|
||||
for (uint32_t i = 0; i < num_formats_cs; i++) {
|
||||
if (formats_for_colorspace[i].format ==
|
||||
cts->preferred.color_format) {
|
||||
// perfect match.
|
||||
*format = formats_for_colorspace[i];
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// we don't have our swapchain default format and colorspace,
|
||||
// but we may have at least one preferred format with the
|
||||
// correct colorspace.
|
||||
for (uint32_t i = 0; i < num_formats_cs; i++) {
|
||||
for (uint32_t j = 0; j < num_pref_formats; j++) {
|
||||
if (formats_for_colorspace[i].format ==
|
||||
preferred_color_formats[j]) {
|
||||
*format = formats_for_colorspace[i];
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// are we still here? this means we have a format with our
|
||||
// preferred colorspace but we have no preferred color format -
|
||||
// maybe we only have 10/12 bpc or 15/16bpp format. return the
|
||||
// first one we have, at least its in the right color space.
|
||||
*format = formats_for_colorspace[0];
|
||||
VK_ERROR(cts->vk, "Returning unknown color format");
|
||||
goto cleanup;
|
||||
|
||||
} else {
|
||||
|
||||
// we have nothing with the preferred colorspace? we can try to
|
||||
// return a preferred format at least
|
||||
for (uint32_t i = 0; i < num_formats; i++) {
|
||||
for (uint32_t j = 0; j < num_pref_formats; j++) {
|
||||
if (formats[i].format ==
|
||||
preferred_color_formats[j]) {
|
||||
*format = formats_for_colorspace[i];
|
||||
VK_ERROR(
|
||||
cts->vk,
|
||||
"Returning known-wrong color "
|
||||
"space! Color shift may occur.");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we are still here, we should just return the first format
|
||||
// we have. we know its the wrong colorspace, and its not on our
|
||||
// list of preferred formats, but its something.
|
||||
*format = formats[0];
|
||||
VK_ERROR(cts->vk,
|
||||
"Returning fallback format! cue up some Kenny "
|
||||
"Loggins, cos we're in the DANGER ZONE!");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
VK_ERROR(cts->vk, "We should not be here");
|
||||
goto error;
|
||||
|
||||
cleanup:
|
||||
free(formats_for_colorspace);
|
||||
free(formats);
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(formats_for_colorspace);
|
||||
free(formats);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
_check_surface_present_mode(struct vk_bundle *vk,
|
||||
VkSurfaceKHR surface,
|
||||
VkPresentModeKHR present_mode)
|
||||
{
|
||||
uint32_t num_present_modes;
|
||||
VkPresentModeKHR *present_modes;
|
||||
vk->vkGetPhysicalDeviceSurfacePresentModesKHR(
|
||||
vk->physical_device, surface, &num_present_modes, NULL);
|
||||
|
||||
if (num_present_modes != 0) {
|
||||
present_modes =
|
||||
U_TYPED_ARRAY_CALLOC(VkPresentModeKHR, num_present_modes);
|
||||
vk->vkGetPhysicalDeviceSurfacePresentModesKHR(
|
||||
vk->physical_device, surface, &num_present_modes,
|
||||
present_modes);
|
||||
} else {
|
||||
VK_ERROR(vk, "Could not enumerate present modes.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_present_modes; i++) {
|
||||
if (present_modes[i] == present_mode) {
|
||||
free(present_modes);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
free(present_modes);
|
||||
VK_ERROR(vk, "Requested present mode not supported.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
comp_target_swapchain_destroy_image_views(struct comp_target_swapchain *cts)
|
||||
{
|
||||
if (cts->base.images == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < cts->base.num_images; i++) {
|
||||
if (cts->base.images[i].view == VK_NULL_HANDLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cts->vk->vkDestroyImageView(cts->vk->device,
|
||||
cts->base.images[i].view, NULL);
|
||||
cts->base.images[i].view = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
free(cts->base.images);
|
||||
cts->base.images = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
comp_target_swapchain_create_image_views(struct comp_target_swapchain *cts)
|
||||
{
|
||||
cts->vk->vkGetSwapchainImagesKHR( //
|
||||
cts->vk->device, // device
|
||||
cts->swapchain.handle, // swapchain
|
||||
&cts->base.num_images, // pSwapchainImageCount
|
||||
NULL); // pSwapchainImages
|
||||
assert(cts->base.num_images > 0);
|
||||
VK_DEBUG(cts->vk, "Creating %d image views.", cts->base.num_images);
|
||||
|
||||
VkImage *images = U_TYPED_ARRAY_CALLOC(VkImage, cts->base.num_images);
|
||||
cts->vk->vkGetSwapchainImagesKHR( //
|
||||
cts->vk->device, // device
|
||||
cts->swapchain.handle, // swapchain
|
||||
&cts->base.num_images, // pSwapchainImageCount
|
||||
images); // pSwapchainImages
|
||||
|
||||
comp_target_swapchain_destroy_image_views(cts);
|
||||
|
||||
cts->base.images = U_TYPED_ARRAY_CALLOC(struct comp_target_image,
|
||||
cts->base.num_images);
|
||||
|
||||
VkImageSubresourceRange subresource_range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < cts->base.num_images; i++) {
|
||||
cts->base.images[i].handle = images[i];
|
||||
vk_create_view(cts->vk, cts->base.images[i].handle,
|
||||
cts->surface.format.format, subresource_range,
|
||||
&cts->base.images[i].view);
|
||||
}
|
||||
|
||||
free(images);
|
||||
}
|
||||
|
||||
void
|
||||
comp_target_swapchain_cleanup(struct comp_target_swapchain *cts)
|
||||
{
|
||||
comp_target_swapchain_destroy_image_views(cts);
|
||||
|
||||
if (cts->swapchain.handle != VK_NULL_HANDLE) {
|
||||
cts->vk->vkDestroySwapchainKHR( //
|
||||
cts->vk->device, // device
|
||||
cts->swapchain.handle, // swapchain
|
||||
NULL); //
|
||||
cts->swapchain.handle = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (cts->surface.handle != VK_NULL_HANDLE) {
|
||||
cts->vk->vkDestroySurfaceKHR( //
|
||||
cts->vk->instance, // instance
|
||||
cts->surface.handle, // surface
|
||||
NULL); //
|
||||
cts->swapchain.handle = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
comp_target_swapchain_init_set_fnptrs(struct comp_target_swapchain *cts)
|
||||
{
|
||||
cts->base.create_images = comp_target_swapchain_create_images;
|
||||
cts->base.acquire = comp_target_swapchain_acquire_next_image;
|
||||
cts->base.present = comp_target_swapchain_present;
|
||||
}
|
||||
|
||||
void
|
||||
comp_target_swapchain_init_post_vulkan(struct comp_target_swapchain *cts,
|
||||
struct vk_bundle *vk)
|
||||
{
|
||||
cts->vk = vk;
|
||||
}
|
109
src/xrt/compositor/main/comp_target_swapchain.h
Normal file
109
src/xrt/compositor/main/comp_target_swapchain.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
// Copyright 2019-2020, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Target Vulkan swapchain code header.
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vk/vk_helpers.h"
|
||||
|
||||
#include "main/comp_target.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Structs.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Wraps and manage VkSwapchainKHR and VkSurfaceKHR, used by @ref comp code.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
struct comp_target_swapchain
|
||||
{
|
||||
//! Base target.
|
||||
struct comp_target base;
|
||||
|
||||
struct vk_bundle *vk;
|
||||
|
||||
struct
|
||||
{
|
||||
VkSwapchainKHR handle;
|
||||
} swapchain;
|
||||
|
||||
struct
|
||||
{
|
||||
VkSurfaceKHR handle;
|
||||
VkSurfaceFormatKHR format;
|
||||
} surface;
|
||||
|
||||
struct
|
||||
{
|
||||
VkFormat color_format;
|
||||
VkColorSpaceKHR color_space;
|
||||
} preferred;
|
||||
|
||||
//! Present mode that the system must support.
|
||||
VkPresentModeKHR present_mode;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Pre Vulkan initialisation, sets function pointers.
|
||||
*/
|
||||
void
|
||||
comp_target_swapchain_init_set_fnptrs(struct comp_target_swapchain *cts);
|
||||
|
||||
/*!
|
||||
* Initialize the given @ref comp_target_swapchain, does not allocate.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
comp_target_swapchain_init_post_vulkan(struct comp_target_swapchain *cts,
|
||||
struct vk_bundle *vk);
|
||||
|
||||
/*!
|
||||
* See comp_target::create_images.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
comp_target_swapchain_create_images(struct comp_target *ct,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
VkFormat color_format,
|
||||
VkColorSpaceKHR color_space,
|
||||
VkPresentModeKHR present_mode);
|
||||
|
||||
/*!
|
||||
* Free all managed resources on the given @ref comp_target_swapchain,
|
||||
* does not free the struct itself.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
comp_target_swapchain_cleanup(struct comp_target_swapchain *cts);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,492 +0,0 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Vulkan swapchain code.
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util/u_misc.h"
|
||||
|
||||
#include "comp_vk_swapchain.h"
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Types, defines and data.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* These formats will be 'preferred' - in future we may wish to give preference
|
||||
* to higher bit depths if they are available, but most display devices we are
|
||||
* interested in should support one these.
|
||||
*/
|
||||
static VkFormat preferred_color_formats[] = {
|
||||
VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_FORMAT_R8G8B8A8_UNORM,
|
||||
VK_FORMAT_B8G8R8A8_UNORM,
|
||||
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Pre declare functions.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
vk_swapchain_create_image_views(struct vk_swapchain *sc);
|
||||
|
||||
static void
|
||||
vk_swapchain_destroy_image_views(struct vk_swapchain *sc);
|
||||
|
||||
static void
|
||||
vk_swapchain_destroy_old(struct vk_swapchain *sc, VkSwapchainKHR old);
|
||||
|
||||
static VkExtent2D
|
||||
vk_swapchain_select_extent(struct vk_swapchain *sc,
|
||||
VkSurfaceCapabilitiesKHR caps,
|
||||
uint32_t width,
|
||||
uint32_t height);
|
||||
|
||||
static bool
|
||||
_find_surface_format(struct vk_swapchain *sc,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceFormatKHR *format);
|
||||
|
||||
static bool
|
||||
_check_surface_present_mode(struct vk_bundle *vk,
|
||||
VkSurfaceKHR surface,
|
||||
VkPresentModeKHR present_mode);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions!
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
vk_swapchain_init(struct vk_swapchain *sc, struct vk_bundle *vk)
|
||||
{
|
||||
sc->vk = vk;
|
||||
}
|
||||
|
||||
void
|
||||
vk_swapchain_create(struct vk_swapchain *sc,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
VkFormat color_format,
|
||||
VkColorSpaceKHR color_space,
|
||||
VkPresentModeKHR present_mode)
|
||||
{
|
||||
VkBool32 supported;
|
||||
VkResult ret;
|
||||
|
||||
// Free old image views.
|
||||
vk_swapchain_destroy_image_views(sc);
|
||||
|
||||
VkSwapchainKHR old_swapchain_handle = sc->swapchain.handle;
|
||||
|
||||
sc->base.num_images = 0;
|
||||
sc->swapchain.handle = VK_NULL_HANDLE;
|
||||
sc->present_mode = present_mode;
|
||||
sc->preferred.color_format = color_format;
|
||||
sc->preferred.color_space = color_space;
|
||||
|
||||
|
||||
// Sanity check.
|
||||
sc->vk->vkGetPhysicalDeviceSurfaceSupportKHR(
|
||||
sc->vk->physical_device, 0, sc->surface.handle, &supported);
|
||||
if (!supported) {
|
||||
VK_ERROR(sc->vk,
|
||||
"vkGetPhysicalDeviceSurfaceSupportKHR: "
|
||||
"surface not supported!");
|
||||
}
|
||||
|
||||
// More sanity checks.
|
||||
if (!_check_surface_present_mode(sc->vk, sc->surface.handle,
|
||||
sc->present_mode)) {
|
||||
// Free old.
|
||||
vk_swapchain_destroy_old(sc, old_swapchain_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the correct format.
|
||||
if (!_find_surface_format(sc, sc->surface.handle,
|
||||
&sc->surface.format)) {
|
||||
// Free old.
|
||||
vk_swapchain_destroy_old(sc, old_swapchain_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the caps first.
|
||||
VkSurfaceCapabilitiesKHR surface_caps;
|
||||
ret = sc->vk->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
sc->vk->physical_device, sc->surface.handle, &surface_caps);
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(sc->vk,
|
||||
"vkGetPhysicalDeviceSurfaceCapabilitiesKHR: %s",
|
||||
vk_result_string(ret));
|
||||
|
||||
// Free old.
|
||||
vk_swapchain_destroy_old(sc, old_swapchain_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the extents of the swapchain.
|
||||
VkExtent2D extent =
|
||||
vk_swapchain_select_extent(sc, surface_caps, width, height);
|
||||
|
||||
// Create the swapchain now.
|
||||
VkSwapchainCreateInfoKHR swapchain_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
|
||||
.surface = sc->surface.handle,
|
||||
.minImageCount = surface_caps.minImageCount,
|
||||
.imageFormat = sc->surface.format.format,
|
||||
.imageColorSpace = sc->surface.format.colorSpace,
|
||||
.imageExtent =
|
||||
{
|
||||
.width = extent.width,
|
||||
.height = extent.height,
|
||||
},
|
||||
.imageArrayLayers = 1,
|
||||
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 0,
|
||||
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
|
||||
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
|
||||
.presentMode = sc->present_mode,
|
||||
.clipped = VK_TRUE,
|
||||
.oldSwapchain = old_swapchain_handle,
|
||||
};
|
||||
|
||||
ret = sc->vk->vkCreateSwapchainKHR(sc->vk->device, &swapchain_info,
|
||||
NULL, &sc->swapchain.handle);
|
||||
|
||||
// Always destroy the old.
|
||||
vk_swapchain_destroy_old(sc, old_swapchain_handle);
|
||||
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(sc->vk, "vkCreateSwapchainKHR: %s",
|
||||
vk_result_string(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set target info.
|
||||
*/
|
||||
|
||||
sc->base.width = extent.width;
|
||||
sc->base.height = extent.height;
|
||||
sc->base.format = sc->surface.format.format;
|
||||
|
||||
vk_swapchain_create_image_views(sc);
|
||||
}
|
||||
|
||||
static VkExtent2D
|
||||
vk_swapchain_select_extent(struct vk_swapchain *sc,
|
||||
VkSurfaceCapabilitiesKHR caps,
|
||||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
// If width (and height) equals the special value 0xFFFFFFFF,
|
||||
// the size of the surface will be set by the swapchain
|
||||
if (caps.currentExtent.width == (uint32_t)-1) {
|
||||
VkExtent2D extent = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
return extent;
|
||||
}
|
||||
|
||||
if (caps.currentExtent.width != width ||
|
||||
caps.currentExtent.height != height) {
|
||||
VK_DEBUG(sc->vk,
|
||||
"Using swap chain extent dimensions %dx%d instead of "
|
||||
"requested %dx%d.",
|
||||
caps.currentExtent.width, caps.currentExtent.height,
|
||||
width, height);
|
||||
}
|
||||
|
||||
return caps.currentExtent;
|
||||
}
|
||||
|
||||
static void
|
||||
vk_swapchain_destroy_old(struct vk_swapchain *sc, VkSwapchainKHR old)
|
||||
{
|
||||
if (old != VK_NULL_HANDLE) {
|
||||
sc->vk->vkDestroySwapchainKHR(sc->vk->device, old, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_swapchain_acquire_next_image(struct vk_swapchain *sc,
|
||||
VkSemaphore semaphore,
|
||||
uint32_t *out_index)
|
||||
{
|
||||
return sc->vk->vkAcquireNextImageKHR( //
|
||||
sc->vk->device, // device
|
||||
sc->swapchain.handle, // timeout
|
||||
UINT64_MAX, // timeout
|
||||
semaphore, // semaphore
|
||||
VK_NULL_HANDLE, // fence
|
||||
out_index); // pImageIndex
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_swapchain_present(struct vk_swapchain *sc,
|
||||
VkQueue queue,
|
||||
uint32_t index,
|
||||
VkSemaphore semaphore)
|
||||
{
|
||||
VkPresentInfoKHR presentInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &semaphore,
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &sc->swapchain.handle,
|
||||
.pImageIndices = &index,
|
||||
};
|
||||
|
||||
return sc->vk->vkQueuePresentKHR(queue, &presentInfo);
|
||||
}
|
||||
|
||||
static bool
|
||||
_find_surface_format(struct vk_swapchain *sc,
|
||||
VkSurfaceKHR surface,
|
||||
VkSurfaceFormatKHR *format)
|
||||
{
|
||||
uint32_t num_formats;
|
||||
VkSurfaceFormatKHR *formats = NULL;
|
||||
sc->vk->vkGetPhysicalDeviceSurfaceFormatsKHR(
|
||||
sc->vk->physical_device, surface, &num_formats, NULL);
|
||||
|
||||
if (num_formats != 0) {
|
||||
formats = U_TYPED_ARRAY_CALLOC(VkSurfaceFormatKHR, num_formats);
|
||||
sc->vk->vkGetPhysicalDeviceSurfaceFormatsKHR(
|
||||
sc->vk->physical_device, surface, &num_formats, formats);
|
||||
} else {
|
||||
VK_ERROR(sc->vk, "Could not enumerate surface formats.");
|
||||
return false;
|
||||
}
|
||||
|
||||
VkSurfaceFormatKHR *formats_for_colorspace = NULL;
|
||||
formats_for_colorspace =
|
||||
U_TYPED_ARRAY_CALLOC(VkSurfaceFormatKHR, num_formats);
|
||||
|
||||
uint32_t num_formats_cs = 0;
|
||||
uint32_t num_pref_formats = ARRAY_SIZE(preferred_color_formats);
|
||||
|
||||
// Gather formats that match our color space, we will select
|
||||
// from these in preference to others.
|
||||
|
||||
for (uint32_t i = 0; i < num_formats; i++) {
|
||||
if (formats[i].colorSpace == sc->preferred.color_space) {
|
||||
formats_for_colorspace[num_formats_cs] = formats[i];
|
||||
num_formats_cs++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_formats_cs > 0) {
|
||||
// we have at least one format with our preferred colorspace
|
||||
// if we have one that is on our preferred formats list, use it
|
||||
|
||||
for (uint32_t i = 0; i < num_formats_cs; i++) {
|
||||
if (formats_for_colorspace[i].format ==
|
||||
sc->preferred.color_format) {
|
||||
// perfect match.
|
||||
*format = formats_for_colorspace[i];
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// we don't have our swapchain default format and colorspace,
|
||||
// but we may have at least one preferred format with the
|
||||
// correct colorspace.
|
||||
for (uint32_t i = 0; i < num_formats_cs; i++) {
|
||||
for (uint32_t j = 0; j < num_pref_formats; j++) {
|
||||
if (formats_for_colorspace[i].format ==
|
||||
preferred_color_formats[j]) {
|
||||
*format = formats_for_colorspace[i];
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// are we still here? this means we have a format with our
|
||||
// preferred colorspace but we have no preferred color format -
|
||||
// maybe we only have 10/12 bpc or 15/16bpp format. return the
|
||||
// first one we have, at least its in the right color space.
|
||||
*format = formats_for_colorspace[0];
|
||||
VK_ERROR(sc->vk, "Returning unknown color format");
|
||||
goto cleanup;
|
||||
|
||||
} else {
|
||||
|
||||
// we have nothing with the preferred colorspace? we can try to
|
||||
// return a preferred format at least
|
||||
for (uint32_t i = 0; i < num_formats; i++) {
|
||||
for (uint32_t j = 0; j < num_pref_formats; j++) {
|
||||
if (formats[i].format ==
|
||||
preferred_color_formats[j]) {
|
||||
*format = formats_for_colorspace[i];
|
||||
VK_ERROR(
|
||||
sc->vk,
|
||||
"Returning known-wrong color "
|
||||
"space! Color shift may occur.");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we are still here, we should just return the first format
|
||||
// we have. we know its the wrong colorspace, and its not on our
|
||||
// list of preferred formats, but its something.
|
||||
*format = formats[0];
|
||||
VK_ERROR(sc->vk,
|
||||
"Returning fallback format! cue up some Kenny "
|
||||
"Loggins, cos we're in the DANGER ZONE!");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
VK_ERROR(sc->vk, "We should not be here");
|
||||
goto error;
|
||||
|
||||
cleanup:
|
||||
free(formats_for_colorspace);
|
||||
free(formats);
|
||||
return true;
|
||||
|
||||
error:
|
||||
free(formats_for_colorspace);
|
||||
free(formats);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
_check_surface_present_mode(struct vk_bundle *vk,
|
||||
VkSurfaceKHR surface,
|
||||
VkPresentModeKHR present_mode)
|
||||
{
|
||||
uint32_t num_present_modes;
|
||||
VkPresentModeKHR *present_modes;
|
||||
vk->vkGetPhysicalDeviceSurfacePresentModesKHR(
|
||||
vk->physical_device, surface, &num_present_modes, NULL);
|
||||
|
||||
if (num_present_modes != 0) {
|
||||
present_modes =
|
||||
U_TYPED_ARRAY_CALLOC(VkPresentModeKHR, num_present_modes);
|
||||
vk->vkGetPhysicalDeviceSurfacePresentModesKHR(
|
||||
vk->physical_device, surface, &num_present_modes,
|
||||
present_modes);
|
||||
} else {
|
||||
VK_ERROR(vk, "Could not enumerate present modes.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_present_modes; i++) {
|
||||
if (present_modes[i] == present_mode) {
|
||||
free(present_modes);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
free(present_modes);
|
||||
VK_ERROR(vk, "Requested present mode not supported.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
vk_swapchain_destroy_image_views(struct vk_swapchain *sc)
|
||||
{
|
||||
if (sc->base.images == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < sc->base.num_images; i++) {
|
||||
if (sc->base.images[i].view == VK_NULL_HANDLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sc->vk->vkDestroyImageView(sc->vk->device,
|
||||
sc->base.images[i].view, NULL);
|
||||
sc->base.images[i].view = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
free(sc->base.images);
|
||||
sc->base.images = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
vk_swapchain_create_image_views(struct vk_swapchain *sc)
|
||||
{
|
||||
sc->vk->vkGetSwapchainImagesKHR( //
|
||||
sc->vk->device, // device
|
||||
sc->swapchain.handle, // swapchain
|
||||
&sc->base.num_images, // pSwapchainImageCount
|
||||
NULL); // pSwapchainImages
|
||||
assert(sc->base.num_images > 0);
|
||||
VK_DEBUG(sc->vk, "Creating %d image views.", sc->base.num_images);
|
||||
|
||||
VkImage *images = U_TYPED_ARRAY_CALLOC(VkImage, sc->base.num_images);
|
||||
sc->vk->vkGetSwapchainImagesKHR( //
|
||||
sc->vk->device, // device
|
||||
sc->swapchain.handle, // swapchain
|
||||
&sc->base.num_images, // pSwapchainImageCount
|
||||
images); // pSwapchainImages
|
||||
|
||||
vk_swapchain_destroy_image_views(sc);
|
||||
|
||||
sc->base.images =
|
||||
U_TYPED_ARRAY_CALLOC(struct comp_target_image, sc->base.num_images);
|
||||
|
||||
VkImageSubresourceRange subresource_range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < sc->base.num_images; i++) {
|
||||
sc->base.images[i].handle = images[i];
|
||||
vk_create_view(sc->vk, sc->base.images[i].handle,
|
||||
sc->surface.format.format, subresource_range,
|
||||
&sc->base.images[i].view);
|
||||
}
|
||||
|
||||
free(images);
|
||||
}
|
||||
|
||||
void
|
||||
vk_swapchain_cleanup(struct vk_swapchain *sc)
|
||||
{
|
||||
vk_swapchain_destroy_image_views(sc);
|
||||
|
||||
if (sc->swapchain.handle != VK_NULL_HANDLE) {
|
||||
sc->vk->vkDestroySwapchainKHR( //
|
||||
sc->vk->device, // device
|
||||
sc->swapchain.handle, // swapchain
|
||||
NULL); //
|
||||
sc->swapchain.handle = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (sc->surface.handle != VK_NULL_HANDLE) {
|
||||
sc->vk->vkDestroySurfaceKHR( //
|
||||
sc->vk->instance, // instance
|
||||
sc->surface.handle, // surface
|
||||
NULL); //
|
||||
sc->swapchain.handle = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Vulkan swapchain code header.
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vk/vk_helpers.h"
|
||||
|
||||
#include "main/comp_target.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Structs.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Wraps and manage VkSwapchainKHR and VkSurfaceKHR, used by @ref comp code.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
struct vk_swapchain
|
||||
{
|
||||
//! Base target.
|
||||
struct comp_target base;
|
||||
|
||||
struct vk_bundle *vk;
|
||||
|
||||
struct
|
||||
{
|
||||
VkSwapchainKHR handle;
|
||||
} swapchain;
|
||||
|
||||
struct
|
||||
{
|
||||
VkSurfaceKHR handle;
|
||||
VkSurfaceFormatKHR format;
|
||||
} surface;
|
||||
|
||||
struct
|
||||
{
|
||||
VkFormat color_format;
|
||||
VkColorSpaceKHR color_space;
|
||||
} preferred;
|
||||
|
||||
//! Present mode that the system must support.
|
||||
VkPresentModeKHR present_mode;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Wraps and manage VkSwapchainKHR and VkSurfaceKHR, used by @ref comp code.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
vk_swapchain_init(struct vk_swapchain *sc, struct vk_bundle *vk);
|
||||
|
||||
/*!
|
||||
* Initialize the given @ref vk_swapchain, does not allocate.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
vk_swapchain_create(struct vk_swapchain *sc,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
VkFormat color_format,
|
||||
VkColorSpaceKHR color_space,
|
||||
VkPresentModeKHR present_mode);
|
||||
|
||||
/*!
|
||||
* Acquire a image index from the given @ref vk_swapchain for rendering.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
VkResult
|
||||
vk_swapchain_acquire_next_image(struct vk_swapchain *sc,
|
||||
VkSemaphore semaphore,
|
||||
uint32_t *index);
|
||||
|
||||
/*!
|
||||
* Make the given @ref vk_swapchain present the next acquired image.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
VkResult
|
||||
vk_swapchain_present(struct vk_swapchain *sc,
|
||||
VkQueue queue,
|
||||
uint32_t index,
|
||||
VkSemaphore semaphore);
|
||||
|
||||
/*!
|
||||
* Free all managed resources on the given @ref vk_swapchain,
|
||||
* does not free the struct itself.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
vk_swapchain_cleanup(struct vk_swapchain *sc);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -10,9 +10,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "main/comp_vk_swapchain.h"
|
||||
#include "main/comp_target_swapchain.h"
|
||||
#include "main/comp_compositor.h"
|
||||
#include "render/comp_render.h"
|
||||
|
||||
#include "xrt/xrt_config_os.h"
|
||||
|
||||
|
@ -36,7 +35,7 @@ extern "C" {
|
|||
struct comp_window
|
||||
{
|
||||
//! This has to be first.
|
||||
struct vk_swapchain swapchain;
|
||||
struct comp_target_swapchain swapchain;
|
||||
|
||||
//! Owning compositor.
|
||||
struct comp_compositor *c;
|
||||
|
@ -49,9 +48,6 @@ struct comp_window
|
|||
*
|
||||
*/
|
||||
|
||||
void
|
||||
comp_window_init_target(struct comp_window *wt);
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
/*!
|
||||
* Create a xcb window.
|
||||
|
|
|
@ -59,7 +59,7 @@ comp_window_android_destroy(struct comp_target *ct)
|
|||
{
|
||||
struct comp_window_android *cwa = (struct comp_window_android *)ct;
|
||||
|
||||
vk_swapchain_cleanup(&cwa->base.swapchain);
|
||||
comp_target_swapchain_cleanup(&cwa->base.swapchain);
|
||||
|
||||
android_custom_surface_destroy(&cwa->custom_surface);
|
||||
|
||||
|
@ -146,6 +146,8 @@ comp_window_android_create(struct comp_compositor *c)
|
|||
struct comp_window_android *w =
|
||||
U_TYPED_CALLOC(struct comp_window_android);
|
||||
|
||||
comp_target_swapchain_init_set_fnptrs(&w->base.swapchain);
|
||||
|
||||
w->base.swapchain.base.name = "Android";
|
||||
w->base.swapchain.base.destroy = comp_window_android_destroy;
|
||||
w->base.swapchain.base.flush = comp_window_android_flush;
|
||||
|
|
|
@ -277,7 +277,7 @@ comp_window_direct_init_swapchain(struct comp_window *w,
|
|||
uint32_t width,
|
||||
uint32_t height)
|
||||
{
|
||||
vk_swapchain_init(&w->swapchain, &w->c->vk);
|
||||
comp_target_swapchain_init_post_vulkan(&w->swapchain, &w->c->vk);
|
||||
|
||||
VkResult ret;
|
||||
ret = comp_window_direct_acquire_xlib_display(w, dpy, display);
|
||||
|
|
|
@ -89,7 +89,7 @@ comp_window_direct_nvidia_create(struct comp_compositor *c)
|
|||
struct comp_window_direct_nvidia *w =
|
||||
U_TYPED_CALLOC(struct comp_window_direct_nvidia);
|
||||
|
||||
comp_window_init_target(&w->base);
|
||||
comp_target_swapchain_init_set_fnptrs(&w->base.swapchain);
|
||||
|
||||
w->base.swapchain.base.name = "direct";
|
||||
w->base.swapchain.base.destroy = comp_window_direct_nvidia_destroy;
|
||||
|
@ -109,7 +109,7 @@ comp_window_direct_nvidia_destroy(struct comp_target *ct)
|
|||
struct comp_window_direct_nvidia *w_direct =
|
||||
(struct comp_window_direct_nvidia *)ct;
|
||||
|
||||
vk_swapchain_cleanup(&w_direct->base.swapchain);
|
||||
comp_target_swapchain_cleanup(&w_direct->base.swapchain);
|
||||
|
||||
for (uint32_t i = 0; i < w_direct->num_displays; i++) {
|
||||
struct comp_window_direct_nvidia_display *d =
|
||||
|
@ -255,7 +255,7 @@ comp_window_direct_nvidia_init_swapchain(struct comp_target *ct,
|
|||
(struct comp_window_direct_nvidia *)ct;
|
||||
struct comp_window *w = &w_direct->base;
|
||||
|
||||
vk_swapchain_init(&w->swapchain, &w->c->vk);
|
||||
comp_target_swapchain_init_post_vulkan(&w->swapchain, &w->c->vk);
|
||||
|
||||
struct comp_window_direct_nvidia_display *d =
|
||||
comp_window_direct_nvidia_current_display(w_direct);
|
||||
|
|
|
@ -111,7 +111,7 @@ comp_window_direct_randr_create(struct comp_compositor *c)
|
|||
struct comp_window_direct_randr *w =
|
||||
U_TYPED_CALLOC(struct comp_window_direct_randr);
|
||||
|
||||
comp_window_init_target(&w->base);
|
||||
comp_target_swapchain_init_set_fnptrs(&w->base.swapchain);
|
||||
|
||||
w->base.swapchain.base.name = "direct";
|
||||
w->base.swapchain.base.destroy = comp_window_direct_randr_destroy;
|
||||
|
@ -131,7 +131,7 @@ comp_window_direct_randr_destroy(struct comp_target *ct)
|
|||
struct comp_window_direct_randr *w_direct =
|
||||
(struct comp_window_direct_randr *)ct;
|
||||
|
||||
vk_swapchain_cleanup(&w_direct->base.swapchain);
|
||||
comp_target_swapchain_cleanup(&w_direct->base.swapchain);
|
||||
|
||||
struct vk_bundle *vk = &w_direct->base.c->vk;
|
||||
|
||||
|
@ -254,7 +254,7 @@ comp_window_direct_randr_init_swapchain(struct comp_target *ct,
|
|||
(struct comp_window_direct_randr *)ct;
|
||||
struct comp_window *w = &w_direct->base;
|
||||
|
||||
vk_swapchain_init(&w->swapchain, &w->c->vk);
|
||||
comp_target_swapchain_init_post_vulkan(&w->swapchain, &w->c->vk);
|
||||
|
||||
struct comp_window_direct_randr_display *d =
|
||||
comp_window_direct_randr_current_display(w_direct);
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright 2020, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Compositor window header.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
#include "main/comp_window.h"
|
||||
|
||||
|
||||
static inline struct comp_window *
|
||||
comp_window(struct comp_target *ct)
|
||||
{
|
||||
return (struct comp_window *)ct;
|
||||
}
|
||||
|
||||
void
|
||||
wt_create_images(struct comp_target *ct,
|
||||
uint32_t preferred_width,
|
||||
uint32_t preferred_height,
|
||||
VkFormat preferred_color_format,
|
||||
VkColorSpaceKHR preferred_color_space,
|
||||
VkPresentModeKHR present_mode)
|
||||
{
|
||||
struct comp_window *cw = comp_window(ct);
|
||||
|
||||
vk_swapchain_create( //
|
||||
&cw->swapchain, //
|
||||
preferred_width, //
|
||||
preferred_height, //
|
||||
preferred_color_format, //
|
||||
preferred_color_space, //
|
||||
present_mode); //
|
||||
}
|
||||
|
||||
VkResult
|
||||
wt_acquire(struct comp_target *ct, VkSemaphore semaphore, uint32_t *out_index)
|
||||
{
|
||||
struct comp_window *cw = comp_window(ct);
|
||||
|
||||
return vk_swapchain_acquire_next_image( //
|
||||
&cw->swapchain, //
|
||||
semaphore, //
|
||||
out_index); //
|
||||
}
|
||||
|
||||
VkResult
|
||||
wt_present(struct comp_target *ct,
|
||||
VkQueue queue,
|
||||
uint32_t index,
|
||||
VkSemaphore semaphore)
|
||||
{
|
||||
struct comp_window *cw = comp_window(ct);
|
||||
|
||||
return vk_swapchain_present( //
|
||||
&cw->swapchain, //
|
||||
queue, //
|
||||
index, //
|
||||
semaphore); //
|
||||
}
|
||||
|
||||
void
|
||||
comp_window_init_target(struct comp_window *wt)
|
||||
{
|
||||
wt->swapchain.base.create_images = wt_create_images;
|
||||
wt->swapchain.base.acquire = wt_acquire;
|
||||
wt->swapchain.base.present = wt_present;
|
||||
}
|
|
@ -121,7 +121,7 @@ comp_window_wayland_destroy(struct comp_target *ct)
|
|||
{
|
||||
struct comp_window_wayland *cww = (struct comp_window_wayland *)ct;
|
||||
|
||||
vk_swapchain_cleanup(&cww->base.swapchain);
|
||||
comp_target_swapchain_cleanup(&cww->base.swapchain);
|
||||
|
||||
if (cww->surface) {
|
||||
wl_surface_destroy(cww->surface);
|
||||
|
@ -207,7 +207,7 @@ comp_window_wayland_init_swapchain(struct comp_target *ct,
|
|||
struct comp_window *w = &w_wayland->base;
|
||||
VkResult ret;
|
||||
|
||||
vk_swapchain_init(&w->swapchain, &w->c->vk);
|
||||
comp_target_swapchain_init_post_vulkan(&w->swapchain, &w->c->vk);
|
||||
|
||||
ret = comp_window_wayland_create_surface(w_wayland,
|
||||
&w->swapchain.surface.handle);
|
||||
|
|
|
@ -127,7 +127,7 @@ comp_window_xcb_create(struct comp_compositor *c)
|
|||
{
|
||||
struct comp_window_xcb *w = U_TYPED_CALLOC(struct comp_window_xcb);
|
||||
|
||||
comp_window_init_target(&w->base);
|
||||
comp_target_swapchain_init_set_fnptrs(&w->base.swapchain);
|
||||
|
||||
w->base.swapchain.base.name = "xcb";
|
||||
w->base.swapchain.base.destroy = comp_window_xcb_destroy;
|
||||
|
@ -146,7 +146,7 @@ comp_window_xcb_destroy(struct comp_target *ct)
|
|||
{
|
||||
struct comp_window_xcb *w_xcb = (struct comp_window_xcb *)ct;
|
||||
|
||||
vk_swapchain_cleanup(&w_xcb->base.swapchain);
|
||||
comp_target_swapchain_cleanup(&w_xcb->base.swapchain);
|
||||
|
||||
xcb_destroy_window(w_xcb->connection, w_xcb->window);
|
||||
xcb_disconnect(w_xcb->connection);
|
||||
|
@ -249,7 +249,7 @@ comp_window_xcb_init_swapchain(struct comp_target *ct,
|
|||
struct comp_window *w = &w_xcb->base;
|
||||
VkResult ret;
|
||||
|
||||
vk_swapchain_init(&w->swapchain, &w->c->vk);
|
||||
comp_target_swapchain_init_post_vulkan(&w->swapchain, &w->c->vk);
|
||||
|
||||
ret =
|
||||
comp_window_xcb_create_surface(w_xcb, &w->swapchain.surface.handle);
|
||||
|
|
|
@ -23,10 +23,9 @@ compositor_srcs = [
|
|||
'main/comp_shaders.c',
|
||||
'main/comp_swapchain.c',
|
||||
'main/comp_target.h',
|
||||
'main/comp_vk_swapchain.c',
|
||||
'main/comp_vk_swapchain.h',
|
||||
'main/comp_target_swapchain.c',
|
||||
'main/comp_target_swapchain.h',
|
||||
'main/comp_window.h',
|
||||
'main/comp_window_target.c',
|
||||
'main/comp_layer_renderer.c',
|
||||
'main/comp_layer.c',
|
||||
'render/comp_buffer.c',
|
||||
|
|
Loading…
Reference in a new issue