The open source OpenXR runtime
0
fork

Configure Feed

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

c/main: Implement XR_KHR_composition_layer_equirect2.

authored by

Lubosz Sarnecki and committed by
Jakob Bornecrantz
3195ba83 9738b4fe

+260 -36
+7 -5
src/xrt/compositor/main/comp_compositor.c
··· 427 427 struct xrt_swapchain *xsc, 428 428 const struct xrt_layer_data *data) 429 429 { 430 - #if 0 431 430 return do_single(xc, xdev, xsc, data); 432 - #else 433 - return XRT_SUCCESS; //! @todo Implement 434 - #endif 435 431 } 436 432 437 433 static xrt_result_t ··· 493 489 image = &layer->scs[0]->images[cyl->sub.image_index]; 494 490 comp_renderer_set_cylinder_layer(c->r, i, image, data); 495 491 } break; 492 + case XRT_LAYER_EQUIRECT: { 493 + struct xrt_layer_equirect_data *eq = 494 + &layer->data.equirect; 495 + struct comp_swapchain_image *image; 496 + image = &layer->scs[0]->images[eq->sub.image_index]; 497 + comp_renderer_set_equirect_layer(c->r, i, image, data); 498 + } break; 496 499 case XRT_LAYER_CUBE: 497 - case XRT_LAYER_EQUIRECT: 498 500 // Should never end up here. 499 501 assert(false); 500 502 }
+106 -14
src/xrt/compositor/main/comp_layer.c
··· 83 83 return true; 84 84 } 85 85 86 + static bool 87 + _init_equirect_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->equirect_ubo.handle, 97 + &self->equirect_ubo.memory)) 98 + return false; 99 + 100 + VkResult res = self->vk->vkMapMemory( 101 + self->vk->device, self->equirect_ubo.memory, 0, VK_WHOLE_SIZE, 0, 102 + &self->equirect_ubo.data); 103 + vk_check_error("vkMapMemory", res, false); 104 + 105 + memcpy(self->equirect_ubo.data, &self->equirect_data, 106 + sizeof(struct layer_equirect_data)); 107 + 108 + return true; 109 + } 110 + 86 111 static void 87 112 _update_descriptor(struct comp_render_layer *self, 88 113 struct vk_bundle *vk, ··· 126 151 vk->vkUpdateDescriptorSets(vk->device, 2, sets, 0, NULL); 127 152 } 128 153 154 + static void 155 + _update_descriptor_equirect(struct comp_render_layer *self, 156 + VkDescriptorSet set, 157 + VkBuffer buffer) 158 + { 159 + VkWriteDescriptorSet *sets = (VkWriteDescriptorSet[]){ 160 + { 161 + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 162 + .dstSet = set, 163 + .dstBinding = 0, 164 + .descriptorCount = 1, 165 + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 166 + .pBufferInfo = 167 + &(VkDescriptorBufferInfo){ 168 + .buffer = buffer, 169 + .offset = 0, 170 + .range = VK_WHOLE_SIZE, 171 + }, 172 + .pTexelBufferView = NULL, 173 + }, 174 + }; 175 + 176 + self->vk->vkUpdateDescriptorSets(self->vk->device, 1, sets, 0, NULL); 177 + } 178 + 129 179 void 130 180 comp_layer_update_descriptors(struct comp_render_layer *self, 131 181 VkSampler sampler, ··· 138 188 } 139 189 140 190 void 191 + comp_layer_update_equirect_descriptor(struct comp_render_layer *self, 192 + struct xrt_layer_equirect_data *data) 193 + { 194 + _update_descriptor_equirect(self, self->descriptor_equirect, 195 + self->equirect_ubo.handle); 196 + 197 + self->equirect_data = (struct layer_equirect_data){ 198 + .radius = data->radius, 199 + .central_horizontal_angle = data->central_horizontal_angle, 200 + .upper_vertical_angle = data->upper_vertical_angle, 201 + .lower_vertical_angle = data->lower_vertical_angle, 202 + }; 203 + memcpy(self->equirect_ubo.data, &self->equirect_data, 204 + sizeof(struct layer_equirect_data)); 205 + } 206 + 207 + void 141 208 comp_layer_update_stereo_descriptors(struct comp_render_layer *self, 142 209 VkSampler left_sampler, 143 210 VkSampler right_sampler, ··· 156 223 static bool 157 224 _init(struct comp_render_layer *self, 158 225 struct vk_bundle *vk, 159 - VkDescriptorSetLayout *layout) 226 + VkDescriptorSetLayout *layout, 227 + VkDescriptorSetLayout *layout_equirect) 160 228 { 161 229 self->vk = vk; 162 230 ··· 168 236 if (!_init_ubos(self)) 169 237 return false; 170 238 171 - uint32_t set_count = 2; 239 + if (!_init_equirect_ubo(self)) 240 + return false; 172 241 173 242 VkDescriptorPoolSize pool_sizes[] = { 174 243 { 175 - .descriptorCount = set_count, 244 + .descriptorCount = 3, 176 245 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 177 246 }, 178 247 { 179 - .descriptorCount = set_count, 248 + .descriptorCount = 2, 180 249 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 181 250 }, 182 251 }; 183 252 184 253 if (!vk_init_descriptor_pool(self->vk, pool_sizes, 185 - ARRAY_SIZE(pool_sizes), set_count, 254 + ARRAY_SIZE(pool_sizes), 3, 186 255 &self->descriptor_pool)) 187 256 return false; 188 257 189 - for (uint32_t eye = 0; eye < set_count; eye++) 258 + for (uint32_t eye = 0; eye < 2; eye++) 190 259 if (!vk_allocate_descriptor_sets( 191 260 self->vk, self->descriptor_pool, 1, layout, 192 261 &self->descriptor_sets[eye])) 193 262 return false; 263 + 264 + if (!vk_allocate_descriptor_sets(self->vk, self->descriptor_pool, 1, 265 + layout_equirect, 266 + &self->descriptor_equirect)) 267 + return false; 194 268 195 269 return true; 196 270 } ··· 225 299 case XRT_LAYER_STEREO_PROJECTION: 226 300 _update_mvp_matrix(self, eye, &proj_scale); 227 301 break; 228 - case XRT_LAYER_QUAD: _update_mvp_matrix(self, eye, vp); break; 229 - case XRT_LAYER_CYLINDER: _update_mvp_matrix(self, eye, vp); break; 302 + case XRT_LAYER_QUAD: 303 + case XRT_LAYER_CYLINDER: 304 + case XRT_LAYER_EQUIRECT: _update_mvp_matrix(self, eye, vp); break; 230 305 case XRT_LAYER_STEREO_PROJECTION_DEPTH: 231 306 case XRT_LAYER_CUBE: 232 - case XRT_LAYER_EQUIRECT: 233 307 // Should never end up here. 234 308 assert(false); 235 309 } 236 310 237 - self->vk->vkCmdBindDescriptorSets( 238 - cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, 239 - &self->descriptor_sets[eye], 0, NULL); 311 + 312 + if (self->type == XRT_LAYER_EQUIRECT) { 313 + const VkDescriptorSet sets[2] = { 314 + self->descriptor_sets[eye], 315 + self->descriptor_equirect, 316 + }; 317 + 318 + self->vk->vkCmdBindDescriptorSets( 319 + cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, 320 + pipeline_layout, 0, 2, sets, 0, NULL); 321 + 322 + } else { 323 + self->vk->vkCmdBindDescriptorSets( 324 + cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, 325 + pipeline_layout, 0, 1, &self->descriptor_sets[eye], 0, 326 + NULL); 327 + } 240 328 241 329 VkDeviceSize offsets[1] = {0}; 242 330 self->vk->vkCmdBindVertexBuffers(cmd_buffer, 0, 1, ··· 369 457 } 370 458 371 459 struct comp_render_layer * 372 - comp_layer_create(struct vk_bundle *vk, VkDescriptorSetLayout *layout) 460 + comp_layer_create(struct vk_bundle *vk, 461 + VkDescriptorSetLayout *layout, 462 + VkDescriptorSetLayout *layout_equirect) 373 463 { 374 464 struct comp_render_layer *q = U_TYPED_CALLOC(struct comp_render_layer); 375 465 376 - _init(q, vk, layout); 466 + _init(q, vk, layout, layout_equirect); 377 467 378 468 if (!_init_cylinder_vertex_buffer(q)) 379 469 return NULL; ··· 386 476 { 387 477 for (uint32_t eye = 0; eye < 2; eye++) 388 478 vk_buffer_destroy(&self->transformation_ubos[eye], self->vk); 479 + 480 + vk_buffer_destroy(&self->equirect_ubo, self->vk); 389 481 390 482 self->vk->vkDestroyDescriptorPool(self->vk->device, 391 483 self->descriptor_pool, NULL);
+19 -1
src/xrt/compositor/main/comp_layer.h
··· 20 20 bool flip_y; 21 21 }; 22 22 23 + struct layer_equirect_data 24 + { 25 + float radius; 26 + float central_horizontal_angle; 27 + float upper_vertical_angle; 28 + float lower_vertical_angle; 29 + }; 30 + 23 31 struct comp_render_layer 24 32 { 25 33 struct vk_bundle *vk; ··· 33 41 struct layer_transformation transformation[2]; 34 42 struct vk_buffer transformation_ubos[2]; 35 43 44 + struct layer_equirect_data equirect_data; 45 + struct vk_buffer equirect_ubo; 46 + 36 47 VkDescriptorPool descriptor_pool; 37 48 VkDescriptorSet descriptor_sets[2]; 49 + VkDescriptorSet descriptor_equirect; 38 50 39 51 struct xrt_matrix_4x4 model_matrix; 40 52 ··· 49 61 }; 50 62 51 63 struct comp_render_layer * 52 - comp_layer_create(struct vk_bundle *vk, VkDescriptorSetLayout *layout); 64 + comp_layer_create(struct vk_bundle *vk, 65 + VkDescriptorSetLayout *layout, 66 + VkDescriptorSetLayout *layout_equirect); 53 67 54 68 void 55 69 comp_layer_draw(struct comp_render_layer *self, ··· 89 103 bool 90 104 comp_layer_update_cylinder_vertex_buffer(struct comp_render_layer *self, 91 105 float central_angle); 106 + 107 + void 108 + comp_layer_update_equirect_descriptor(struct comp_render_layer *self, 109 + struct xrt_layer_equirect_data *data);
+72 -14
src/xrt/compositor/main/comp_layer_renderer.c
··· 112 112 } 113 113 114 114 static bool 115 + _init_descriptor_layout_equirect(struct comp_layer_renderer *self) 116 + { 117 + struct vk_bundle *vk = self->vk; 118 + 119 + VkDescriptorSetLayoutCreateInfo info = { 120 + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 121 + .bindingCount = 1, 122 + .pBindings = 123 + (VkDescriptorSetLayoutBinding[]){ 124 + { 125 + .binding = 0, 126 + .descriptorCount = 1, 127 + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 128 + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, 129 + }, 130 + }, 131 + }; 132 + 133 + VkResult res = vk->vkCreateDescriptorSetLayout( 134 + vk->device, &info, NULL, &self->descriptor_set_layout_equirect); 135 + 136 + vk_check_error("vkCreateDescriptorSetLayout", res, false); 137 + 138 + return true; 139 + } 140 + 141 + static bool 115 142 _init_pipeline_layout(struct comp_layer_renderer *self) 116 143 { 117 144 struct vk_bundle *vk = self->vk; 118 145 146 + const VkDescriptorSetLayout set_layouts[2] = { 147 + self->descriptor_set_layout, self->descriptor_set_layout_equirect}; 148 + 119 149 VkPipelineLayoutCreateInfo info = { 120 150 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, 121 - .setLayoutCount = 1, 122 - .pSetLayouts = &self->descriptor_set_layout, 123 - .pushConstantRangeCount = 0, 124 - .pPushConstantRanges = NULL, 151 + .setLayoutCount = 2, 152 + .pSetLayouts = set_layouts, 125 153 }; 126 154 127 155 VkResult res = vk->vkCreatePipelineLayout(vk->device, &info, NULL, ··· 162 190 163 191 static bool 164 192 _init_graphics_pipeline(struct comp_layer_renderer *self, 165 - struct comp_shaders *s, 193 + VkShaderModule shader_vert, 194 + VkShaderModule shader_frag, 166 195 bool premultiplied_alpha, 167 196 VkPipeline *pipeline) 168 197 { ··· 218 247 { 219 248 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 220 249 .stage = VK_SHADER_STAGE_VERTEX_BIT, 221 - .module = s->layer_vert, 250 + .module = shader_vert, 222 251 .pName = "main", 223 252 }, 224 253 { 225 254 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 226 255 .stage = VK_SHADER_STAGE_FRAGMENT_BIT, 227 - .module = s->layer_frag, 256 + .module = shader_frag, 228 257 .pName = "main", 229 258 }, 230 259 }; ··· 347 376 { 348 377 struct xrt_matrix_4x4 vp_world; 349 378 struct xrt_matrix_4x4 vp_eye; 379 + struct xrt_matrix_4x4 vp_inv; 350 380 math_matrix_4x4_multiply(&self->mat_projection[eye], 351 381 &self->mat_world_view[eye], &vp_world); 352 382 math_matrix_4x4_multiply(&self->mat_projection[eye], 353 383 &self->mat_eye_view[eye], &vp_eye); 354 384 385 + math_matrix_4x4_inverse_view_projection( 386 + &self->mat_world_view[eye], &self->mat_projection[eye], &vp_inv); 355 387 356 388 for (uint32_t i = 0; i < self->num_layers; i++) { 357 389 bool unpremultiplied_alpha = ··· 370 402 unpremultiplied_alpha 371 403 ? self->pipeline_premultiplied_alpha 372 404 : self->pipeline_unpremultiplied_alpha; 373 - comp_layer_draw(self->layers[i], eye, pipeline, pipeline_layout, 374 - cmd_buffer, vertex_buffer, &vp_world, &vp_eye); 405 + 406 + if (self->layers[i]->type == XRT_LAYER_EQUIRECT) { 407 + pipeline = self->pipeline_equirect; 408 + comp_layer_draw(self->layers[i], eye, pipeline, 409 + pipeline_layout, cmd_buffer, 410 + vertex_buffer, &vp_inv, &vp_inv); 411 + } else { 412 + comp_layer_draw(self->layers[i], eye, pipeline, 413 + pipeline_layout, cmd_buffer, 414 + vertex_buffer, &vp_world, &vp_eye); 415 + } 375 416 } 376 417 } 377 418 ··· 436 477 437 478 for (uint32_t i = 0; i < self->num_layers; i++) { 438 479 self->layers[i] = 439 - comp_layer_create(vk, &self->descriptor_set_layout); 480 + comp_layer_create(vk, &self->descriptor_set_layout, 481 + &self->descriptor_set_layout_equirect); 440 482 } 441 483 } 442 484 ··· 489 531 490 532 if (!_init_descriptor_layout(self)) 491 533 return false; 534 + if (!_init_descriptor_layout_equirect(self)) 535 + return false; 492 536 if (!_init_pipeline_layout(self)) 493 537 return false; 494 538 if (!_init_pipeline_cache(self)) 495 539 return false; 496 - if (!_init_graphics_pipeline(self, s, false, 497 - &self->pipeline_premultiplied_alpha)) 540 + 541 + 542 + if (!_init_graphics_pipeline(self, s->layer_vert, s->layer_frag, false, 543 + &self->pipeline_premultiplied_alpha)) { 498 544 return false; 499 - if (!_init_graphics_pipeline(self, s, true, 500 - &self->pipeline_unpremultiplied_alpha)) 545 + } 546 + 547 + if (!_init_graphics_pipeline(self, s->layer_vert, s->layer_frag, true, 548 + &self->pipeline_unpremultiplied_alpha)) { 501 549 return false; 550 + } 551 + 552 + if (!_init_graphics_pipeline(self, s->equirect_vert, s->equirect_frag, 553 + true, &self->pipeline_equirect)) { 554 + return false; 555 + } 556 + 502 557 if (!_init_vertex_buffer(self)) 503 558 return false; 504 559 ··· 631 686 vk->vkDestroyPipelineLayout(vk->device, self->pipeline_layout, NULL); 632 687 vk->vkDestroyDescriptorSetLayout(vk->device, 633 688 self->descriptor_set_layout, NULL); 689 + vk->vkDestroyDescriptorSetLayout( 690 + vk->device, self->descriptor_set_layout_equirect, NULL); 634 691 vk->vkDestroyPipeline(vk->device, self->pipeline_premultiplied_alpha, 635 692 NULL); 636 693 vk->vkDestroyPipeline(vk->device, self->pipeline_unpremultiplied_alpha, 637 694 NULL); 695 + vk->vkDestroyPipeline(vk->device, self->pipeline_equirect, NULL); 638 696 639 697 for (uint32_t i = 0; i < ARRAY_SIZE(self->shader_modules); i++) 640 698 vk->vkDestroyShaderModule(vk->device, self->shader_modules[i],
+3
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_equirect; 42 43 VkDescriptorSetLayout descriptor_set_layout; 44 + VkDescriptorSetLayout descriptor_set_layout_equirect; 45 + 43 46 VkPipelineLayout pipeline_layout; 44 47 VkPipelineCache pipeline_cache; 45 48
+34
src/xrt/compositor/main/comp_renderer.c
··· 502 502 } 503 503 504 504 void 505 + comp_renderer_set_equirect_layer(struct comp_renderer *r, 506 + uint32_t layer, 507 + struct comp_swapchain_image *image, 508 + struct xrt_layer_data *data) 509 + { 510 + 511 + struct xrt_vec3 s = {1.0f, 1.0f, 1.0f}; 512 + struct xrt_matrix_4x4 model_matrix; 513 + math_matrix_4x4_model(&data->equirect.pose, &s, &model_matrix); 514 + 515 + comp_layer_set_flip_y(r->lr->layers[layer], data->flip_y); 516 + 517 + struct comp_render_layer *l = r->lr->layers[layer]; 518 + l->type = XRT_LAYER_EQUIRECT; 519 + l->visibility = data->equirect.visibility; 520 + l->flags = data->flags; 521 + l->view_space = 522 + (data->flags & XRT_LAYER_COMPOSITION_VIEW_SPACE_BIT) != 0; 523 + l->transformation_ubo_binding = r->lr->transformation_ubo_binding; 524 + l->texture_binding = r->lr->texture_binding; 525 + 526 + comp_layer_update_descriptors( 527 + l, image->repeat_sampler, 528 + get_image_view(image, data->flags, data->equirect.sub.array_index)); 529 + 530 + comp_layer_update_equirect_descriptor(l, &data->equirect); 531 + 532 + for (uint32_t i = 0; i < 2; i++) { 533 + l->transformation[i].offset = data->equirect.sub.rect.offset; 534 + l->transformation[i].extent = data->equirect.sub.rect.extent; 535 + } 536 + } 537 + 538 + void 505 539 comp_renderer_draw(struct comp_renderer *r) 506 540 { 507 541 renderer_get_view_projection(r);
+6
src/xrt/compositor/main/comp_renderer.h
··· 74 74 struct xrt_layer_data *data); 75 75 76 76 void 77 + comp_renderer_set_equirect_layer(struct comp_renderer *r, 78 + uint32_t layer, 79 + struct comp_swapchain_image *image, 80 + struct xrt_layer_data *data); 81 + 82 + void 77 83 comp_renderer_allocate_layers(struct comp_renderer *self, uint32_t num_layers); 78 84 79 85 void
+10 -2
src/xrt/compositor/shaders/equirect.frag
··· 6 6 7 7 layout (location = 0) in vec2 uv; 8 8 9 - layout (binding = 0, std140) uniform Transformation { 9 + layout (set = 0, binding = 0, std140) uniform Transformation { 10 10 mat4 mvp; 11 11 ivec2 offset; 12 12 ivec2 extent; 13 13 bool flip_y; 14 14 } ubo; 15 - layout (binding = 1) uniform sampler2D image; 15 + 16 + layout (set = 0, binding = 1) uniform sampler2D image; 17 + 18 + layout (set = 1, binding = 0, std140) uniform Equirect { 19 + float radius; 20 + float central_horizontal_angle; 21 + float upper_vertical_angle; 22 + float lower_vertical_angle; 23 + } equirect; 16 24 17 25 layout (location = 0) out vec4 out_color; 18 26
+3
src/xrt/include/xrt/xrt_compositor.h
··· 263 263 264 264 struct xrt_pose pose; 265 265 float radius; 266 + float central_horizontal_angle; 267 + float upper_vertical_angle; 268 + float lower_vertical_angle; 266 269 }; 267 270 268 271 /*!