Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
90fa6bd
Initial commit.
Grzegorz-Smagacz-Mobica Aug 3, 2023
59c5386
MAJOR: removed entirely mesh calculation based on the trigonometric m…
Grzegorz-Smagacz-Mobica Aug 9, 2023
b808ea1
Major changes. Making use of GL_ARB_sparse_texture2 extension in the …
Grzegorz-Smagacz-Mobica Aug 24, 2023
c40b917
update
Grzegorz-Smagacz-Mobica Sep 19, 2023
d839c92
Core functionalities are working as expected. To be reviewed.
Grzegorz-Smagacz-Mobica Sep 20, 2023
b349e47
Minor updates, mostly cleanup
Grzegorz-Smagacz-Mobica Sep 21, 2023
77e41b7
Clang Tidy Check fixes
Grzegorz-Smagacz-Mobica Sep 22, 2023
03d3fb6
Clang Format Check fixes
Grzegorz-Smagacz-Mobica Sep 22, 2023
38c906b
* Rebased with main branch
Grzegorz-Smagacz-Mobica Sep 27, 2023
2cda0c3
* Now loading the least detailed mip level is done before the first f…
Grzegorz-Smagacz-Mobica Sep 29, 2023
88c30a2
* Added features from the UI level, now displaying memory-related sta…
Grzegorz-Smagacz-Mobica Oct 3, 2023
5b8ad7f
* Fixed the bug that caused black-spots to appear on screen
Grzegorz-Smagacz-Mobica Oct 5, 2023
d79749a
* Now memory is allocated dynamically during the run-time
Grzegorz-Smagacz-Mobica Oct 19, 2023
5ebaaeb
* Fixed validation-layer-errors related to deframentation process
Grzegorz-Smagacz-Mobica Oct 21, 2023
dd9a846
* Updated the screenshot
Grzegorz-Smagacz-Mobica Oct 26, 2023
39b4c1f
* Minor changes to match the PR's General & Sample Checklists
Grzegorz-Smagacz-Mobica Oct 30, 2023
23941f6
* Fixed Ubuntu compilation issues and Copyright checks
Grzegorz-Smagacz-Mobica Nov 20, 2023
73197ca
* Minor stylistic changes
Grzegorz-Smagacz-Mobica Nov 24, 2023
813dce0
* Rebase
Grzegorz-Smagacz-Mobica Dec 4, 2023
6a72036
* missing static_cast
Grzegorz-Smagacz-Mobica Dec 11, 2023
b166c91
* minor rework, fixing a validation layer warning
Grzegorz-Smagacz-Mobica Dec 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
** xref:samples/extensions/ray_queries/README.adoc[Ray queries]
** xref:samples/extensions/ray_tracing_reflection/README.adoc[Ray tracing reflection]
** xref:samples/extensions/shader_object/README.adoc[Shader Object]
** xref:samples/extensions/sparse_image/README.adoc[Sparse Image]
** xref:samples/extensions/synchronization_2/README.adoc[Synchronization 2]
** xref:samples/extensions/timeline_semaphore/README.adoc[Timeline semaphore]
** xref:samples/extensions/vertex_dynamic_state/README.adoc[Vertex dynamic state]
Expand Down
1 change: 1 addition & 0 deletions samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ set(ORDER_LIST
"fragment_shader_barycentric"
"gshader_to_mshader"
"color_write_enable"
"sparse_image"

#Performance Samples
"swapchain_images"
Expand Down
30 changes: 30 additions & 0 deletions samples/extensions/sparse_image/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2023, Mobica Limited
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 the "License";
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

get_filename_component(FOLDER_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_LIST_DIR} PATH)
get_filename_component(CATEGORY_NAME ${PARENT_DIR} NAME)

add_sample(
ID ${FOLDER_NAME}
CATEGORY ${CATEGORY_NAME}
AUTHOR "Mobica"
NAME "sparse_image"
DESCRIPTION "This sample is showcasing the potential usage of the sparse-image-binding and sparse-image-residency features. It works with the concept of Virtual Textures, allowing textures to be rendered without being entirely allocated in the memory."
SHADER_FILES_GLSL
"sparse_image/sparse.vert"
"sparse_image/sparse.frag")
161 changes: 161 additions & 0 deletions samples/extensions/sparse_image/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
////
- Copyright (c) 2023, Mobica Limited
-
- SPDX-License-Identifier: Apache-2.0
-
- Licensed under the Apache License, Version 2.0 the "License";
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
////

== Sparse image

