VK_EXT_fragment_density_map_offset
This extension extends VK_EXT_fragment_density_map to allow for finer control over the location of the local framebuffer regions in a render pass with a fragment density map attachment.
This extension is a promotion of VK_QCOM_fragment_density_map_offset, with the addition of support for dynamic rendering. As that extension already shipped before proposal documents existed, this document has been written retroactively during promotion to EXT. |
1. Problem Statement
Some use-cases for VK_EXT_fragment_density_map, such as eye-tracking foveation, require the fragment density map to be updated often. This can cause a distracting flickering effect for the user as local framebuffer regions pop in and out of high-density portion of the fragment density map. A method is needed for finer-grained control over the location of the high-density region without sudden jumps.
2. Solution Space
The location and sizes of the local framebuffer regions are purposefully made opaque in the original extension, so there is no way to directly control them. The typical use-case involves translating a given fixed fragment density map, with independent control needed for each layer of the framebuffer, so the simplest solution is to give the implementation a per-layer offset for sampling the fragment density map with the expectation that the implementation should offset the location of the local framebuffer regions in the opposite direction whenever possible in order to smoothly scroll the local framebuffer regions.
3. Proposal
A new structure is added that can be chained to VkSubpassEndInfo or VkRenderingEndInfoEXT which adds per-layer offsets to the fragment density map.
3.1. Features
There is a single new feature:
typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesEXT {
VkStructureType sType;
void* pNext;
VkBool32 fragmentDensityMapOffset;
} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesEXT;
3.2. Properties
Implementations may require an alignment for the offset, so this extension adds a property for the granularity that the offset must be aligned to:
typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT {
VkStructureType sType;
void* pNext;
VkExtent2D fragmentDensityOffsetGranularity;
} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesEXT;
3.3. Functionality
3.3.1. Image Creation
#define VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT ((VkImageCreateFlagBits)0x00008000)
When fragment density offsets are used, the images for all attachments in the
render pass, including color attachments, resolve attachments, and the fragment
density map attachment, must be created with the new
VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT
usage.
3.3.2. Dynamic Rendering with fragment density map offsets
Dynamic rendering support has been added since the original VK_QCOM_fragment_density_map_offset extension was released. This requires the addition of a new command to terminate a dynamic rendering pass:
VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering2EXT(
VkCommandBuffer commandBuffer,
const VkRenderingEndInfoEXT* pRenderingEndInfo);
-
commandBuffer
is the command buffer into which the command is recorded. -
pRenderingEndInfo
is an optional pointer to aVkRenderingEndInfoEXT
struct which can utilize apNext
chain to provide additional rendering info.
typedef struct VkRenderingEndInfoEXT {
VkStructureType sType;
const void* pNext;
} VkRenderingEndInfoEXT;
-
sType
isVK_STRUCTURE_TYPE_RENDERING_END_INFO_EXT
. -
pNext
can be used to chain a pointer to aVkRenderPassFragmentDensityMapOffsetEndInfoEXT
struct.
3.3.3. Specifying fragment density map offsets
Fragment density map offsets are set using the following struct chained to either a
VkRenderingEndInfoEXT
or VkSubpassEndInfo
struct:
typedef struct VkRenderPassFragmentDensityMapOffsetEndInfoEXT {
VkStructureType sType;
const void* pNext;
uint32_t fragmentDensityOffsetCount;
const VkOffset2D* pFragmentDensityOffsets;
} VkRenderPassFragmentDensityMapOffsetEndInfoEXT;
-
fragmentDensityOffsetCount
is the number of offsets being specified. -
pFragmentDensityOffsets`
is a pointer to an array ofVkOffset2D
structs, each of which describes the offset per layer.
Before sampling the fragment density map, the framebuffer region center coordinates are
offsetted using the values in pFragmentDensityOffsets
and clamped to the
framebuffer dimensions.
4. Issues
4.1. How should suspending and resuming render passes be handled?
Suspending and resuming render passes are merged into one larger render pass,
so we have to choose choose one of the passes to provide the offsets. We
somewhat arbitrarily choose the last render pass in submission order. That is,
VkRenderPassFragmentDensityMapOffsetEndInfoEXT
is ignored unless the render
pass is not suspending.