···11-// Copyright 2019-2023, Collabora, Ltd.
11+// Copyright 2019-2024, Collabora, Ltd.
22// SPDX-License-Identifier: BSL-1.0
33/*!
44 * @file
···2222struct comp_layer;
232324242525+/*
2626+ *
2727+ * Input data struct.
2828+ *
2929+ */
3030+3131+/*!
3232+ * The input data needed for a single view, it shared between both GFX and CS
3333+ * paths. To fully render a single view two "rendering" might be needed, the
3434+ * first being the layer squashing, and the second is the distortion step. The
3535+ * target for the layer squashing is referred to as "layer" or "scratch" and
3636+ * prefixed with `layer` if needs be. The other final step is referred to as
3737+ * "distortion target" or just "target", and is prefixed with `target`.
3838+ */
3939+struct comp_render_view_data
4040+{
4141+ //! New world pose of this view.
4242+ struct xrt_pose world_pose;
4343+4444+ //! New eye pose of this view.
4545+ struct xrt_pose eye_pose;
4646+4747+ /*!
4848+ * New fov of this view, used for the layer scratch image. Needs to
4949+ * match distortion parameters if distortion is used.
5050+ */
5151+ struct xrt_fov fov;
5252+5353+ /*!
5454+ * The layer image for this view (aka scratch image),
5555+ * used for barrier operations.
5656+ */
5757+ VkImage image;
5858+5959+ /*!
6060+ * View into layer image (aka scratch image),
6161+ * used for both GFX (read/write) and CS (read) paths.
6262+ */
6363+ VkImageView srgb_view;
6464+6565+ /*!
6666+ * Pre-view layer target viewport_data (where in the image we should
6767+ * render the view).
6868+ */
6969+ struct render_viewport_data layer_viewport_data;
7070+7171+ /*!
7272+ * When sampling from the layer image (aka scratch image), how should we
7373+ * transform it to get to the pixels correctly.
7474+ */
7575+ struct xrt_normalized_rect layer_norm_rect;
7676+7777+ //! Go from UV to tanangle for the target, this needs to match @p fov.
7878+ struct xrt_normalized_rect target_pre_transform;
7979+8080+ // Distortion target viewport data (aka target).
8181+ struct render_viewport_data target_viewport_data;
8282+8383+ struct
8484+ {
8585+ //! Per-view layer target resources.
8686+ struct render_gfx_target_resources *rtr;
8787+8888+ //! Distortion target vertex rotation information.
8989+ struct xrt_matrix_2x2 vertex_rot;
9090+ } gfx;
9191+9292+ struct
9393+ {
9494+ //! Only used on compute path.
9595+ VkImageView unorm_view;
9696+ } cs;
9797+};
9898+9999+/*!
100100+ * The input data needed for a complete layer squashing distortion rendering
101101+ * to a target. This struct is shared between GFX and CS paths.
102102+ */
103103+struct comp_render_dispatch_data
104104+{
105105+ struct comp_render_view_data views[2];
106106+107107+ //! The number of views currently in this dispatch data.
108108+ uint32_t view_count;
109109+110110+ //! Fast path can be disabled for mirroing so needs to be an argument.
111111+ bool fast_path;
112112+113113+ //! Very often true, can be disabled for debugging.
114114+ bool do_timewarp;
115115+116116+ struct
117117+ {
118118+ // The resources needed for the target.
119119+ struct render_gfx_target_resources *rtr;
120120+ } gfx;
121121+122122+ struct
123123+ {
124124+ // Target image for distortion, used for barrier.
125125+ VkImage target_image;
126126+127127+ // Target image view for distortion.
128128+ VkImageView target_unorm_view;
129129+ } cs;
130130+};
131131+132132+133133+/*
134134+ *
135135+ * Gfx functions.
136136+ *
137137+ */
138138+139139+static inline void
140140+comp_render_gfx_initial_init(struct comp_render_dispatch_data *data,
141141+ struct render_gfx_target_resources *rtr,
142142+ bool fast_path,
143143+ bool do_timewarp)
144144+{
145145+ U_ZERO(data);
146146+147147+ data->fast_path = fast_path;
148148+ data->do_timewarp = do_timewarp;
149149+ data->gfx.rtr = rtr;
150150+}
151151+152152+static inline void
153153+comp_render_gfx_add_view(struct comp_render_dispatch_data *data,
154154+ const struct xrt_pose *world_pose,
155155+ const struct xrt_pose *eye_pose,
156156+ const struct xrt_fov *fov,
157157+ struct render_gfx_target_resources *rtr,
158158+ const struct render_viewport_data *layer_viewport_data,
159159+ const struct xrt_normalized_rect *layer_norm_rect,
160160+ VkImage image,
161161+ VkImageView srgb_view,
162162+ const struct xrt_matrix_2x2 *vertex_rot,
163163+ const struct render_viewport_data *target_viewport_data)
164164+{
165165+ uint32_t i = data->view_count++;
166166+167167+ assert(i < ARRAY_SIZE(data->views));
168168+169169+ struct comp_render_view_data *view = &data->views[i];
170170+171171+ render_calc_uv_to_tangent_lengths_rect(fov, &view->target_pre_transform);
172172+173173+ view->world_pose = *world_pose;
174174+ view->eye_pose = *eye_pose;
175175+ view->fov = *fov;
176176+ view->image = image;
177177+ view->srgb_view = srgb_view;
178178+ view->layer_viewport_data = *layer_viewport_data;
179179+ view->layer_norm_rect = *layer_norm_rect;
180180+ view->target_viewport_data = *target_viewport_data;
181181+182182+ view->gfx.rtr = rtr;
183183+ view->gfx.vertex_rot = *vertex_rot;
184184+}
185185+25186/*!
26187 * Helper function that takes a set of layers, new device poses, a scratch
27188 * images with associated @ref render_gfx_target_resources and writes the needed
28189 * commands to the @ref render_gfx to do a full composition with distortion.
29190 * The scratch images are optionally used to squash layers should it not be
3030- * possible to do a @p fast_path. Will use the render passes of the targets
3131- * which set the layout.
191191+ * possible to do a @p comp_render_dispatch_data::fast_path. Will use the render
192192+ * passes of the targets which set the layout.
32193 *
3333- * The render passes of @p rsi_rtrs must be created with a final_layout of
3434- * VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL or there will be validation errors.
194194+ * The render passes of @p comp_render_dispatch_data::views::rtr must be created
195195+ * with a final_layout of VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL or there will
196196+ * be validation errors.
35197 *
36198 * Expected layouts:
37199 * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
···47209 */
48210void
49211comp_render_gfx_dispatch(struct render_gfx *rr,
5050- struct render_scratch_images *rsi,
5151- struct render_gfx_target_resources rsi_rtrs[2],
52212 const struct comp_layer *layers,
53213 const uint32_t layer_count,
5454- struct xrt_pose world_poses[2],
5555- struct xrt_pose eye_poses[2],
5656- struct xrt_fov fovs[2],
5757- struct xrt_matrix_2x2 vertex_rots[2],
5858- struct render_gfx_target_resources *rtr,
5959- const struct render_viewport_data viewport_datas[2],
6060- bool fast_path,
6161- bool do_timewarp);
214214+ const struct comp_render_dispatch_data *d);
215215+216216+217217+/*
218218+ *
219219+ * CS functions.
220220+ *
221221+ */
222222+223223+static inline void
224224+comp_render_cs_initial_init(struct comp_render_dispatch_data *data,
225225+ VkImage target_image,
226226+ VkImageView target_unorm_view,
227227+ bool fast_path,
228228+ bool do_timewarp)
229229+{
230230+ U_ZERO(data);
62231232232+ data->fast_path = fast_path;
233233+ data->do_timewarp = do_timewarp;
234234+235235+ data->cs.target_image = target_image;
236236+ data->cs.target_unorm_view = target_unorm_view;
237237+}
238238+239239+static inline void
240240+comp_render_cs_add_view(struct comp_render_dispatch_data *data,
241241+ const struct xrt_pose *world_pose,
242242+ const struct xrt_pose *eye_pose,
243243+ const struct xrt_fov *fov,
244244+ const struct render_viewport_data *layer_viewport_data,
245245+ const struct xrt_normalized_rect *layer_norm_rect,
246246+ VkImage image,
247247+ VkImageView srgb_view,
248248+ VkImageView unorm_view,
249249+ const struct render_viewport_data *target_viewport_data)
250250+{
251251+ uint32_t i = data->view_count++;
252252+253253+ assert(i < ARRAY_SIZE(data->views));
254254+255255+ struct comp_render_view_data *view = &data->views[i];
256256+257257+ render_calc_uv_to_tangent_lengths_rect(fov, &view->target_pre_transform);
258258+259259+ view->world_pose = *world_pose;
260260+ view->eye_pose = *eye_pose;
261261+ view->fov = *fov;
262262+ view->layer_viewport_data = *layer_viewport_data;
263263+ view->layer_norm_rect = *layer_norm_rect;
264264+ view->image = image;
265265+ view->srgb_view = srgb_view;
266266+ view->target_viewport_data = *target_viewport_data;
267267+268268+ view->cs.unorm_view = unorm_view;
269269+}
6327064271/*!
65272 * Helper to dispatch the layer squasher for a single view.
···87294 bool do_timewarp);
8829589296/*!
9090- * Helper function to dispatch the layer squasher, designed for stereo views.
297297+ * Helper function to dispatch the layer squasher, works on any number of views.
91298 *
92299 * All source layer images needs to be in the correct image layout, no barrier
93300 * is inserted for them. The target images are barried from undefined to general
···104311 * @ingroup comp_util
105312 */
106313void
107107-comp_render_cs_stereo_layers(struct render_compute *crc,
108108- const struct comp_layer *layers,
109109- const uint32_t layer_count,
110110- const struct xrt_normalized_rect pre_transforms[2],
111111- const struct xrt_pose world_poses[2],
112112- const struct xrt_pose eye_poses[2],
113113- const VkImage target_images[2],
114114- const VkImageView target_image_views[2],
115115- const struct render_viewport_data target_views[2],
116116- VkImageLayout transition_to,
117117- bool do_timewarp);
118118-119119-/*!
120120- * Helper function that takes a set of layers, new device poses, a scratch
121121- * images and writes the needed commands to the @ref render_compute to squash
122122- * the given layers into the given scratch images. Will insert barriers to
123123- * change the scratch images to the needed layout.
124124- *
125125- * Expected layouts:
126126- * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
127127- * * Scratch images: Any
128128- *
129129- * After call layouts:
130130- * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
131131- * * Scratch images: @p transition_to
132132- *
133133- * @ingroup comp_util
134134- */
135135-void
136136-comp_render_cs_stereo_layers_to_scratch(struct render_compute *crc,
137137- const struct xrt_normalized_rect pre_transforms[2],
138138- struct xrt_pose world_poses[2],
139139- struct xrt_pose eye_poses[2],
140140- const struct comp_layer *layers,
141141- const uint32_t layer_count,
142142- struct render_scratch_images *rsi,
143143- VkImageLayout transition_to,
144144- bool do_timewarp);
314314+comp_render_cs_layers(struct render_compute *crc,
315315+ const struct comp_layer *layers,
316316+ const uint32_t layer_count,
317317+ const struct comp_render_dispatch_data *d,
318318+ VkImageLayout transition_to);
145319146320/*!
147321 * Helper function that takes a set of layers, new device poses, a scratch
···149323 * composition with distortion. The scratch images are optionally used to squash
150324 * layers should it not be possible to do a fast_path. Will insert barriers to
151325 * change the scratch images and target images to the needed layout.
326326+ *
327327+ * Currently limited to exactly two views.
152328 *
153329 * Expected layouts:
154330 * * Layer images: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
···164340 */
165341void
166342comp_render_cs_dispatch(struct render_compute *crc,
167167- struct render_scratch_images *rsi,
168168- struct xrt_pose world_poses[2],
169169- struct xrt_pose eye_poses[2],
170343 const struct comp_layer *layers,
171344 const uint32_t layer_count,
172172- VkImage target_image,
173173- VkImageView target_image_view,
174174- const struct render_viewport_data views[2],
175175- bool fast_path,
176176- bool do_timewarp);
345345+ const struct comp_render_dispatch_data *d);
177346178347179348#ifdef __cplusplus