diff --git a/src/xrt/compositor/main/comp_renderer.c b/src/xrt/compositor/main/comp_renderer.c index fd59857ae..67c709e78 100644 --- a/src/xrt/compositor/main/comp_renderer.c +++ b/src/xrt/compositor/main/comp_renderer.c @@ -847,10 +847,11 @@ do_gfx_mesh(struct comp_renderer *r, i, // view_index &viewport_datas[i]); // viewport_data - render_gfx_mesh_draw( // - rr, // rr - i, // mesh_index - descriptor_sets[i]); // descriptor_set + render_gfx_mesh_draw( // + rr, // rr + i, // mesh_index + descriptor_sets[i], // descriptor_set + false); // do_timewarp render_gfx_end_view(rr); } diff --git a/src/xrt/compositor/render/render_gfx.c b/src/xrt/compositor/render/render_gfx.c index f09fc146b..7cfdfa77e 100644 --- a/src/xrt/compositor/render/render_gfx.c +++ b/src/xrt/compositor/render/render_gfx.c @@ -295,6 +295,11 @@ do_ubo_and_src_alloc_and_write(struct render_gfx *rr, * */ +struct mesh_params +{ + uint32_t do_timewarp; +}; + XRT_CHECK_RESULT static VkResult create_mesh_pipeline(struct vk_bundle *vk, VkRenderPass render_pass, @@ -303,6 +308,7 @@ create_mesh_pipeline(struct vk_bundle *vk, uint32_t src_binding, uint32_t mesh_index_count_total, uint32_t mesh_stride, + const struct mesh_params *params, VkShaderModule mesh_vert, VkShaderModule mesh_frag, VkPipeline *out_mesh_pipeline) @@ -409,11 +415,31 @@ create_mesh_pipeline(struct vk_bundle *vk, }; // clang-format on +#define ENTRY(ID, FIELD) \ + { \ + .constantID = ID, \ + .offset = offsetof(struct mesh_params, FIELD), \ + .size = sizeof(params->FIELD), \ + } + + VkSpecializationMapEntry vert_entries[] = { + ENTRY(0, do_timewarp), + }; +#undef ENTRY + + VkSpecializationInfo vert_specialization_info = { + .mapEntryCount = ARRAY_SIZE(vert_entries), + .pMapEntries = vert_entries, + .dataSize = sizeof(*params), + .pData = params, + }; + VkPipelineShaderStageCreateInfo shader_stages[2] = { { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .stage = VK_SHADER_STAGE_VERTEX_BIT, .module = mesh_vert, + .pSpecializationInfo = &vert_specialization_info, .pName = "main", }, { @@ -482,6 +508,10 @@ render_gfx_render_pass_init(struct render_gfx_render_pass *rgrp, &rgrp->render_pass); // out_render_pass VK_CHK_WITH_RET(ret, "create_implicit_render_pass", false); + struct mesh_params simple_params = { + .do_timewarp = false, + }; + ret = create_mesh_pipeline( // vk, // vk_bundle rgrp->render_pass, // render_pass @@ -490,11 +520,30 @@ render_gfx_render_pass_init(struct render_gfx_render_pass *rgrp, r->mesh.src_binding, // src_binding r->mesh.index_count_total, // mesh_index_count_total r->mesh.stride, // mesh_stride + &simple_params, // params r->shaders->mesh_vert, // mesh_vert r->shaders->mesh_frag, // mesh_frag &rgrp->mesh.pipeline); // out_mesh_pipeline VK_CHK_WITH_RET(ret, "create_mesh_pipeline", false); + struct mesh_params timewarp_params = { + .do_timewarp = true, + }; + + ret = create_mesh_pipeline( // + vk, // vk_bundle + rgrp->render_pass, // render_pass + r->mesh.pipeline_layout, // pipeline_layout + r->pipeline_cache, // pipeline_cache + r->mesh.src_binding, // src_binding + r->mesh.index_count_total, // mesh_index_count_total + r->mesh.stride, // mesh_stride + &timewarp_params, // params + r->shaders->mesh_vert, // mesh_vert + r->shaders->mesh_frag, // mesh_frag + &rgrp->mesh.pipeline_timewarp); // out_mesh_pipeline + VK_CHK_WITH_RET(ret, "create_mesh_pipeline", false); + // Set fields. rgrp->r = r; rgrp->format = format; @@ -512,6 +561,7 @@ render_gfx_render_pass_close(struct render_gfx_render_pass *rgrp) D(RenderPass, rgrp->render_pass); D(Pipeline, rgrp->mesh.pipeline); + D(Pipeline, rgrp->mesh.pipeline_timewarp); U_ZERO(rgrp); } @@ -771,7 +821,7 @@ render_gfx_mesh_alloc_and_write(struct render_gfx *rr, } void -render_gfx_mesh_draw(struct render_gfx *rr, uint32_t mesh_index, VkDescriptorSet descriptor_set) +render_gfx_mesh_draw(struct render_gfx *rr, uint32_t mesh_index, VkDescriptorSet descriptor_set, bool do_timewarp) { struct vk_bundle *vk = vk_from_rr(rr); struct render_resources *r = rr->r; @@ -792,10 +842,13 @@ render_gfx_mesh_draw(struct render_gfx *rr, uint32_t mesh_index, VkDescriptorSet 0, // dynamicOffsetCount NULL); // pDynamicOffsets + // Select which pipeline we want. + VkPipeline pipeline = do_timewarp ? rr->rtr->rgrp->mesh.pipeline_timewarp : rr->rtr->rgrp->mesh.pipeline; + vk->vkCmdBindPipeline( // r->cmd, // commandBuffer VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint - rr->rtr->rgrp->mesh.pipeline); // pipeline + pipeline); // pipeline /* diff --git a/src/xrt/compositor/render/render_interface.h b/src/xrt/compositor/render/render_interface.h index 59179f707..3f15cf321 100644 --- a/src/xrt/compositor/render/render_interface.h +++ b/src/xrt/compositor/render/render_interface.h @@ -686,8 +686,11 @@ struct render_gfx_render_pass struct { - //! Pipeline layout used for mesh, does not depend on framebuffer. + //! Pipeline layout used for mesh, without timewarp. VkPipeline pipeline; + + //! Pipeline layout used for mesh, with timewarp. + VkPipeline pipeline_timewarp; } mesh; }; @@ -887,12 +890,12 @@ render_gfx_mesh_alloc_and_write(struct render_gfx *rr, /*! * Dispatch one mesh shader instance, using the give @p mesh_index as source for - * mesh geometry. + * mesh geometry, timewarp selectable via @p do_timewarp. * * @public @memberof render_gfx */ void -render_gfx_mesh_draw(struct render_gfx *rr, uint32_t mesh_index, VkDescriptorSet descriptor_set); +render_gfx_mesh_draw(struct render_gfx *rr, uint32_t mesh_index, VkDescriptorSet descriptor_set, bool do_timewarp); /*!