c/main: Use new debuggable scratch images

This commit is contained in:
Jakob Bornecrantz committed 2024-01-04 16:23:28 +00:00
1 parent e7d8cc0310
commit 03c8a1a14e
3 files changed
+212 -70

No files matched your search

+40 -4
View File
@@ -1,4 +1,4 @@
// Copyright 2019-2023, Collabora, Ltd.
// Copyright 2019-2024, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
@@ -291,7 +291,11 @@ compositor_layer_commit(struct xrt_compositor *xc, xrt_graphics_sync_handle_t sy
* We have a fast path for single projection layer that goes directly
* to the distortion shader, so no need to use the layer renderer.
*/
bool fast_path = can_do_one_projection_layer_fast_path(c) && !c->mirroring_to_debug_gui && !c->peek;
bool fast_path = //
!c->peek && //
!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;
@@ -344,6 +348,22 @@ compositor_destroy(struct xrt_compositor *xc)
COMP_DEBUG(c, "COMP_DESTROY");
// Need to do this as early as possible.
u_var_remove_root(c);
// Destroy any Vulkan resources, even if not used.
for (uint32_t i = 0; i < ARRAY_SIZE(c->scratch.views); i++) {
comp_scratch_single_images_free(&c->scratch.views[i], &c->base.vk);
}
// Destroy the scratch images fully, we initialized all of them.
for (uint32_t i = 0; i < ARRAY_SIZE(c->scratch.views); i++) {
comp_scratch_single_images_destroy(&c->scratch.views[i]);
}
// Make sure we are not holding onto any swapchains.
u_swapchain_debug_destroy(&c->debug.sc);
// Make sure we don't have anything to destroy.
comp_swapchain_shared_garbage_collect(&c->base.cscs);
@@ -377,8 +397,7 @@ compositor_destroy(struct xrt_compositor *xc)
vk->instance = VK_NULL_HANDLE;
}
u_var_remove_root(c);
// Can do this now.
u_frame_times_widget_teardown(&c->compositor_frame_times);
comp_base_fini(&c->base);
@@ -938,6 +957,14 @@ comp_main_create_system_compositor(struct xrt_device *xdev,
// Init the settings to default.
comp_settings_init(&c->settings, xdev);
// Init this before the renderer.
u_swapchain_debug_init(&c->debug.sc);
// Init these before the renderer, not all might be used.
for (uint32_t i = 0; i < ARRAY_SIZE(c->scratch.views); i++) {
comp_scratch_single_images_init(&c->scratch.views[i]);
}
c->last_frame_time_ns = os_monotonic_get_ns();
double scale = c->settings.viewport_scale;
@@ -1012,6 +1039,8 @@ comp_main_create_system_compositor(struct xrt_device *xdev,
/*
* Rest of info.
*/
// Hardcoded for now.
uint32_t view_count = 2;
struct xrt_system_compositor_info sys_info_storage = {0};
struct xrt_system_compositor_info *sys_info = &sys_info_storage;
@@ -1057,8 +1086,15 @@ comp_main_create_system_compositor(struct xrt_device *xdev,
u_var_add_ro_f32(c, &c->compositor_frame_times.fps, "FPS (Compositor)");
u_var_add_bool(c, &c->debug.atw_off, "Debug: ATW OFF");
u_var_add_bool(c, &c->debug.disable_fast_path, "Debug: Disable fast path");
u_var_add_f32_timing(c, c->compositor_frame_times.debug_var, "Frame Times (Compositor)");
// Only add active views.
for (uint32_t i = 0; i < view_count; i++) {
char tmp[] = "View[X_XXX_XXX]";
snprintf(tmp, sizeof(tmp), "View[%u]", i);
u_var_add_native_images_debug(c, &c->scratch.views[i].unid, tmp);
}
//! @todo: Query all supported refresh rates of the current mode
sys_info->refresh_rate_count = 1;
+14 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2019-2022, Collabora, Ltd.
// Copyright 2019-2024, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
@@ -17,9 +17,11 @@
#include "util/u_index_fifo.h"
#include "util/u_logging.h"
#include "util/u_frame_times_widget.h"
#include "util/u_native_images_debug.h"
#include "util/comp_base.h"
#include "util/comp_sync.h"
#include "util/comp_scratch.h"
#include "util/comp_swapchain.h"
#include "render/render_interface.h"
@@ -138,10 +140,21 @@ struct comp_compositor
struct comp_frame rendering;
} frame;
struct
{
// Per-view scratch images.
struct comp_scratch_single_images views[2];
} scratch;
struct
{
//! Temporarily disable ATW
bool atw_off;
//! Should the fast path be disabled.
bool disable_fast_path;
struct u_swapchain_debug sc;
} debug;
//! If true, part of the compositor startup will be delayed until a session is started
+158 -65
View File
@@ -105,14 +105,17 @@ struct comp_renderer
struct comp_mirror_to_debug_gui mirror_to_debug_gui;
//! Scratch images used for layer squasher.
struct render_scratch_images scratch;
//! Render pass for graphics pipeline rendering to the scratch buffer.
struct render_gfx_render_pass scratch_render_pass;
//! Targets for rendering to the scratch buffer.
struct render_gfx_target_resources scratch_targets[2];
struct
{
struct
{
//! Targets for rendering to the scratch buffer.
struct render_gfx_target_resources targets[COMP_SCRATCH_NUM_IMAGES];
} views[2];
} scratch;
//! @}
@@ -151,6 +154,49 @@ struct comp_renderer
//! @}
};
struct comp_scratch_view_state
{
uint32_t index;
bool used;
};
struct comp_render_scratch_state
{
struct comp_scratch_view_state views[2];
};
/*
*
* Scratch helpers.
*
*/
static void
scratch_get_init(struct comp_render_scratch_state *crss, struct comp_renderer *r, uint32_t view_count)
{
struct comp_compositor *c = r->c;
U_ZERO(crss);
for (uint32_t i = 0; i < view_count; i++) {
comp_scratch_single_images_get(&c->scratch.views[i], &crss->views[i].index);
}
}
static void
scratch_get_fini(struct comp_render_scratch_state *crss, struct comp_renderer *r, uint32_t view_count)
{
struct comp_compositor *c = r->c;
for (uint32_t i = 0; i < view_count; i++) {
if (crss->views[i].used) {
comp_scratch_single_images_done(&c->scratch.views[i]);
} else {
comp_scratch_single_images_discard(&c->scratch.views[i]);
}
}
}
/*
*
@@ -515,6 +561,9 @@ renderer_ensure_images_and_renderings(struct comp_renderer *r, bool force_recrea
static void
renderer_init(struct comp_renderer *r, struct comp_compositor *c, VkExtent2D scratch_extent)
{
COMP_TRACE_MARKER();
bool bret;
r->c = c;
r->settings = &c->settings;
@@ -522,12 +571,7 @@ renderer_init(struct comp_renderer *r, struct comp_compositor *c, VkExtent2D scr
r->fenced_buffer = -1;
r->rtr_array = NULL;
bool bret = render_scratch_images_ensure(&c->nr, &r->scratch, scratch_extent);
if (!bret) {
COMP_ERROR(c, "render_scratch_images_ensure: false");
assert(false && "Whelp, can't return an error. But should never really fail.");
}
// Shared render pass between all scratch images.
render_gfx_render_pass_init( //
&r->scratch_render_pass, // rgrp
&r->c->nr, // r
@@ -535,13 +579,23 @@ renderer_init(struct comp_renderer *r, struct comp_compositor *c, VkExtent2D scr
VK_ATTACHMENT_LOAD_OP_CLEAR, // load_op
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // final_layout
for (uint32_t i = 0; i < ARRAY_SIZE(r->scratch_targets); i++) {
render_gfx_target_resources_init( //
&r->scratch_targets[i], //
&r->c->nr, //
&r->scratch_render_pass, //
r->scratch.color[i].srgb_view, //
scratch_extent); //
for (uint32_t i = 0; i < ARRAY_SIZE(r->scratch.views); i++) {
bret = comp_scratch_single_images_ensure(&r->c->scratch.views[i], &r->c->base.vk, scratch_extent);
if (!bret) {
COMP_ERROR(c, "comp_scratch_single_images_ensure: false");
assert(false && "Whelp, can't return an error. But should never really fail.");
}
for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) {
struct render_scratch_color_image *rsci = &c->scratch.views[i].images[k];
render_gfx_target_resources_init( //
&r->scratch.views[i].targets[k], //
&r->c->nr, //
&r->scratch_render_pass, //
rsci->srgb_view, //
scratch_extent); //
}
}
// Try to early-allocate these, in case we can.
@@ -553,7 +607,7 @@ renderer_init(struct comp_renderer *r, struct comp_compositor *c, VkExtent2D scr
&r->mirror_to_debug_gui, //
vk, //
&c->shaders, //
r->scratch.extent); //
scratch_extent); //
if (ret != VK_SUCCESS) {
COMP_ERROR(c, "comp_mirror_init: %s", vk_result_string(ret));
assert(false && "Whelp, can't return a error. But should never really fail.");
@@ -762,15 +816,14 @@ renderer_fini(struct comp_renderer *r)
comp_mirror_fini(&r->mirror_to_debug_gui, vk);
// Do this after the layer renderer.
for (uint32_t i = 0; i < ARRAY_SIZE(r->scratch_targets); i++) {
render_gfx_target_resources_close(&r->scratch_targets[i]);
for (uint32_t i = 0; i < ARRAY_SIZE(r->scratch.views); i++) {
for (uint32_t k = 0; k < COMP_SCRATCH_NUM_IMAGES; k++) {
render_gfx_target_resources_close(&r->scratch.views[i].targets[k]);
}
}
// Do this after the layer renderer and targert resources.
render_gfx_render_pass_close(&r->scratch_render_pass);
// Destroy any scratch images created.
render_scratch_images_close(&r->c->nr, &r->scratch);
}
@@ -784,7 +837,10 @@ renderer_fini(struct comp_renderer *r)
* @pre render_gfx_init(rr, &c->nr)
*/
static XRT_CHECK_RESULT VkResult
dispatch_graphics(struct comp_renderer *r, struct render_gfx *rr, enum comp_target_fov_source fov_source)
dispatch_graphics(struct comp_renderer *r,
struct render_gfx *rr,
struct comp_render_scratch_state *crss,
enum comp_target_fov_source fov_source)
{
COMP_TRACE_MARKER();
@@ -823,8 +879,6 @@ dispatch_graphics(struct comp_renderer *r, struct render_gfx *rr, enum comp_targ
world_poses, // world_poses[2]
eye_poses); // eye_poses[2]
// Scratch image we are rendering to.
struct render_scratch_images *rsi = &r->scratch;
// The arguments for the dispatch function.
struct comp_render_dispatch_data data;
@@ -835,18 +889,24 @@ dispatch_graphics(struct comp_renderer *r, struct render_gfx *rr, enum comp_targ
do_timewarp); // do_timewarp
for (uint32_t i = 0; i < 2; i++) {
// Scratch color image.
struct render_scratch_color_image *rsci = &rsi->color[i];
// Which image of the scratch images for this view are we using.
uint32_t scratch_index = crss->views[i].index;
// The set of scratch images we are using for this view.
struct comp_scratch_single_images *scratch_view = &c->scratch.views[i];
// The render target resources for the scratch images.
struct render_gfx_target_resources *rsci_rtr = &r->scratch_targets[i];
struct render_gfx_target_resources *rsci_rtr = &r->scratch.views[i].targets[scratch_index];
// Scratch color image.
struct render_scratch_color_image *rsci = &scratch_view->images[scratch_index];
// Use the whole scratch image.
struct render_viewport_data layer_viewport_data = {
.x = 0,
.y = 0,
.w = rsi->extent.width,
.h = rsi->extent.height,
.w = scratch_view->info.width,
.h = scratch_view->info.height,
};
// Scratch image covers the whole image.
@@ -864,6 +924,12 @@ dispatch_graphics(struct comp_renderer *r, struct render_gfx *rr, enum comp_targ
rsci->srgb_view, // srgb_view
&vertex_rots[i], // vertex_rot
&viewport_datas[i]); // target_viewport_data
if (layer_count == 0) {
crss->views[i].used = false;
} else {
crss->views[i].used = !fast_path;
}
}
// Start the graphics pipeline.
@@ -899,7 +965,10 @@ dispatch_graphics(struct comp_renderer *r, struct render_gfx *rr, enum comp_targ
* @pre render_compute_init(crc, &c->nr)
*/
static XRT_CHECK_RESULT VkResult
dispatch_compute(struct comp_renderer *r, struct render_compute *crc, enum comp_target_fov_source fov_source)
dispatch_compute(struct comp_renderer *r,
struct render_compute *crc,
struct comp_render_scratch_state *crss,
enum comp_target_fov_source fov_source)
{
COMP_TRACE_MARKER();
@@ -932,9 +1001,6 @@ dispatch_compute(struct comp_renderer *r, struct render_compute *crc, enum comp_
struct render_viewport_data views[2];
calc_viewport_data(r, &views[0], &views[1]);
// Scratch image we are rendering to.
struct render_scratch_images *rsi = &r->scratch;
// The arguments for the dispatch function.
struct comp_render_dispatch_data data;
comp_render_cs_initial_init( //
@@ -945,15 +1011,21 @@ dispatch_compute(struct comp_renderer *r, struct render_compute *crc, enum comp_
do_timewarp); // do_timewarp
for (uint32_t i = 0; i < 2; i++) {
// Which image of the scratch images for this view are we using.
uint32_t scratch_index = crss->views[i].index;
// The set of scratch images we are using for this view.
struct comp_scratch_single_images *scratch_view = &c->scratch.views[i];
// Scratch color image.
struct render_scratch_color_image *rsci = &rsi->color[i];
struct render_scratch_color_image *rsci = &scratch_view->images[scratch_index];
// Use the whole scratch image.
struct render_viewport_data layer_viewport_data = {
.x = 0,
.y = 0,
.w = rsi->extent.width,
.h = rsi->extent.height,
.w = scratch_view->info.width,
.h = scratch_view->info.height,
};
// Scratch image covers the whole image.
@@ -970,6 +1042,12 @@ dispatch_compute(struct comp_renderer *r, struct render_compute *crc, enum comp_
rsci->srgb_view, // srgb_view
rsci->unorm_view, // unorm_view
&views[i]); // target_viewport_data
if (layer_count == 0) {
crss->views[i].used = false;
} else {
crss->views[i].used = !fast_path;
}
}
// Start the compute pipeline.
@@ -1042,8 +1120,13 @@ comp_renderer_draw(struct comp_renderer *r)
comp_target_update_timings(ct);
// Hardcoded for now.
uint32_t view_count = 2;
enum comp_target_fov_source fov_source = COMP_TARGET_FOV_SOURCE_DISTORTION;
// For sratch image debugging.
struct comp_render_scratch_state crss;
scratch_get_init(&crss, r, view_count);
bool use_compute = r->settings->use_compute;
struct render_gfx rr = {0};
struct render_compute crc = {0};
@@ -1051,10 +1134,10 @@ comp_renderer_draw(struct comp_renderer *r)
VkResult res = VK_SUCCESS;
if (use_compute) {
render_compute_init(&crc, &c->nr);
res = dispatch_compute(r, &crc, fov_source);
res = dispatch_compute(r, &crc, &crss, fov_source);
} else {
render_gfx_init(&rr, &c->nr);
res = dispatch_graphics(r, &rr, fov_source);
res = dispatch_graphics(r, &rr, &crss, fov_source);
}
if (res != VK_SUCCESS) {
return XRT_ERROR_VULKAN;
@@ -1063,20 +1146,22 @@ comp_renderer_draw(struct comp_renderer *r)
#ifdef XRT_FEATURE_WINDOW_PEEK
if (c->peek) {
switch (comp_window_peek_get_eye(c->peek)) {
case COMP_WINDOW_PEEK_EYE_LEFT:
comp_window_peek_blit( //
c->peek, //
r->scratch.color[0].image, //
r->scratch.extent.width, //
r->scratch.extent.height); //
break;
case COMP_WINDOW_PEEK_EYE_RIGHT:
comp_window_peek_blit( //
c->peek, //
r->scratch.color[1].image, //
r->scratch.extent.width, //
r->scratch.extent.height); //
break;
case COMP_WINDOW_PEEK_EYE_LEFT: {
struct comp_scratch_single_images *view = &c->scratch.views[0];
comp_window_peek_blit( //
c->peek, //
view->images[crss.views[0].index].image, //
view->info.width, //
view->info.height); //
} break;
case COMP_WINDOW_PEEK_EYE_RIGHT: {
struct comp_scratch_single_images *view = &c->scratch.views[1];
comp_window_peek_blit( //
c->peek, //
view->images[crss.views[1].index].image, //
view->info.width, //
view->info.height); //
} break;
case COMP_WINDOW_PEEK_EYE_BOTH:
/* TODO: display the undistorted image */
comp_window_peek_blit(c->peek, c->target->images[r->acquired_buffer].handle, c->target->width,
@@ -1101,22 +1186,26 @@ comp_renderer_draw(struct comp_renderer *r)
comp_mirror_fixup_ui_state(&r->mirror_to_debug_gui, c);
if (comp_mirror_is_ready_and_active(&r->mirror_to_debug_gui, c, predicted_display_time_ns)) {
struct comp_scratch_single_images *view = &c->scratch.views[0];
struct render_scratch_color_image *rsci = &view->images[crss.views[0].index];
VkExtent2D extent = {view->info.width, view->info.width};
// Used for both, want clamp to edge to no bring in black.
VkSampler clamp_to_edge = c->nr.samplers.clamp_to_edge;
// Covers the whole view.
struct xrt_normalized_rect rect = {0, 0, 1.0f, 1.0f};
xret = comp_mirror_do_blit( //
&r->mirror_to_debug_gui, //
&c->base.vk, //
frame_id, //
predicted_display_time_ns, //
r->scratch.color[0].image, //
r->scratch.color[0].srgb_view, //
clamp_to_edge, //
r->scratch.extent, //
rect); //
xret = comp_mirror_do_blit( //
&r->mirror_to_debug_gui, //
&c->base.vk, //
frame_id, //
predicted_display_time_ns, //
rsci->image, //
rsci->srgb_view, //
clamp_to_edge, //
extent, //
rect); //
}
/*
@@ -1128,6 +1217,10 @@ comp_renderer_draw(struct comp_renderer *r)
*/
renderer_wait_queue_idle(r);
// Finalize the scratch images, send to debug UI if active.
scratch_get_fini(&crss, r, view_count);
// Check timestamps.
if (xret == XRT_SUCCESS) {
/*
* Get timestamps of GPU work (if available).