Skip to content

Commit b78f8b2

Browse files
committed
addressing more comments.
1 parent 41e336e commit b78f8b2

File tree

1 file changed

+61
-46
lines changed

1 file changed

+61
-46
lines changed

en/Building_a_Simple_Engine/Mobile_Development/03_performance_optimizations.adoc

Lines changed: 61 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,27 @@ Mobile devices have significantly different hardware constraints compared to des
1313
We focus on mobile‑specific decisions here. For general Vulkan image creation, staging uploads, and descriptor setup, refer back to earlier chapters in the engine series—link:../Engine_Architecture/04_resource_management.adoc[Resource Management], link:../Engine_Architecture/05_rendering_pipeline.adoc[Rendering Pipeline]—or the Vulkan Guide (https://docs.vulkan.org/guide/latest/).
1414
====
1515

16-
Textures are often the largest consumers of memory in a graphics application. Optimizing them is crucial for mobile performance.
16+
Textures are often the largest consumers of memory in a graphics application. Optimizing them is crucial for performance on both mobile and desktop.
1717

1818
==== Efficient Texture Formats
1919

20-
Choosing the right texture format is crucial for mobile performance:
20+
Choosing the right texture format is crucial across platforms; what differs is which formats are natively supported by a given device/driver:
2121

2222
1. *Compressed Formats*: Use hardware-supported compressed formats whenever possible:
23-
- *ASTC* (Adaptive Scalable Texture Compression): Widely supported on modern mobile GPUs, offers excellent quality-to-size ratio with flexible block sizes.
24-
- *ETC2/EAC*: Required for OpenGL ES 3.0 and supported by most Android devices.
23+
- *ASTC* (Adaptive Scalable Texture Compression): Widely supported on modern mobile GPUs and increasingly available on desktop; excellent quality-to-size ratio with flexible block sizes.
24+
- *ETC2/EAC*: Required for OpenGL ES 3.0 and supported by most Android devices; commonly available on Vulkan stacks, too.
2525
- *PVRTC*: Primarily supported on iOS devices with PowerVR GPUs.
26-
- *BC* (Block Compression): More common on desktop but supported by some high-end mobile GPUs.
26+
- *BC* (Block Compression, a.k.a. DXT/BCn): Ubiquitous on desktop; supported by some mobile GPUs.
2727

28-
2. *Format Selection Based on Content*: Choose formats based on the type of texture:
29-
- Use ASTC 4x4 or 6x6 for normal maps and detailed textures.
30-
- Use ASTC 8x8 or 12x12 for diffuse/albedo textures.
31-
- Consider using R8 for single-channel textures like height maps.
28+
2. *Format Selection Based on Content and Support*: Choose formats based on the type of texture and what the device reports:
29+
- For high detail (normals, roughness): prefer ASTC 4x4 or 6x6 when supported; on desktop, BC5/BC7 are common alternatives.
30+
- For albedo/basecolor: ASTC 6x6–8x8 works well when available; on desktop, BC1/BC7 are typical.
31+
- For single-channel data: consider R8 or compressed single-channel alternatives when available.
32+
33+
[NOTE]
34+
====
35+
This guidance is not mobile-only: block compression reduces memory footprint and bandwidth on all platforms. The Mobile chapter highlights it because bandwidth and power are tighter constraints on phones/tablets. On desktop, the same benefits apply; the primary difference is which formats are commonly available (e.g., BC on desktop, ASTC/ETC2 on many mobile devices).
36+
====
3237

3338
Here's how to check for and use compressed formats in Vulkan:
3439

@@ -61,57 +66,67 @@ vk::Format find_supported_format(vk::PhysicalDevice physical_device,
6166
}
6267
6368
vk::Format find_best_compressed_format(vk::PhysicalDevice physical_device) {
64-
// Try ASTC formats first (best quality-to-size ratio)
69+
// Choose based on reported feature support; benefits apply on mobile and desktop.
70+
vk::PhysicalDeviceFeatures features = physical_device.getFeatures();
71+
72+
// Candidate lists
6573
std::vector<vk::Format> astc_formats = {
6674
vk::Format::eAstc8x8SrgbBlock,
6775
vk::Format::eAstc6x6SrgbBlock,
6876
vk::Format::eAstc4x4SrgbBlock
6977
};
70-
71-
try {
72-
return find_supported_format(
73-
physical_device,
74-
astc_formats,
75-
vk::ImageTiling::eOptimal,
76-
vk::FormatFeatureFlagBits::eSampledImage
77-
);
78-
} catch (const std::runtime_error&) {
79-
// ASTC not supported, try ETC2
80-
}
81-
78+
std::vector<vk::Format> bc_formats = {
79+
vk::Format::eBc7SrgbBlock,
80+
vk::Format::eBc3SrgbBlock,
81+
vk::Format::eBc1SrgbBlock
82+
};
8283
std::vector<vk::Format> etc2_formats = {
8384
vk::Format::eEtc2R8G8B8A8SrgbBlock,
8485
vk::Format::eEtc2R8G8B8SrgbBlock
8586
};
8687
87-
try {
88-
return find_supported_format(
89-
physical_device,
90-
etc2_formats,
91-
vk::ImageTiling::eOptimal,
92-
vk::FormatFeatureFlagBits::eSampledImage
93-
);
94-
} catch (const std::runtime_error&) {
95-
// ETC2 not supported, try BC
88+
// Build a simple preference order:
89+
// - If only BC is supported, try BC first (typical on desktop-only stacks).
90+
// - If ASTC is supported, try ASTC (common on mobile; also available on some desktop drivers).
91+
// - Then try the remaining supported families.
92+
std::vector<std::vector<vk::Format>> preference;
93+
94+
if (features.textureCompressionBC && !features.textureCompressionASTC_LDR) {
95+
preference.push_back(bc_formats);
96+
}
97+
if (features.textureCompressionASTC_LDR) {
98+
preference.push_back(astc_formats);
99+
}
100+
if (features.textureCompressionBC && features.textureCompressionASTC_LDR) {
101+
// Both supported; add BC as alternative if not already first
102+
if (preference.empty() || preference[0] != bc_formats) {
103+
preference.push_back(bc_formats);
104+
}
105+
}
106+
if (features.textureCompressionETC2) {
107+
preference.push_back(etc2_formats);
96108
}
97109
98-
std::vector<vk::Format> bc_formats = {
99-
vk::Format::eBc7SrgbBlock,
100-
vk::Format::eBc3SrgbBlock,
101-
vk::Format::eBc1SrgbBlock
102-
};
110+
// As a fallback, try all families regardless of feature bits (some drivers may expose formats via properties).
111+
if (preference.empty()) {
112+
preference = { astc_formats, etc2_formats, bc_formats };
113+
}
103114
104-
try {
105-
return find_supported_format(
106-
physical_device,
107-
bc_formats,
108-
vk::ImageTiling::eOptimal,
109-
vk::FormatFeatureFlagBits::eSampledImage
110-
);
111-
} catch (const std::runtime_error&) {
112-
// Fall back to uncompressed
113-
return vk::Format::eR8G8B8A8Srgb;
115+
for (const auto& family : preference) {
116+
try {
117+
return find_supported_format(
118+
physical_device,
119+
family,
120+
vk::ImageTiling::eOptimal,
121+
vk::FormatFeatureFlagBits::eSampledImage
122+
);
123+
} catch (const std::runtime_error&) {
124+
// Try next family
125+
}
114126
}
127+
128+
// Fall back to uncompressed
129+
return vk::Format::eR8G8B8A8Srgb;
115130
}
116131
----
117132

0 commit comments

Comments
 (0)