ifdef::site-gen-antora[]
TIP: The source for this sample can be found in the https://github.com/KhronosGroup/Vulkan-Samples/tree/main/samples/extensions/sparse_image[Khronos Vulkan samples github repository].
endif::[]

image::./images/sparse_image_screenshot.png[Sample]

== Overview

The usage of
https://registry.khronos.org/vulkan/site/spec/latest/chapters/sparsemem.html[Sparse
Resources] allows for less restrict memory binding in comparison to a
standard resource.

The key differences between standard and sparse resources, showcased in
this sample are:

* Sparse resources can be bound non-contiguously to one or more
VkDeviceMemory allocations;
* Sparse resources can be re-bound to different memory allocations over
the lifetime of the resource;

The sample demonstrates usage of the Sparse Image feature by rendering a
high-resolution texture with only a fraction of the total image size
actually allocated on the device's memory. This is possible by
dynamically loading required memory areas, generating mip levels for
outer parts, removing unused memory and finally: binding an image in
real-time.

== Enabling features

There are 3 features to be enabled:

* sparseBinding;
* sparseResidencyImage2D;
* shaderResourceResidency;

First two, are the key features required for the usage of the sparse
image resources. The last one - shaderResourceResidency, is required for
the fragment shader to be able to detect which parts of the image are
allocated in the memory.

[source,c++]
----
void SparseImage::request_gpu_features(vkb::PhysicalDevice &gpu)
{
if (gpu.get_features().sparseBinding && gpu.get_features().sparseResidencyImage2D && gpu.get_features().shaderResourceResidency)
{
gpu.get_mutable_requested_features().sparseBinding = VK_TRUE;
gpu.get_mutable_requested_features().sparseResidencyImage2D = VK_TRUE;
gpu.get_mutable_requested_features().shaderResourceResidency = VK_TRUE;
}
----

== Enabling extensions

There is a single extensions used in this sample:

* GL_ARB_sparse_texture2;

This extension is used only by the fragment shader, but requires
shaderResourceResidency feature to be enabled first. What this extension
does, is allowing the fragment to check if the memory for the particular
fragment is actually allocated or not. Because of this extension, it is
possible to keep checking the residency from the fragment shader, and
basically use the most detailed data available.

[source,glsl]
----
#extension GL_ARB_sparse_texture2 : enable
----

[source,glsl]
----
for(; (lod <= maxLOD) && !sparseTexelsResidentARB(residencyCode); lod += 1)
{
residencyCode = sparseTextureLodARB(texSampler, fragTexCoord, lod, color);
}
----


== How is required LOD calculated?

The whole method is well-described in the source file. In general, the
value of LOD is obtained by calculating: What is the ratio between x or y
movement on the screen, to the u or v movement on the texture?

The idea is, that when moving pixel-by-pixel along the x or y axis
on-screen, if the small on-screen step causes a significant step
on-texture, then the area is far away from the observer and
a less-detailed mip-level is required.

The formula used for those calculations is:

LOD = log2 (max(dT / dx, dT / dy)); where:

* dT is an on-texture-step in texels,
* dx, dy are on-screen-steps in pixels.


== User Interface

The user can alter the application by using the GUI.

These are available options:

* Color highlight - if enabled, areas of a particular LOD usage are
color-highlighted.
* Memory defragmentation - if enabled, memory pages are reallocated from
low-occupied sectors to higher-occupied (but available) sectors to keep the
overall number of allocations as low as possible.
* Update prioritization - if enabled, the application is focused on
processing the most actual requests and discards remainings from the
previous requests. This can be observed when dynamically moving the
camera around.
* Blocks per cycle - describes up to how many blocks can be updated per
a single render cycle. The total number of blocks is defined as: (Vertical
blocks) * (Horizontal blocks).
* Vertical blocks - describes the number of columns the texture is
divided into.
* Horizontal blocks - describes the number of rows the texture is
divided into.

Additionally, GUI contains memory usage data. It describes (in pages)
what are the virtual requirements (what if the whole image was allocated
in the memory) and what is the actual, current allocation on the
device.


== Conclusion

The primary usage of the sparse image feature is generally speaking
dedicated for cases where too much device's memory is occupied. Keeping
a low-detailed mip-level constantly in the memory and dynamically
loading required areas when the camera changes, is the way to handle
terrain mega-textures. The downside of these solution is that there is a
possibility of a bottleneck problem when constantly transferring
required memory chunks from the CPU to the device. The other downside is
that since the application decides what memory is going to be allocated,
it must take care of the calculations such as: "`what level of detail is
required?`". This creates an unwanted CPU overhead.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading