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:
Rylie Pavlik 2024-08-28 10:31:00 -05:00 committed by Marge Bot
parent 9f6f6c6df7
commit 338d85543b
13 changed files with 463 additions and 153 deletions

View 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.

View file

@ -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

View file

@ -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);

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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;
};

View 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);
}

View 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

View file

@ -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;

View file

@ -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;

View file

@ -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");

View file

@ -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];