1e5c31af7Sopenharmony_ci// Copyright 2018-2024 The Khronos Group Inc. 2e5c31af7Sopenharmony_ci// 3e5c31af7Sopenharmony_ci// SPDX-License-Identifier: CC-BY-4.0 4e5c31af7Sopenharmony_ci 5e5c31af7Sopenharmony_ci[[fragmentdensitymapops]] 6e5c31af7Sopenharmony_ci= Fragment Density Map Operations 7e5c31af7Sopenharmony_ci 8e5c31af7Sopenharmony_ci 9e5c31af7Sopenharmony_ci== Fragment Density Map Operations Overview 10e5c31af7Sopenharmony_ci 11e5c31af7Sopenharmony_ciWhen a fragment is generated in a render pass that has a fragment density 12e5c31af7Sopenharmony_cimap attachment, its area is determined by the properties of the local 13e5c31af7Sopenharmony_ciframebuffer region that the fragment occupies. 14e5c31af7Sopenharmony_ciThe framebuffer is divided into a uniform grid of these local regions, and 15e5c31af7Sopenharmony_citheir fragment area property is derived from the density map with the 16e5c31af7Sopenharmony_cifollowing operations: 17e5c31af7Sopenharmony_ci 18e5c31af7Sopenharmony_ci * <<fragmentdensitymap-fetch-density-value,Fetch density value>> 19e5c31af7Sopenharmony_ci ** <<fragmentdensitymap-component-swizzle,Component swizzle>> 20e5c31af7Sopenharmony_ci ** <<fragmentdensitymap-component-mapping,Component mapping>> 21e5c31af7Sopenharmony_ci * <<fragmentdensitymap-conversion-to-fragment-area,Fragment area 22e5c31af7Sopenharmony_ci conversion>> 23e5c31af7Sopenharmony_ci ** <<fragmentdensitymap-fragment-area-filter,Fragment area filter>> 24e5c31af7Sopenharmony_ci ** <<fragmentdensitymap-fragment-area-clamp,Fragment area clamp>> 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci[[fragmentdensitymap-fetch-density-value]] 28e5c31af7Sopenharmony_ci== Fetch Density Value 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ciifndef::VK_QCOM_fragment_density_map_offset[] 31e5c31af7Sopenharmony_ciEach local framebuffer region at center coordinate [eq]#(x,y)# fetches a 32e5c31af7Sopenharmony_citexel from the fragment density map at integer coordinates: 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci {empty}:: latexmath:[i = 35e5c31af7Sopenharmony_ci \left\lfloor{\frac{x}{fragmentDensityTexelSize_{width}}}\right\rfloor] 36e5c31af7Sopenharmony_ci {empty}:: latexmath:[j = 37e5c31af7Sopenharmony_ci \left\lfloor{\frac{y}{fragmentDensityTexelSize_{height}}}\right\rfloor] 38e5c31af7Sopenharmony_ciendif::VK_QCOM_fragment_density_map_offset[] 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ciifdef::VK_QCOM_fragment_density_map_offset[] 41e5c31af7Sopenharmony_ciEach local framebuffer region at center coordinate [eq]#(x,y)# fetches a 42e5c31af7Sopenharmony_citexel from the fragment density map. 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ciFirst, the local framebuffer region center coordinate [eq]#(x,y)# is offset 45e5c31af7Sopenharmony_ciby the value specified in 46e5c31af7Sopenharmony_cislink:VkSubpassFragmentDensityMapOffsetEndInfoQCOM. 47e5c31af7Sopenharmony_ciIf no offset is specified, then the default offset [eq]#(0,0)# is used. 48e5c31af7Sopenharmony_ciThe offsetted coordinate [eq]#(x',y')# is computed as follows: 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ci[latexmath] 51e5c31af7Sopenharmony_ci[latexmath] 52e5c31af7Sopenharmony_ci++++++++++++++++++++++++ 53e5c31af7Sopenharmony_ci\begin{aligned} 54e5c31af7Sopenharmony_cix' &= \mathbin{clamp}(x + pFragmentDensityOffsets[layer]_{x}, 0, framebuffer_{width} - 1) \\ 55e5c31af7Sopenharmony_ciy' &= \mathbin{clamp}(y + pFragmentDensityOffsets[layer]_{y}, 0, framebuffer_{height} - 1) \\ 56e5c31af7Sopenharmony_ci\end{aligned} 57e5c31af7Sopenharmony_ci++++++++++++++++++++++++ 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ciThe offsetted coordinate [eq]#(x',y')# fetches a texel from the fragment 60e5c31af7Sopenharmony_cidensity map at integer coordinates: 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ci {empty}:: latexmath:[i = 63e5c31af7Sopenharmony_ci \left\lfloor{\frac{x'}{fragmentDensityTexelSize_{width}}}\right\rfloor] 64e5c31af7Sopenharmony_ci {empty}:: latexmath:[j = 65e5c31af7Sopenharmony_ci \left\lfloor{\frac{y'}{fragmentDensityTexelSize_{height}}}\right\rfloor] 66e5c31af7Sopenharmony_ciendif::VK_QCOM_fragment_density_map_offset[] 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ciWhere the size of each region in the framebuffer is: 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci {empty}:: latexmath:[fragmentDensityTexelSize'_{width} = 71e5c31af7Sopenharmony_ci {2^{\lceil{\log_2(\frac{framebuffer_{width}}{fragmentDensityMap_{width}})}\rceil}}] 72e5c31af7Sopenharmony_ci {empty}:: latexmath:[fragmentDensityTexelSize'_{height} = 73e5c31af7Sopenharmony_ci {2^{\lceil{\log_2(\frac{framebuffer_{height}}{fragmentDensityMap_{height}})}\rceil}}] 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ciThis region is subject to the limits in 76e5c31af7Sopenharmony_cisname:VkPhysicalDeviceFragmentDensityMapPropertiesEXT and therefore the 77e5c31af7Sopenharmony_cifinal region size is clamped: 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci {empty}:: latexmath:[fragmentDensityTexelSize_{width} = 80e5c31af7Sopenharmony_ci \mathbin{clamp}(fragmentDensityTexelSize'_{width},minFragmentDensityTexelSize_{width},maxFragmentDensityTexelSize_{width})] 81e5c31af7Sopenharmony_ci {empty}:: latexmath:[fragmentDensityTexelSize_{height} = 82e5c31af7Sopenharmony_ci \mathbin{clamp}(fragmentDensityTexelSize'_{height},minFragmentDensityTexelSize_{height},maxFragmentDensityTexelSize_{height})] 83e5c31af7Sopenharmony_ci 84e5c31af7Sopenharmony_ciWhen multiview is enabled for the render pass and the fragment density map 85e5c31af7Sopenharmony_ciattachment view was created with pname:layerCount greater than `1`, the 86e5c31af7Sopenharmony_cilayer used for offsets and for fetching from the fragment density map is: 87e5c31af7Sopenharmony_ci 88e5c31af7Sopenharmony_ci {empty}:: latexmath:[layer = baseArrayLayer + ViewIndex] 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ciOtherwise: 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ci {empty}:: latexmath:[layer = baseArrayLayer] 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ciThe texel fetched from the density map at [eq]#(i,j,layer)# is next 95e5c31af7Sopenharmony_ciconverted to density with the following operations. 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci[[fragmentdensitymap-component-swizzle]] 99e5c31af7Sopenharmony_ci=== Component Swizzle 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_ciThe pname:components member of slink:VkImageViewCreateInfo is applied to the 102e5c31af7Sopenharmony_cifetched texel as defined in <<textures-component-swizzle,Image component 103e5c31af7Sopenharmony_ciswizzle>>. 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ci[[fragmentdensitymap-component-mapping]] 107e5c31af7Sopenharmony_ci=== Component Mapping 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ciThe swizzled texel's components are mapped to a density value: 110e5c31af7Sopenharmony_ci 111e5c31af7Sopenharmony_ci {empty}:: latexmath:[densityValue_{xy} = (C'_{r},C'_{g})] 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ci[[fragmentdensitymap-conversion-to-fragment-area]] 115e5c31af7Sopenharmony_ci== Fragment Area Conversion 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ciFragment area for the framebuffer region is undefined: if the density 118e5c31af7Sopenharmony_cifetched is not a normalized floating-point value greater than `0.0`. 119e5c31af7Sopenharmony_ciOtherwise, the fetched fragment area for that region is derived as: 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci {empty}:: latexmath:[fragmentArea_{wh} = \frac{1.0}{densityValue_{xy}}] 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci[[fragmentdensitymap-fragment-area-filter]] 125e5c31af7Sopenharmony_ci=== Fragment Area Filter 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ciOptionally, the implementation may: fetch additional density map texels in 128e5c31af7Sopenharmony_cian implementation defined window around [eq]#(i,j)#. 129e5c31af7Sopenharmony_ciThe texels follow the standard conversion steps up to and including 130e5c31af7Sopenharmony_ci<<fragmentdensitymap-conversion-to-fragment-area,fragment area conversion>>. 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ciA single fetched fragment area for the framebuffer region is chosen by the 133e5c31af7Sopenharmony_ciimplementation and must: have an area between the _min_ and _max_ areas of 134e5c31af7Sopenharmony_cithe fetched set. 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci[[fragmentdensitymap-fragment-area-clamp]] 138e5c31af7Sopenharmony_ci=== Fragment Area Clamp 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ciThe implementation may: clamp the fetched fragment area to one that it 141e5c31af7Sopenharmony_cisupports. 142e5c31af7Sopenharmony_ciThe clamped fragment area must: have a size less than or equal to the 143e5c31af7Sopenharmony_cioriginal fetched value. 144e5c31af7Sopenharmony_ciImplementations may: vary the supported set of fragment areas per 145e5c31af7Sopenharmony_ciframebuffer region. 146e5c31af7Sopenharmony_ciFragment area [eq]#(1,1)# must: always be in the supported set. 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci[NOTE] 149e5c31af7Sopenharmony_ci.Note 150e5c31af7Sopenharmony_ci==== 151e5c31af7Sopenharmony_ciFor example, if the fetched fragment area is [eq]#(1,4)# but the 152e5c31af7Sopenharmony_ciimplementation only supports areas of [eq]#{(1,1),(2,2)}#, it could choose 153e5c31af7Sopenharmony_cito clamp the area to [eq]#(2,2)# since it has the same size as [eq]#(1,4)#. 154e5c31af7Sopenharmony_ciWhile this would produce fragments that have lower quality strictly in the 155e5c31af7Sopenharmony_cix-axis, the overall density is maintained. 156e5c31af7Sopenharmony_ci==== 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_ciThe clamped fragment area is assigned to the corresponding framebuffer 159e5c31af7Sopenharmony_ciregion. 160