Skip to content

Commit d60f6e1

Browse files
committed
Use attachmentless render pass for mouse picking.
1 parent 9d477e3 commit d60f6e1

File tree

5 files changed

+46
-45
lines changed

5 files changed

+46
-45
lines changed

impl/vulkan/Frame.cpp

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,7 +1019,7 @@ vk_gltf_viewer::vulkan::Frame::PassthruResources::PassthruResources(
10191019
const vk::Extent2D &extent,
10201020
vk::CommandBuffer graphicsCommandBuffer
10211021
) : extent { extent },
1022-
mousePickingAttachmentGroup { sharedData.gpu, extent },
1022+
mousePickingAttachmentGroup { value_if(sharedData.gpu.workaround.attachmentLessRenderPass, [&] { return ag::MousePicking { sharedData.gpu, extent }; }) },
10231023
hoveringNodeOutlineJumpFloodResources { sharedData.gpu, extent },
10241024
hoveringNodeJumpFloodSeedAttachmentGroup { sharedData.gpu, hoveringNodeOutlineJumpFloodResources.image },
10251025
selectedNodeOutlineJumpFloodResources { sharedData.gpu, extent },
@@ -1091,17 +1091,21 @@ vk_gltf_viewer::vulkan::Frame::PassthruResources::PassthruResources(
10911091
image, subresourceRange
10921092
};
10931093
};
1094+
1095+
boost::container::static_vector<vk::ImageMemoryBarrier, 6> imageMemoryBarriers {
1096+
layoutTransitionBarrier(vk::ImageLayout::eGeneral, hoveringNodeOutlineJumpFloodResources.image, { vk::ImageAspectFlagBits::eColor, 0, 1, 1, 1 } /* pong image */),
1097+
layoutTransitionBarrier(vk::ImageLayout::eDepthAttachmentOptimal, hoveringNodeJumpFloodSeedAttachmentGroup.depthStencilAttachment->image, vku::fullSubresourceRange(vk::ImageAspectFlagBits::eDepth)),
1098+
layoutTransitionBarrier(vk::ImageLayout::eGeneral, selectedNodeOutlineJumpFloodResources.image, { vk::ImageAspectFlagBits::eColor, 0, 1, 1, 1 } /* pong image */),
1099+
layoutTransitionBarrier(vk::ImageLayout::eDepthAttachmentOptimal, selectedNodeJumpFloodSeedAttachmentGroup.depthStencilAttachment->image, vku::fullSubresourceRange(vk::ImageAspectFlagBits::eDepth)),
1100+
layoutTransitionBarrier(vk::ImageLayout::eGeneral, bloomImage, { vk::ImageAspectFlagBits::eColor, 1, vk::RemainingArrayLayers, 0, 1 }),
1101+
};
1102+
if (mousePickingAttachmentGroup) {
1103+
imageMemoryBarriers.push_back(layoutTransitionBarrier(vk::ImageLayout::eDepthAttachmentOptimal, mousePickingAttachmentGroup->depthStencilAttachment->image, vku::fullSubresourceRange(vk::ImageAspectFlagBits::eDepth)));
1104+
}
1105+
10941106
graphicsCommandBuffer.pipelineBarrier(
10951107
vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eBottomOfPipe,
1096-
{}, {}, {},
1097-
{
1098-
layoutTransitionBarrier(vk::ImageLayout::eDepthAttachmentOptimal, mousePickingAttachmentGroup.depthStencilAttachment->image, vku::fullSubresourceRange(vk::ImageAspectFlagBits::eDepth)),
1099-
layoutTransitionBarrier(vk::ImageLayout::eGeneral, hoveringNodeOutlineJumpFloodResources.image, { vk::ImageAspectFlagBits::eColor, 0, 1, 1, 1 } /* pong image */),
1100-
layoutTransitionBarrier(vk::ImageLayout::eDepthAttachmentOptimal, hoveringNodeJumpFloodSeedAttachmentGroup.depthStencilAttachment->image, vku::fullSubresourceRange(vk::ImageAspectFlagBits::eDepth)),
1101-
layoutTransitionBarrier(vk::ImageLayout::eGeneral, selectedNodeOutlineJumpFloodResources.image, { vk::ImageAspectFlagBits::eColor, 0, 1, 1, 1 } /* pong image */),
1102-
layoutTransitionBarrier(vk::ImageLayout::eDepthAttachmentOptimal, selectedNodeJumpFloodSeedAttachmentGroup.depthStencilAttachment->image, vku::fullSubresourceRange(vk::ImageAspectFlagBits::eDepth)),
1103-
layoutTransitionBarrier(vk::ImageLayout::eGeneral, bloomImage, { vk::ImageAspectFlagBits::eColor, 1, vk::RemainingArrayLayers, 0, 1 }),
1104-
});
1108+
{}, {}, {}, imageMemoryBarriers);
11051109
}
11061110

