mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-29 01:48:31 +00:00
c/main: Add readback to gui_window_record
This commit is contained in:
parent
2e8f572a4d
commit
86a1ba32e5
|
@ -6,6 +6,7 @@
|
|||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Moses Turner <moses@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*
|
||||
*
|
||||
|
@ -363,7 +364,7 @@ compositor_layer_commit(struct xrt_compositor *xc, int64_t frame_id, xrt_graphic
|
|||
* 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);
|
||||
bool fast_path = can_do_one_projection_layer_fast_path(c) && !c->mirroring_to_debug_gui;
|
||||
c->base.slot.one_projection_layer_fast_path = fast_path;
|
||||
|
||||
|
||||
|
@ -1171,6 +1172,25 @@ xrt_gfx_provider_create_system(struct xrt_device *xdev, struct xrt_system_compos
|
|||
|
||||
c->last_frame_time_ns = os_monotonic_get_ns();
|
||||
|
||||
float scale = c->settings.viewport_scale;
|
||||
|
||||
if (scale > 2.0) {
|
||||
scale = 2.0;
|
||||
COMP_DEBUG(c, "Clamped scale to 200%%\n");
|
||||
}
|
||||
|
||||
uint32_t w0 = (uint32_t)(xdev->hmd->views[0].display.w_pixels * scale);
|
||||
uint32_t h0 = (uint32_t)(xdev->hmd->views[0].display.h_pixels * scale);
|
||||
uint32_t w1 = (uint32_t)(xdev->hmd->views[1].display.w_pixels * scale);
|
||||
uint32_t h1 = (uint32_t)(xdev->hmd->views[1].display.h_pixels * scale);
|
||||
|
||||
uint32_t w0_2 = xdev->hmd->views[0].display.w_pixels * 2;
|
||||
uint32_t h0_2 = xdev->hmd->views[0].display.h_pixels * 2;
|
||||
uint32_t w1_2 = xdev->hmd->views[1].display.w_pixels * 2;
|
||||
uint32_t h1_2 = xdev->hmd->views[1].display.h_pixels * 2;
|
||||
|
||||
c->view_extents.width = w0;
|
||||
c->view_extents.height = h0;
|
||||
|
||||
// Need to select window backend before creating Vulkan, then
|
||||
// swapchain will initialize the window fully and the swapchain,
|
||||
|
@ -1256,22 +1276,7 @@ xrt_gfx_provider_create_system(struct xrt_device *xdev, struct xrt_system_compos
|
|||
memcpy(sys_info->compositor_vk_deviceUUID, c->settings.selected_gpu_deviceUUID, XRT_GPU_UUID_SIZE);
|
||||
memcpy(sys_info->client_vk_deviceUUID, c->settings.client_gpu_deviceUUID, XRT_GPU_UUID_SIZE);
|
||||
|
||||
float scale = c->settings.viewport_scale;
|
||||
|
||||
if (scale > 2.0) {
|
||||
scale = 2.0;
|
||||
COMP_DEBUG(c, "Clamped scale to 200%%\n");
|
||||
}
|
||||
|
||||
uint32_t w0 = (uint32_t)(xdev->hmd->views[0].display.w_pixels * scale);
|
||||
uint32_t h0 = (uint32_t)(xdev->hmd->views[0].display.h_pixels * scale);
|
||||
uint32_t w1 = (uint32_t)(xdev->hmd->views[1].display.w_pixels * scale);
|
||||
uint32_t h1 = (uint32_t)(xdev->hmd->views[1].display.h_pixels * scale);
|
||||
|
||||
uint32_t w0_2 = xdev->hmd->views[0].display.w_pixels * 2;
|
||||
uint32_t h0_2 = xdev->hmd->views[0].display.h_pixels * 2;
|
||||
uint32_t w1_2 = xdev->hmd->views[1].display.w_pixels * 2;
|
||||
uint32_t h1_2 = xdev->hmd->views[1].display.h_pixels * 2;
|
||||
|
||||
// clang-format off
|
||||
sys_info->views[0].recommended.width_pixels = w0;
|
||||
|
@ -1328,6 +1333,8 @@ xrt_gfx_provider_create_system(struct xrt_device *xdev, struct xrt_system_compos
|
|||
|
||||
u_var_add_f32_timing(c, ft, "Frame Times (Compositor)");
|
||||
|
||||
comp_renderer_add_debug_vars(c->r);
|
||||
|
||||
c->compositor_frame_times.debug_var = ft;
|
||||
|
||||
c->state = COMP_STATE_READY;
|
||||
|
|
|
@ -99,6 +99,12 @@ struct comp_compositor
|
|||
//! State for generating the correct set of events.
|
||||
enum comp_state state;
|
||||
|
||||
// Extents of one view, in pixels.
|
||||
VkExtent2D view_extents;
|
||||
|
||||
//! Are we mirroring any of the views to the debug gui? If so, turn off the fast path.
|
||||
bool mirroring_to_debug_gui;
|
||||
|
||||
/*!
|
||||
* @brief Data exclusive to the begin_frame/end_frame for computing an
|
||||
* estimate of the app's needs.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2019-2021, Collabora, Ltd.
|
||||
// Copyright 2019-2022, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
|
@ -6,23 +6,33 @@
|
|||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Moses Turner <moses@collabora.com>
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
#include "xrt/xrt_defines.h"
|
||||
#include "xrt/xrt_frame.h"
|
||||
#include "xrt/xrt_compositor.h"
|
||||
|
||||
#include "os/os_time.h"
|
||||
|
||||
#include "math/m_api.h"
|
||||
#include "math/m_vec3.h"
|
||||
#include "math/m_matrix_4x4_f64.h"
|
||||
#include "math/m_space.h"
|
||||
|
||||
#include "util/u_misc.h"
|
||||
#include "util/u_trace_marker.h"
|
||||
#include "util/u_distortion_mesh.h"
|
||||
#include "util/u_sink.h"
|
||||
#include "util/u_var.h"
|
||||
#include "util/u_frame.h"
|
||||
|
||||
#include "main/comp_layer_renderer.h"
|
||||
#include "math/m_api.h"
|
||||
#include "math/m_vec3.h"
|
||||
#include "math/m_matrix_4x4_f64.h"
|
||||
|
||||
|
||||
#include "vk/vk_helpers.h"
|
||||
#include "vk/vk_image_readback_to_xf_pool.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -52,6 +62,19 @@ struct comp_renderer
|
|||
struct comp_compositor *c;
|
||||
struct comp_settings *settings;
|
||||
|
||||
struct
|
||||
{
|
||||
// Hint: enable/disable is in c->mirroring_to_debug_gui. It's there because comp_renderer is just a
|
||||
// forward decl to comp_compositor.c
|
||||
struct u_sink_debug debug_sink;
|
||||
VkExtent2D image_extent;
|
||||
uint64_t sequence;
|
||||
|
||||
struct vk_image_readback_to_xf_pool *pool;
|
||||
|
||||
} mirror_to_debug_gui;
|
||||
|
||||
|
||||
struct
|
||||
{
|
||||
VkSemaphore present_complete;
|
||||
|
@ -433,19 +456,11 @@ renderer_create_layer_renderer(struct comp_renderer *r)
|
|||
}
|
||||
|
||||
VkExtent2D extent;
|
||||
if (r->c->target->surface_transform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR ||
|
||||
r->c->target->surface_transform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
|
||||
// Swapping width and height, since we are pre rotating
|
||||
extent = (VkExtent2D){
|
||||
.width = r->c->xdev->hmd->screens[0].h_pixels,
|
||||
.height = r->c->xdev->hmd->screens[0].w_pixels,
|
||||
};
|
||||
} else {
|
||||
extent = (VkExtent2D){
|
||||
.width = r->c->xdev->hmd->screens[0].w_pixels,
|
||||
.height = r->c->xdev->hmd->screens[0].h_pixels,
|
||||
};
|
||||
}
|
||||
|
||||
extent = (VkExtent2D){
|
||||
.width = r->c->view_extents.width,
|
||||
.height = r->c->view_extents.height,
|
||||
};
|
||||
|
||||
r->lr = comp_layer_renderer_create(vk, &r->c->shaders, extent, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
if (layer_count != 0) {
|
||||
|
@ -541,6 +556,17 @@ renderer_create(struct comp_renderer *r, struct comp_compositor *c)
|
|||
|
||||
// Try to early-allocate these, in case we can.
|
||||
renderer_ensure_images_and_renderings(r, false);
|
||||
|
||||
double orig_width = r->lr->extent.width;
|
||||
double orig_height = r->lr->extent.height;
|
||||
|
||||
double mul = 1080.0 / orig_height;
|
||||
|
||||
r->mirror_to_debug_gui.image_extent.width = orig_width * mul;
|
||||
r->mirror_to_debug_gui.image_extent.height = orig_height * mul;
|
||||
|
||||
vk_image_readback_to_xf_pool_create(vk, r->mirror_to_debug_gui.image_extent, &r->mirror_to_debug_gui.pool,
|
||||
XRT_FORMAT_R8G8B8X8);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -732,6 +758,9 @@ renderer_destroy(struct comp_renderer *r)
|
|||
{
|
||||
struct vk_bundle *vk = &r->c->base.vk;
|
||||
|
||||
// Left eye readback
|
||||
vk_image_readback_to_xf_pool_destroy(vk, &r->mirror_to_debug_gui.pool);
|
||||
|
||||
// Command buffers
|
||||
renderer_close_renderings_and_fences(r);
|
||||
|
||||
|
@ -1235,6 +1264,154 @@ comp_renderer_set_equirect2_layer(struct comp_renderer *r,
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
can_mirror_to_debug_gui(struct comp_renderer *r)
|
||||
{
|
||||
return r->c->mirroring_to_debug_gui && u_sink_debug_is_active(&r->mirror_to_debug_gui.debug_sink);
|
||||
}
|
||||
|
||||
static void
|
||||
mirror_to_debug_gui_do_blit(struct comp_renderer *r)
|
||||
{
|
||||
struct vk_bundle *vk = &r->c->base.vk;
|
||||
|
||||
struct vk_image_readback_to_xf *wrap = NULL;
|
||||
|
||||
if (!vk_image_readback_to_xf_pool_get_unused_frame(vk, r->mirror_to_debug_gui.pool, &wrap)) {
|
||||
return;
|
||||
}
|
||||
|
||||
VkCommandBuffer cmd;
|
||||
vk_init_cmd_buffer(vk, &cmd);
|
||||
|
||||
VkImage copy_from = r->lr->framebuffers[0].image;
|
||||
|
||||
#if 0
|
||||
bool fast = r->c->base.slot.one_projection_layer_fast_path;
|
||||
|
||||
|
||||
if (fast) {
|
||||
switch (layer->data.type) {
|
||||
case XRT_LAYER_STEREO_PROJECTION: {
|
||||
copy_from = layer->sc_array[0]->vkic.images[layer->data.stereo.l.sub.image_index].handle;
|
||||
} break;
|
||||
case XRT_LAYER_STEREO_PROJECTION_DEPTH: {
|
||||
copy_from = layer->sc_array[0]->vkic.images[layer->data.stereo_depth.l.sub.image_index].handle;
|
||||
} break;
|
||||
default: assert(false);
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
VkImageSubresourceRange first_color_level_subresource_range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
};
|
||||
|
||||
// Barrier to make destination a destination
|
||||
vk_insert_image_memory_barrier( //
|
||||
vk, // vk_bundle
|
||||
cmd, // cmdbuffer
|
||||
wrap->image, // image
|
||||
VK_ACCESS_HOST_READ_BIT, // srcAccessMask
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
|
||||
wrap->layout, // oldImageLayout
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newImageLayout
|
||||
VK_PIPELINE_STAGE_HOST_BIT, // srcStageMask
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, // dstStageMask
|
||||
first_color_level_subresource_range); // subresourceRange
|
||||
|
||||
// Barrier to make source a source
|
||||
vk_insert_image_memory_barrier( //
|
||||
vk, // vk_bundle
|
||||
cmd, // cmdbuffer
|
||||
copy_from, // image
|
||||
VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
|
||||
VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // oldImageLayout
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newImageLayout
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // srcStageMask
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, // dstStageMask
|
||||
first_color_level_subresource_range); // subresourceRange
|
||||
|
||||
|
||||
VkImageBlit blit = {0};
|
||||
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.srcSubresource.layerCount = 1;
|
||||
|
||||
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
blit.dstSubresource.layerCount = 1;
|
||||
|
||||
blit.srcOffsets[1].x = r->lr->extent.width;
|
||||
blit.srcOffsets[1].y = r->lr->extent.height;
|
||||
blit.srcOffsets[1].z = 1;
|
||||
|
||||
|
||||
blit.dstOffsets[1].x = r->mirror_to_debug_gui.image_extent.width;
|
||||
blit.dstOffsets[1].y = r->mirror_to_debug_gui.image_extent.height;
|
||||
blit.dstOffsets[1].z = 1;
|
||||
|
||||
vk->vkCmdBlitImage( //
|
||||
cmd, // commandBuffer
|
||||
copy_from, // srcImage
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // srcImageLayout
|
||||
wrap->image, // dstImage
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // dstImageLayout
|
||||
1, // regionCount
|
||||
&blit, // pRegions
|
||||
VK_FILTER_LINEAR // filter
|
||||
);
|
||||
|
||||
wrap->layout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
|
||||
// Reset destination
|
||||
vk_insert_image_memory_barrier( //
|
||||
vk, // vk_bundle
|
||||
cmd, // cmdbuffer
|
||||
wrap->image, // image
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
|
||||
VK_ACCESS_HOST_READ_BIT, // dstAccessMask
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldImageLayout
|
||||
wrap->layout, // newImageLayout
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask
|
||||
VK_PIPELINE_STAGE_HOST_BIT, // dstStageMask
|
||||
first_color_level_subresource_range); // subresourceRange
|
||||
|
||||
// Reset src
|
||||
vk_insert_image_memory_barrier( //
|
||||
vk, // vk_bundle
|
||||
cmd, // cmdbuffer
|
||||
copy_from, // image
|
||||
VK_ACCESS_TRANSFER_READ_BIT, // srcAccessMask
|
||||
VK_ACCESS_SHADER_WRITE_BIT, // dstAccessMask
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // oldImageLayout
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newImageLayout
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // dstStageMask
|
||||
first_color_level_subresource_range); // subresourceRange
|
||||
|
||||
// Waits for command to finish.
|
||||
vk_submit_cmd_buffer(vk, cmd);
|
||||
|
||||
wrap->base_frame.source_timestamp = wrap->base_frame.timestamp =
|
||||
r->c->frame.rendering.predicted_display_time_ns;
|
||||
wrap->base_frame.source_id = r->mirror_to_debug_gui.sequence++;
|
||||
|
||||
|
||||
struct xrt_frame *frame = &wrap->base_frame;
|
||||
wrap = NULL;
|
||||
u_sink_debug_push_frame(&r->mirror_to_debug_gui.debug_sink, frame);
|
||||
xrt_frame_reference(&frame, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_draw(struct comp_renderer *r)
|
||||
{
|
||||
|
@ -1282,9 +1459,14 @@ comp_renderer_draw(struct comp_renderer *r)
|
|||
renderer_present_swapchain_image(r, c->frame.rendering.desired_present_time_ns,
|
||||
c->frame.rendering.present_slop_ns);
|
||||
|
||||
|
||||
// Clear the frame.
|
||||
c->frame.rendering.id = -1;
|
||||
|
||||
if (can_mirror_to_debug_gui(r)) {
|
||||
mirror_to_debug_gui_do_blit(r);
|
||||
}
|
||||
|
||||
/*
|
||||
* This fixes a lot of validation issues as it makes sure that the
|
||||
* command buffer has completed and all resources referred by it can
|
||||
|
@ -1294,6 +1476,8 @@ comp_renderer_draw(struct comp_renderer *r)
|
|||
*/
|
||||
renderer_wait_gpu_idle(r);
|
||||
|
||||
|
||||
|
||||
if (use_compute) {
|
||||
comp_rendering_compute_close(&crc);
|
||||
} else {
|
||||
|
@ -1352,3 +1536,11 @@ comp_renderer_destroy(struct comp_renderer **ptr_r)
|
|||
free(r);
|
||||
*ptr_r = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_add_debug_vars(struct comp_renderer *r)
|
||||
{
|
||||
// 1.2 % 2.3;
|
||||
u_var_add_bool(r->c, &r->c->mirroring_to_debug_gui, "Display left eye to GUI (slow)");
|
||||
u_var_add_sink_debug(r->c, &r->mirror_to_debug_gui.debug_sink, "Left view!");
|
||||
}
|
||||
|
|
|
@ -128,6 +128,9 @@ comp_renderer_allocate_layers(struct comp_renderer *self, uint32_t layer_count);
|
|||
void
|
||||
comp_renderer_destroy_layers(struct comp_renderer *self);
|
||||
|
||||
void
|
||||
comp_renderer_add_debug_vars(struct comp_renderer *self);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue