xrt: Enable XR_KHR_composition_layer_cube

Co-authored-by: Bjorn Swenson <bjorn@collabora.com>
This commit is contained in:
Simon Zeni 2022-07-12 14:31:57 -04:00 committed by Jakob Bornecrantz
parent 5063e76d16
commit 90f708d91c
17 changed files with 212 additions and 16 deletions

View file

@ -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)

View file

@ -0,0 +1 @@
main: Render cube layer

View file

@ -0,0 +1 @@
Enable cube layer submission

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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)
{

View file

@ -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.
*

View file

@ -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;
};

View file

@ -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);

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -250,7 +250,6 @@ struct xrt_layer_cube_data
struct xrt_sub_image sub;
struct xrt_pose pose;
uint32_t image_array_index;
};
/*!

View file

@ -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