// Copyright 2019-2024, Collabora, Ltd. // Copyright 2024-2025, NVIDIA CORPORATION. // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief Higher level interface for rendering a frame. * @author Jakob Bornecrantz * @author Christoph Haag * @author Fernando Velazquez Innella * @author Rylie Pavlik * @ingroup comp_util */ #include "comp_high_level_render.h" /* * * Common * */ void chl_frame_state_init(struct chl_frame_state *frame_state, struct render_resources *rr, uint32_t view_count, bool do_timewarp, bool fast_path, struct chl_scratch *scratch) { assert(rr != NULL); assert(rr->vk != NULL); assert(view_count <= rr->view_count); U_ZERO(frame_state); frame_state->view_count = view_count; frame_state->scratch = scratch; comp_render_initial_init( // &frame_state->data, // data fast_path, // fast_path do_timewarp); // do_timewarp chl_scratch_state_init_and_get(&frame_state->scratch_state, scratch); } void chl_frame_state_fini(struct chl_frame_state *frame_state) { if (frame_state->scratch == NULL) { return; } chl_scratch_state_discard_or_done(&frame_state->scratch_state, frame_state->scratch); U_ZERO(frame_state); } /* * * Graphics * */ void chl_frame_state_gfx_set_views(struct chl_frame_state *frame_state, const struct xrt_pose world_poses[XRT_MAX_VIEWS], const struct xrt_pose eye_poses[XRT_MAX_VIEWS], const struct xrt_fov fovs[XRT_MAX_VIEWS], uint32_t layer_count) { for (uint32_t i = 0; i < frame_state->view_count; i++) { // Which image of the scratch images for this view are we using. uint32_t scratch_index = frame_state->scratch_state.views[i].index; // The set of scratch images we are using for this view. struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; // The render target resources for the scratch images. struct render_gfx_target_resources *rsci_rtr = &frame_state->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 = scratch_view->info.width, .h = scratch_view->info.height, }; comp_render_gfx_add_squash_view( // &frame_state->data, // &world_poses[i], // &eye_poses[i], // &fovs[i], // rsci->image, // squash_image rsci_rtr, // squash_rtr &layer_viewport_data); // squash_viewport_data if (layer_count == 0) { frame_state->scratch_state.views[i].used = false; } else { frame_state->scratch_state.views[i].used = !frame_state->data.fast_path; } } } void chl_frame_state_gfx_set_target(struct chl_frame_state *frame_state, struct render_gfx_target_resources *target_rtr, const struct render_viewport_data target_viewport_datas[XRT_MAX_VIEWS], const struct xrt_matrix_2x2 vertex_rots[XRT_MAX_VIEWS]) { // Add the target info. comp_render_gfx_add_target(&frame_state->data, target_rtr); for (uint32_t i = 0; i < frame_state->view_count; i++) { // Which image of the scratch images for this view are we using. uint32_t scratch_index = frame_state->scratch_state.views[i].index; // The set of scratch images we are using for this view. struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; // Scratch image covers the whole image. struct xrt_normalized_rect layer_norm_rect = {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}; VkImageView sample_view = comp_scratch_single_images_get_sample_view(scratch_view, scratch_index); comp_render_gfx_add_target_view( // &frame_state->data, // sample_view, // squash_as_src_sample_view &layer_norm_rect, // squash_as_src_norm_rect &vertex_rots[i], // target_vertex_rot &target_viewport_datas[i]); // target_viewport_data } } /* * * Compute * */ void chl_frame_state_cs_set_views(struct chl_frame_state *frame_state, const struct xrt_pose world_poses_scanout_begin[XRT_MAX_VIEWS], const struct xrt_pose world_poses_scanout_end[XRT_MAX_VIEWS], const struct xrt_pose eye_poses[XRT_MAX_VIEWS], const struct xrt_fov fovs[XRT_MAX_VIEWS], uint32_t layer_count) { for (uint32_t i = 0; i < frame_state->view_count; i++) { // Which image of the scratch images for this view are we using. uint32_t scratch_index = frame_state->scratch_state.views[i].index; // The set of scratch images we are using for this view. struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; // 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 = scratch_view->info.width, .h = scratch_view->info.height, }; VkImageView storage_view = comp_scratch_single_images_get_storage_view(scratch_view, scratch_index); comp_render_cs_add_squash_view( // &frame_state->data, // &world_poses_scanout_begin[i], // &world_poses_scanout_end[i], // &eye_poses[i], // &fovs[i], // rsci->image, // squash_image storage_view, // squash_storage_view &layer_viewport_data); // squash_viewport_data if (layer_count == 0) { frame_state->scratch_state.views[i].used = false; } else { frame_state->scratch_state.views[i].used = !frame_state->data.fast_path; } } } void chl_frame_state_cs_set_target(struct chl_frame_state *frame_state, VkImage target_image, VkImageView target_storage_view, const struct render_viewport_data views[XRT_MAX_VIEWS]) { // Add the target info. comp_render_cs_add_target( // &frame_state->data, // data target_image, // target_image target_storage_view); // target_unorm_view for (uint32_t i = 0; i < frame_state->view_count; i++) { // Which image of the scratch images for this view are we using. uint32_t scratch_index = frame_state->scratch_state.views[i].index; // The set of scratch images we are using for this view. struct comp_scratch_single_images *scratch_view = &frame_state->scratch->views[i].cssi; // Scratch image covers the whole image. struct xrt_normalized_rect layer_norm_rect = {.x = 0.0f, .y = 0.0f, .w = 1.0f, .h = 1.0f}; VkImageView sample_view = comp_scratch_single_images_get_sample_view(scratch_view, scratch_index); comp_render_cs_add_target_view( // &frame_state->data, // sample_view, // squash_as_src_sample_view &layer_norm_rect, // squash_as_src_norm_rect &views[i]); // target_viewport_data } }