1// Copyright 2018-2021 The Khronos Group, Inc. 2// 3// SPDX-License-Identifier: CC-BY-4.0 4 5[[fragmentdensitymapops]] 6= Fragment Density Map Operations 7 8== Fragment Density Map Operations Overview 9 10When a fragment is generated in a render pass that has a fragment density 11map attachment, its area is determined by the properties of the local 12framebuffer region that the fragment occupies. 13The framebuffer is divided into a uniform grid of these local regions, and 14their fragment area property is derived from the density map with the 15following operations: 16 17 * <<fragmentdensitymap-fetch-density-value,Fetch density value>> 18 ** <<fragmentdensitymap-component-swizzle,Component swizzle>> 19 ** <<fragmentdensitymap-component-mapping,Component mapping>> 20 * <<fragmentdensitymap-conversion-to-fragment-area,Fragment area 21 conversion>> 22 ** <<fragmentdensitymap-fragment-area-filter,Fragment area filter>> 23 ** <<fragmentdensitymap-fragment-area-clamp,Fragment area clamp>> 24 25 26[[fragmentdensitymap-fetch-density-value]] 27== Fetch Density Value 28 29Each local framebuffer region at center coordinate [eq]#(x,y)# fetches a 30texel from the fragment density map at integer coordinates: 31 32 {empty}:: latexmath:[i = 33 \left\lfloor{\frac{x}{fragmentDensityTexelSize_{width}}}\right\rfloor] 34 {empty}:: latexmath:[j = 35 \left\lfloor{\frac{y}{fragmentDensityTexelSize_{height}}}\right\rfloor] 36 37Where the size of each region in the framebuffer is: 38 39 {empty}:: latexmath:[fragmentDensityTexelSize'_{width} = 40 {2^{\lceil{\log_2(\frac{framebuffer_{width}}{fragmentDensityMap_{width}})}\rceil}}] 41 {empty}:: latexmath:[fragmentDensityTexelSize'_{height} = 42 {2^{\lceil{\log_2(\frac{framebuffer_{height}}{fragmentDensityMap_{height}})}\rceil}}] 43 44This region is subject to the limits in 45sname:VkPhysicalDeviceFragmentDensityMapPropertiesEXT and therefore the 46final region size is clamped: 47 48 {empty}:: latexmath:[fragmentDensityTexelSize_{width} = 49 \mathbin{clamp}(fragmentDensityTexelSize'_{width},minFragmentDensityTexelSize_{width},maxFragmentDensityTexelSize_{width})] 50 {empty}:: latexmath:[fragmentDensityTexelSize_{height} = 51 \mathbin{clamp}(fragmentDensityTexelSize'_{height},minFragmentDensityTexelSize_{height},maxFragmentDensityTexelSize_{height})] 52 53When multiview is enabled for the render pass and the fragment density map 54attachment view was created with pname:layerCount greater than `1`, the 55density map layer that the texel is fetched from is: 56 57 {empty}:: latexmath:[layer = baseArrayLayer + ViewIndex] 58 59Otherwise: 60 61 {empty}:: latexmath:[layer = baseArrayLayer] 62 63The texel fetched from the density map at [eq]#(i,j,layer)# is next 64converted to density with the following operations. 65 66 67[[fragmentdensitymap-component-swizzle]] 68=== Component Swizzle 69 70The pname:components member of slink:VkImageViewCreateInfo is applied to the 71fetched texel as defined in <<textures-component-swizzle,Image component 72swizzle>>. 73 74 75[[fragmentdensitymap-component-mapping]] 76=== Component Mapping 77 78The swizzled texel's components are mapped to a density value: 79 80 {empty}:: latexmath:[densityValue_{xy} = (C'_{r},C'_{g})] 81 82 83[[fragmentdensitymap-conversion-to-fragment-area]] 84== Fragment Area Conversion 85 86Fragment area for the framebuffer region is undefined: if the density 87fetched is not a normalized floating-point value greater than `0.0`. 88Otherwise, the fetched fragment area for that region is derived as: 89 90 {empty}:: latexmath:[fragmentArea_{wh} = \frac{1.0}{densityValue_{xy}}] 91 92 93[[fragmentdensitymap-fragment-area-filter]] 94=== Fragment Area Filter 95 96Optionally, the implementation may: fetch additional density map texels in 97an implementation defined window around [eq]#(i,j)#. 98The texels follow the standard conversion steps up to and including 99<<fragmentdensitymap-conversion-to-fragment-area,fragment area conversion>>. 100 101A single fetched fragment area for the framebuffer region is chosen by the 102implementation and must: have an area between the _min_ and _max_ areas of 103the fetched set. 104 105 106[[fragmentdensitymap-fragment-area-clamp]] 107=== Fragment Area Clamp 108 109The implementation may: clamp the fetched fragment area to one that it 110supports. 111The clamped fragment area must: have a size less than or equal to the 112original fetched value. 113Implementations may: vary the supported set of fragment areas per 114framebuffer region. 115Fragment area [eq]#(1,1)# must: always be in the supported set. 116 117[NOTE] 118.Note 119==== 120For example, if the fetched fragment area is [eq]#(1,4)# but the 121implementation only supports areas of [eq]#{(1,1),(2,2)}#, it could choose 122to clamp the area to [eq]#(2,2)# since it has the same size as [eq]#(1,4)#. 123While this would produce fragments that have lower quality strictly in the 124x-axis, the overall density is maintained. 125==== 126 127The clamped fragment area is assigned to the corresponding framebuffer 128region. 129