16. Fragment Density Map Operations

16.1. Fragment Density Map Operations Overview

When a fragment is generated in a render pass that has a fragment density map attachment, its area is determined by the properties of the local framebuffer region that the fragment occupies. The framebuffer is divided into a uniform grid of these local regions, and their fragment area property is derived from the density map with the following operations:

16.2. Fetch Density Value

Each local framebuffer region at center coordinate (x,y) fetches a texel from the fragment density map at integer coordinates:

\(i = \lfloor{\frac{x}{fragmentDensityTexelSize_{width}}}\rfloor\)

\(j = \lfloor{\frac{y}{fragmentDensityTexelSize_{height}}}\rfloor\)

Where the size of each region in the framebuffer is:

\(fragmentDensityTexelSize'_{width} = {2^{\lceil{\log_2(\frac{framebuffer_{width}}{fragmentDensityMap_{width}})}\rceil}}\)

\(fragmentDensityTexelSize'_{height} = {2^{\lceil{\log_2(\frac{framebuffer_{height}}{fragmentDensityMap_{height}})}\rceil}}\)

This region is subject to the limits in VkPhysicalDeviceFragmentDensityMapPropertiesEXT and therefore the final region size is clamped:

\(fragmentDensityTexelSize_{width} = \mathbin{clamp}(fragmentDensityTexelSize'_{width},minFragmentDensityTexelSize_{width},maxFragmentDensityTexelSize_{width})\)

\(fragmentDensityTexelSize_{height} = \mathbin{clamp}(fragmentDensityTexelSize'_{height},minFragmentDensityTexelSize_{height},maxFragmentDensityTexelSize_{height})\)

When multiview is enabled for the render pass and the fragment density map attachment view was created with layerCount greater than 1, the density map layer that the texel is fetched from is:

\(layer = baseArrayLayer + ViewIndex\)

Otherwise:

\(layer = baseArrayLayer\)

The texel fetched from the density map at (i,j,layer) is next converted to density with the following operations.

16.2.1. Component Swizzle

The components member of VkImageViewCreateInfo is applied to the fetched texel as defined in Image component swizzle.

16.2.2. Component Mapping

The swizzled texel’s components are mapped to a density value:

\(densityValue_{xy} = (C'_{r},C'_{g})\)

16.3. Fragment Area Conversion

Fragment area for the framebuffer region is undefined if the density fetched is not a normalized floating-point value greater than 0.0. Otherwise, the fetched fragment area for that region is derived as:

\(fragmentArea_{wh} = \frac{1.0}{densityValue_{xy}}\)

16.3.1. Fragment Area Filter

Optionally, the implementation may fetch additional density map texels in an implementation defined window around (i,j). The texels follow the standard conversion steps up to and including fragment area conversion.

A single fetched fragment area for the framebuffer region is chosen by the implementation and must have an area between the min and max areas of the fetched set.

16.3.2. Fragment Area Clamp

The implementation may clamp the fetched fragment area to one that it supports. The clamped fragment area must have a size less than or equal to the original fetched value. Implementations may vary the supported set of fragment areas per framebuffer region. Fragment area (1,1) must always be in the supported set.

Note

For example, if the fetched fragment area is (1,4) but the implementation only supports areas of {(1,1),(2,2)}, it could choose to clamp the area to (2,2) since it has the same size as (1,4). While this would produce fragments that have lower quality strictly in the x-axis, the overall density is maintained.

The clamped fragment area is assigned to the corresponding framebuffer region.