1use alloc::vec::Vec;
2
3use ash::vk;
4
5impl super::PrivateCapabilities {
6 pub fn map_texture_format(&self, format: wgt::TextureFormat) -> vk::Format {
7 use ash::vk::Format as F;
8 use wgt::TextureFormat as Tf;
9 use wgt::{AstcBlock, AstcChannel};
10 match format {
11 Tf::R8Unorm => F::R8_UNORM,
12 Tf::R8Snorm => F::R8_SNORM,
13 Tf::R8Uint => F::R8_UINT,
14 Tf::R8Sint => F::R8_SINT,
15 Tf::R16Uint => F::R16_UINT,
16 Tf::R16Sint => F::R16_SINT,
17 Tf::R16Unorm => F::R16_UNORM,
18 Tf::R16Snorm => F::R16_SNORM,
19 Tf::R16Float => F::R16_SFLOAT,
20 Tf::Rg8Unorm => F::R8G8_UNORM,
21 Tf::Rg8Snorm => F::R8G8_SNORM,
22 Tf::Rg8Uint => F::R8G8_UINT,
23 Tf::Rg8Sint => F::R8G8_SINT,
24 Tf::Rg16Unorm => F::R16G16_UNORM,
25 Tf::Rg16Snorm => F::R16G16_SNORM,
26 Tf::R32Uint => F::R32_UINT,
27 Tf::R32Sint => F::R32_SINT,
28 Tf::R32Float => F::R32_SFLOAT,
29 Tf::Rg16Uint => F::R16G16_UINT,
30 Tf::Rg16Sint => F::R16G16_SINT,
31 Tf::Rg16Float => F::R16G16_SFLOAT,
32 Tf::Rgba8Unorm => F::R8G8B8A8_UNORM,
33 Tf::Rgba8UnormSrgb => F::R8G8B8A8_SRGB,
34 Tf::Bgra8UnormSrgb => F::B8G8R8A8_SRGB,
35 Tf::Rgba8Snorm => F::R8G8B8A8_SNORM,
36 Tf::Bgra8Unorm => F::B8G8R8A8_UNORM,
37 Tf::Rgba8Uint => F::R8G8B8A8_UINT,
38 Tf::Rgba8Sint => F::R8G8B8A8_SINT,
39 Tf::Rgb10a2Uint => F::A2B10G10R10_UINT_PACK32,
40 Tf::Rgb10a2Unorm => F::A2B10G10R10_UNORM_PACK32,
41 Tf::Rg11b10Ufloat => F::B10G11R11_UFLOAT_PACK32,
42 Tf::R64Uint => F::R64_UINT,
43 Tf::Rg32Uint => F::R32G32_UINT,
44 Tf::Rg32Sint => F::R32G32_SINT,
45 Tf::Rg32Float => F::R32G32_SFLOAT,
46 Tf::Rgba16Uint => F::R16G16B16A16_UINT,
47 Tf::Rgba16Sint => F::R16G16B16A16_SINT,
48 Tf::Rgba16Unorm => F::R16G16B16A16_UNORM,
49 Tf::Rgba16Snorm => F::R16G16B16A16_SNORM,
50 Tf::Rgba16Float => F::R16G16B16A16_SFLOAT,
51 Tf::Rgba32Uint => F::R32G32B32A32_UINT,
52 Tf::Rgba32Sint => F::R32G32B32A32_SINT,
53 Tf::Rgba32Float => F::R32G32B32A32_SFLOAT,
54 Tf::Depth32Float => F::D32_SFLOAT,
55 Tf::Depth32FloatStencil8 => F::D32_SFLOAT_S8_UINT,
56 Tf::Depth24Plus => {
57 if self.texture_d24 {
58 F::X8_D24_UNORM_PACK32
59 } else {
60 F::D32_SFLOAT
61 }
62 }
63 Tf::Depth24PlusStencil8 => {
64 if self.texture_d24_s8 {
65 F::D24_UNORM_S8_UINT
66 } else {
67 F::D32_SFLOAT_S8_UINT
68 }
69 }
70 Tf::Stencil8 => {
71 if self.texture_s8 {
72 F::S8_UINT
73 } else if self.texture_d24_s8 {
74 F::D24_UNORM_S8_UINT
75 } else {
76 F::D32_SFLOAT_S8_UINT
77 }
78 }
79 Tf::Depth16Unorm => F::D16_UNORM,
80 Tf::NV12 => F::G8_B8R8_2PLANE_420_UNORM,
81 Tf::P010 => F::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
82 Tf::Rgb9e5Ufloat => F::E5B9G9R9_UFLOAT_PACK32,
83 Tf::Bc1RgbaUnorm => F::BC1_RGBA_UNORM_BLOCK,
84 Tf::Bc1RgbaUnormSrgb => F::BC1_RGBA_SRGB_BLOCK,
85 Tf::Bc2RgbaUnorm => F::BC2_UNORM_BLOCK,
86 Tf::Bc2RgbaUnormSrgb => F::BC2_SRGB_BLOCK,
87 Tf::Bc3RgbaUnorm => F::BC3_UNORM_BLOCK,
88 Tf::Bc3RgbaUnormSrgb => F::BC3_SRGB_BLOCK,
89 Tf::Bc4RUnorm => F::BC4_UNORM_BLOCK,
90 Tf::Bc4RSnorm => F::BC4_SNORM_BLOCK,
91 Tf::Bc5RgUnorm => F::BC5_UNORM_BLOCK,
92 Tf::Bc5RgSnorm => F::BC5_SNORM_BLOCK,
93 Tf::Bc6hRgbUfloat => F::BC6H_UFLOAT_BLOCK,
94 Tf::Bc6hRgbFloat => F::BC6H_SFLOAT_BLOCK,
95 Tf::Bc7RgbaUnorm => F::BC7_UNORM_BLOCK,
96 Tf::Bc7RgbaUnormSrgb => F::BC7_SRGB_BLOCK,
97 Tf::Etc2Rgb8Unorm => F::ETC2_R8G8B8_UNORM_BLOCK,
98 Tf::Etc2Rgb8UnormSrgb => F::ETC2_R8G8B8_SRGB_BLOCK,
99 Tf::Etc2Rgb8A1Unorm => F::ETC2_R8G8B8A1_UNORM_BLOCK,
100 Tf::Etc2Rgb8A1UnormSrgb => F::ETC2_R8G8B8A1_SRGB_BLOCK,
101 Tf::Etc2Rgba8Unorm => F::ETC2_R8G8B8A8_UNORM_BLOCK,
102 Tf::Etc2Rgba8UnormSrgb => F::ETC2_R8G8B8A8_SRGB_BLOCK,
103 Tf::EacR11Unorm => F::EAC_R11_UNORM_BLOCK,
104 Tf::EacR11Snorm => F::EAC_R11_SNORM_BLOCK,
105 Tf::EacRg11Unorm => F::EAC_R11G11_UNORM_BLOCK,
106 Tf::EacRg11Snorm => F::EAC_R11G11_SNORM_BLOCK,
107 Tf::Astc { block, channel } => match channel {
108 AstcChannel::Unorm => match block {
109 AstcBlock::B4x4 => F::ASTC_4X4_UNORM_BLOCK,
110 AstcBlock::B5x4 => F::ASTC_5X4_UNORM_BLOCK,
111 AstcBlock::B5x5 => F::ASTC_5X5_UNORM_BLOCK,
112 AstcBlock::B6x5 => F::ASTC_6X5_UNORM_BLOCK,
113 AstcBlock::B6x6 => F::ASTC_6X6_UNORM_BLOCK,
114 AstcBlock::B8x5 => F::ASTC_8X5_UNORM_BLOCK,
115 AstcBlock::B8x6 => F::ASTC_8X6_UNORM_BLOCK,
116 AstcBlock::B8x8 => F::ASTC_8X8_UNORM_BLOCK,
117 AstcBlock::B10x5 => F::ASTC_10X5_UNORM_BLOCK,
118 AstcBlock::B10x6 => F::ASTC_10X6_UNORM_BLOCK,
119 AstcBlock::B10x8 => F::ASTC_10X8_UNORM_BLOCK,
120 AstcBlock::B10x10 => F::ASTC_10X10_UNORM_BLOCK,
121 AstcBlock::B12x10 => F::ASTC_12X10_UNORM_BLOCK,
122 AstcBlock::B12x12 => F::ASTC_12X12_UNORM_BLOCK,
123 },
124 AstcChannel::UnormSrgb => match block {
125 AstcBlock::B4x4 => F::ASTC_4X4_SRGB_BLOCK,
126 AstcBlock::B5x4 => F::ASTC_5X4_SRGB_BLOCK,
127 AstcBlock::B5x5 => F::ASTC_5X5_SRGB_BLOCK,
128 AstcBlock::B6x5 => F::ASTC_6X5_SRGB_BLOCK,
129 AstcBlock::B6x6 => F::ASTC_6X6_SRGB_BLOCK,
130 AstcBlock::B8x5 => F::ASTC_8X5_SRGB_BLOCK,
131 AstcBlock::B8x6 => F::ASTC_8X6_SRGB_BLOCK,
132 AstcBlock::B8x8 => F::ASTC_8X8_SRGB_BLOCK,
133 AstcBlock::B10x5 => F::ASTC_10X5_SRGB_BLOCK,
134 AstcBlock::B10x6 => F::ASTC_10X6_SRGB_BLOCK,
135 AstcBlock::B10x8 => F::ASTC_10X8_SRGB_BLOCK,
136 AstcBlock::B10x10 => F::ASTC_10X10_SRGB_BLOCK,
137 AstcBlock::B12x10 => F::ASTC_12X10_SRGB_BLOCK,
138 AstcBlock::B12x12 => F::ASTC_12X12_SRGB_BLOCK,
139 },
140 AstcChannel::Hdr => match block {
141 AstcBlock::B4x4 => F::ASTC_4X4_SFLOAT_BLOCK_EXT,
142 AstcBlock::B5x4 => F::ASTC_5X4_SFLOAT_BLOCK_EXT,
143 AstcBlock::B5x5 => F::ASTC_5X5_SFLOAT_BLOCK_EXT,
144 AstcBlock::B6x5 => F::ASTC_6X5_SFLOAT_BLOCK_EXT,
145 AstcBlock::B6x6 => F::ASTC_6X6_SFLOAT_BLOCK_EXT,
146 AstcBlock::B8x5 => F::ASTC_8X5_SFLOAT_BLOCK_EXT,
147 AstcBlock::B8x6 => F::ASTC_8X6_SFLOAT_BLOCK_EXT,
148 AstcBlock::B8x8 => F::ASTC_8X8_SFLOAT_BLOCK_EXT,
149 AstcBlock::B10x5 => F::ASTC_10X5_SFLOAT_BLOCK_EXT,
150 AstcBlock::B10x6 => F::ASTC_10X6_SFLOAT_BLOCK_EXT,
151 AstcBlock::B10x8 => F::ASTC_10X8_SFLOAT_BLOCK_EXT,
152 AstcBlock::B10x10 => F::ASTC_10X10_SFLOAT_BLOCK_EXT,
153 AstcBlock::B12x10 => F::ASTC_12X10_SFLOAT_BLOCK_EXT,
154 AstcBlock::B12x12 => F::ASTC_12X12_SFLOAT_BLOCK_EXT,
155 },
156 },
157 }
158 }
159}
160
161pub fn map_vk_surface_formats(sf: vk::SurfaceFormatKHR) -> Option<wgt::TextureFormat> {
162 use ash::vk::Format as F;
163 use wgt::TextureFormat as Tf;
164 Some(match sf.color_space {
166 vk::ColorSpaceKHR::SRGB_NONLINEAR => match sf.format {
167 F::B8G8R8A8_UNORM => Tf::Bgra8Unorm,
168 F::B8G8R8A8_SRGB => Tf::Bgra8UnormSrgb,
169 F::R8G8B8A8_SNORM => Tf::Rgba8Snorm,
170 F::R8G8B8A8_UNORM => Tf::Rgba8Unorm,
171 F::R8G8B8A8_SRGB => Tf::Rgba8UnormSrgb,
172 _ => return None,
173 },
174 vk::ColorSpaceKHR::EXTENDED_SRGB_LINEAR_EXT => match sf.format {
175 F::R16G16B16A16_SFLOAT => Tf::Rgba16Float,
176 F::R16G16B16A16_SNORM => Tf::Rgba16Snorm,
177 F::R16G16B16A16_UNORM => Tf::Rgba16Unorm,
178 F::A2B10G10R10_UNORM_PACK32 => Tf::Rgb10a2Unorm,
179 _ => return None,
180 },
181 _ => return None,
182 })
183}
184
185impl crate::Attachment<'_, super::TextureView> {
186 pub(super) fn make_attachment_key(&self, ops: crate::AttachmentOps) -> super::AttachmentKey {
187 super::AttachmentKey {
188 format: self.view.raw_format,
189 layout: derive_image_layout(self.usage, self.view.format),
190 ops,
191 }
192 }
193}
194
195impl crate::ColorAttachment<'_, super::TextureView> {
196 pub(super) unsafe fn make_vk_clear_color(&self) -> vk::ClearColorValue {
197 let cv = &self.clear_value;
198 match self.target.view.format.sample_type(None, None).unwrap() {
199 wgt::TextureSampleType::Float { .. } => vk::ClearColorValue {
200 float32: [cv.r as f32, cv.g as f32, cv.b as f32, cv.a as f32],
201 },
202 wgt::TextureSampleType::Sint => vk::ClearColorValue {
203 int32: [cv.r as i32, cv.g as i32, cv.b as i32, cv.a as i32],
204 },
205 wgt::TextureSampleType::Uint => vk::ClearColorValue {
206 uint32: [cv.r as u32, cv.g as u32, cv.b as u32, cv.a as u32],
207 },
208 wgt::TextureSampleType::Depth => unreachable!(),
209 }
210 }
211}
212
213pub fn derive_image_layout(usage: wgt::TextureUses, format: wgt::TextureFormat) -> vk::ImageLayout {
214 let is_color = !format.is_depth_stencil_format();
216 match usage {
217 wgt::TextureUses::UNINITIALIZED => vk::ImageLayout::UNDEFINED,
218 wgt::TextureUses::COPY_SRC => vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
219 wgt::TextureUses::COPY_DST => vk::ImageLayout::TRANSFER_DST_OPTIMAL,
220 wgt::TextureUses::RESOURCE if is_color => vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
221 wgt::TextureUses::COLOR_TARGET => vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
222 wgt::TextureUses::DEPTH_STENCIL_WRITE => vk::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
223 _ => {
224 if usage == wgt::TextureUses::PRESENT {
225 vk::ImageLayout::PRESENT_SRC_KHR
226 } else if is_color {
227 vk::ImageLayout::GENERAL
228 } else {
229 vk::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL
230 }
231 }
232 }
233}
234
235pub fn map_texture_usage(usage: wgt::TextureUses) -> vk::ImageUsageFlags {
236 let mut flags = vk::ImageUsageFlags::empty();
237 if usage.contains(wgt::TextureUses::COPY_SRC) {
238 flags |= vk::ImageUsageFlags::TRANSFER_SRC;
239 }
240 if usage.contains(wgt::TextureUses::COPY_DST) {
241 flags |= vk::ImageUsageFlags::TRANSFER_DST;
242 }
243 if usage.contains(wgt::TextureUses::RESOURCE) {
244 flags |= vk::ImageUsageFlags::SAMPLED;
245 }
246 if usage.contains(wgt::TextureUses::COLOR_TARGET) {
247 flags |= vk::ImageUsageFlags::COLOR_ATTACHMENT;
248 }
249 if usage
250 .intersects(wgt::TextureUses::DEPTH_STENCIL_READ | wgt::TextureUses::DEPTH_STENCIL_WRITE)
251 {
252 flags |= vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT;
253 }
254 if usage.intersects(
255 wgt::TextureUses::STORAGE_READ_ONLY
256 | wgt::TextureUses::STORAGE_WRITE_ONLY
257 | wgt::TextureUses::STORAGE_READ_WRITE
258 | wgt::TextureUses::STORAGE_ATOMIC,
259 ) {
260 flags |= vk::ImageUsageFlags::STORAGE;
261 }
262 flags
263}
264
265pub fn map_texture_usage_to_barrier(
266 usage: wgt::TextureUses,
267) -> (vk::PipelineStageFlags, vk::AccessFlags) {
268 let mut stages = vk::PipelineStageFlags::empty();
269 let mut access = vk::AccessFlags::empty();
270 let shader_stages = vk::PipelineStageFlags::VERTEX_SHADER
271 | vk::PipelineStageFlags::FRAGMENT_SHADER
272 | vk::PipelineStageFlags::COMPUTE_SHADER;
273
274 if usage.contains(wgt::TextureUses::COPY_SRC) {
275 stages |= vk::PipelineStageFlags::TRANSFER;
276 access |= vk::AccessFlags::TRANSFER_READ;
277 }
278 if usage.contains(wgt::TextureUses::COPY_DST) {
279 stages |= vk::PipelineStageFlags::TRANSFER;
280 access |= vk::AccessFlags::TRANSFER_WRITE;
281 }
282 if usage.contains(wgt::TextureUses::RESOURCE) {
283 stages |= shader_stages;
284 access |= vk::AccessFlags::SHADER_READ;
285 }
286 if usage.contains(wgt::TextureUses::COLOR_TARGET) {
287 stages |= vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT;
288 access |= vk::AccessFlags::COLOR_ATTACHMENT_READ | vk::AccessFlags::COLOR_ATTACHMENT_WRITE;
289 }
290 if usage.intersects(wgt::TextureUses::DEPTH_STENCIL_READ) {
291 stages |= vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS
292 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS;
293 access |= vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ;
294 }
295 if usage.intersects(wgt::TextureUses::DEPTH_STENCIL_WRITE) {
296 stages |= vk::PipelineStageFlags::EARLY_FRAGMENT_TESTS
297 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS;
298 access |= vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ
299 | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_WRITE;
300 }
301 if usage.intersects(
302 wgt::TextureUses::STORAGE_READ_ONLY
303 | wgt::TextureUses::STORAGE_READ_WRITE
304 | wgt::TextureUses::STORAGE_ATOMIC,
305 ) {
306 stages |= shader_stages;
307 access |= vk::AccessFlags::SHADER_READ;
308 }
309 if usage.intersects(
310 wgt::TextureUses::STORAGE_WRITE_ONLY
311 | wgt::TextureUses::STORAGE_READ_WRITE
312 | wgt::TextureUses::STORAGE_ATOMIC,
313 ) {
314 stages |= shader_stages;
315 access |= vk::AccessFlags::SHADER_WRITE;
316 }
317
318 if usage == wgt::TextureUses::UNINITIALIZED || usage == wgt::TextureUses::PRESENT {
319 (
320 vk::PipelineStageFlags::TOP_OF_PIPE,
321 vk::AccessFlags::empty(),
322 )
323 } else {
324 (stages, access)
325 }
326}
327
328pub fn map_vk_image_usage(usage: vk::ImageUsageFlags) -> wgt::TextureUses {
329 let mut bits = wgt::TextureUses::empty();
330 if usage.contains(vk::ImageUsageFlags::TRANSFER_SRC) {
331 bits |= wgt::TextureUses::COPY_SRC;
332 }
333 if usage.contains(vk::ImageUsageFlags::TRANSFER_DST) {
334 bits |= wgt::TextureUses::COPY_DST;
335 }
336 if usage.contains(vk::ImageUsageFlags::SAMPLED) {
337 bits |= wgt::TextureUses::RESOURCE;
338 }
339 if usage.contains(vk::ImageUsageFlags::COLOR_ATTACHMENT) {
340 bits |= wgt::TextureUses::COLOR_TARGET;
341 }
342 if usage.contains(vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT) {
343 bits |= wgt::TextureUses::DEPTH_STENCIL_READ | wgt::TextureUses::DEPTH_STENCIL_WRITE;
344 }
345 if usage.contains(vk::ImageUsageFlags::STORAGE) {
346 bits |= wgt::TextureUses::STORAGE_READ_ONLY
347 | wgt::TextureUses::STORAGE_WRITE_ONLY
348 | wgt::TextureUses::STORAGE_READ_WRITE
349 | wgt::TextureUses::STORAGE_ATOMIC;
350 }
351 bits
352}
353
354pub fn map_texture_dimension(dim: wgt::TextureDimension) -> vk::ImageType {
355 match dim {
356 wgt::TextureDimension::D1 => vk::ImageType::TYPE_1D,
357 wgt::TextureDimension::D2 => vk::ImageType::TYPE_2D,
358 wgt::TextureDimension::D3 => vk::ImageType::TYPE_3D,
359 }
360}
361
362pub fn map_index_format(index_format: wgt::IndexFormat) -> vk::IndexType {
363 match index_format {
364 wgt::IndexFormat::Uint16 => vk::IndexType::UINT16,
365 wgt::IndexFormat::Uint32 => vk::IndexType::UINT32,
366 }
367}
368
369pub fn map_vertex_format(vertex_format: wgt::VertexFormat) -> vk::Format {
370 use wgt::VertexFormat as Vf;
371 match vertex_format {
372 Vf::Uint8 => vk::Format::R8_UINT,
373 Vf::Uint8x2 => vk::Format::R8G8_UINT,
374 Vf::Uint8x4 => vk::Format::R8G8B8A8_UINT,
375 Vf::Sint8 => vk::Format::R8_SINT,
376 Vf::Sint8x2 => vk::Format::R8G8_SINT,
377 Vf::Sint8x4 => vk::Format::R8G8B8A8_SINT,
378 Vf::Unorm8 => vk::Format::R8_UNORM,
379 Vf::Unorm8x2 => vk::Format::R8G8_UNORM,
380 Vf::Unorm8x4 => vk::Format::R8G8B8A8_UNORM,
381 Vf::Snorm8 => vk::Format::R8_SNORM,
382 Vf::Snorm8x2 => vk::Format::R8G8_SNORM,
383 Vf::Snorm8x4 => vk::Format::R8G8B8A8_SNORM,
384 Vf::Uint16 => vk::Format::R16_UINT,
385 Vf::Uint16x2 => vk::Format::R16G16_UINT,
386 Vf::Uint16x4 => vk::Format::R16G16B16A16_UINT,
387 Vf::Sint16 => vk::Format::R16_SINT,
388 Vf::Sint16x2 => vk::Format::R16G16_SINT,
389 Vf::Sint16x4 => vk::Format::R16G16B16A16_SINT,
390 Vf::Unorm16 => vk::Format::R16_UNORM,
391 Vf::Unorm16x2 => vk::Format::R16G16_UNORM,
392 Vf::Unorm16x4 => vk::Format::R16G16B16A16_UNORM,
393 Vf::Snorm16 => vk::Format::R16_SNORM,
394 Vf::Snorm16x2 => vk::Format::R16G16_SNORM,
395 Vf::Snorm16x4 => vk::Format::R16G16B16A16_SNORM,
396 Vf::Float16 => vk::Format::R16_SFLOAT,
397 Vf::Float16x2 => vk::Format::R16G16_SFLOAT,
398 Vf::Float16x4 => vk::Format::R16G16B16A16_SFLOAT,
399 Vf::Float32 => vk::Format::R32_SFLOAT,
400 Vf::Float32x2 => vk::Format::R32G32_SFLOAT,
401 Vf::Float32x3 => vk::Format::R32G32B32_SFLOAT,
402 Vf::Float32x4 => vk::Format::R32G32B32A32_SFLOAT,
403 Vf::Uint32 => vk::Format::R32_UINT,
404 Vf::Uint32x2 => vk::Format::R32G32_UINT,
405 Vf::Uint32x3 => vk::Format::R32G32B32_UINT,
406 Vf::Uint32x4 => vk::Format::R32G32B32A32_UINT,
407 Vf::Sint32 => vk::Format::R32_SINT,
408 Vf::Sint32x2 => vk::Format::R32G32_SINT,
409 Vf::Sint32x3 => vk::Format::R32G32B32_SINT,
410 Vf::Sint32x4 => vk::Format::R32G32B32A32_SINT,
411 Vf::Float64 => vk::Format::R64_SFLOAT,
412 Vf::Float64x2 => vk::Format::R64G64_SFLOAT,
413 Vf::Float64x3 => vk::Format::R64G64B64_SFLOAT,
414 Vf::Float64x4 => vk::Format::R64G64B64A64_SFLOAT,
415 Vf::Unorm10_10_10_2 => vk::Format::A2B10G10R10_UNORM_PACK32,
416 Vf::Unorm8x4Bgra => vk::Format::B8G8R8A8_UNORM,
417 }
418}
419
420pub fn map_aspects(aspects: crate::FormatAspects) -> vk::ImageAspectFlags {
421 let mut flags = vk::ImageAspectFlags::empty();
422 if aspects.contains(crate::FormatAspects::COLOR) {
423 flags |= vk::ImageAspectFlags::COLOR;
424 }
425 if aspects.contains(crate::FormatAspects::DEPTH) {
426 flags |= vk::ImageAspectFlags::DEPTH;
427 }
428 if aspects.contains(crate::FormatAspects::STENCIL) {
429 flags |= vk::ImageAspectFlags::STENCIL;
430 }
431 if aspects.contains(crate::FormatAspects::PLANE_0) {
432 flags |= vk::ImageAspectFlags::PLANE_0;
433 }
434 if aspects.contains(crate::FormatAspects::PLANE_1) {
435 flags |= vk::ImageAspectFlags::PLANE_1;
436 }
437 if aspects.contains(crate::FormatAspects::PLANE_2) {
438 flags |= vk::ImageAspectFlags::PLANE_2;
439 }
440 flags
441}
442
443pub fn map_attachment_ops(
444 op: crate::AttachmentOps,
445) -> (vk::AttachmentLoadOp, vk::AttachmentStoreOp) {
446 let load_op = if op.contains(crate::AttachmentOps::LOAD) {
447 vk::AttachmentLoadOp::LOAD
448 } else {
449 vk::AttachmentLoadOp::CLEAR
450 };
451 let store_op = if op.contains(crate::AttachmentOps::STORE) {
452 vk::AttachmentStoreOp::STORE
453 } else {
454 vk::AttachmentStoreOp::DONT_CARE
455 };
456 (load_op, store_op)
457}
458
459pub fn map_present_mode(mode: wgt::PresentMode) -> vk::PresentModeKHR {
460 match mode {
461 wgt::PresentMode::Immediate => vk::PresentModeKHR::IMMEDIATE,
462 wgt::PresentMode::Mailbox => vk::PresentModeKHR::MAILBOX,
463 wgt::PresentMode::Fifo => vk::PresentModeKHR::FIFO,
464 wgt::PresentMode::FifoRelaxed => vk::PresentModeKHR::FIFO_RELAXED,
465 wgt::PresentMode::AutoNoVsync | wgt::PresentMode::AutoVsync => {
466 unreachable!("Cannot create swapchain with Auto PresentationMode")
467 }
468 }
469}
470
471pub fn map_vk_present_mode(mode: vk::PresentModeKHR) -> Option<wgt::PresentMode> {
472 const FIFO_LATEST_READY: vk::PresentModeKHR = vk::PresentModeKHR::from_raw(1_000_361_000);
474
475 match mode {
477 vk::PresentModeKHR::IMMEDIATE => Some(wgt::PresentMode::Immediate),
478 vk::PresentModeKHR::MAILBOX => Some(wgt::PresentMode::Mailbox),
479 vk::PresentModeKHR::FIFO => Some(wgt::PresentMode::Fifo),
480 vk::PresentModeKHR::FIFO_RELAXED => Some(wgt::PresentMode::FifoRelaxed),
481
482 vk::PresentModeKHR::SHARED_DEMAND_REFRESH => None,
484 vk::PresentModeKHR::SHARED_CONTINUOUS_REFRESH => None,
485 FIFO_LATEST_READY => None,
486
487 _ => {
488 log::debug!("Unrecognized present mode {mode:?}");
489 None
490 }
491 }
492}
493
494pub fn map_composite_alpha_mode(mode: wgt::CompositeAlphaMode) -> vk::CompositeAlphaFlagsKHR {
495 match mode {
496 wgt::CompositeAlphaMode::Opaque => vk::CompositeAlphaFlagsKHR::OPAQUE,
497 wgt::CompositeAlphaMode::PreMultiplied => vk::CompositeAlphaFlagsKHR::PRE_MULTIPLIED,
498 wgt::CompositeAlphaMode::PostMultiplied => vk::CompositeAlphaFlagsKHR::POST_MULTIPLIED,
499 wgt::CompositeAlphaMode::Inherit => vk::CompositeAlphaFlagsKHR::INHERIT,
500 wgt::CompositeAlphaMode::Auto => unreachable!(),
501 }
502}
503
504pub fn map_vk_composite_alpha(flags: vk::CompositeAlphaFlagsKHR) -> Vec<wgt::CompositeAlphaMode> {
505 let mut modes = Vec::new();
506 if flags.contains(vk::CompositeAlphaFlagsKHR::OPAQUE) {
507 modes.push(wgt::CompositeAlphaMode::Opaque);
508 }
509 if flags.contains(vk::CompositeAlphaFlagsKHR::PRE_MULTIPLIED) {
510 modes.push(wgt::CompositeAlphaMode::PreMultiplied);
511 }
512 if flags.contains(vk::CompositeAlphaFlagsKHR::POST_MULTIPLIED) {
513 modes.push(wgt::CompositeAlphaMode::PostMultiplied);
514 }
515 if flags.contains(vk::CompositeAlphaFlagsKHR::INHERIT) {
516 modes.push(wgt::CompositeAlphaMode::Inherit);
517 }
518 modes
519}
520
521pub fn map_buffer_usage(usage: wgt::BufferUses) -> vk::BufferUsageFlags {
522 let mut flags = vk::BufferUsageFlags::empty();
523 if usage.contains(wgt::BufferUses::COPY_SRC) {
524 flags |= vk::BufferUsageFlags::TRANSFER_SRC;
525 }
526 if usage.contains(wgt::BufferUses::COPY_DST) {
527 flags |= vk::BufferUsageFlags::TRANSFER_DST;
528 }
529 if usage.contains(wgt::BufferUses::UNIFORM) {
530 flags |= vk::BufferUsageFlags::UNIFORM_BUFFER;
531 }
532 if usage.intersects(wgt::BufferUses::STORAGE_READ_ONLY | wgt::BufferUses::STORAGE_READ_WRITE) {
533 flags |= vk::BufferUsageFlags::STORAGE_BUFFER;
534 }
535 if usage.contains(wgt::BufferUses::INDEX) {
536 flags |= vk::BufferUsageFlags::INDEX_BUFFER;
537 }
538 if usage.contains(wgt::BufferUses::VERTEX) {
539 flags |= vk::BufferUsageFlags::VERTEX_BUFFER;
540 }
541 if usage.contains(wgt::BufferUses::INDIRECT) {
542 flags |= vk::BufferUsageFlags::INDIRECT_BUFFER;
543 }
544 if usage.contains(wgt::BufferUses::ACCELERATION_STRUCTURE_SCRATCH) {
545 flags |= vk::BufferUsageFlags::STORAGE_BUFFER | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS;
546 }
547 if usage.intersects(
548 wgt::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT
549 | wgt::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT,
550 ) {
551 flags |= vk::BufferUsageFlags::ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_KHR
552 | vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS;
553 }
554 if usage.intersects(wgt::BufferUses::ACCELERATION_STRUCTURE_QUERY) {
555 flags |= vk::BufferUsageFlags::TRANSFER_DST;
556 }
557 flags
558}
559
560pub fn map_buffer_usage_to_barrier(
561 usage: wgt::BufferUses,
562) -> (vk::PipelineStageFlags, vk::AccessFlags) {
563 let mut stages = vk::PipelineStageFlags::empty();
564 let mut access = vk::AccessFlags::empty();
565 let shader_stages = vk::PipelineStageFlags::VERTEX_SHADER
566 | vk::PipelineStageFlags::FRAGMENT_SHADER
567 | vk::PipelineStageFlags::COMPUTE_SHADER;
568
569 if usage.contains(wgt::BufferUses::MAP_READ) {
570 stages |= vk::PipelineStageFlags::HOST;
571 access |= vk::AccessFlags::HOST_READ;
572 }
573 if usage.contains(wgt::BufferUses::MAP_WRITE) {
574 stages |= vk::PipelineStageFlags::HOST;
575 access |= vk::AccessFlags::HOST_WRITE;
576 }
577 if usage.contains(wgt::BufferUses::COPY_SRC) {
578 stages |= vk::PipelineStageFlags::TRANSFER;
579 access |= vk::AccessFlags::TRANSFER_READ;
580 }
581 if usage.contains(wgt::BufferUses::COPY_DST) {
582 stages |= vk::PipelineStageFlags::TRANSFER;
583 access |= vk::AccessFlags::TRANSFER_WRITE;
584 }
585 if usage.contains(wgt::BufferUses::UNIFORM) {
586 stages |= shader_stages;
587 access |= vk::AccessFlags::UNIFORM_READ;
588 }
589 if usage.intersects(wgt::BufferUses::STORAGE_READ_ONLY) {
590 stages |= shader_stages;
591 access |= vk::AccessFlags::SHADER_READ;
592 }
593 if usage.intersects(wgt::BufferUses::STORAGE_READ_WRITE) {
594 stages |= shader_stages;
595 access |= vk::AccessFlags::SHADER_READ | vk::AccessFlags::SHADER_WRITE;
596 }
597 if usage.contains(wgt::BufferUses::INDEX) {
598 stages |= vk::PipelineStageFlags::VERTEX_INPUT;
599 access |= vk::AccessFlags::INDEX_READ;
600 }
601 if usage.contains(wgt::BufferUses::VERTEX) {
602 stages |= vk::PipelineStageFlags::VERTEX_INPUT;
603 access |= vk::AccessFlags::VERTEX_ATTRIBUTE_READ;
604 }
605 if usage.contains(wgt::BufferUses::INDIRECT) {
606 stages |= vk::PipelineStageFlags::DRAW_INDIRECT;
607 access |= vk::AccessFlags::INDIRECT_COMMAND_READ;
608 }
609 if usage.intersects(
610 wgt::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT
611 | wgt::BufferUses::TOP_LEVEL_ACCELERATION_STRUCTURE_INPUT
612 | wgt::BufferUses::ACCELERATION_STRUCTURE_SCRATCH,
613 ) {
614 stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR;
615 access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR
616 | vk::AccessFlags::ACCELERATION_STRUCTURE_WRITE_KHR
617 | vk::AccessFlags::SHADER_READ;
618 }
619 if usage.contains(wgt::BufferUses::ACCELERATION_STRUCTURE_QUERY) {
620 stages |= vk::PipelineStageFlags::TRANSFER;
621 access |= vk::AccessFlags::TRANSFER_WRITE;
622 }
623
624 (stages, access)
625}
626
627pub fn map_view_dimension(dim: wgt::TextureViewDimension) -> vk::ImageViewType {
628 match dim {
629 wgt::TextureViewDimension::D1 => vk::ImageViewType::TYPE_1D,
630 wgt::TextureViewDimension::D2 => vk::ImageViewType::TYPE_2D,
631 wgt::TextureViewDimension::D2Array => vk::ImageViewType::TYPE_2D_ARRAY,
632 wgt::TextureViewDimension::Cube => vk::ImageViewType::CUBE,
633 wgt::TextureViewDimension::CubeArray => vk::ImageViewType::CUBE_ARRAY,
634 wgt::TextureViewDimension::D3 => vk::ImageViewType::TYPE_3D,
635 }
636}
637
638pub fn map_copy_extent(extent: &crate::CopyExtent) -> vk::Extent3D {
639 vk::Extent3D {
640 width: extent.width,
641 height: extent.height,
642 depth: extent.depth,
643 }
644}
645
646pub fn map_subresource_range(
647 range: &wgt::ImageSubresourceRange,
648 format: wgt::TextureFormat,
649) -> vk::ImageSubresourceRange {
650 vk::ImageSubresourceRange {
651 aspect_mask: map_aspects(crate::FormatAspects::new(format, range.aspect)),
652 base_mip_level: range.base_mip_level,
653 level_count: range.mip_level_count.unwrap_or(vk::REMAINING_MIP_LEVELS),
654 base_array_layer: range.base_array_layer,
655 layer_count: range
656 .array_layer_count
657 .unwrap_or(vk::REMAINING_ARRAY_LAYERS),
658 }
659}
660
661pub(super) fn map_subresource_range_combined_aspect(
664 range: &wgt::ImageSubresourceRange,
665 format: wgt::TextureFormat,
666 private_caps: &super::PrivateCapabilities,
667) -> vk::ImageSubresourceRange {
668 let mut range = map_subresource_range(range, format);
669 if !private_caps.texture_s8 && format == wgt::TextureFormat::Stencil8 {
670 range.aspect_mask |= vk::ImageAspectFlags::DEPTH;
671 }
672 range
673}
674
675pub fn map_subresource_layers(
676 base: &crate::TextureCopyBase,
677) -> (vk::ImageSubresourceLayers, vk::Offset3D) {
678 let offset = vk::Offset3D {
679 x: base.origin.x as i32,
680 y: base.origin.y as i32,
681 z: base.origin.z as i32,
682 };
683 let subresource = vk::ImageSubresourceLayers {
684 aspect_mask: map_aspects(base.aspect),
685 mip_level: base.mip_level,
686 base_array_layer: base.array_layer,
687 layer_count: 1,
688 };
689 (subresource, offset)
690}
691
692pub fn map_filter_mode(mode: wgt::FilterMode) -> vk::Filter {
693 match mode {
694 wgt::FilterMode::Nearest => vk::Filter::NEAREST,
695 wgt::FilterMode::Linear => vk::Filter::LINEAR,
696 }
697}
698
699pub fn map_mip_filter_mode(mode: wgt::FilterMode) -> vk::SamplerMipmapMode {
700 match mode {
701 wgt::FilterMode::Nearest => vk::SamplerMipmapMode::NEAREST,
702 wgt::FilterMode::Linear => vk::SamplerMipmapMode::LINEAR,
703 }
704}
705
706pub fn map_address_mode(mode: wgt::AddressMode) -> vk::SamplerAddressMode {
707 match mode {
708 wgt::AddressMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE,
709 wgt::AddressMode::Repeat => vk::SamplerAddressMode::REPEAT,
710 wgt::AddressMode::MirrorRepeat => vk::SamplerAddressMode::MIRRORED_REPEAT,
711 wgt::AddressMode::ClampToBorder => vk::SamplerAddressMode::CLAMP_TO_BORDER,
712 }
714}
715
716pub fn map_border_color(border_color: wgt::SamplerBorderColor) -> vk::BorderColor {
717 match border_color {
718 wgt::SamplerBorderColor::TransparentBlack | wgt::SamplerBorderColor::Zero => {
719 vk::BorderColor::FLOAT_TRANSPARENT_BLACK
720 }
721 wgt::SamplerBorderColor::OpaqueBlack => vk::BorderColor::FLOAT_OPAQUE_BLACK,
722 wgt::SamplerBorderColor::OpaqueWhite => vk::BorderColor::FLOAT_OPAQUE_WHITE,
723 }
724}
725
726pub fn map_comparison(fun: wgt::CompareFunction) -> vk::CompareOp {
727 use wgt::CompareFunction as Cf;
728 match fun {
729 Cf::Never => vk::CompareOp::NEVER,
730 Cf::Less => vk::CompareOp::LESS,
731 Cf::LessEqual => vk::CompareOp::LESS_OR_EQUAL,
732 Cf::Equal => vk::CompareOp::EQUAL,
733 Cf::GreaterEqual => vk::CompareOp::GREATER_OR_EQUAL,
734 Cf::Greater => vk::CompareOp::GREATER,
735 Cf::NotEqual => vk::CompareOp::NOT_EQUAL,
736 Cf::Always => vk::CompareOp::ALWAYS,
737 }
738}
739
740pub fn map_shader_stage(stage: wgt::ShaderStages) -> vk::ShaderStageFlags {
741 let mut flags = vk::ShaderStageFlags::empty();
742 if stage.contains(wgt::ShaderStages::VERTEX) {
743 flags |= vk::ShaderStageFlags::VERTEX;
744 }
745 if stage.contains(wgt::ShaderStages::FRAGMENT) {
746 flags |= vk::ShaderStageFlags::FRAGMENT;
747 }
748 if stage.contains(wgt::ShaderStages::COMPUTE) {
749 flags |= vk::ShaderStageFlags::COMPUTE;
750 }
751 if stage.contains(wgt::ShaderStages::TASK) {
752 flags |= vk::ShaderStageFlags::TASK_EXT;
753 }
754 if stage.contains(wgt::ShaderStages::MESH) {
755 flags |= vk::ShaderStageFlags::MESH_EXT;
756 }
757 flags
758}
759
760pub fn map_binding_type(ty: wgt::BindingType) -> vk::DescriptorType {
761 match ty {
762 wgt::BindingType::Buffer {
763 ty,
764 has_dynamic_offset,
765 ..
766 } => match ty {
767 wgt::BufferBindingType::Storage { .. } => match has_dynamic_offset {
768 true => vk::DescriptorType::STORAGE_BUFFER_DYNAMIC,
769 false => vk::DescriptorType::STORAGE_BUFFER,
770 },
771 wgt::BufferBindingType::Uniform => match has_dynamic_offset {
772 true => vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC,
773 false => vk::DescriptorType::UNIFORM_BUFFER,
774 },
775 },
776 wgt::BindingType::Sampler { .. } => vk::DescriptorType::SAMPLER,
777 wgt::BindingType::Texture { .. } => vk::DescriptorType::SAMPLED_IMAGE,
778 wgt::BindingType::StorageTexture { .. } => vk::DescriptorType::STORAGE_IMAGE,
779 wgt::BindingType::AccelerationStructure { .. } => {
780 vk::DescriptorType::ACCELERATION_STRUCTURE_KHR
781 }
782 wgt::BindingType::ExternalTexture => unimplemented!(),
783 }
784}
785
786pub fn map_topology(topology: wgt::PrimitiveTopology) -> vk::PrimitiveTopology {
787 use wgt::PrimitiveTopology as Pt;
788 match topology {
789 Pt::PointList => vk::PrimitiveTopology::POINT_LIST,
790 Pt::LineList => vk::PrimitiveTopology::LINE_LIST,
791 Pt::LineStrip => vk::PrimitiveTopology::LINE_STRIP,
792 Pt::TriangleList => vk::PrimitiveTopology::TRIANGLE_LIST,
793 Pt::TriangleStrip => vk::PrimitiveTopology::TRIANGLE_STRIP,
794 }
795}
796
797pub fn map_polygon_mode(mode: wgt::PolygonMode) -> vk::PolygonMode {
798 match mode {
799 wgt::PolygonMode::Fill => vk::PolygonMode::FILL,
800 wgt::PolygonMode::Line => vk::PolygonMode::LINE,
801 wgt::PolygonMode::Point => vk::PolygonMode::POINT,
802 }
803}
804
805pub fn map_front_face(front_face: wgt::FrontFace) -> vk::FrontFace {
806 match front_face {
807 wgt::FrontFace::Cw => vk::FrontFace::CLOCKWISE,
808 wgt::FrontFace::Ccw => vk::FrontFace::COUNTER_CLOCKWISE,
809 }
810}
811
812pub fn map_cull_face(face: wgt::Face) -> vk::CullModeFlags {
813 match face {
814 wgt::Face::Front => vk::CullModeFlags::FRONT,
815 wgt::Face::Back => vk::CullModeFlags::BACK,
816 }
817}
818
819pub fn map_stencil_op(op: wgt::StencilOperation) -> vk::StencilOp {
820 use wgt::StencilOperation as So;
821 match op {
822 So::Keep => vk::StencilOp::KEEP,
823 So::Zero => vk::StencilOp::ZERO,
824 So::Replace => vk::StencilOp::REPLACE,
825 So::Invert => vk::StencilOp::INVERT,
826 So::IncrementClamp => vk::StencilOp::INCREMENT_AND_CLAMP,
827 So::IncrementWrap => vk::StencilOp::INCREMENT_AND_WRAP,
828 So::DecrementClamp => vk::StencilOp::DECREMENT_AND_CLAMP,
829 So::DecrementWrap => vk::StencilOp::DECREMENT_AND_WRAP,
830 }
831}
832
833pub fn map_stencil_face(
834 face: &wgt::StencilFaceState,
835 compare_mask: u32,
836 write_mask: u32,
837) -> vk::StencilOpState {
838 vk::StencilOpState {
839 fail_op: map_stencil_op(face.fail_op),
840 pass_op: map_stencil_op(face.pass_op),
841 depth_fail_op: map_stencil_op(face.depth_fail_op),
842 compare_op: map_comparison(face.compare),
843 compare_mask,
844 write_mask,
845 reference: 0,
846 }
847}
848
849fn map_blend_factor(factor: wgt::BlendFactor) -> vk::BlendFactor {
850 use wgt::BlendFactor as Bf;
851 match factor {
852 Bf::Zero => vk::BlendFactor::ZERO,
853 Bf::One => vk::BlendFactor::ONE,
854 Bf::Src => vk::BlendFactor::SRC_COLOR,
855 Bf::OneMinusSrc => vk::BlendFactor::ONE_MINUS_SRC_COLOR,
856 Bf::SrcAlpha => vk::BlendFactor::SRC_ALPHA,
857 Bf::OneMinusSrcAlpha => vk::BlendFactor::ONE_MINUS_SRC_ALPHA,
858 Bf::Dst => vk::BlendFactor::DST_COLOR,
859 Bf::OneMinusDst => vk::BlendFactor::ONE_MINUS_DST_COLOR,
860 Bf::DstAlpha => vk::BlendFactor::DST_ALPHA,
861 Bf::OneMinusDstAlpha => vk::BlendFactor::ONE_MINUS_DST_ALPHA,
862 Bf::SrcAlphaSaturated => vk::BlendFactor::SRC_ALPHA_SATURATE,
863 Bf::Constant => vk::BlendFactor::CONSTANT_COLOR,
864 Bf::OneMinusConstant => vk::BlendFactor::ONE_MINUS_CONSTANT_COLOR,
865 Bf::Src1 => vk::BlendFactor::SRC1_COLOR,
866 Bf::OneMinusSrc1 => vk::BlendFactor::ONE_MINUS_SRC1_COLOR,
867 Bf::Src1Alpha => vk::BlendFactor::SRC1_ALPHA,
868 Bf::OneMinusSrc1Alpha => vk::BlendFactor::ONE_MINUS_SRC1_ALPHA,
869 }
870}
871
872fn map_blend_op(operation: wgt::BlendOperation) -> vk::BlendOp {
873 use wgt::BlendOperation as Bo;
874 match operation {
875 Bo::Add => vk::BlendOp::ADD,
876 Bo::Subtract => vk::BlendOp::SUBTRACT,
877 Bo::ReverseSubtract => vk::BlendOp::REVERSE_SUBTRACT,
878 Bo::Min => vk::BlendOp::MIN,
879 Bo::Max => vk::BlendOp::MAX,
880 }
881}
882
883pub fn map_blend_component(
884 component: &wgt::BlendComponent,
885) -> (vk::BlendOp, vk::BlendFactor, vk::BlendFactor) {
886 let op = map_blend_op(component.operation);
887 let src = map_blend_factor(component.src_factor);
888 let dst = map_blend_factor(component.dst_factor);
889 (op, src, dst)
890}
891
892pub fn map_pipeline_statistics(
893 types: wgt::PipelineStatisticsTypes,
894) -> vk::QueryPipelineStatisticFlags {
895 use wgt::PipelineStatisticsTypes as Pst;
896 let mut flags = vk::QueryPipelineStatisticFlags::empty();
897 if types.contains(Pst::VERTEX_SHADER_INVOCATIONS) {
898 flags |= vk::QueryPipelineStatisticFlags::VERTEX_SHADER_INVOCATIONS;
899 }
900 if types.contains(Pst::CLIPPER_INVOCATIONS) {
901 flags |= vk::QueryPipelineStatisticFlags::CLIPPING_INVOCATIONS;
902 }
903 if types.contains(Pst::CLIPPER_PRIMITIVES_OUT) {
904 flags |= vk::QueryPipelineStatisticFlags::CLIPPING_PRIMITIVES;
905 }
906 if types.contains(Pst::FRAGMENT_SHADER_INVOCATIONS) {
907 flags |= vk::QueryPipelineStatisticFlags::FRAGMENT_SHADER_INVOCATIONS;
908 }
909 if types.contains(Pst::COMPUTE_SHADER_INVOCATIONS) {
910 flags |= vk::QueryPipelineStatisticFlags::COMPUTE_SHADER_INVOCATIONS;
911 }
912 flags
913}
914
915pub fn map_acceleration_structure_format(
916 format: crate::AccelerationStructureFormat,
917) -> vk::AccelerationStructureTypeKHR {
918 match format {
919 crate::AccelerationStructureFormat::TopLevel => vk::AccelerationStructureTypeKHR::TOP_LEVEL,
920 crate::AccelerationStructureFormat::BottomLevel => {
921 vk::AccelerationStructureTypeKHR::BOTTOM_LEVEL
922 }
923 }
924}
925
926pub fn map_acceleration_structure_build_mode(
927 format: crate::AccelerationStructureBuildMode,
928) -> vk::BuildAccelerationStructureModeKHR {
929 match format {
930 crate::AccelerationStructureBuildMode::Build => {
931 vk::BuildAccelerationStructureModeKHR::BUILD
932 }
933 crate::AccelerationStructureBuildMode::Update => {
934 vk::BuildAccelerationStructureModeKHR::UPDATE
935 }
936 }
937}
938
939pub fn map_acceleration_structure_flags(
940 flags: crate::AccelerationStructureBuildFlags,
941) -> vk::BuildAccelerationStructureFlagsKHR {
942 let mut vk_flags = vk::BuildAccelerationStructureFlagsKHR::empty();
943
944 if flags.contains(crate::AccelerationStructureBuildFlags::PREFER_FAST_TRACE) {
945 vk_flags |= vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_TRACE;
946 }
947
948 if flags.contains(crate::AccelerationStructureBuildFlags::PREFER_FAST_BUILD) {
949 vk_flags |= vk::BuildAccelerationStructureFlagsKHR::PREFER_FAST_BUILD;
950 }
951
952 if flags.contains(crate::AccelerationStructureBuildFlags::ALLOW_UPDATE) {
953 vk_flags |= vk::BuildAccelerationStructureFlagsKHR::ALLOW_UPDATE;
954 }
955
956 if flags.contains(crate::AccelerationStructureBuildFlags::LOW_MEMORY) {
957 vk_flags |= vk::BuildAccelerationStructureFlagsKHR::LOW_MEMORY;
958 }
959
960 if flags.contains(crate::AccelerationStructureBuildFlags::ALLOW_COMPACTION) {
961 vk_flags |= vk::BuildAccelerationStructureFlagsKHR::ALLOW_COMPACTION
962 }
963
964 if flags.contains(crate::AccelerationStructureBuildFlags::ALLOW_RAY_HIT_VERTEX_RETURN) {
965 vk_flags |= vk::BuildAccelerationStructureFlagsKHR::ALLOW_DATA_ACCESS
966 }
967
968 vk_flags
969}
970
971pub fn map_acceleration_structure_geometry_flags(
972 flags: crate::AccelerationStructureGeometryFlags,
973) -> vk::GeometryFlagsKHR {
974 let mut vk_flags = vk::GeometryFlagsKHR::empty();
975
976 if flags.contains(crate::AccelerationStructureGeometryFlags::OPAQUE) {
977 vk_flags |= vk::GeometryFlagsKHR::OPAQUE;
978 }
979
980 if flags.contains(crate::AccelerationStructureGeometryFlags::NO_DUPLICATE_ANY_HIT_INVOCATION) {
981 vk_flags |= vk::GeometryFlagsKHR::NO_DUPLICATE_ANY_HIT_INVOCATION;
982 }
983
984 vk_flags
985}
986
987pub fn map_acceleration_structure_usage_to_barrier(
988 usage: crate::AccelerationStructureUses,
989 features: wgt::Features,
990) -> (vk::PipelineStageFlags, vk::AccessFlags) {
991 let mut stages = vk::PipelineStageFlags::empty();
992 let mut access = vk::AccessFlags::empty();
993
994 if usage.contains(crate::AccelerationStructureUses::BUILD_INPUT) {
995 stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR;
996 access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR;
997 }
998 if usage.contains(crate::AccelerationStructureUses::QUERY_INPUT) {
999 stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR;
1000 access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR;
1001 }
1002 if usage.contains(crate::AccelerationStructureUses::BUILD_OUTPUT) {
1003 stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR;
1004 access |= vk::AccessFlags::ACCELERATION_STRUCTURE_WRITE_KHR;
1005 }
1006 if usage.contains(crate::AccelerationStructureUses::SHADER_INPUT)
1007 && features.contains(wgt::Features::EXPERIMENTAL_RAY_QUERY)
1008 {
1009 stages |= vk::PipelineStageFlags::VERTEX_SHADER
1010 | vk::PipelineStageFlags::FRAGMENT_SHADER
1011 | vk::PipelineStageFlags::COMPUTE_SHADER;
1012 access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR;
1013 }
1014 if usage.contains(crate::AccelerationStructureUses::COPY_SRC) {
1015 stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR;
1016 access |= vk::AccessFlags::ACCELERATION_STRUCTURE_READ_KHR;
1017 }
1018 if usage.contains(crate::AccelerationStructureUses::COPY_DST) {
1019 stages |= vk::PipelineStageFlags::ACCELERATION_STRUCTURE_BUILD_KHR;
1020 access |= vk::AccessFlags::ACCELERATION_STRUCTURE_WRITE_KHR;
1021 }
1022
1023 (stages, access)
1024}