The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

c/layers: Implement equirect1 rendering.

Add equirect1 boilerplate, shader files, ubo and pipeline.

authored by

Lubosz Sarnecki and committed by
Jakob Bornecrantz
4995854d dc45a201

+182 -4
+2
src/xrt/compositor/CMakeLists.txt
··· 6 6 shaders/mesh.vert 7 7 shaders/layer.frag 8 8 shaders/layer.vert 9 + shaders/equirect1.vert 10 + shaders/equirect1.frag 9 11 shaders/equirect2.vert 10 12 shaders/equirect2.frag 11 13 )
+3
src/xrt/compositor/main/comp_compositor.h
··· 141 141 VkShaderModule mesh_vert; 142 142 VkShaderModule mesh_frag; 143 143 144 + VkShaderModule equirect1_vert; 145 + VkShaderModule equirect1_frag; 146 + 144 147 VkShaderModule equirect2_vert; 145 148 VkShaderModule equirect2_frag; 146 149
+48 -2
src/xrt/compositor/main/comp_layer.c
··· 84 84 } 85 85 86 86 static bool 87 + _init_equirect1_ubo(struct comp_render_layer *self) 88 + { 89 + VkBufferUsageFlags usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 90 + VkMemoryPropertyFlags properties = 91 + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 92 + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | 93 + VK_MEMORY_PROPERTY_HOST_CACHED_BIT; 94 + 95 + if (!vk_buffer_init(self->vk, sizeof(struct layer_transformation), 96 + usage, properties, &self->equirect1_ubo.handle, 97 + &self->equirect1_ubo.memory)) 98 + return false; 99 + 100 + VkResult res = self->vk->vkMapMemory( 101 + self->vk->device, self->equirect1_ubo.memory, 0, VK_WHOLE_SIZE, 0, 102 + &self->equirect1_ubo.data); 103 + vk_check_error("vkMapMemory", res, false); 104 + 105 + memcpy(self->equirect1_ubo.data, &self->equirect1_data, 106 + sizeof(struct layer_equirect1_data)); 107 + 108 + return true; 109 + } 110 + 111 + static bool 87 112 _init_equirect2_ubo(struct comp_render_layer *self) 88 113 { 89 114 VkBufferUsageFlags usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; ··· 188 213 } 189 214 190 215 void 216 + comp_layer_update_equirect1_descriptor(struct comp_render_layer *self, 217 + struct xrt_layer_equirect1_data *data) 218 + { 219 + _update_descriptor_equirect(self, self->descriptor_equirect, 220 + self->equirect1_ubo.handle); 221 + 222 + self->equirect1_data = (struct layer_equirect1_data){ 223 + .radius = data->radius, 224 + .scale = data->scale, 225 + .bias = data->bias, 226 + }; 227 + memcpy(self->equirect1_ubo.data, &self->equirect1_data, 228 + sizeof(struct layer_equirect1_data)); 229 + } 230 + 231 + void 191 232 comp_layer_update_equirect2_descriptor(struct comp_render_layer *self, 192 233 struct xrt_layer_equirect2_data *data) 193 234 { ··· 234 275 math_matrix_4x4_identity(&self->model_matrix); 235 276 236 277 if (!_init_ubos(self)) 278 + return false; 279 + 280 + if (!_init_equirect1_ubo(self)) 237 281 return false; 238 282 239 283 if (!_init_equirect2_ubo(self)) ··· 301 345 break; 302 346 case XRT_LAYER_QUAD: 303 347 case XRT_LAYER_CYLINDER: 348 + case XRT_LAYER_EQUIRECT1: 304 349 case XRT_LAYER_EQUIRECT2: _update_mvp_matrix(self, eye, vp); break; 305 350 case XRT_LAYER_STEREO_PROJECTION_DEPTH: 306 351 case XRT_LAYER_CUBE: 307 - case XRT_LAYER_EQUIRECT1: 308 352 // Should never end up here. 309 353 assert(false); 310 354 } 311 355 312 356 313 - if (self->type == XRT_LAYER_EQUIRECT2) { 357 + if (self->type == XRT_LAYER_EQUIRECT1 || 358 + self->type == XRT_LAYER_EQUIRECT2) { 314 359 const VkDescriptorSet sets[2] = { 315 360 self->descriptor_sets[eye], 316 361 self->descriptor_equirect, ··· 478 523 for (uint32_t eye = 0; eye < 2; eye++) 479 524 vk_buffer_destroy(&self->transformation_ubos[eye], self->vk); 480 525 526 + vk_buffer_destroy(&self->equirect1_ubo, self->vk); 481 527 vk_buffer_destroy(&self->equirect2_ubo, self->vk); 482 528 483 529 self->vk->vkDestroyDescriptorPool(self->vk->device,
+14
src/xrt/compositor/main/comp_layer.h
··· 20 20 bool flip_y; 21 21 }; 22 22 23 + struct layer_equirect1_data 24 + { 25 + struct xrt_vec2 scale; 26 + struct xrt_vec2 bias; 27 + float radius; 28 + }; 29 + 23 30 struct layer_equirect2_data 24 31 { 25 32 float radius; ··· 40 47 41 48 struct layer_transformation transformation[2]; 42 49 struct vk_buffer transformation_ubos[2]; 50 + 51 + struct layer_equirect1_data equirect1_data; 52 + struct vk_buffer equirect1_ubo; 43 53 44 54 struct layer_equirect2_data equirect2_data; 45 55 struct vk_buffer equirect2_ubo; ··· 103 113 bool 104 114 comp_layer_update_cylinder_vertex_buffer(struct comp_render_layer *self, 105 115 float central_angle); 116 + 117 + void 118 + comp_layer_update_equirect1_descriptor(struct comp_render_layer *self, 119 + struct xrt_layer_equirect1_data *data); 106 120 107 121 void 108 122 comp_layer_update_equirect2_descriptor(struct comp_render_layer *self,
+11
src/xrt/compositor/main/comp_layer_renderer.c
··· 412 412 comp_layer_draw(self->layers[i], eye, pipeline, 413 413 pipeline_layout, cmd_buffer, 414 414 vertex_buffer, &vp_inv, &vp_inv); 415 + } else if (self->layers[i]->type == XRT_LAYER_EQUIRECT1) { 416 + pipeline = self->pipeline_equirect1; 417 + comp_layer_draw(self->layers[i], eye, pipeline, 418 + pipeline_layout, cmd_buffer, 419 + vertex_buffer, &vp_inv, &vp_inv); 415 420 } else { 416 421 comp_layer_draw(self->layers[i], eye, pipeline, 417 422 pipeline_layout, cmd_buffer, ··· 553 558 return false; 554 559 } 555 560 561 + if (!_init_graphics_pipeline(self, s->equirect1_vert, s->equirect1_frag, 562 + true, &self->pipeline_equirect1)) { 563 + return false; 564 + } 565 + 556 566 if (!_init_graphics_pipeline(self, s->equirect2_vert, s->equirect2_frag, 557 567 true, &self->pipeline_equirect2)) { 558 568 return false; ··· 696 706 NULL); 697 707 vk->vkDestroyPipeline(vk->device, self->pipeline_unpremultiplied_alpha, 698 708 NULL); 709 + vk->vkDestroyPipeline(vk->device, self->pipeline_equirect1, NULL); 699 710 vk->vkDestroyPipeline(vk->device, self->pipeline_equirect2, NULL); 700 711 701 712 for (uint32_t i = 0; i < ARRAY_SIZE(self->shader_modules); i++)
+1
src/xrt/compositor/main/comp_layer_renderer.h
··· 39 39 VkShaderModule shader_modules[2]; 40 40 VkPipeline pipeline_premultiplied_alpha; 41 41 VkPipeline pipeline_unpremultiplied_alpha; 42 + VkPipeline pipeline_equirect1; 42 43 VkPipeline pipeline_equirect2; 43 44 VkDescriptorSetLayout descriptor_set_layout; 44 45 VkDescriptorSetLayout descriptor_set_layout_equirect;
+1 -2
src/xrt/compositor/main/comp_renderer.c
··· 601 601 get_image_view(image, data->flags, 602 602 data->equirect1.sub.array_index)); 603 603 604 - // TODO! 605 - // comp_layer_update_equirect1_descriptor(l, &data->equirect1); 604 + comp_layer_update_equirect1_descriptor(l, &data->equirect1); 606 605 607 606 for (uint32_t i = 0; i < 2; i++) { 608 607 l->transformation[i].offset = data->equirect1.sub.rect.offset;
+13
src/xrt/compositor/main/comp_shaders.c
··· 22 22 23 23 #include "shaders/layer.frag.h" 24 24 #include "shaders/layer.vert.h" 25 + #include "shaders/equirect1.frag.h" 26 + #include "shaders/equirect1.vert.h" 25 27 #include "shaders/equirect2.frag.h" 26 28 #include "shaders/equirect2.vert.h" 27 29 #include "shaders/mesh.frag.h" ··· 90 92 &s->mesh_frag)); // out 91 93 92 94 C(shader_load(vk, // vk_bundle 95 + shaders_equirect1_vert, // data 96 + sizeof(shaders_equirect1_vert), // size 97 + &s->equirect1_vert)); // out 98 + C(shader_load(vk, // vk_bundle 99 + shaders_equirect1_frag, // data 100 + sizeof(shaders_equirect1_frag), // size 101 + &s->equirect1_frag)); // out 102 + 103 + C(shader_load(vk, // vk_bundle 93 104 shaders_equirect2_vert, // data 94 105 sizeof(shaders_equirect2_vert), // size 95 106 &s->equirect2_vert)); // out ··· 123 134 { 124 135 D(mesh_vert); 125 136 D(mesh_frag); 137 + D(equirect1_vert); 138 + D(equirect1_frag); 126 139 D(equirect2_vert); 127 140 D(equirect2_frag); 128 141 D(layer_vert);
+48
src/xrt/compositor/shaders/equirect1.frag
··· 1 + // Copyright 2020 Collabora Ltd. 2 + // Author: Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 3 + // SPDX-License-Identifier: BSL-1.0 4 + 5 + #version 460 6 + 7 + layout (location = 0) in vec2 uv; 8 + 9 + layout (set = 0, binding = 0, std140) uniform Transformation { 10 + mat4 mvp; 11 + ivec2 offset; 12 + ivec2 extent; 13 + bool flip_y; 14 + } ubo; 15 + 16 + layout (set = 0, binding = 1) uniform sampler2D image; 17 + 18 + layout (set = 1, binding = 0, std140) uniform Equirect { 19 + vec2 scale; 20 + vec2 bias; 21 + float radius; 22 + } equirect; 23 + 24 + layout (location = 0) out vec4 out_color; 25 + 26 + const float PI = 3.1416; 27 + 28 + void main () 29 + { 30 + vec2 uv_sub = vec2(ubo.offset) + uv * vec2(ubo.extent); 31 + uv_sub /= textureSize(image, 0); 32 + 33 + vec2 frag_coord = vec2(uv_sub) * 2 - 1; 34 + 35 + vec4 view_dir = normalize(ubo.mvp * vec4(frag_coord.x, -frag_coord.y, 1, 1)); 36 + 37 + float lat = atan(view_dir.x, -view_dir.z) / (2 * PI); 38 + float lon = acos(view_dir.y) / PI; 39 + 40 + lat *= equirect.scale.x; 41 + lon *= equirect.scale.y; 42 + 43 + lat += equirect.bias.x; 44 + lon += equirect.bias.y; 45 + 46 + out_color = texture(image, vec2(lat, lon)); 47 + } 48 +
+39
src/xrt/compositor/shaders/equirect1.vert
··· 1 + // Copyright 2020 Collabora Ltd. 2 + // Author: Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 3 + // SPDX-License-Identifier: BSL-1.0 4 + 5 + #version 460 6 + 7 + layout (binding = 0, std140) uniform Transformation { 8 + mat4 mvp; 9 + ivec2 offset; 10 + ivec2 extent; 11 + bool flip_y; 12 + } transformation; 13 + 14 + layout (location = 0) in vec3 position; 15 + layout (location = 1) in vec2 uv; 16 + 17 + layout (location = 0) out vec2 out_uv; 18 + 19 + 20 + out gl_PerVertex { 21 + vec4 gl_Position; 22 + }; 23 + 24 + const mat4 mvp = mat4( 25 + 2, 0, 0, 0, 26 + 0, 2, 0, 0, 27 + 0, 0, 1, 0, 28 + 0, 0, 0, 1 29 + ); 30 + 31 + void main() { 32 + gl_Position = mvp * vec4 (position, 1.0f); 33 + gl_Position.y = -gl_Position.y; 34 + out_uv = uv; 35 + 36 + if (transformation.flip_y) { 37 + out_uv.y = 1.0 - out_uv.y; 38 + } 39 + }
+2
src/xrt/compositor/shaders/meson.build
··· 6 6 'mesh.vert', 7 7 'layer.vert', 8 8 'layer.frag', 9 + 'equirect1.vert', 10 + 'equirect1.frag', 9 11 'equirect2.vert', 10 12 'equirect2.frag' 11 13 ]