Skip to content

Commit 484430a

Browse files
authored
clarify and standardize format compatibility rules for storage images and texel buffers in documentation. (#332)
1 parent bbee9ee commit 484430a

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

chapters/storage_image_and_texel_buffers.adoc

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,9 @@ OpDecorate %storageTexelBuffer Binding 0
327327
%storageTexelBuffer = OpVariable %ptr UniformConstant
328328
----
329329

330-
==== Using non-rgba Format for Texel Buffer
330+
==== Using non-rgba Format for Texel Buffer
331331

332-
A common mistake when dealing with Texel Buffers is forgetting you are accessing a single texel at a time.
332+
A common mistake when dealing with Texel Buffers is forgetting you are accessing a single texel at a time.
333333
This texel format can have 1 to 4 components (`R8` vs `RGBA8`).
334334
Some shading languages, such as GLSL, require you to write all 4 components where the extra components are ignored.
335335

@@ -478,13 +478,13 @@ When using storage images and texel buffers, it's crucial to understand the form
478478

479479
=== Differences in Format Compatibility Rules
480480

481-
The format compatibility rules differ between storage images and texel buffers in subtle but important ways:
481+
The format compatibility rules for storage images and texel buffers are the same:
482482

483483
1. **Storage Images**: The format specified in the shader (SPIR-V Image Format) must **exactly match** the format used when creating the VkImageView (Vulkan Format).
484484

485-
2. **Texel Buffers**: The format compatibility is more relaxed. The shader can access the data as long as the format is compatible with the buffer view format according to the format compatibility classes.
485+
2. **Texel Buffers**: The format specified in the shader (SPIR-V Image Format) must **exactly match** the format used when creating the VkBufferView (Vulkan Format).
486486

487-
This difference means that storage images have stricter format requirements than texel buffers, which can lead to confusion when working with both resource types.
487+
Both resource types require exact format matching between the shader and the view. The views must always match the shader exactly.
488488

489489
=== SPIR-V Image Format and Vulkan Format Compatibility
490490

@@ -505,35 +505,35 @@ layout(set = 0, binding = 0, rgba8) uniform image2D storageImage;
505505

506506
==== Texel Buffers Format Requirements
507507

508-
For texel buffers, the format compatibility is determined by the format compatibility classes. Formats within the same compatibility class can be used interchangeably, with the shader performing the necessary conversions.
508+
For texel buffers, just like storage images, the format specified in the shader must exactly match the format of the buffer view according to the SPIR-V Image Format and Vulkan Format compatibility table. There is no automatic format conversion or component swizzling.
509509

510510
[source,glsl]
511511
----
512512
// For uniform texel buffers, the format is not specified in the shader
513513
layout(set = 0, binding = 0) uniform textureBuffer uniformTexelBuffer;
514514
515-
// The VkBufferView can be created with any compatible format
516-
// For example, both VK_FORMAT_R8G8B8A8_UNORM and VK_FORMAT_B8G8R8A8_UNORM would work
515+
// The VkBufferView must be created with a format that exactly matches what the shader expects
516+
// For example, if the shader expects RGBA data, VK_FORMAT_R8G8B8A8_UNORM must be used
517517
----
518518

519-
For storage texel buffers, a format is specified in the shader, but the compatibility rules are still more relaxed than for storage images:
519+
For storage texel buffers, a format is specified in the shader, and it must exactly match the format used for the VkBufferView:
520520

521521
[source,glsl]
522522
----
523523
// SPIR-V format Rgba8 (maps to VK_FORMAT_R8G8B8A8_UNORM)
524524
layout(set = 0, binding = 0, rgba8) uniform imageBuffer storageTexelBuffer;
525525
526-
// The VkBufferView should ideally be created with VK_FORMAT_R8G8B8A8_UNORM
527-
// But formats in the same compatibility class may work on some implementations
526+
// The VkBufferView must be created with VK_FORMAT_R8G8B8A8_UNORM
527+
// Using a different format, even in the same compatibility class, results in undefined behavior
528528
----
529529

530530
=== Component Swizzling
531531

532-
Component swizzling is another area where storage images and texel buffers differ:
532+
For both storage images and texel buffers, component swizzling works the same way:
533533

534534
1. **Storage Images**: No automatic component swizzling occurs. The components are accessed exactly as they are stored in memory. If you need to swizzle components, (e.g., convert between RGBA and BGRA), you must do it manually in your shader code.
535535

536-
2. **Texel Buffers**: Some implementations may perform automatic component swizzling based on the format compatibility class. However, this behavior is not guaranteed across all implementations, so it's best practice to match formats exactly when possible.
536+
2. **Texel Buffers**: Just like storage images, no automatic component swizzling occurs. The components are accessed exactly as they are stored in memory. If you need to swizzle components, you must do it manually in your shader code.
537537

538538
3. **Image Views**: For sampled images (not storage images), you can use the `VkComponentMapping` structure in `VkImageViewCreateInfo` to specify component swizzling. This is not applicable to storage images or texel buffers.
539539

@@ -543,6 +543,7 @@ Several types of format mismatches can occur, all of which result in undefined b
543543

544544
1. **Component Size Mismatch**: When the component size in the SPIR-V format differs from the Vulkan format.
545545
- Example: SPIR-V format `Rgba32f` (32-bit float components) with `VK_FORMAT_R8G8B8A8_UNORM` (8-bit components)
546+
- Example: SPIR-V format `R32ui` (32-bit unsigned int) with `VK_FORMAT_R8_UINT` (8-bit unsigned int) - this is invalid, resulting in undefined behavior with no implicit bitcasting
546547

547548
2. **Component Count Mismatch**: When the number of components in the SPIR-V format differs from the Vulkan format.
548549
- **More Components Written**: SPIR-V format `Rgba8` (4 components) with `VK_FORMAT_R8_UNORM` (1 component)
@@ -595,19 +596,19 @@ layout(set = 0, binding = 0) uniform image2D storageImage;
595596

596597
==== For Texel Buffers
597598

598-
1. **Match the Formats When Possible**: While texel buffers have more relaxed format compatibility rules, it's still best practice to match formats exactly when possible.
599+
1. **Match the Formats Exactly**: Ensure that the VkBufferView format exactly matches the SPIR-V Image Format as defined in the compatibility table, just as with storage images.
600+
- For example, if your shader uses `rgba8` (SPIR-V format `Rgba8`), create your VkBufferView with `VK_FORMAT_R8G8B8A8_UNORM`.
601+
- Using a different format, even in the same compatibility class, results in undefined behavior.
599602

600-
2. **Use Format Compatibility Classes**: If you need to work with different formats, ensure they are in the same format compatibility class.
601-
602-
3. **Handle Component Swizzling in Shader**: If you're working with formats that have different component orders (e.g., RGBA vs. BGRA), handle the swizzling explicitly in your shader code to ensure consistent behavior across all implementations.
603+
2. **Handle Component Swizzling in Shader**: If you need to work with formats that have different component orders (e.g., RGBA vs. BGRA), handle the swizzling explicitly in your shader code, as no automatic swizzling occurs.
603604

604605
=== Important Considerations
605606

606-
- When a format mismatch occurs with storage images, the entire image memory becomes undefined, not just the texels being written.
607-
- Even formats that are in the same compatibility class (e.g., `VK_FORMAT_R8G8B8A8_UNORM` and `VK_FORMAT_B8G8R8A8_UNORM`) must match exactly for storage images.
608-
- Texel buffers have more relaxed format compatibility rules, but it's still best practice to match formats exactly when possible.
607+
- When a format mismatch occurs with either storage images or texel buffers, the entire memory becomes undefined, not just the texels being written.
608+
- Even formats that are in the same compatibility class (e.g., `VK_FORMAT_R8G8B8A8_UNORM` and `VK_FORMAT_B8G8R8A8_UNORM`) must match exactly for both storage images and texel buffers.
609+
- Both storage images and texel buffers have the same strict format compatibility rules - the formats specified in the shader must exactly match the formats used in the views.
609610
- The validation warnings for format mismatches are intended to help developers identify potential issues, as these mismatches can lead to subtle bugs that might not be immediately clear.
610-
- Component swizzling must be handled manually for storage images, while some automatic swizzling may occur for texel buffers on some implementations.
611+
- Component swizzling must be handled manually for both storage images and texel buffers, as no automatic swizzling occurs for either resource type.
611612

612613
== Best Practices
613614

0 commit comments

Comments
 (0)