mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 02:26:16 +00:00
c/util: Extract comp_layer_accum, formerly comp_layer_slot, and reduce coupling.
The "secret" the implementation is hiding is how calls and layers turn into a single structure. Not a great secret but functionality that is needed. c/util: Use comp_layer_accum in comp_base and derived implmentations. c/util: zero the other swapchains. c/util: Inline two functions. Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2317>
This commit is contained in:
parent
9f6f6c6df7
commit
338d85543b
2
doc/changes/compositor/mr.2317.md
Normal file
2
doc/changes/compositor/mr.2317.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
- Add: New `comp_layer_accum` helper, factored out from `comp_base`, that collects layers and swapchains for a frame.
|
||||
- Change: Modify `comp_base` to use `comp_layer_accum` helper, instead of inlining that code. Users of `comp_base` will need to update their code accordingly.
|
|
@ -146,6 +146,8 @@ if(XRT_HAVE_VULKAN)
|
|||
comp_util STATIC
|
||||
util/comp_base.h
|
||||
util/comp_base.c
|
||||
util/comp_layer_accum.h
|
||||
util/comp_layer_accum.c
|
||||
util/comp_render.h
|
||||
util/comp_render_cs.c
|
||||
util/comp_render_gfx.c
|
||||
|
|
|
@ -264,20 +264,16 @@ compositor_discard_frame(struct xrt_compositor *xc, int64_t frame_id)
|
|||
static bool
|
||||
can_do_one_projection_layer_fast_path(struct comp_compositor *c)
|
||||
{
|
||||
if (c->base.slot.layer_count != 1) {
|
||||
if (c->base.layer_accum.layer_count != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct comp_layer *layer = &c->base.slot.layers[0];
|
||||
struct comp_layer *layer = &c->base.layer_accum.layers[0];
|
||||
enum xrt_layer_type type = layer->data.type;
|
||||
|
||||
// Handled by the distortion shader.
|
||||
if (type != XRT_LAYER_PROJECTION && //
|
||||
type != XRT_LAYER_PROJECTION_DEPTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return type == XRT_LAYER_PROJECTION || //
|
||||
type == XRT_LAYER_PROJECTION_DEPTH;
|
||||
}
|
||||
|
||||
static XRT_CHECK_RESULT xrt_result_t
|
||||
|
@ -298,7 +294,7 @@ compositor_layer_commit(struct xrt_compositor *xc, xrt_graphics_sync_handle_t sy
|
|||
!c->mirroring_to_debug_gui && //
|
||||
!c->debug.disable_fast_path && //
|
||||
can_do_one_projection_layer_fast_path(c); //
|
||||
c->base.slot.one_projection_layer_fast_path = fast_path;
|
||||
c->base.frame_params.one_projection_layer_fast_path = fast_path;
|
||||
|
||||
|
||||
u_graphics_sync_unref(&sync_handle);
|
||||
|
|
|
@ -348,8 +348,8 @@ calc_pose_data(struct comp_renderer *r,
|
|||
out_eye[i] = eye_pose;
|
||||
|
||||
// For remote rendering targets.
|
||||
r->c->base.slot.fovs[i] = fov;
|
||||
r->c->base.slot.poses[i] = result.pose;
|
||||
r->c->base.frame_params.fovs[i] = fov;
|
||||
r->c->base.frame_params.poses[i] = result.pose;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,16 +856,16 @@ dispatch_graphics(struct comp_renderer *r,
|
|||
VkResult ret;
|
||||
|
||||
// Basics
|
||||
const struct comp_layer *layers = c->base.slot.layers;
|
||||
uint32_t layer_count = c->base.slot.layer_count;
|
||||
bool fast_path = c->base.slot.one_projection_layer_fast_path;
|
||||
const struct comp_layer *layers = c->base.layer_accum.layers;
|
||||
uint32_t layer_count = c->base.layer_accum.layer_count;
|
||||
bool fast_path = c->base.frame_params.one_projection_layer_fast_path;
|
||||
bool do_timewarp = !c->debug.atw_off;
|
||||
|
||||
// Resources for the distortion render target.
|
||||
struct render_gfx_target_resources *rtr = &r->rtr_array[r->acquired_buffer];
|
||||
|
||||
// Consistency check.
|
||||
assert(!fast_path || c->base.slot.layer_count >= 1);
|
||||
assert(!fast_path || c->base.layer_accum.layer_count >= 1);
|
||||
|
||||
// Viewport information.
|
||||
struct render_viewport_data viewport_datas[XRT_MAX_VIEWS];
|
||||
|
@ -982,9 +982,9 @@ dispatch_compute(struct comp_renderer *r,
|
|||
VkResult ret;
|
||||
|
||||
// Basics
|
||||
const struct comp_layer *layers = c->base.slot.layers;
|
||||
uint32_t layer_count = c->base.slot.layer_count;
|
||||
bool fast_path = c->base.slot.one_projection_layer_fast_path;
|
||||
const struct comp_layer *layers = c->base.layer_accum.layers;
|
||||
uint32_t layer_count = c->base.layer_accum.layer_count;
|
||||
bool fast_path = c->base.frame_params.one_projection_layer_fast_path;
|
||||
bool do_timewarp = !c->debug.atw_off;
|
||||
|
||||
// Device view information.
|
||||
|
|
|
@ -425,7 +425,7 @@ null_compositor_layer_commit(struct xrt_compositor *xc, xrt_graphics_sync_handle
|
|||
struct null_compositor *c = null_compositor(xc);
|
||||
NULL_TRACE(c, "LAYER_COMMIT");
|
||||
|
||||
int64_t frame_id = c->base.slot.data.frame_id;
|
||||
int64_t frame_id = c->base.layer_accum.data.frame_id;
|
||||
|
||||
/*
|
||||
* The null compositor doesn't render any frames, but needs to do
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
// Copyright 2019-2023, Collabora, Ltd.
|
||||
// Copyright 2019-2024, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Helper implementation for native compositors.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
|
||||
#include "util/comp_layer_accum.h"
|
||||
#include "util/comp_sync.h"
|
||||
#include "util/u_wait.h"
|
||||
#include "util/u_trace_marker.h"
|
||||
|
||||
|
@ -21,26 +24,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
static xrt_result_t
|
||||
do_single_layer(struct xrt_compositor *xc,
|
||||
struct xrt_device *xdev,
|
||||
struct xrt_swapchain *xsc,
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
|
||||
uint32_t layer_id = cb->slot.layer_count;
|
||||
|
||||
struct comp_layer *layer = &cb->slot.layers[layer_id];
|
||||
layer->sc_array[0] = comp_swapchain(xsc);
|
||||
layer->sc_array[1] = NULL;
|
||||
layer->data = *data;
|
||||
|
||||
cb->slot.layer_count++;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -48,6 +31,7 @@ do_single_layer(struct xrt_compositor *xc,
|
|||
*
|
||||
*/
|
||||
|
||||
//! Delegates to code in `comp_swapchain`
|
||||
static xrt_result_t
|
||||
base_get_swapchain_create_properties(struct xrt_compositor *xc,
|
||||
const struct xrt_swapchain_create_info *info,
|
||||
|
@ -56,6 +40,7 @@ base_get_swapchain_create_properties(struct xrt_compositor *xc,
|
|||
return comp_swapchain_get_create_properties(info, xsccp);
|
||||
}
|
||||
|
||||
//! Delegates to code in `comp_swapchain`
|
||||
static xrt_result_t
|
||||
base_create_swapchain(struct xrt_compositor *xc,
|
||||
const struct xrt_swapchain_create_info *info,
|
||||
|
@ -73,6 +58,7 @@ base_create_swapchain(struct xrt_compositor *xc,
|
|||
return comp_swapchain_create(&cb->vk, &cb->cscs, info, &xsccp, out_xsc);
|
||||
}
|
||||
|
||||
//! Delegates to code in `comp_swapchain`
|
||||
static xrt_result_t
|
||||
base_import_swapchain(struct xrt_compositor *xc,
|
||||
const struct xrt_swapchain_create_info *info,
|
||||
|
@ -85,6 +71,7 @@ base_import_swapchain(struct xrt_compositor *xc,
|
|||
return comp_swapchain_import(&cb->vk, &cb->cscs, info, native_images, image_count, out_xsc);
|
||||
}
|
||||
|
||||
//! Delegates to code in `comp_sync`
|
||||
static xrt_result_t
|
||||
base_import_fence(struct xrt_compositor *xc, xrt_graphics_sync_handle_t handle, struct xrt_compositor_fence **out_xcf)
|
||||
{
|
||||
|
@ -93,6 +80,7 @@ base_import_fence(struct xrt_compositor *xc, xrt_graphics_sync_handle_t handle,
|
|||
return comp_fence_import(&cb->vk, handle, out_xcf);
|
||||
}
|
||||
|
||||
//! Delegates to code in `comp_semaphore`
|
||||
static xrt_result_t
|
||||
base_create_semaphore(struct xrt_compositor *xc,
|
||||
xrt_graphics_sync_handle_t *out_handle,
|
||||
|
@ -107,11 +95,7 @@ static xrt_result_t
|
|||
base_layer_begin(struct xrt_compositor *xc, const struct xrt_layer_frame_data *data)
|
||||
{
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
|
||||
cb->slot.data = *data;
|
||||
cb->slot.layer_count = 0;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
return comp_layer_accum_begin(&cb->layer_accum, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -121,19 +105,7 @@ base_layer_projection(struct xrt_compositor *xc,
|
|||
const struct xrt_layer_data *data)
|
||||
{
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
|
||||
uint32_t layer_id = cb->slot.layer_count;
|
||||
|
||||
struct comp_layer *layer = &cb->slot.layers[layer_id];
|
||||
assert(ARRAY_SIZE(layer->sc_array) >= data->view_count);
|
||||
for (uint32_t i = 0; i < data->view_count; ++i) {
|
||||
layer->sc_array[i] = comp_swapchain(xsc[i]);
|
||||
}
|
||||
layer->data = *data;
|
||||
|
||||
cb->slot.layer_count++;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
return comp_layer_accum_projection(&cb->layer_accum, xsc, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -144,19 +116,7 @@ base_layer_projection_depth(struct xrt_compositor *xc,
|
|||
const struct xrt_layer_data *data)
|
||||
{
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
|
||||
uint32_t layer_id = cb->slot.layer_count;
|
||||
|
||||
struct comp_layer *layer = &cb->slot.layers[layer_id];
|
||||
for (uint32_t i = 0; i < data->view_count; ++i) {
|
||||
layer->sc_array[i] = comp_swapchain(xsc[i]);
|
||||
layer->sc_array[i + data->view_count] = comp_swapchain(d_xsc[i]);
|
||||
}
|
||||
layer->data = *data;
|
||||
|
||||
cb->slot.layer_count++;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
return comp_layer_accum_projection_depth(&cb->layer_accum, xsc, d_xsc, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -165,7 +125,8 @@ base_layer_quad(struct xrt_compositor *xc,
|
|||
struct xrt_swapchain *xsc,
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
return do_single_layer(xc, xdev, xsc, data);
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
return comp_layer_accum_quad(&cb->layer_accum, xsc, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -174,7 +135,8 @@ base_layer_cube(struct xrt_compositor *xc,
|
|||
struct xrt_swapchain *xsc,
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
return do_single_layer(xc, xdev, xsc, data);
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
return comp_layer_accum_cube(&cb->layer_accum, xsc, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -183,7 +145,8 @@ base_layer_cylinder(struct xrt_compositor *xc,
|
|||
struct xrt_swapchain *xsc,
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
return do_single_layer(xc, xdev, xsc, data);
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
return comp_layer_accum_cylinder(&cb->layer_accum, xsc, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -192,7 +155,8 @@ base_layer_equirect1(struct xrt_compositor *xc,
|
|||
struct xrt_swapchain *xsc,
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
return do_single_layer(xc, xdev, xsc, data);
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
return comp_layer_accum_equirect1(&cb->layer_accum, xsc, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
@ -201,7 +165,8 @@ base_layer_equirect2(struct xrt_compositor *xc,
|
|||
struct xrt_swapchain *xsc,
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
return do_single_layer(xc, xdev, xsc, data);
|
||||
struct comp_base *cb = comp_base(xc);
|
||||
return comp_layer_accum_equirect2(&cb->layer_accum, xsc, data);
|
||||
}
|
||||
|
||||
static xrt_result_t
|
||||
|
|
|
@ -1,63 +1,33 @@
|
|||
// Copyright 2019-2023, Collabora, Ltd.
|
||||
// Copyright 2019-2024, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Helper implementation for native compositors.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/comp_sync.h"
|
||||
#include "util/comp_swapchain.h"
|
||||
#include "util/comp_layer_accum.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define COMP_MAX_LAYERS 16
|
||||
|
||||
/*!
|
||||
* A single layer.
|
||||
* Additional per-frame parameters.
|
||||
*
|
||||
* Independent of graphics API, swapchain implementation, etc.
|
||||
*
|
||||
* @ingroup comp_util
|
||||
* @see comp_layer_slot
|
||||
*/
|
||||
struct comp_layer
|
||||
struct comp_frame_params
|
||||
{
|
||||
/*!
|
||||
* Up to four compositor swapchains referenced per layer.
|
||||
*
|
||||
* Unused elements should be set to null.
|
||||
*/
|
||||
struct comp_swapchain *sc_array[XRT_MAX_VIEWS * 2];
|
||||
|
||||
/*!
|
||||
* All basic (trivially-serializable) data associated with a layer.
|
||||
*/
|
||||
struct xrt_layer_data data;
|
||||
};
|
||||
|
||||
/*!
|
||||
* A stack of layers.
|
||||
*
|
||||
* @ingroup comp_util
|
||||
* @see comp_base
|
||||
*/
|
||||
struct comp_layer_slot
|
||||
{
|
||||
//! The per frame data.
|
||||
struct xrt_layer_frame_data data;
|
||||
|
||||
//! All of the layers.
|
||||
struct comp_layer layers[COMP_MAX_LAYERS];
|
||||
|
||||
//! Number of submitted layers.
|
||||
uint32_t layer_count;
|
||||
|
||||
//! Special case one layer projection/projection-depth fast-path.
|
||||
bool one_projection_layer_fast_path;
|
||||
|
||||
|
@ -108,8 +78,11 @@ struct comp_base
|
|||
//! Swapchain garbage collector, used by swapchain, child class needs to call.
|
||||
struct comp_swapchain_shared cscs;
|
||||
|
||||
//! We only need to track a single slot.
|
||||
struct comp_layer_slot slot;
|
||||
//! Collect layers for a single frame.
|
||||
struct comp_layer_accum layer_accum;
|
||||
|
||||
//! Parameters for a single frame.
|
||||
struct comp_frame_params frame_params;
|
||||
};
|
||||
|
||||
|
||||
|
|
129
src/xrt/compositor/util/comp_layer_accum.c
Normal file
129
src/xrt/compositor/util/comp_layer_accum.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Copyright 2019-2024, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Re-assemble a collection of composition layers submitted for a frame.
|
||||
*
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
|
||||
#include "comp_layer_accum.h"
|
||||
#include "util/u_misc.h"
|
||||
#include "xrt/xrt_compositor.h"
|
||||
#include "xrt/xrt_limits.h"
|
||||
|
||||
// Shared implementation of accumulating a layer with only a single swapchain image.
|
||||
static xrt_result_t
|
||||
push_single_swapchain_layer(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data)
|
||||
{
|
||||
uint32_t layer_id = cla->layer_count;
|
||||
|
||||
struct comp_layer *layer = &cla->layers[layer_id];
|
||||
U_ZERO_ARRAY(layer->sc_array);
|
||||
layer->sc_array[0] = xsc;
|
||||
layer->data = *data;
|
||||
|
||||
cla->layer_count++;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
struct xrt_swapchain *
|
||||
comp_layer_get_swapchain(const struct comp_layer *cl, uint32_t swapchain_index)
|
||||
{
|
||||
|
||||
return cl->sc_array[swapchain_index];
|
||||
}
|
||||
|
||||
struct xrt_swapchain *
|
||||
comp_layer_get_depth_swapchain(const struct comp_layer *cl, uint32_t swapchain_index)
|
||||
{
|
||||
|
||||
assert(cl->data.type == XRT_LAYER_PROJECTION_DEPTH);
|
||||
return cl->sc_array[XRT_MAX_VIEWS + swapchain_index];
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_begin(struct comp_layer_accum *cla, const struct xrt_layer_frame_data *data)
|
||||
{
|
||||
cla->data = *data;
|
||||
cla->layer_count = 0;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_projection(struct comp_layer_accum *cla,
|
||||
struct xrt_swapchain *xsc[XRT_MAX_VIEWS],
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
|
||||
uint32_t layer_id = cla->layer_count;
|
||||
|
||||
struct comp_layer *layer = &cla->layers[layer_id];
|
||||
assert(ARRAY_SIZE(layer->sc_array) >= data->view_count);
|
||||
U_ZERO_ARRAY(layer->sc_array);
|
||||
for (uint32_t i = 0; i < data->view_count; ++i) {
|
||||
layer->sc_array[i] = xsc[i];
|
||||
}
|
||||
layer->data = *data;
|
||||
|
||||
cla->layer_count++;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_projection_depth(struct comp_layer_accum *cla,
|
||||
struct xrt_swapchain *xsc[XRT_MAX_VIEWS],
|
||||
struct xrt_swapchain *d_xsc[XRT_MAX_VIEWS],
|
||||
const struct xrt_layer_data *data)
|
||||
{
|
||||
|
||||
uint32_t layer_id = cla->layer_count;
|
||||
|
||||
struct comp_layer *layer = &cla->layers[layer_id];
|
||||
U_ZERO_ARRAY(layer->sc_array);
|
||||
for (uint32_t i = 0; i < data->view_count; ++i) {
|
||||
layer->sc_array[i] = xsc[i];
|
||||
layer->sc_array[i + data->view_count] = d_xsc[i];
|
||||
}
|
||||
layer->data = *data;
|
||||
|
||||
cla->layer_count++;
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_quad(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data)
|
||||
{
|
||||
return push_single_swapchain_layer(cla, xsc, data);
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_cube(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data)
|
||||
{
|
||||
return push_single_swapchain_layer(cla, xsc, data);
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_cylinder(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data)
|
||||
{
|
||||
return push_single_swapchain_layer(cla, xsc, data);
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_equirect1(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data)
|
||||
{
|
||||
return push_single_swapchain_layer(cla, xsc, data);
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
comp_layer_accum_equirect2(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data)
|
||||
{
|
||||
return push_single_swapchain_layer(cla, xsc, data);
|
||||
}
|
212
src/xrt/compositor/util/comp_layer_accum.h
Normal file
212
src/xrt/compositor/util/comp_layer_accum.h
Normal file
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2019-2024, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Re-assemble a collection of composition layers submitted for a frame.
|
||||
*
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xrt/xrt_compositor.h"
|
||||
#include "xrt/xrt_limits.h"
|
||||
#include "xrt/xrt_results.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define COMP_MAX_LAYERS 16
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct xrt_swapchain;
|
||||
|
||||
/*!
|
||||
* A single layer in a @ref comp_layer_accum.
|
||||
*
|
||||
* Independent of graphics API, swapchain implementation, etc.
|
||||
*
|
||||
* @ingroup comp_util
|
||||
* @see comp_layer_accum
|
||||
*/
|
||||
struct comp_layer
|
||||
{
|
||||
/*!
|
||||
* Up to two compositor swapchains referenced per view (color and depth) for a layer.
|
||||
*
|
||||
* Unused elements should be set to null.
|
||||
*/
|
||||
struct xrt_swapchain *sc_array[XRT_MAX_VIEWS * 2];
|
||||
|
||||
/*!
|
||||
* All basic (trivially-serializable) data associated with a layer.
|
||||
*/
|
||||
struct xrt_layer_data data;
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* Get a (color) swapchain associated with a layer.
|
||||
*
|
||||
* @param cla self
|
||||
* @param swapchain_index index of swapchain - typically this is 0 for most layers, the view index for projection.
|
||||
|
||||
* @public @memberof comp_layer
|
||||
*/
|
||||
struct xrt_swapchain *
|
||||
comp_layer_get_swapchain(const struct comp_layer *cl, uint32_t swapchain_index);
|
||||
|
||||
|
||||
/*!
|
||||
* Get a depth swapchain associated with a (projection with depth) layer
|
||||
*
|
||||
* @param cla self
|
||||
* @param swapchain_index index of **color** swapchain - typically this is the view index.
|
||||
*
|
||||
* @public @memberof comp_layer
|
||||
*/
|
||||
struct xrt_swapchain *
|
||||
comp_layer_get_depth_swapchain(const struct comp_layer *cl, uint32_t swapchain_index);
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* Collect a stack of layers - one frame's worth.
|
||||
*
|
||||
* Independent of graphics API, swapchain implementation, etc.
|
||||
*
|
||||
* Used to turn the step by step "one call per layer" compositor API back
|
||||
* into a single structure per frame.
|
||||
*
|
||||
* @ingroup comp_util
|
||||
* @see comp_layer
|
||||
*/
|
||||
struct comp_layer_accum
|
||||
{
|
||||
//! The per frame data, supplied by `begin`.
|
||||
struct xrt_layer_frame_data data;
|
||||
|
||||
//! All of the layers.
|
||||
struct comp_layer layers[COMP_MAX_LAYERS];
|
||||
|
||||
//! Number of submitted layers.
|
||||
uint32_t layer_count;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Reset all layer data and reset count to 0.
|
||||
*
|
||||
* Call at the beginning of a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_begin(struct comp_layer_accum *cla, const struct xrt_layer_frame_data *data);
|
||||
|
||||
/*!
|
||||
* Accumulate swapchains and data for a projection layer for a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_projection(struct comp_layer_accum *cla,
|
||||
struct xrt_swapchain *xsc[XRT_MAX_VIEWS],
|
||||
const struct xrt_layer_data *data);
|
||||
|
||||
/*!
|
||||
* Accumulate swapchains and data for a projection layer (with depth image) for a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_projection_depth(struct comp_layer_accum *cla,
|
||||
struct xrt_swapchain *xsc[XRT_MAX_VIEWS],
|
||||
struct xrt_swapchain *d_xsc[XRT_MAX_VIEWS],
|
||||
const struct xrt_layer_data *data);
|
||||
/*!
|
||||
* Accumulate swapchain and data for a quad layer for a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_quad(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data);
|
||||
|
||||
|
||||
/*!
|
||||
* Accumulate swapchain and data for a cube layer for a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_cube(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data);
|
||||
|
||||
|
||||
/*!
|
||||
* Accumulate swapchain and data for a cylinder layer for a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_cylinder(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data);
|
||||
|
||||
|
||||
/*!
|
||||
* Accumulate swapchain and data for an equirect(1) layer for a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_equirect1(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data);
|
||||
|
||||
|
||||
/*!
|
||||
* Accumulate swapchain and data for an equirect2 layer for a frame.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
xrt_result_t
|
||||
comp_layer_accum_equirect2(struct comp_layer_accum *cla, struct xrt_swapchain *xsc, const struct xrt_layer_data *data);
|
||||
|
||||
|
||||
/*!
|
||||
* Get a (color) swapchain associated with a layer.
|
||||
*
|
||||
* @param cla self
|
||||
* @param layer_index index of layer
|
||||
* @param swapchain_index index of swapchain - typically this is 0 for most layers, the view index for projection.
|
||||
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
inline struct xrt_swapchain *
|
||||
comp_layer_accum_get_swapchain(const struct comp_layer_accum *cla, uint32_t layer_index, uint32_t swapchain_index)
|
||||
{
|
||||
assert(layer_index < cla->layer_count);
|
||||
return cla->layers[layer_index].sc_array[swapchain_index];
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get a depth swapchain associated with a (projection with depth) layer
|
||||
*
|
||||
* @param cla self
|
||||
* @param layer_index index of layer
|
||||
* @param swapchain_index index of **color** swapchain - typically this is the view index.
|
||||
*
|
||||
* @public @memberof comp_layer_accum
|
||||
*/
|
||||
inline struct xrt_swapchain *
|
||||
comp_layer_accum_get_depth_swapchain(const struct comp_layer_accum *cla, uint32_t layer_index, uint32_t swapchain_index)
|
||||
{
|
||||
assert(layer_index < cla->layer_count);
|
||||
assert(cla->layers[layer_index].data.type == XRT_LAYER_PROJECTION_DEPTH);
|
||||
return cla->layers[layer_index].sc_array[XRT_MAX_VIEWS + swapchain_index];
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -6,9 +6,11 @@
|
|||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Christoph Haag <christoph.haag@collabora.com>
|
||||
* @author Fernando Velazquez Innella <finnella@magicleap.com>
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
#include "util/comp_layer_accum.h"
|
||||
#include "xrt/xrt_compositor.h"
|
||||
|
||||
#include "os/os_time.h"
|
||||
|
@ -34,6 +36,23 @@
|
|||
*
|
||||
*/
|
||||
|
||||
static inline const struct comp_swapchain_image *
|
||||
get_layer_image(const struct comp_layer *layer, uint32_t swapchain_index, uint32_t image_index)
|
||||
{
|
||||
|
||||
const struct comp_swapchain *sc = (struct comp_swapchain *)(comp_layer_get_swapchain(layer, swapchain_index));
|
||||
return &sc->images[image_index];
|
||||
}
|
||||
|
||||
static inline const struct comp_swapchain_image *
|
||||
get_layer_depth_image(const struct comp_layer *layer, uint32_t swapchain_index, uint32_t image_index)
|
||||
{
|
||||
|
||||
const struct comp_swapchain *sc =
|
||||
(struct comp_swapchain *)(comp_layer_get_depth_swapchain(layer, swapchain_index));
|
||||
return &sc->images[image_index];
|
||||
}
|
||||
|
||||
static inline void
|
||||
do_cs_equirect2_layer(const struct xrt_layer_data *data,
|
||||
const struct comp_layer *layer,
|
||||
|
@ -49,10 +68,10 @@ do_cs_equirect2_layer(const struct xrt_layer_data *data,
|
|||
struct render_compute_layer_ubo_data *ubo_data,
|
||||
uint32_t *out_cur_image)
|
||||
{
|
||||
const struct xrt_layer_equirect2_data *eq2 = &data->equirect2;
|
||||
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[0]->images[eq2->sub.image_index];
|
||||
uint32_t array_index = eq2->sub.array_index;
|
||||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_equirect2_data *eq2 = &layer_data->equirect2;
|
||||
const uint32_t array_index = eq2->sub.array_index;
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, 0, eq2->sub.image_index);
|
||||
|
||||
// Image to use.
|
||||
src_samplers[cur_image] = clamp_to_edge;
|
||||
|
@ -112,18 +131,19 @@ do_cs_projection_layer(const struct xrt_layer_data *data,
|
|||
bool do_timewarp,
|
||||
uint32_t *out_cur_image)
|
||||
{
|
||||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_projection_view_data *vd = NULL;
|
||||
const struct xrt_layer_depth_data *dvd = NULL;
|
||||
|
||||
if (data->type == XRT_LAYER_PROJECTION) {
|
||||
view_index_to_projection_data(view_index, data, &vd);
|
||||
if (layer_data->type == XRT_LAYER_PROJECTION) {
|
||||
view_index_to_projection_data(view_index, layer_data, &vd);
|
||||
} else {
|
||||
view_index_to_depth_data(view_index, data, &vd, &dvd);
|
||||
view_index_to_depth_data(view_index, layer_data, &vd, &dvd);
|
||||
}
|
||||
|
||||
uint32_t sc_array_index = is_view_index_right(view_index) ? 1 : 0;
|
||||
uint32_t array_index = vd->sub.array_index;
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[sc_array_index]->images[vd->sub.image_index];
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, sc_array_index, vd->sub.image_index);
|
||||
|
||||
// Color
|
||||
src_samplers[cur_image] = clamp_to_border_black;
|
||||
|
@ -134,7 +154,7 @@ do_cs_projection_layer(const struct xrt_layer_data *data,
|
|||
if (data->type == XRT_LAYER_PROJECTION_DEPTH) {
|
||||
uint32_t d_array_index = dvd->sub.array_index;
|
||||
const struct comp_swapchain_image *d_image =
|
||||
&layer->sc_array[sc_array_index + 2]->images[dvd->sub.image_index];
|
||||
get_layer_depth_image(layer, sc_array_index, dvd->sub.image_index);
|
||||
|
||||
src_samplers[cur_image] = clamp_to_edge; // Edge to keep depth stable at edges.
|
||||
src_image_views[cur_image] = get_image_view(d_image, data->flags, d_array_index);
|
||||
|
@ -174,10 +194,10 @@ do_cs_quad_layer(const struct xrt_layer_data *data,
|
|||
struct render_compute_layer_ubo_data *ubo_data,
|
||||
uint32_t *out_cur_image)
|
||||
{
|
||||
const struct xrt_layer_quad_data *q = &data->quad;
|
||||
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[0]->images[q->sub.image_index];
|
||||
uint32_t array_index = q->sub.array_index;
|
||||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_quad_data *q = &layer_data->quad;
|
||||
const uint32_t array_index = q->sub.array_index;
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, 0, q->sub.image_index);
|
||||
|
||||
// Image to use.
|
||||
src_samplers[cur_image] = clamp_to_edge;
|
||||
|
@ -257,10 +277,10 @@ do_cs_cylinder_layer(const struct xrt_layer_data *data,
|
|||
struct render_compute_layer_ubo_data *ubo_data,
|
||||
uint32_t *out_cur_image)
|
||||
{
|
||||
const struct xrt_layer_cylinder_data *c = &data->cylinder;
|
||||
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[0]->images[c->sub.image_index];
|
||||
uint32_t array_index = c->sub.array_index;
|
||||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_cylinder_data *c = &layer_data->cylinder;
|
||||
const uint32_t array_index = c->sub.array_index;
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, 0, c->sub.image_index);
|
||||
|
||||
// Image to use.
|
||||
src_samplers[cur_image] = clamp_to_edge;
|
||||
|
@ -268,7 +288,7 @@ do_cs_cylinder_layer(const struct xrt_layer_data *data,
|
|||
|
||||
// Used for Subimage and OpenGL flip.
|
||||
set_post_transform_rect( //
|
||||
data, // data
|
||||
layer_data, // data
|
||||
&c->sub.norm_rect, // src_norm_rect
|
||||
false, // invert_flip
|
||||
&ubo_data->post_transforms[cur_layer]); // out_norm_rect
|
||||
|
@ -284,7 +304,7 @@ do_cs_cylinder_layer(const struct xrt_layer_data *data,
|
|||
struct xrt_matrix_4x4 model_inv;
|
||||
math_matrix_4x4_inverse(&model, &model_inv);
|
||||
|
||||
const struct xrt_matrix_4x4 *v = is_layer_view_space(data) ? eye_view_mat : world_view_mat;
|
||||
const struct xrt_matrix_4x4 *v = is_layer_view_space(layer_data) ? eye_view_mat : world_view_mat;
|
||||
|
||||
struct xrt_matrix_4x4 v_inv;
|
||||
math_matrix_4x4_inverse(v, &v_inv);
|
||||
|
@ -413,7 +433,7 @@ do_cs_distortion_for_layer(struct render_compute *crc,
|
|||
struct xrt_normalized_rect src_norm_rect;
|
||||
VkImageView src_image_view;
|
||||
uint32_t array_index = vds[i]->sub.array_index;
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[i]->images[vds[i]->sub.image_index];
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, i, vds[i]->sub.image_index);
|
||||
|
||||
// Gather data.
|
||||
world_pose = d->views[i].world_pose;
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
* @file
|
||||
* @brief Compositor gfx rendering code.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Rylie Pavlik <rylie.pavlik@collabora.com>
|
||||
* @ingroup comp_util
|
||||
*/
|
||||
|
||||
#include "xrt/xrt_compositor.h"
|
||||
#include "util/comp_swapchain.h"
|
||||
|
||||
#include "math/m_api.h"
|
||||
#include "math/m_mathinclude.h"
|
||||
|
@ -217,6 +219,14 @@ calc_mvp_rot_only(struct gfx_layer_view_state *state,
|
|||
*
|
||||
*/
|
||||
|
||||
static inline const struct comp_swapchain_image *
|
||||
get_layer_image(const struct comp_layer *layer, uint32_t swapchain_index, uint32_t image_index)
|
||||
{
|
||||
|
||||
const struct comp_swapchain *sc = (struct comp_swapchain *)(comp_layer_get_swapchain(layer, swapchain_index));
|
||||
return &sc->images[image_index];
|
||||
}
|
||||
|
||||
static inline void
|
||||
add_layer(struct gfx_layer_view_state *state, const struct xrt_layer_data *data, VkDescriptorSet descriptor_set)
|
||||
{
|
||||
|
@ -236,12 +246,12 @@ do_cylinder_layer(struct render_gfx *rr,
|
|||
{
|
||||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_cylinder_data *c = &layer_data->cylinder;
|
||||
const uint32_t array_index = c->sub.array_index;
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, 0, c->sub.image_index);
|
||||
|
||||
struct vk_bundle *vk = rr->r->vk;
|
||||
VkResult ret;
|
||||
|
||||
const uint32_t array_index = c->sub.array_index;
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[0]->images[c->sub.image_index];
|
||||
|
||||
// Color
|
||||
VkSampler src_sampler = clamp_to_edge; // WIP: Is this correct?
|
||||
VkImageView src_image_view = get_image_view(image, layer_data->flags, array_index);
|
||||
|
@ -300,12 +310,12 @@ do_equirect2_layer(struct render_gfx *rr,
|
|||
{
|
||||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_equirect2_data *eq2 = &layer_data->equirect2;
|
||||
const uint32_t array_index = eq2->sub.array_index;
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, 0, eq2->sub.image_index);
|
||||
|
||||
struct vk_bundle *vk = rr->r->vk;
|
||||
VkResult ret;
|
||||
|
||||
const uint32_t array_index = eq2->sub.array_index;
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[0]->images[eq2->sub.image_index];
|
||||
|
||||
// Color
|
||||
VkSampler src_sampler = clamp_to_edge;
|
||||
VkImageView src_image_view = get_image_view(image, layer_data->flags, array_index);
|
||||
|
@ -365,8 +375,6 @@ do_projection_layer(struct render_gfx *rr,
|
|||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_projection_view_data *vd = NULL;
|
||||
const struct xrt_layer_depth_data *dvd = NULL;
|
||||
struct vk_bundle *vk = rr->r->vk;
|
||||
VkResult ret;
|
||||
|
||||
if (layer_data->type == XRT_LAYER_PROJECTION) {
|
||||
view_index_to_projection_data(view_index, layer_data, &vd);
|
||||
|
@ -376,8 +384,10 @@ do_projection_layer(struct render_gfx *rr,
|
|||
|
||||
uint32_t sc_array_index = is_view_index_right(view_index) ? 1 : 0;
|
||||
uint32_t array_index = vd->sub.array_index;
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[sc_array_index]->images[vd->sub.image_index];
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, sc_array_index, vd->sub.image_index);
|
||||
|
||||
struct vk_bundle *vk = rr->r->vk;
|
||||
VkResult ret;
|
||||
// Color
|
||||
VkSampler src_sampler = clamp_to_border_black;
|
||||
VkImageView src_image_view = get_image_view(image, layer_data->flags, array_index);
|
||||
|
@ -426,12 +436,12 @@ do_quad_layer(struct render_gfx *rr,
|
|||
{
|
||||
const struct xrt_layer_data *layer_data = &layer->data;
|
||||
const struct xrt_layer_quad_data *q = &layer_data->quad;
|
||||
const uint32_t array_index = q->sub.array_index;
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, 0, q->sub.image_index);
|
||||
|
||||
struct vk_bundle *vk = rr->r->vk;
|
||||
VkResult ret;
|
||||
|
||||
const uint32_t array_index = q->sub.array_index;
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[0]->images[q->sub.image_index];
|
||||
|
||||
// Color
|
||||
VkSampler src_sampler = clamp_to_edge;
|
||||
VkImageView src_image_view = get_image_view(image, layer_data->flags, array_index);
|
||||
|
@ -762,7 +772,8 @@ do_mesh_from_proj(struct render_gfx *rr,
|
|||
struct gfx_mesh_data md = XRT_STRUCT_INIT;
|
||||
for (uint32_t i = 0; i < d->view_count; i++) {
|
||||
const uint32_t array_index = vds[i]->sub.array_index;
|
||||
const struct comp_swapchain_image *image = &layer->sc_array[i]->images[vds[i]->sub.image_index];
|
||||
|
||||
const struct comp_swapchain_image *image = get_layer_image(layer, 0, vds[i]->sub.image_index);
|
||||
|
||||
struct xrt_pose src_pose;
|
||||
struct xrt_fov src_fov;
|
||||
|
|
|
@ -433,7 +433,7 @@ sdl_compositor_layer_commit(struct xrt_compositor *xc, xrt_graphics_sync_handle_
|
|||
|
||||
struct sdl_program *sp = from_comp(xc);
|
||||
struct sdl_compositor *c = &sp->c;
|
||||
int64_t frame_id = c->base.slot.data.frame_id;
|
||||
int64_t frame_id = c->base.layer_accum.data.frame_id;
|
||||
|
||||
SC_TRACE(c, "LAYER_COMMIT");
|
||||
|
||||
|
|
|
@ -112,13 +112,13 @@ sdl_program_plus_render(struct sdl_program_plus *spp_ptr)
|
|||
// Nothing for now.
|
||||
}
|
||||
|
||||
if (spp.c.base.slot.layer_count == 0) {
|
||||
if (spp.c.base.layer_accum.layer_count == 0) {
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
} else if (spp.c.base.slot.layers[0].data.type == XRT_LAYER_PROJECTION ||
|
||||
spp.c.base.slot.layers[0].data.type == XRT_LAYER_PROJECTION_DEPTH) {
|
||||
} else if (spp.c.base.layer_accum.layers[0].data.type == XRT_LAYER_PROJECTION ||
|
||||
spp.c.base.layer_accum.layers[0].data.type == XRT_LAYER_PROJECTION_DEPTH) {
|
||||
|
||||
auto &l = spp.c.base.slot.layers[0];
|
||||
auto &l = spp.c.base.layer_accum.layers[0];
|
||||
auto &ssc = *(sdl_swapchain *)l.sc_array[0];
|
||||
GLuint tex = ssc.textures[l.data.proj.v[0].sub.image_index];
|
||||
|
||||
|
|
Loading…
Reference in a new issue