-
-
Notifications
You must be signed in to change notification settings - Fork 26.4k
Implement texture mip-level streaming #113429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tdaven
wants to merge
8
commits into
godotengine:master
Choose a base branch
from
tdaven:texture-stream-rework
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+4,324
−43
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
095c8d8
When enabled, materials provide feedback on texture usage during
tdaven eeb2262
Add a texture replacement fast path.
tdaven 09a0639
Refactor I/O throttling.
tdaven 94725d0
Fix streamed texture preview.
tdaven 74595d8
Add suffix to size.
tdaven 5a7a65a
Refactor when and how early-z is forced on.
tdaven 466f2ed
Ensure dimension can't go below 1.
tdaven 44bc372
Add constants to try and make code easier to read.
tdaven File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <?xml version="1.0" encoding="UTF-8" ?> | ||
| <class name="ResourceImporterStreamedTexture" inherits="ResourceImporter" api_type="editor" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> | ||
| <brief_description> | ||
| Imports an image as a streaming-capable texture for dynamic mipmap loading. | ||
| </brief_description> | ||
| <description> | ||
| This importer creates [StreamedTexture2D] resources that support dynamic mipmap streaming. When texture streaming is enabled in the Project Settings ([member ProjectSettings.rendering/textures/streaming/enabled]), these textures can have their mipmap levels dynamically loaded and unloaded based on usage, significantly reducing VRAM consumption for projects with many large textures. | ||
| The streaming system monitors which textures are visible in each frame and loads appropriate mipmap levels accordingly. Textures that are far from the camera or not currently visible have their higher-resolution mipmap levels unloaded, while textures being displayed up close are loaded at higher resolutions. | ||
| For textures that don't need streaming support, use [ResourceImporterTexture] instead. | ||
| </description> | ||
| <tutorials> | ||
| </tutorials> | ||
| <members> | ||
| <member name="compress/channel_pack" type="int" setter="" getter="" default="0"> | ||
| Controls how color channels should be used in the imported texture. | ||
| [b]sRGB Friendly:[/b] Prevents the R and RG color formats from being used, as they do not support nonlinear sRGB encoding. | ||
| [b]Optimized:[/b] Allows the RG color format to be used if the texture does not use the blue channel. This reduces memory usage if the texture's blue channel can be discarded (all pixels must have a blue value of [code]0[/code]). | ||
| </member> | ||
| <member name="compress/hdr_compression" type="int" setter="" getter="" default="1"> | ||
| Controls how VRAM compression should be performed for HDR images. | ||
| [b]Disabled:[/b] Never use VRAM compression for HDR textures, regardless of whether they're opaque or transparent. Instead, the texture is converted to RGBE9995 (9-bits per channel + 5-bit exponent = 32 bits per pixel) to reduce memory usage compared to a half-float or single-precision float image format. | ||
| [b]Opaque Only:[/b] Only uses VRAM compression for opaque HDR textures. This is due to a limitation of HDR formats, as there is no VRAM-compressed HDR format that supports transparency at the same time. | ||
| [b]Always:[/b] Force VRAM compression even for HDR textures with an alpha channel. To perform this, the alpha channel is discarded on import. | ||
| [b]Note:[/b] Only effective on Radiance HDR ([code].hdr[/code]) and OpenEXR ([code].exr[/code]) images. | ||
| </member> | ||
| <member name="compress/high_quality" type="bool" setter="" getter="" default="false"> | ||
| If [code]true[/code], uses BPTC compression on desktop platforms and ASTC compression on mobile platforms. When using BPTC, BC7 is used for SDR textures and BC6H is used for HDR textures. | ||
| If [code]false[/code], uses the faster but lower-quality S3TC compression on desktop platforms and ETC2 on mobile/web platforms. When using S3TC, DXT1 (BC1) is used for opaque textures and DXT5 (BC3) is used for transparent or normal map (RGTC) textures. | ||
| BPTC and ASTC support VRAM compression for HDR textures, but S3TC and ETC2 do not (see [member compress/hdr_compression]). | ||
| </member> | ||
| <member name="compress/normal_map" type="int" setter="" getter="" default="0"> | ||
| When using a texture as normal map, only the red and green channels are required. Given regular texture compression algorithms produce artifacts that don't look that nice in normal maps, the RGTC compression format is the best fit for this data. Forcing this option to Enable will make Godot import the image as RGTC compressed. By default, it's set to Detect. This means that if the texture is ever detected to be used as a normal map, it will be changed to Enable and reimported automatically. | ||
| </member> | ||
| <member name="roughness/mode" type="int" setter="" getter="" default="0"> | ||
| The color channel to consider as a roughness map in this texture. Only effective if Roughness > Src Normal is not empty. | ||
| </member> | ||
| <member name="roughness/src_normal" type="String" setter="" getter="" default=""""> | ||
| The path to the texture to consider as a normal map for roughness filtering on import. Specifying this can help decrease specular aliasing slightly in 3D. | ||
| </member> | ||
| <member name="streaming/max_lod_override" type="int" setter="" getter="" default="0"> | ||
| The maximum LOD (mipmap level) that can be loaded for this texture. Lower values allow higher resolution. A value of [code]0[/code] uses the global setting from [member ProjectSettings.rendering/textures/streaming/max_lod]. Values [code]1[/code] to [code]14[/code] correspond to LOD levels [code]0[/code] to [code]13[/code]. | ||
| </member> | ||
| <member name="streaming/min_lod_override" type="int" setter="" getter="" default="0"> | ||
| The minimum LOD (mipmap level) the texture starts at when loaded. Higher values result in lower initial resolution. A value of [code]0[/code] uses the global setting from [member ProjectSettings.rendering/textures/streaming/min_lod]. Values [code]1[/code] to [code]14[/code] correspond to LOD levels [code]0[/code] to [code]13[/code]. | ||
| </member> | ||
| </members> | ||
| </class> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <?xml version="1.0" encoding="UTF-8" ?> | ||
| <class name="StreamedTexture2D" inherits="Texture2D" api_type="core" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> | ||
| <brief_description> | ||
| A texture that supports dynamic mipmap streaming for optimized VRAM usage. | ||
| </brief_description> | ||
| <description> | ||
| StreamedTexture2D is a texture type that supports dynamic mipmap streaming. When texture streaming is enabled in the Project Settings ([member ProjectSettings.rendering/textures/streaming/enabled]), these textures can have their mipmap levels dynamically loaded and unloaded based on usage. | ||
| The texture streaming system monitors which textures are visible in each frame and at what resolution they're being displayed. Textures that are far from the camera or not currently visible have their higher-resolution mipmap levels unloaded to save VRAM, while textures being displayed up close are loaded at higher resolutions. | ||
| This texture type is automatically created when importing images with the streaming-compatible importer. | ||
| </description> | ||
| <tutorials> | ||
| </tutorials> | ||
| <methods> | ||
| <method name="load"> | ||
| <return type="int" enum="Error" /> | ||
| <param index="0" name="path" type="String" /> | ||
| <description> | ||
| Loads the texture from the specified [param path]. | ||
| </description> | ||
| </method> | ||
| </methods> | ||
| <members> | ||
| <member name="load_path" type="String" setter="load" getter="get_load_path" default=""""> | ||
| The [StreamedTexture2D]'s file path to a [code].stex[/code] file. | ||
| </member> | ||
| <member name="max_lod_override" type="int" setter="set_max_lod_override" getter="get_max_lod_override" default="0"> | ||
| Overrides the maximum LOD (mipmap level) that can be loaded for this specific texture. Lower values allow higher resolution. A value of [code]0[/code] uses the global setting from [member ProjectSettings.rendering/textures/streaming/max_lod]. Values [code]1[/code] to [code]14[/code] correspond to LOD levels [code]0[/code] to [code]13[/code]. | ||
| </member> | ||
| <member name="min_lod_override" type="int" setter="set_min_lod_override" getter="get_min_lod_override" default="0"> | ||
| Overrides the minimum LOD (mipmap level) this texture starts at when loaded. Higher values result in lower initial resolution. A value of [code]0[/code] uses the global setting from [member ProjectSettings.rendering/textures/streaming/min_lod]. Values [code]1[/code] to [code]14[/code] correspond to LOD levels [code]0[/code] to [code]13[/code]. | ||
| </member> | ||
| <member name="resource_local_to_scene" type="bool" setter="set_local_to_scene" getter="is_local_to_scene" overrides="Resource" default="false" /> | ||
| </members> | ||
| </class> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| <?xml version="1.0" encoding="UTF-8" ?> | ||
| <class name="TextureStreaming" inherits="Object" api_type="core" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> | ||
| <brief_description> | ||
| Manages dynamic texture mipmap streaming to optimize VRAM usage. | ||
| </brief_description> | ||
| <description> | ||
| The TextureStreaming singleton manages dynamic loading and unloading of texture mipmap levels based on what is visible in the current frame. This allows projects with many large textures to significantly reduce VRAM usage while maintaining visual quality for visible textures. | ||
| Texture streaming works by analyzing shader feedback to determine which textures are actively being used and at what resolution they're being displayed. Textures that are far from the camera or not currently visible have their higher-resolution mipmap levels unloaded, while textures being displayed up close are loaded at higher resolutions. | ||
| The system includes a memory budget feature that automatically manages texture resolutions to stay within a specified VRAM limit. When the budget is exceeded, the system prioritizes textures based on how recently they were used and how much screen space they occupy. | ||
| [b]Note:[/b] Texture streaming must be enabled in the Project Settings ([member ProjectSettings.rendering/textures/streaming/enabled]) and textures must be imported with streaming support to use this feature. | ||
| </description> | ||
| <tutorials> | ||
| </tutorials> | ||
| <methods> | ||
| <method name="flush_texture_streaming"> | ||
| <return type="void" /> | ||
| <description> | ||
| Forces all currently queued texture streaming operations to complete immediately, bypassing the normal gradual transition and I/O throttling. This immediately loads or unloads mipmap levels to reach the target resolution for all managed textures, then emits the [signal flush_completed] signal. Useful during loading screens or when teleporting the player to ensure all textures are at their optimal resolution without a visible transition. | ||
| </description> | ||
| </method> | ||
| <method name="get_memory_budget_bytes_used"> | ||
| <return type="int" /> | ||
| <description> | ||
| Returns the current VRAM usage of streamed textures in bytes. This represents the total memory consumed by all streamed textures at their currently loaded mipmap levels. | ||
| </description> | ||
| </method> | ||
| </methods> | ||
| <members> | ||
| <member name="max_lod_override" type="int" setter="set_max_lod_override" getter="get_max_lod_override" default="-1"> | ||
| Overrides the maximum LOD (mipmap level) that can be loaded for streamed textures at runtime. Lower values allow higher resolution textures. Valid values are [code]0[/code] (full resolution) to [code]13[/code] (lowest resolution). Values outside that range clear the override and use the default from [member ProjectSettings.rendering/textures/streaming/max_lod]; when no override is active this property returns [code]-1[/code]. | ||
| </member> | ||
| <member name="memory_budget_mb_override" type="int" setter="set_memory_budget_mb_override" getter="get_memory_budget_mb_override" default="4294967295"> | ||
| Overrides the memory budget for streamed textures at runtime (in megabytes). When the budget is exceeded, the system reduces texture resolution to stay within the limit. A value of [code]UINT32_MAX[/code] ([code]4294967295[/code], the maximum unsigned 32-bit integer) disables the override and uses the default from [member ProjectSettings.rendering/textures/streaming/memory_budget_mb]. | ||
| </member> | ||
| <member name="min_lod_override" type="int" setter="set_min_lod_override" getter="get_min_lod_override" default="-1"> | ||
| Overrides the minimum LOD (mipmap level) that textures start at when loaded. Higher values result in lower initial resolution. Valid values are [code]0[/code] (full resolution) to [code]13[/code] (lowest resolution). Values outside that range clear the override and use the default from [member ProjectSettings.rendering/textures/streaming/min_lod]; when no override is active this property returns [code]-1[/code]. | ||
| </member> | ||
| </members> | ||
| <signals> | ||
| <signal name="flush_completed"> | ||
| <description> | ||
| Emitted when a texture streaming flush operation finishes, after [method flush_texture_streaming] has been called and all managed textures have reached their target resolutions. | ||
| </description> | ||
| </signal> | ||
| </signals> | ||
| </class> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this fully indefinitely, or until
memory_budget_mbpushes out a texture that is not currently used?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will reduce in quality each period (5000 ms in this case) until it ready the lowest quality. Obviously, lower quality levels free up less and less memory so the effect of memory levels off.
If it is set to zero, then textures never degrade unless under memory pressure.