mirror of
https://github.com/lbgos/rift-s-linux.git
synced 2026-10-28 13:01:52 +01:00
c/util: Add high level scratch helper
Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2493>
This commit is contained in:
1 parent
ea9fff0517
commit
fe2d906e8b
3 files changed
+346
No files matched your search
@@ -146,6 +146,8 @@ if(XRT_HAVE_VULKAN)
|
||||
comp_util STATIC
|
||||
util/comp_base.h
|
||||
util/comp_base.c
|
||||
util/comp_high_level_scratch.c
|
||||
util/comp_high_level_scratch.h
|
||||
util/comp_layer_accum.h
|
||||
util/comp_layer_accum.c
|
||||
util/comp_render.h
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
// Copyright 2019-2024, Collabora, Ltd.
|
||||
// Copyright 2024-2025, NVIDIA CORPORATION.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Higher level interface for scratch images.
|
||||
* @author Jakob Bornecrantz <tbornecrantz@nvidia.com>
|
||||
* @author Andrei Aristarkhov <aaristarkhov@nvidia.com>
|
||||
* @author Gareth Morgan <gmorgan@nvidia.com>
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
|
||||
#include "comp_high_level_scratch.h"
|
||||
|
||||
|
||||
void
|
||||
chl_scratch_init(struct chl_scratch *scratch)
|
||||
{
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(scratch->views); i++) {
|
||||
comp_scratch_single_images_init(&scratch->views[i].cssi);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
chl_scratch_fini(struct chl_scratch *scratch)
|
||||
{
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(scratch->views); i++) {
|
||||
comp_scratch_single_images_destroy(&scratch->views[i].cssi);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
chl_scratch_ensure(struct chl_scratch *scratch,
|
||||
struct render_resources *rr,
|
||||
uint32_t view_count,
|
||||
VkExtent2D extent,
|
||||
const VkFormat format)
|
||||
{
|
||||
struct vk_bundle *vk = rr->vk;
|
||||
bool bret = false;
|
||||
|
||||
// Is everything already correct?
|
||||
if (scratch->view_count == view_count && //
|
||||
scratch->extent.width == extent.width && //
|
||||
scratch->extent.height == extent.height && //
|
||||
scratch->format == format) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Free all old resources.
|
||||
chl_scratch_free_resources(scratch, rr);
|
||||
|
||||
// Shared render pass between all scratch images.
|
||||
bret = render_gfx_render_pass_init( //
|
||||
&scratch->render_pass, // rgrp
|
||||
rr, // struct render_resources
|
||||
format, // format
|
||||
VK_ATTACHMENT_LOAD_OP_CLEAR, // load_op
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // final_layout
|
||||
if (!bret) {
|
||||
VK_ERROR(vk, "render_gfx_render_pass_init: false");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Need to track if the render pass has been initialized.
|
||||
scratch->render_pass_initialized = true;
|
||||
|
||||
for (uint32_t i = 0; i < view_count; i++) {
|
||||
// Helper.
|
||||
struct comp_scratch_single_images *cssi = &scratch->views[i].cssi;
|
||||
|
||||
if (format == VK_FORMAT_R8G8B8A8_SRGB) {
|
||||
// Special creation function for the mutable format.
|
||||
bret = comp_scratch_single_images_ensure_mutable(cssi, vk, extent);
|
||||
} else {
|
||||
bret = comp_scratch_single_images_ensure(cssi, vk, extent, format);
|
||||
}
|
||||
|
||||
if (!bret) {
|
||||
VK_ERROR(vk, "comp_scratch_single_images_ensure[_mutable]: false");
|
||||
// Free any that has already been allocated.
|
||||
chl_scratch_free_resources(scratch, rr);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) {
|
||||
|
||||
/*
|
||||
* For graphics parts we use the same image view as the
|
||||
* source. In other words the sRGB image view for the
|
||||
* non-linear formats.
|
||||
*/
|
||||
VkImageView target_image_view = chl_scratch_get_sample_view(scratch, i, k);
|
||||
|
||||
render_gfx_target_resources_init( //
|
||||
&scratch->views[i].targets[k], // rtr
|
||||
rr, // struct render_resources
|
||||
&scratch->render_pass, // struct render_gfx_render_pass
|
||||
target_image_view, // target
|
||||
extent); // extent
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the count, doing it this way means free_resources
|
||||
* will free the allocated images correctly. The count is one
|
||||
* more then the index.
|
||||
*/
|
||||
scratch->view_count = i + 1;
|
||||
}
|
||||
|
||||
// Update the cached values.
|
||||
scratch->extent = extent;
|
||||
scratch->format = format;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
chl_scratch_free_resources(struct chl_scratch *scratch, struct render_resources *rr)
|
||||
{
|
||||
struct vk_bundle *vk = rr->vk;
|
||||
|
||||
for (uint32_t i = 0; i < scratch->view_count; i++) {
|
||||
for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) {
|
||||
render_gfx_target_resources_fini(&scratch->views[i].targets[k]);
|
||||
}
|
||||
|
||||
comp_scratch_single_images_free(&scratch->views[i].cssi, vk);
|
||||
}
|
||||
|
||||
// Nothing allocated.
|
||||
scratch->view_count = 0;
|
||||
scratch->extent.width = 0;
|
||||
scratch->extent.height = 0;
|
||||
scratch->format = VK_FORMAT_UNDEFINED;
|
||||
|
||||
// Do this after the image targets as they reference the render pass.
|
||||
if (scratch->render_pass_initialized) {
|
||||
render_gfx_render_pass_fini(&scratch->render_pass);
|
||||
scratch->render_pass_initialized = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
// Copyright 2019-2024, Collabora, Ltd.
|
||||
// Copyright 2024-2025, NVIDIA CORPORATION.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Higher level interface for scratch images.
|
||||
* @author Jakob Bornecrantz <tbornecrantz@nvidia.com>
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "render/render_interface.h"
|
||||
|
||||
#include "comp_scratch.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Scratch images that can be used for staging buffers.
|
||||
*
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
struct chl_scratch
|
||||
{
|
||||
//! Shared render passed for the views.
|
||||
struct render_gfx_render_pass render_pass;
|
||||
|
||||
struct
|
||||
{
|
||||
//! Per-view scratch images.
|
||||
struct comp_scratch_single_images cssi;
|
||||
|
||||
//! Targets for rendering to the scratch buffer.
|
||||
struct render_gfx_target_resources targets[COMP_SCRATCH_NUM_IMAGES];
|
||||
} views[XRT_MAX_VIEWS];
|
||||
|
||||
/*!
|
||||
* Number of views that has been ensured and have Vulkan resources,
|
||||
* all comp_scratch_single_images are always inited.
|
||||
*/
|
||||
uint32_t view_count;
|
||||
|
||||
//! The extent used to create the images.
|
||||
VkExtent2D extent;
|
||||
|
||||
//! Format requested.
|
||||
VkFormat format;
|
||||
|
||||
//! Has the render pass been initialized.
|
||||
bool render_pass_initialized;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Must becalled before used and before the scratch images are registered with
|
||||
* the u_var system.
|
||||
*
|
||||
* @memberof chl_scratch
|
||||
*/
|
||||
void
|
||||
chl_scratch_init(struct chl_scratch *scratch);
|
||||
|
||||
/*!
|
||||
* Resources must be manually called before calling this functions, and the
|
||||
* scratch images unregistered from the u_var system.
|
||||
*
|
||||
* @memberof chl_scratch
|
||||
*/
|
||||
void
|
||||
chl_scratch_fini(struct chl_scratch *scratch);
|
||||
|
||||
/*!
|
||||
* Ensure the scratch images and the render target resources are created.
|
||||
*
|
||||
* @memberof chl_scratch
|
||||
*/
|
||||
bool
|
||||
chl_scratch_ensure(struct chl_scratch *scratch,
|
||||
struct render_resources *rr,
|
||||
uint32_t view_count,
|
||||
VkExtent2D extent,
|
||||
const VkFormat format);
|
||||
|
||||
/*!
|
||||
* Free all Vulkan resources that this scratch has created.
|
||||
*
|
||||
* @memberof chl_scratch
|
||||
*/
|
||||
void
|
||||
chl_scratch_free_resources(struct chl_scratch *scratch, struct render_resources *rr);
|
||||
|
||||
/*!
|
||||
* Get the image, see @ref comp_scratch_single_images_get_image.
|
||||
*
|
||||
* @memberof chl_scratch
|
||||
*/
|
||||
static inline VkImage
|
||||
chl_scratch_get_image(struct chl_scratch *scratch, uint32_t view_index, uint32_t image_index)
|
||||
{
|
||||
return comp_scratch_single_images_get_image(&scratch->views[view_index].cssi, image_index);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get the sample view, see @ref comp_scratch_single_images_get_sample_view.
|
||||
*
|
||||
* @memberof chl_scratch
|
||||
*/
|
||||
static inline VkImageView
|
||||
chl_scratch_get_sample_view(struct chl_scratch *scratch, uint32_t view_index, uint32_t image_index)
|
||||
{
|
||||
return comp_scratch_single_images_get_sample_view(&scratch->views[view_index].cssi, image_index);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get the storage view, see @ref comp_scratch_single_images_get_storage_view.
|
||||
*
|
||||
* @memberof chl_scratch
|
||||
*/
|
||||
static inline VkImageView
|
||||
chl_scratch_get_storage_view(struct chl_scratch *scratch, uint32_t view_index, uint32_t image_index)
|
||||
{
|
||||
return comp_scratch_single_images_get_storage_view(&scratch->views[view_index].cssi, image_index);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* State
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Per view frame state tracking which index was gotten and if it was used.
|
||||
*
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
struct chl_scratch_state_view
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
bool used;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Used to track the index of images gotten for the images, and if it has been
|
||||
* used. The user will need to mark images as used.
|
||||
*
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
struct chl_scratch_state
|
||||
{
|
||||
struct chl_scratch_state_view views[XRT_MAX_VIEWS];
|
||||
};
|
||||
|
||||
/*!
|
||||
* Zeros out the struct and calls get on all the images, setting the @p index
|
||||
* field on the state for each view.
|
||||
*
|
||||
* @memberof chl_scratch_state
|
||||
*/
|
||||
static inline void
|
||||
chl_scratch_state_init_and_get(struct chl_scratch_state *scratch_state, struct chl_scratch *scratch)
|
||||
{
|
||||
U_ZERO(scratch_state);
|
||||
|
||||
// Loop over all the of the images in the scratch view.
|
||||
for (uint32_t i = 0; i < scratch->view_count; i++) {
|
||||
comp_scratch_single_images_get(&scratch->views[i].cssi, &scratch_state->views[i].index);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Calls discard or done on all the scratch images, it calls done if the @p used
|
||||
* field is set to true.
|
||||
*
|
||||
* @memberof chl_scratch_state
|
||||
*/
|
||||
static inline void
|
||||
chl_scratch_state_discard_or_done(struct chl_scratch_state *scratch_state, struct chl_scratch *scratch)
|
||||
{
|
||||
// Loop over all the of the images in the scratch view.
|
||||
for (uint32_t i = 0; i < scratch->view_count; i++) {
|
||||
if (scratch_state->views[i].used) {
|
||||
comp_scratch_single_images_done(&scratch->views[i].cssi);
|
||||
} else {
|
||||
comp_scratch_single_images_discard(&scratch->views[i].cssi);
|
||||
}
|
||||
}
|
||||
|
||||
U_ZERO(scratch_state);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in new issue
Block a user