From 90f708d91c31a82988a1950006e24cbbcf634154 Mon Sep 17 00:00:00 2001 From: Simon Zeni <simon@bl4ckb0ne.ca> Date: Tue, 12 Jul 2022 14:31:57 -0400 Subject: [PATCH] xrt: Enable XR_KHR_composition_layer_cube Co-authored-by: Bjorn Swenson <bjorn@collabora.com> --- CMakeLists.txt | 2 +- doc/changes/compositor/mr.1421.md | 1 + doc/changes/xrt/mr.1421.md | 1 + src/xrt/compositor/CMakeLists.txt | 19 ++++++--- src/xrt/compositor/main/comp_compositor.c | 12 +++++- src/xrt/compositor/main/comp_layer.c | 4 +- src/xrt/compositor/main/comp_layer_renderer.c | 16 ++++++++ src/xrt/compositor/main/comp_layer_renderer.h | 1 + src/xrt/compositor/main/comp_renderer.c | 27 +++++++++++++ src/xrt/compositor/main/comp_renderer.h | 12 ++++++ src/xrt/compositor/render/render_interface.h | 3 ++ src/xrt/compositor/render/render_shaders.c | 22 ++++++++++ src/xrt/compositor/shaders/cube.frag | 27 +++++++++++++ src/xrt/compositor/shaders/cube.vert | 36 +++++++++++++++++ src/xrt/compositor/util/comp_base.c | 4 -- src/xrt/include/xrt/xrt_compositor.h | 1 - .../oxr/oxr_session_frame_end.c | 40 ++++++++++++++++++- 17 files changed, 212 insertions(+), 16 deletions(-) create mode 100644 doc/changes/compositor/mr.1421.md create mode 100644 doc/changes/xrt/mr.1421.md create mode 100644 src/xrt/compositor/shaders/cube.frag create mode 100644 src/xrt/compositor/shaders/cube.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index e7ec6bb6e..c490d3f19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -312,7 +312,7 @@ if(NOT DEFINED XRT_FEATURE_OPENXR_LAYER_DEPTH) set(XRT_FEATURE_OPENXR_LAYER_DEPTH ON) endif() if(NOT DEFINED XRT_FEATURE_OPENXR_LAYER_CUBE) - set(XRT_FEATURE_OPENXR_LAYER_CUBE OFF) + set(XRT_FEATURE_OPENXR_LAYER_CUBE ON) endif() if(NOT DEFINED XRT_FEATURE_OPENXR_LAYER_CYLINDER) set(XRT_FEATURE_OPENXR_LAYER_CYLINDER ON) diff --git a/doc/changes/compositor/mr.1421.md b/doc/changes/compositor/mr.1421.md new file mode 100644 index 000000000..b63755466 --- /dev/null +++ b/doc/changes/compositor/mr.1421.md @@ -0,0 +1 @@ +main: Render cube layer diff --git a/doc/changes/xrt/mr.1421.md b/doc/changes/xrt/mr.1421.md new file mode 100644 index 000000000..91ac6ee1c --- /dev/null +++ b/doc/changes/xrt/mr.1421.md @@ -0,0 +1 @@ +Enable cube layer submission diff --git a/src/xrt/compositor/CMakeLists.txt b/src/xrt/compositor/CMakeLists.txt index 72384dd53..a2242105f 100644 --- a/src/xrt/compositor/CMakeLists.txt +++ b/src/xrt/compositor/CMakeLists.txt @@ -111,11 +111,7 @@ endif() # if(XRT_HAVE_VULKAN) - spirv_shaders( - SHADER_HEADERS - SPIRV_VERSION - 1.0 # Currently targeting Vulkan 1.0 - SOURCES + set(SHADERS shaders/clear.comp shaders/distortion.comp shaders/mesh.frag @@ -127,6 +123,19 @@ if(XRT_HAVE_VULKAN) shaders/equirect2.vert shaders/equirect2.frag ) + if(XRT_FEATURE_OPENXR_LAYER_CUBE) + list(APPEND SHADERS + shaders/cube.vert + shaders/cube.frag + ) + endif() + + spirv_shaders( + SHADER_HEADERS + SPIRV_VERSION + 1.0 # Currently targeting Vulkan 1.0 + SOURCES ${SHADERS} + ) add_library( comp_render STATIC diff --git a/src/xrt/compositor/main/comp_compositor.c b/src/xrt/compositor/main/comp_compositor.c index 95b094397..a1943eb3d 100644 --- a/src/xrt/compositor/main/comp_compositor.c +++ b/src/xrt/compositor/main/comp_compositor.c @@ -283,13 +283,23 @@ do_graphics_layers(struct comp_compositor *c) comp_renderer_set_equirect2_layer(c->r, i, image, data); } break; #endif + case XRT_LAYER_CUBE: { +#ifdef XRT_FEATURE_OPENXR_LAYER_CUBE + struct xrt_layer_cube_data *cu = &layer->data.cube; + struct comp_swapchain_image *image; + image = &layer->sc_array[0]->images[cu->sub.image_index]; + comp_renderer_set_cube_layer(c->r, i, image, data); +#else + COMP_WARN(c, "XR_KHR_composition_layer_cube support not enabled"); +#endif + } break; #ifndef XRT_FEATURE_OPENXR_LAYER_EQUIRECT1 case XRT_LAYER_EQUIRECT1: #endif #ifndef XRT_FEATURE_OPENXR_LAYER_EQUIRECT2 case XRT_LAYER_EQUIRECT2: #endif - case XRT_LAYER_CUBE: + default: // Should never end up here. assert(false); } diff --git a/src/xrt/compositor/main/comp_layer.c b/src/xrt/compositor/main/comp_layer.c index 6d848988c..546164627 100644 --- a/src/xrt/compositor/main/comp_layer.c +++ b/src/xrt/compositor/main/comp_layer.c @@ -340,9 +340,9 @@ comp_layer_draw(struct comp_render_layer *self, case XRT_LAYER_QUAD: case XRT_LAYER_CYLINDER: case XRT_LAYER_EQUIRECT1: - case XRT_LAYER_EQUIRECT2: _update_mvp_matrix(self, eye, vp); break; + case XRT_LAYER_EQUIRECT2: + case XRT_LAYER_CUBE: _update_mvp_matrix(self, eye, vp); break; case XRT_LAYER_STEREO_PROJECTION_DEPTH: - case XRT_LAYER_CUBE: // Should never end up here. assert(false); } diff --git a/src/xrt/compositor/main/comp_layer_renderer.c b/src/xrt/compositor/main/comp_layer_renderer.c index 7737a3d9e..60cac9eea 100644 --- a/src/xrt/compositor/main/comp_layer_renderer.c +++ b/src/xrt/compositor/main/comp_layer_renderer.c @@ -335,6 +335,7 @@ static float plane_vertices[PLANE_VERTICES * 5] = { -0.5, 0.5, 0, 0, 0, -0.5, -0.5, 0, 0, 1, }; + // clang-format on static bool @@ -390,6 +391,12 @@ _render_eye(struct comp_layer_renderer *self, pipeline = self->pipeline_equirect1; comp_layer_draw(self->layers[i], eye, pipeline, pipeline_layout, cmd_buffer, vertex_buffer, &vp_inv, &vp_inv); +#if defined(XRT_FEATURE_OPENXR_LAYER_CUBE) + } else if (self->layers[i]->type == XRT_LAYER_CUBE) { + pipeline = self->pipeline_cube; + comp_layer_draw(self->layers[i], eye, pipeline, pipeline_layout, cmd_buffer, vertex_buffer, + &vp_inv, &vp_inv); +#endif } else { comp_layer_draw(self->layers[i], eye, pipeline, pipeline_layout, cmd_buffer, vertex_buffer, &vp_world, &vp_eye); @@ -528,6 +535,12 @@ _init(struct comp_layer_renderer *self, return false; } +#if defined(XRT_FEATURE_OPENXR_LAYER_CUBE) + if (!_init_graphics_pipeline(self, s->cube_vert, s->cube_frag, true, &self->pipeline_cube)) { + return false; + } +#endif + if (!_init_vertex_buffer(self)) return false; @@ -676,6 +689,9 @@ comp_layer_renderer_destroy(struct comp_layer_renderer **ptr_clr) vk->vkDestroyPipeline(vk->device, self->pipeline_unpremultiplied_alpha, NULL); vk->vkDestroyPipeline(vk->device, self->pipeline_equirect1, NULL); vk->vkDestroyPipeline(vk->device, self->pipeline_equirect2, NULL); +#if defined(XRT_FEATURE_OPENXR_LAYER_CUBE) + vk->vkDestroyPipeline(vk->device, self->pipeline_cube, NULL); +#endif for (uint32_t i = 0; i < ARRAY_SIZE(self->shader_modules); i++) vk->vkDestroyShaderModule(vk->device, self->shader_modules[i], NULL); diff --git a/src/xrt/compositor/main/comp_layer_renderer.h b/src/xrt/compositor/main/comp_layer_renderer.h index d1dee6771..34e233fdf 100644 --- a/src/xrt/compositor/main/comp_layer_renderer.h +++ b/src/xrt/compositor/main/comp_layer_renderer.h @@ -40,6 +40,7 @@ struct comp_layer_renderer VkPipeline pipeline_unpremultiplied_alpha; VkPipeline pipeline_equirect1; VkPipeline pipeline_equirect2; + VkPipeline pipeline_cube; VkDescriptorSetLayout descriptor_set_layout; VkDescriptorSetLayout descriptor_set_layout_equirect; diff --git a/src/xrt/compositor/main/comp_renderer.c b/src/xrt/compositor/main/comp_renderer.c index 4c1db38c0..cfe2bf2ef 100644 --- a/src/xrt/compositor/main/comp_renderer.c +++ b/src/xrt/compositor/main/comp_renderer.c @@ -1294,6 +1294,33 @@ comp_renderer_set_equirect2_layer(struct comp_renderer *r, } #endif +#ifdef XRT_FEATURE_OPENXR_LAYER_CUBE +void +comp_renderer_set_cube_layer(struct comp_renderer *r, + uint32_t layer, + struct comp_swapchain_image *image, + struct xrt_layer_data *data) +{ + + struct xrt_vec3 s = {1.0f, 1.0f, 1.0f}; + struct xrt_matrix_4x4 model_matrix; + math_matrix_4x4_model(&data->cube.pose, &s, &model_matrix); + + comp_layer_set_flip_y(r->lr->layers[layer], data->flip_y); + + struct comp_render_layer *l = r->lr->layers[layer]; + l->type = XRT_LAYER_CUBE; + l->visibility = data->cube.visibility; + l->flags = data->flags; + l->view_space = (data->flags & XRT_LAYER_COMPOSITION_VIEW_SPACE_BIT) != 0; + l->transformation_ubo_binding = r->lr->transformation_ubo_binding; + l->texture_binding = r->lr->texture_binding; + + comp_layer_update_descriptors(l, image->repeat_sampler, + get_image_view(image, data->flags, data->cube.sub.array_index)); +} +#endif + static void mirror_to_debug_gui_fixup_ui_state(struct comp_renderer *r) { diff --git a/src/xrt/compositor/main/comp_renderer.h b/src/xrt/compositor/main/comp_renderer.h index 27d9ff7a5..cfad48132 100644 --- a/src/xrt/compositor/main/comp_renderer.h +++ b/src/xrt/compositor/main/comp_renderer.h @@ -110,6 +110,18 @@ comp_renderer_set_equirect2_layer(struct comp_renderer *r, struct xrt_layer_data *data); #endif +#ifdef XRT_FEATURE_OPENXR_LAYER_CUBE +/*! + * @public @memberof comp_renderer + * @ingroup comp_main + */ +void +comp_renderer_set_cube_layer(struct comp_renderer *r, + uint32_t layer, + struct comp_swapchain_image *image, + struct xrt_layer_data *data); +#endif + /*! * Allocate an internal array of per-layer data with the given number of elements. * diff --git a/src/xrt/compositor/render/render_interface.h b/src/xrt/compositor/render/render_interface.h index 2a1360016..ce2ecf433 100644 --- a/src/xrt/compositor/render/render_interface.h +++ b/src/xrt/compositor/render/render_interface.h @@ -86,6 +86,9 @@ struct render_shaders VkShaderModule equirect2_vert; VkShaderModule equirect2_frag; + VkShaderModule cube_vert; + VkShaderModule cube_frag; + VkShaderModule layer_vert; VkShaderModule layer_frag; }; diff --git a/src/xrt/compositor/render/render_shaders.c b/src/xrt/compositor/render/render_shaders.c index 859629d61..f1d9f7dfb 100644 --- a/src/xrt/compositor/render/render_shaders.c +++ b/src/xrt/compositor/render/render_shaders.c @@ -21,6 +21,8 @@ #pragma GCC diagnostic ignored "-Wnewline-eof" #endif +#include "xrt/xrt_config_build.h" + #include "shaders/clear.comp.h" #include "shaders/distortion.comp.h" #include "shaders/layer.frag.h" @@ -32,6 +34,11 @@ #include "shaders/mesh.frag.h" #include "shaders/mesh.vert.h" +#ifdef XRT_FEATURE_OPENXR_LAYER_CUBE +#include "shaders/cube.frag.h" +#include "shaders/cube.vert.h" +#endif + #if defined(__GNUC__) #pragma GCC diagnostic pop #endif @@ -118,6 +125,17 @@ render_shaders_load(struct render_shaders *s, struct vk_bundle *vk) sizeof(shaders_equirect2_frag), // size &s->equirect2_frag)); // out +#ifdef XRT_FEATURE_OPENXR_LAYER_CUBE + C(shader_load(vk, // vk_bundle + shaders_cube_vert, // data + sizeof(shaders_cube_vert), // size + &s->cube_vert)); // out + C(shader_load(vk, // vk_bundle + shaders_cube_frag, // data + sizeof(shaders_cube_frag), // size + &s->cube_frag)); // out +#endif + C(shader_load(vk, // vk_bundle shaders_layer_vert, // data sizeof(shaders_layer_vert), // size @@ -149,6 +167,10 @@ render_shaders_close(struct render_shaders *s, struct vk_bundle *vk) D(equirect1_frag); D(equirect2_vert); D(equirect2_frag); +#ifdef XRT_FEATURE_OPENXR_LAYER_CUBE + D(cube_vert); + D(cube_frag); +#endif D(layer_vert); D(layer_frag); diff --git a/src/xrt/compositor/shaders/cube.frag b/src/xrt/compositor/shaders/cube.frag new file mode 100644 index 000000000..518358e4d --- /dev/null +++ b/src/xrt/compositor/shaders/cube.frag @@ -0,0 +1,27 @@ +// Copyright 2020 Simon Zeni <simon@bl4ckb0ne.ca> +// Author: Simon Zeni <simon@bl4ckb0ne.ca> +// Author: Bjorn Swenson <bjorn@collabora.com> +// SPDX-License-Identifier: BSL-1.0 + +#version 460 + +layout (binding = 0, std140) uniform Transformation +{ + mat4 mvp; + ivec2 offset; + ivec2 extent; + bool flip_y; +} ubo; + +layout (binding = 1) uniform samplerCube cube; + +layout (location = 0) in vec2 uv; +layout (location = 0) out vec4 out_color; + +void main () +{ + vec2 frag_coord = vec2(uv) * 2 - 1; + vec4 view_dir = normalize(ubo.mvp * vec4(frag_coord.x, frag_coord.y, 1, 1)); + + out_color = texture(cube, view_dir.xyz); +} diff --git a/src/xrt/compositor/shaders/cube.vert b/src/xrt/compositor/shaders/cube.vert new file mode 100644 index 000000000..d9d5066fc --- /dev/null +++ b/src/xrt/compositor/shaders/cube.vert @@ -0,0 +1,36 @@ +// Copyright 2020 Simon Zeni <simon@bl4ckb0ne.ca> +// Author: Simon Zeni <simon@bl4ckb0ne.ca> +// Author: Bjorn Swenson <bjorn@collabora.com> +// SPDX-License-Identifier: BSL-1.0 + +#version 460 + +layout (binding = 0, std140) uniform Transformation +{ + mat4 mvp; + ivec2 offset; + ivec2 extent; + bool flip_y; +} transformation; + +layout (location = 0) in vec3 position; +layout (location = 1) in vec2 uv; +layout (location = 0) out vec2 out_uv; + +const mat4 mvp = mat4( + 2, 0, 0, 0, + 0, 2, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 +); + +void main() { + gl_Position = mvp * vec4(position, 1.0); + gl_Position.y *= -1.; + + out_uv = uv; + + if (transformation.flip_y) { + out_uv.y = 1.0 - out_uv.y; + } +} diff --git a/src/xrt/compositor/util/comp_base.c b/src/xrt/compositor/util/comp_base.c index ee63b89c4..b03946d69 100644 --- a/src/xrt/compositor/util/comp_base.c +++ b/src/xrt/compositor/util/comp_base.c @@ -177,11 +177,7 @@ base_layer_cube(struct xrt_compositor *xc, struct xrt_swapchain *xsc, const struct xrt_layer_data *data) { -#if 0 return do_single_layer(xc, xdev, xsc, data); -#else - return XRT_SUCCESS; //! @todo Implement -#endif } static xrt_result_t diff --git a/src/xrt/include/xrt/xrt_compositor.h b/src/xrt/include/xrt/xrt_compositor.h index 8fa4c2ba5..5697b561f 100644 --- a/src/xrt/include/xrt/xrt_compositor.h +++ b/src/xrt/include/xrt/xrt_compositor.h @@ -250,7 +250,6 @@ struct xrt_layer_cube_data struct xrt_sub_image sub; struct xrt_pose pose; - uint32_t image_array_index; }; /*! diff --git a/src/xrt/state_trackers/oxr/oxr_session_frame_end.c b/src/xrt/state_trackers/oxr/oxr_session_frame_end.c index a9a67f649..0e1945c58 100644 --- a/src/xrt/state_trackers/oxr/oxr_session_frame_end.c +++ b/src/xrt/state_trackers/oxr/oxr_session_frame_end.c @@ -1034,7 +1034,7 @@ submit_projection_layer(struct oxr_session *sess, return XR_SUCCESS; } -static void +static XrResult submit_cube_layer(struct oxr_session *sess, struct xrt_compositor *xc, struct oxr_logger *log, @@ -1044,7 +1044,43 @@ submit_cube_layer(struct oxr_session *sess, uint64_t oxr_timestamp, uint64_t xrt_timestamp) { - // Not implemented + struct oxr_swapchain *sc = XRT_CAST_OXR_HANDLE_TO_PTR(struct oxr_swapchain *, cube->swapchain); + struct oxr_space *spc = XRT_CAST_OXR_HANDLE_TO_PTR(struct oxr_space *, cube->space); + + struct xrt_layer_data data = {0}; + + data.type = XRT_LAYER_CUBE; + data.name = XRT_INPUT_GENERIC_HEAD_POSE; + data.timestamp = xrt_timestamp; + data.flags = convert_layer_flags(cube->layerFlags); + + if (spc->space_type == OXR_SPACE_TYPE_REFERENCE_VIEW) { + data.flags |= XRT_LAYER_COMPOSITION_VIEW_SPACE_BIT; + } + + data.cube.visibility = convert_eye_visibility(cube->eyeVisibility); + + data.cube.sub.image_index = sc->released.index; + data.cube.sub.array_index = cube->imageArrayIndex; + + struct xrt_pose pose = { + .orientation = + { + .x = cube->orientation.x, + .y = cube->orientation.y, + .z = cube->orientation.z, + .w = cube->orientation.w, + }, + .position = XRT_VEC3_ZERO, + }; + + if (!handle_space(log, sess, spc, &pose, inv_offset, oxr_timestamp, &data.cube.pose)) { + return XR_SUCCESS; + } + + CALL_CHK(xrt_comp_layer_cube(xc, head, sc->swapchain, &data)); + + return XR_SUCCESS; } static XrResult