11071111
vk::raii::DescriptorPool vk_gltf_viewer::vulkan::Frame::createDescriptorPool() const {
@@ -1268,11 +1272,13 @@ void vk_gltf_viewer::vulkan::Frame::recordScenePrepassCommands(vk::CommandBuffer
12681272
1,
12691273
0,
12701274
vk::ArrayProxyNoTemporaries<const vk::RenderingAttachmentInfo>{},
1271-
vku::unsafeAddress(vk::RenderingAttachmentInfo {
1272-
*passthruResources->mousePickingAttachmentGroup.depthStencilAttachment->view, vk::ImageLayout::eDepthAttachmentOptimal,
1273-
{}, {}, {},
1274-
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare, vk::ClearDepthStencilValue { 0.f, 0U },
1275-
}),
1275+
value_address(passthruResources->mousePickingAttachmentGroup.transform([](const ag::MousePicking &ag) {
1276+
return vk::RenderingAttachmentInfo {
1277+
*ag.depthStencilAttachment->view, vk::ImageLayout::eDepthAttachmentOptimal,
1278+
{}, {}, {},
1279+
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
1280+
};
1281+
})),
12761282
});
12771283
drawPrimitives(renderingNodes->mousePickingIndirectDrawCommandBuffers);
12781284
cb.endRenderingKHR();
@@ -1342,11 +1348,13 @@ void vk_gltf_viewer::vulkan::Frame::recordScenePrepassCommands(vk::CommandBuffer
13421348
1,
13431349
0,
13441350
vk::ArrayProxyNoTemporaries<const vk::RenderingAttachmentInfo>{},
1345-
sharedData.gpu.workaround.attachmentLessRenderPass ? vku::unsafeAddress(vk::RenderingAttachmentInfo {
1346-
*passthruResources->mousePickingAttachmentGroup.depthStencilAttachment->view, vk::ImageLayout::eDepthAttachmentOptimal,
1347-
{}, {}, {},
1348-
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
1349-
}) : nullptr,
1351+
value_address(passthruResources->mousePickingAttachmentGroup.transform([](const ag::MousePicking &ag) {
1352+
return vk::RenderingAttachmentInfo {
1353+
*ag.depthStencilAttachment->view, vk::ImageLayout::eDepthAttachmentOptimal,
1354+
{}, {}, {},
1355+
vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare,
1356+
};
1357+
})),
13501358
});
13511359
drawPrimitives(renderingNodes->multiNodeMousePickingIndirectDrawCommandBuffers);
13521360
cb.endRenderingKHR();

