@@ -9,12 +9,18 @@ import vku;
9
9
10
10
import vk_gltf_viewer.shader.jump_flood_seed_frag;
11
11
import vk_gltf_viewer.shader.jump_flood_seed_vert;
12
+ import vk_gltf_viewer.shader_selector.mask_jump_flood_seed_frag;
13
+ import vk_gltf_viewer.shader_selector.mask_jump_flood_seed_vert;
12
14
export import vk_gltf_viewer.vulkan.pipeline.PrepassPipelineConfig;
13
15
export import vk_gltf_viewer.vulkan.pipeline_layout.PrimitiveNoShading;
14
16
import vk_gltf_viewer.vulkan.specialization_constants.SpecializationMap;
15
17
16
18
namespace vk_gltf_viewer ::vulkan::inline pipeline {
17
- export class JumpFloodSeedRenderPipeline final : public vk::raii::Pipeline {
19
+ export template <bool Mask>
20
+ class JumpFloodSeedRenderPipeline ;
21
+
22
+ export template <>
23
+ class JumpFloodSeedRenderPipeline <false > final : public vk::raii::Pipeline {
18
24
public:
19
25
JumpFloodSeedRenderPipeline (
20
26
const vk::raii::Device &device LIFETIMEBOUND,
@@ -27,6 +33,25 @@ namespace vk_gltf_viewer::vulkan::inline pipeline {
27
33
28
34
[[nodiscard]] static VertexShaderSpecialization getVertexShaderSpecialization (const PrepassPipelineConfig<false > &config) noexcept ;
29
35
};
36
+
37
+ export template <>
38
+ class JumpFloodSeedRenderPipeline <true > final : public vk::raii::Pipeline {
39
+ public:
40
+ JumpFloodSeedRenderPipeline (
41
+ const vk::raii::Device &device LIFETIMEBOUND,
42
+ const pl::PrimitiveNoShading &pipelineLayout LIFETIMEBOUND,
43
+ const PrepassPipelineConfig<true > &config
44
+ );
45
+
46
+ private:
47
+ struct VertexShaderSpecialization ;
48
+ struct FragmentShaderSpecialization ;
49
+
50
+ [[nodiscard]] static std::array<int , 2 > getVertexShaderVariants (const PrepassPipelineConfig<true > &config) noexcept ;
51
+ [[nodiscard]] static VertexShaderSpecialization getVertexShaderSpecialization (const PrepassPipelineConfig<true > &config) noexcept ;
52
+ [[nodiscard]] static std::array<int , 2 > getFragmentShaderVariants (const PrepassPipelineConfig<true > &config) noexcept ;
53
+ [[nodiscard]] static FragmentShaderSpecialization getFragmentShaderSpecialization (const PrepassPipelineConfig<true > &config) noexcept ;
54
+ };
30
55
}
31
56
32
57
#if !defined(__GNUC__) || defined(__clang__)
@@ -36,14 +61,16 @@ module :private;
36
61
#define FWD (...) static_cast <decltype (__VA_ARGS__)&&>(__VA_ARGS__)
37
62
#define LIFT (...) [](auto &&...xs) { return __VA_ARGS__ (FWD (xs)...); }
38
63
39
- struct vk_gltf_viewer ::vulkan::pipeline::JumpFloodSeedRenderPipeline::VertexShaderSpecialization {
64
+ // ----- JumpFloodSeedRenderPipeline<false> -----
65
+
66
+ struct vk_gltf_viewer ::vulkan::pipeline::JumpFloodSeedRenderPipeline<false >::VertexShaderSpecialization {
40
67
std::uint32_t positionComponentType;
41
68
vk::Bool32 positionNormalized;
42
69
std::uint32_t positionMorphTargetCount;
43
70
std::uint32_t skinAttributeCount;
44
71
};
45
72
46
- vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline::JumpFloodSeedRenderPipeline (
73
+ vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline< false > ::JumpFloodSeedRenderPipeline(
47
74
const vk::raii::Device &device,
48
75
const pl::PrimitiveNoShading &pipelineLayout,
49
76
const PrepassPipelineConfig<false > &config
@@ -87,11 +114,127 @@ vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline::JumpFloodSeedRend
87
114
}.get () };
88
115
}() } { }
89
116
90
- [[nodiscard]] vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline::VertexShaderSpecialization vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline::getVertexShaderSpecialization (const PrepassPipelineConfig<false > &config) noexcept {
117
+ [[nodiscard]] auto vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline<false >::getVertexShaderSpecialization(
118
+ const PrepassPipelineConfig<false > &config
119
+ ) noexcept -> VertexShaderSpecialization {
91
120
return {
92
121
.positionComponentType = getGLComponentType (config.positionComponentType ),
93
122
.positionNormalized = config.positionNormalized ,
94
123
.positionMorphTargetCount = config.positionMorphTargetCount ,
95
124
.skinAttributeCount = config.skinAttributeCount ,
96
125
};
97
- }
126
+ }
127
+
128
+ // ----- JumpFloodSeedRenderPipeline<true> -----
129
+
130
+ struct vk_gltf_viewer ::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >::VertexShaderSpecialization {
131
+ std::uint32_t positionComponentType;
132
+ vk::Bool32 positionNormalized;
133
+ std::uint32_t baseColorTexcoordComponentType;
134
+ vk::Bool32 baseColorTexcoordNormalized;
135
+ std::uint32_t color0ComponentType;
136
+ std::uint32_t positionMorphTargetCount;
137
+ std::uint32_t skinAttributeCount;
138
+ };
139
+
140
+ struct vk_gltf_viewer ::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >::FragmentShaderSpecialization {
141
+ vk::Bool32 useTextureTransform;
142
+ };
143
+
144
+ vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >::JumpFloodSeedRenderPipeline::JumpFloodSeedRenderPipeline(
145
+ const vk::raii::Device &device,
146
+ const pl::PrimitiveNoShading &pipelineLayout,
147
+ const PrepassPipelineConfig<true > &config
148
+ ) : Pipeline { [&] -> Pipeline {
149
+ return { device, nullptr , vk::StructureChain {
150
+ vku::getDefaultGraphicsPipelineCreateInfo (
151
+ createPipelineStages (
152
+ device,
153
+ vku::Shader {
154
+ std::apply (LIFT (shader_selector::mask_jump_flood_seed_vert), getVertexShaderVariants (config)),
155
+ vk::ShaderStageFlagBits::eVertex,
156
+ vku::unsafeAddress (vk::SpecializationInfo {
157
+ SpecializationMap<VertexShaderSpecialization>::value,
158
+ vku::unsafeProxy (getVertexShaderSpecialization (config)),
159
+ }),
160
+ },
161
+ vku::Shader {
162
+ std::apply (LIFT (shader_selector::mask_jump_flood_seed_frag), getFragmentShaderVariants (config)),
163
+ vk::ShaderStageFlagBits::eFragment,
164
+ vku::unsafeAddress (vk::SpecializationInfo {
165
+ SpecializationMap<FragmentShaderSpecialization>::value,
166
+ vku::unsafeProxy (getFragmentShaderSpecialization (config)),
167
+ }),
168
+ }).get (),
169
+ *pipelineLayout, 1 , true )
170
+ .setPInputAssemblyState (vku::unsafeAddress (vk::PipelineInputAssemblyStateCreateInfo {
171
+ {},
172
+ config.topologyClass .value_or (vk::PrimitiveTopology::eTriangleList),
173
+ }))
174
+ .setPDepthStencilState (vku::unsafeAddress (vk::PipelineDepthStencilStateCreateInfo {
175
+ {},
176
+ true , true , vk::CompareOp::eGreater, // Use reverse Z.
177
+ }))
178
+ .setPDynamicState (vku::unsafeAddress (vk::PipelineDynamicStateCreateInfo {
179
+ {},
180
+ vku::unsafeProxy ({
181
+ vk::DynamicState::eViewport,
182
+ vk::DynamicState::eScissor,
183
+ vk::DynamicState::ePrimitiveTopology,
184
+ vk::DynamicState::eCullMode,
185
+ }),
186
+ })),
187
+ vk::PipelineRenderingCreateInfo {
188
+ {},
189
+ vku::unsafeProxy (vk::Format::eR16G16Uint),
190
+ vk::Format::eD32Sfloat,
191
+ }
192
+ }.get () };
193
+ }() } { }
194
+
195
+ std::array<int , 2 > vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >::getVertexShaderVariants(
196
+ const PrepassPipelineConfig<true > &config
197
+ ) noexcept {
198
+ return {
199
+ config.baseColorTexcoordComponentTypeAndNormalized .has_value (),
200
+ config.color0AlphaComponentType .has_value (),
201
+ };
202
+ }
203
+
204
+ auto vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >::getVertexShaderSpecialization(
205
+ const PrepassPipelineConfig<true > &config
206
+ ) noexcept -> VertexShaderSpecialization {
207
+ VertexShaderSpecialization result {
208
+ .positionComponentType = getGLComponentType (config.positionComponentType ),
209
+ .positionNormalized = config.positionNormalized ,
210
+ .color0ComponentType = config.color0AlphaComponentType .transform (fastgltf::getGLComponentType).value_or (0U ),
211
+ .positionMorphTargetCount = config.positionMorphTargetCount ,
212
+ .skinAttributeCount = config.skinAttributeCount ,
213
+ };
214
+
215
+ if (config.baseColorTexcoordComponentTypeAndNormalized ) {
216
+ result.baseColorTexcoordComponentType = getGLComponentType (config.baseColorTexcoordComponentTypeAndNormalized ->first );
217
+ result.baseColorTexcoordNormalized = config.baseColorTexcoordComponentTypeAndNormalized ->second ;
218
+ }
219
+
220
+ return result;
221
+ }
222
+
223
+ std::array<int , 2 > vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >::getFragmentShaderVariants(
224
+ const PrepassPipelineConfig<true > &config
225
+ ) noexcept {
226
+ return {
227
+ config.baseColorTexcoordComponentTypeAndNormalized .has_value (),
228
+ config.color0AlphaComponentType .has_value (),
229
+ };
230
+ }
231
+
232
+ auto vk_gltf_viewer::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >::getFragmentShaderSpecialization(
233
+ const PrepassPipelineConfig<true > &config
234
+ ) noexcept -> FragmentShaderSpecialization {
235
+ return { config.useTextureTransform };
236
+ }
237
+
238
+ // Explicit template instantiations.
239
+ extern template class vk_gltf_viewer ::vulkan::pipeline::JumpFloodSeedRenderPipeline<false >;
240
+ extern template class vk_gltf_viewer ::vulkan::pipeline::JumpFloodSeedRenderPipeline<true >;
0 commit comments