interface/vulkan/Frame.cppm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ namespace vk_gltf_viewer::vulkan {
167167
vk::Extent2D extent;
168168

169169
// Mouse picking.
170-
ag::MousePicking mousePickingAttachmentGroup;
170+
std::optional<ag::MousePicking> mousePickingAttachmentGroup; // has only value if Gpu::attachmentLessRenderPass == true.
171171

172172
// Outline calculation using JFA.
173173
JumpFloodResources hoveringNodeOutlineJumpFloodResources;

interface/vulkan/SharedData.cppm

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ auto vk_gltf_viewer::vulkan::SharedData::getPrepassPipelines(
190190

191191
return ranges::try_emplace_if_not_exists(prepassPipelines, config, [&] -> PrepassPipelines<false> {
192192
return {
193-
.nodeMousePickingRenderPipeline = { gpu.device, mousePickingPipelineLayout, config },
193+
.nodeMousePickingRenderPipeline = { gpu, mousePickingPipelineLayout, config },
194194
.multiNodeMousePickingRenderPipeline = { gpu, mousePickingPipelineLayout, config },
195195
.jumpFloodSeedRenderingPipeline = { gpu.device, primitiveNoShadingPipelineLayout, config },
196196
};
@@ -231,7 +231,7 @@ auto vk_gltf_viewer::vulkan::SharedData::getMaskPrepassPipelines(
231231

232232
return ranges::try_emplace_if_not_exists(maskPrepassPipelines, config, [&] -> PrepassPipelines<true> {
233233
return {
234-
.nodeMousePickingRenderPipeline = { gpu.device, mousePickingPipelineLayout, config },
234+
.nodeMousePickingRenderPipeline = { gpu, mousePickingPipelineLayout, config },
235235
.multiNodeMousePickingRenderPipeline = { gpu, mousePickingPipelineLayout, config },
236236
.jumpFloodSeedRenderingPipeline = { gpu.device, primitiveNoShadingPipelineLayout, config },
237237
};

interface/vulkan/pipeline/NodeMousePickingRenderPipeline.cppm

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import vk_gltf_viewer.shader.node_mouse_picking_frag;
1111
import vk_gltf_viewer.shader.node_mouse_picking_vert;
1212
import vk_gltf_viewer.shader_selector.mask_node_mouse_picking_frag;
1313
import vk_gltf_viewer.shader_selector.mask_node_mouse_picking_vert;
14+
export import vk_gltf_viewer.vulkan.Gpu;
1415
export import vk_gltf_viewer.vulkan.pipeline.PrepassPipelineConfig;
1516
export import vk_gltf_viewer.vulkan.pipeline_layout.MousePicking;
1617
import vk_gltf_viewer.vulkan.specialization_constants.SpecializationMap;
@@ -23,7 +24,7 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
2324
class NodeMousePickingRenderPipeline<false> final : public vk::raii::Pipeline {
2425
public:
2526
NodeMousePickingRenderPipeline(
26-
const vk::raii::Device &device LIFETIMEBOUND,
27+
const Gpu &gpu LIFETIMEBOUND,
2728
const pl::MousePicking &pipelineLayout LIFETIMEBOUND,
2829
const PrepassPipelineConfig<false> &config
2930
);
@@ -38,7 +39,7 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
3839
class NodeMousePickingRenderPipeline<true> final : public vk::raii::Pipeline {
3940
public:
4041
NodeMousePickingRenderPipeline(
41-
const vk::raii::Device &device LIFETIMEBOUND,
42+
const Gpu &gpu LIFETIMEBOUND,
4243
const pl::MousePicking &pipelineLayout LIFETIMEBOUND,
4344
const PrepassPipelineConfig<true> &config
4445
);
@@ -71,14 +72,14 @@ struct vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<false>::
7172
};
7273

7374
vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<false>::NodeMousePickingRenderPipeline(
74-
const vk::raii::Device &device,
75+
const Gpu &gpu,
7576
const pl::MousePicking &pipelineLayout,
7677
const PrepassPipelineConfig<false> &config
7778
) : Pipeline { [&] -> Pipeline {
78-
return { device, nullptr, vk::StructureChain {
79+
return { gpu.device, nullptr, vk::StructureChain {
7980
vku::getDefaultGraphicsPipelineCreateInfo(
8081
createPipelineStages(
81-
device,
82+
gpu.device,
8283
vku::Shader {
8384
shader::node_mouse_picking_vert,
8485
vk::ShaderStageFlagBits::eVertex,
@@ -88,15 +89,12 @@ vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<false>::NodeMou
8889
}),
8990
},
9091
vku::Shader { shader::node_mouse_picking_frag, vk::ShaderStageFlagBits::eFragment }).get(),
91-
*pipelineLayout, 0, true)
92+
// See doc about Gpu::Workaround::attachmentLessRenderPass.
93+
*pipelineLayout, 0, gpu.workaround.attachmentLessRenderPass)
9294
.setPInputAssemblyState(vku::unsafeAddress(vk::PipelineInputAssemblyStateCreateInfo {
9395
{},
9496
config.topologyClass.value_or(vk::PrimitiveTopology::eTriangleList),
9597
}))
96-
.setPDepthStencilState(vku::unsafeAddress(vk::PipelineDepthStencilStateCreateInfo {
97-
{},
98-
true, true, vk::CompareOp::eGreater, // Use reverse Z.
99-
}))
10098
.setPDynamicState(vku::unsafeAddress(vk::PipelineDynamicStateCreateInfo {
10199
{},
102100
vku::unsafeProxy({
@@ -109,7 +107,7 @@ vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<false>::NodeMou
109107
vk::PipelineRenderingCreateInfo {
110108
{},
111109
{},
112-
vk::Format::eD32Sfloat,
110+
gpu.workaround.attachmentLessRenderPass ? vk::Format::eD32Sfloat : vk::Format::eUndefined,
113111
},
114112
}.get() };
115113
}() } { }
@@ -142,14 +140,14 @@ struct vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<true>::F
142140
};
143141

144142
vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<true>::NodeMousePickingRenderPipeline(
145-
const vk::raii::Device &device,
143+
const Gpu &gpu,
146144
const pl::MousePicking &pipelineLayout,
147145
const PrepassPipelineConfig<true> &config
148146
) : Pipeline { [&] -> Pipeline {
149-
return { device, nullptr, vk::StructureChain {
147+
return { gpu.device, nullptr, vk::StructureChain {
150148
vku::getDefaultGraphicsPipelineCreateInfo(
151149
createPipelineStages(
152-
device,
150+
gpu.device,
153151
vku::Shader {
154152
std::apply(LIFT(shader_selector::mask_node_mouse_picking_vert), getVertexShaderVariants(config)),
155153
vk::ShaderStageFlagBits::eVertex,
@@ -166,15 +164,12 @@ vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<true>::NodeMous
166164
vku::unsafeProxy(getFragmentShaderSpecialization(config)),
167165
}),
168166
}).get(),
169-
*pipelineLayout, 0, true)
167+
// See doc about Gpu::Workaround::attachmentLessRenderPass.
168+
*pipelineLayout, 0, gpu.workaround.attachmentLessRenderPass)
170169
.setPInputAssemblyState(vku::unsafeAddress(vk::PipelineInputAssemblyStateCreateInfo {
171170
{},
172171
config.topologyClass.value_or(vk::PrimitiveTopology::eTriangleList),
173172
}))
174-
.setPDepthStencilState(vku::unsafeAddress(vk::PipelineDepthStencilStateCreateInfo {
175-
{},
176-
true, true, vk::CompareOp::eGreater, // Use reverse Z.
177-
}))
178173
.setPDynamicState(vku::unsafeAddress(vk::PipelineDynamicStateCreateInfo {
179174
{},
180175
vku::unsafeProxy({
@@ -187,7 +182,7 @@ vk_gltf_viewer::vulkan::pipeline::NodeMousePickingRenderPipeline<true>::NodeMous
187182
vk::PipelineRenderingCreateInfo {
188183
{},
189184
{},
190-
vk::Format::eD32Sfloat,
185+
gpu.workaround.attachmentLessRenderPass ? vk::Format::eD32Sfloat : vk::Format::eUndefined,
191186
},
192187
}.get() };
193188
}() } { }

shaders/node_mouse_picking.frag

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ layout (set = 1, binding = 0) buffer MousePickingResultBuffer {
66
uint packedNodeIndexAndDepth;
77
};
88

9-
layout (early_fragment_tests) in;
10-
119
void main(){
1210
atomicMax(packedNodeIndexAndDepth, (uint(gl_FragCoord.z * 65535) << 16) | inNodeIndex);
1311
}

0 commit comments

Comments
 (0)