textures.txt
1 // Copyright (c) 2015-2019 Khronos Group. This work is licensed under a 2 // Creative Commons Attribution 4.0 International License; see 3 // http://creativecommons.org/licenses/by/4.0/ 4 5 [[textures]] 6 = Image Operations 7 8 == Image Operations Overview 9 10 Vulkan Image Operations are operations performed by those SPIR-V Image 11 Instructions which take an code:OpTypeImage (representing a 12 sname:VkImageView) or code:OpTypeSampledImage (representing a 13 (sname:VkImageView, sname:VkSampler) pair) and texel coordinates as 14 operands, and return a value based on one or more neighboring texture 15 elements (_texels_) in the image. 16 17 [NOTE] 18 .Note 19 ==== 20 Texel is a term which is a combination of the words texture and element. 21 Early interactive computer graphics supported texture operations on 22 textures, a small subset of the image operations on images described here. 23 The discrete samples remain essentially equivalent, however, so we retain 24 the historical term texel to refer to them. 25 ==== 26 27 Image Operations include the functionality of the following SPIR-V Image 28 Instructions: 29 30 * code:OpImageSample* and code:OpImageSparseSample* read one or more 31 neighboring texels of the image, and <<textures-texel-filtering,filter>> 32 the texel values based on the state of the sampler. 33 ** Instructions with code:ImplicitLod in the name 34 <<textures-level-of-detail-operation,determine>> the LOD used in the 35 sampling operation based on the coordinates used in neighboring 36 fragments. 37 ** Instructions with code:ExplicitLod in the name 38 <<textures-level-of-detail-operation,determine>> the LOD used in the 39 sampling operation based on additional coordinates. 40 ** Instructions with code:Proj in the name apply homogeneous 41 <<textures-projection,projection>> to the coordinates. 42 * code:OpImageFetch and code:OpImageSparseFetch return a single texel of 43 the image. 44 No sampler is used. 45 * code:OpImage*code:Gather and code:OpImageSparse*code:Gather read 46 neighboring texels and <<textures-gather,return a single component>> of 47 each. 48 * code:OpImageRead (and code:OpImageSparseRead) and code:OpImageWrite read 49 and write, respectively, a texel in the image. 50 No sampler is used. 51 ifdef::VK_NV_shader_image_footprint[] 52 * code:OpImageSampleFootprintNV identifies and returns information about 53 the set of texels in the image that would be accessed by an equivalent 54 code:OpImageSample* instruction. 55 endif::VK_NV_shader_image_footprint[] 56 * Instructions with code:Dref in the name apply 57 <<textures-depth-compare-operation,depth comparison>> on the texel 58 values. 59 * Instructions with code:Sparse in the name additionally return a 60 <<textures-sparse-residency,sparse residency>> code. 61 62 [[textures-texel-coordinate-systems]] 63 === Texel Coordinate Systems 64 65 Images are addressed by _texel coordinates_. 66 There are three _texel coordinate systems_: 67 68 * normalized texel coordinates [eq]#[0.0, 1.0]# 69 * unnormalized texel coordinates [eq]#[0.0, width / height / depth)# 70 * integer texel coordinates [eq]#[0, width / height / depth)# 71 72 SPIR-V code:OpImageFetch, code:OpImageSparseFetch, code:OpImageRead, 73 code:OpImageSparseRead, and code:OpImageWrite instructions use integer texel 74 coordinates. 75 Other image instructions can: use either normalized or unnormalized texel 76 coordinates (selected by the pname:unnormalizedCoordinates state of the 77 sampler used in the instruction), but there are 78 <<samplers-unnormalizedCoordinates,limitations>> on what operations, image 79 state, and sampler state is supported. 80 Normalized coordinates are logically 81 <<textures-normalized-to-unnormalized,converted>> to unnormalized as part of 82 image operations, and <<textures-normalized-operations,certain steps>> are 83 only performed on normalized coordinates. 84 The array layer coordinate is always treated as unnormalized even when other 85 coordinates are normalized. 86 87 Normalized texel coordinates are referred to as [eq]#(s,t,r,q,a)#, with the 88 coordinates having the following meanings: 89 90 * [eq]#s#: Coordinate in the first dimension of an image. 91 * [eq]#t#: Coordinate in the second dimension of an image. 92 * [eq]#r#: Coordinate in the third dimension of an image. 93 ** [eq]#(s,t,r)# are interpreted as a direction vector for Cube images. 94 * [eq]#q#: Fourth coordinate, for homogeneous (projective) coordinates. 95 * [eq]#a#: Coordinate for array layer. 96 97 The coordinates are extracted from the SPIR-V operand based on the 98 dimensionality of the image variable and type of instruction. 99 For code:Proj instructions, the components are in order [eq]#(s [,t] [,r] 100 q)#, with [eq]#t# and [eq]#r# being conditionally present based on the 101 code:Dim of the image. 102 For non-code:Proj instructions, the coordinates are [eq]#(s [,t] [,r] 103 [,a])#, with [eq]#t# and [eq]#r# being conditionally present based on the 104 code:Dim of the image and [eq]#a# being conditionally present based on the 105 code:Arrayed property of the image. 106 Projective image instructions are not supported on code:Arrayed images. 107 108 Unnormalized texel coordinates are referred to as [eq]#(u,v,w,a)#, with the 109 coordinates having the following meanings: 110 111 * [eq]#u#: Coordinate in the first dimension of an image. 112 * [eq]#v#: Coordinate in the second dimension of an image. 113 * [eq]#w#: Coordinate in the third dimension of an image. 114 * [eq]#a#: Coordinate for array layer. 115 116 Only the [eq]#u# and [eq]#v# coordinates are directly extracted from the 117 SPIR-V operand, because only 1D and 2D (non-code:Arrayed) dimensionalities 118 support unnormalized coordinates. 119 The components are in order [eq]#(u [,v])#, with [eq]#v# being conditionally 120 present when the dimensionality is 2D. 121 When normalized coordinates are converted to unnormalized coordinates, all 122 four coordinates are used. 123 124 Integer texel coordinates are referred to as [eq]#(i,j,k,l,n)#, with the 125 coordinates having the following meanings: 126 127 * [eq]#i#: Coordinate in the first dimension of an image. 128 * [eq]#j#: Coordinate in the second dimension of an image. 129 * [eq]#k#: Coordinate in the third dimension of an image. 130 * [eq]#l#: Coordinate for array layer. 131 * [eq]#n#: Coordinate for the sample index. 132 133 They are extracted from the SPIR-V operand in order [eq]#(i, [,j], [,k], 134 [,l])#, with [eq]#j# and [eq]#k# conditionally present based on the code:Dim 135 of the image, and [eq]#l# conditionally present based on the code:Arrayed 136 property of the image. 137 [eq]#n# is conditionally present and is taken from the code:Sample image 138 operand. 139 140 For all coordinate types, unused coordinates are assigned a value of zero. 141 142 [[textures-texel-coordinate-systems-diagrams]] 143 image::{images}/vulkantexture0-ll.svg[align="center",title="Texel Coordinate Systems, Linear Filtering",opts="{imageopts}"] 144 The Texel Coordinate Systems - For the example shown of an 8{times}4 texel 145 two dimensional image. 146 147 * Normalized texel coordinates: 148 ** The [eq]#s# coordinate goes from 0.0 to 1.0. 149 ** The [eq]#t# coordinate goes from 0.0 to 1.0. 150 * Unnormalized texel coordinates: 151 ** The [eq]#u# coordinate within the range 0.0 to 8.0 is within the image, 152 otherwise it is outside the image. 153 ** The [eq]#v# coordinate within the range 0.0 to 4.0 is within the image, 154 otherwise it is outside the image. 155 * Integer texel coordinates: 156 ** The [eq]#i# coordinate within the range 0 to 7 addresses texels within 157 the image, otherwise it is outside the image. 158 ** The [eq]#j# coordinate within the range 0 to 3 addresses texels within 159 the image, otherwise it outside the image. 160 * Also shown for linear filtering: 161 ** Given the unnormalized coordinates [eq]#(u,v)#, the four texels 162 selected are [eq]#i~0~j~0~#, [eq]#i~1~j~0~#, [eq]#i~0~j~1~#, and 163 [eq]#i~1~j~1~#. 164 ** The fractions [eq]#{alpha}# and [eq]#{beta}#. 165 ** Given the offset [eq]#{DeltaUpper}~i~# and [eq]#{DeltaUpper}~j~#, the 166 four texels selected by the offset are [eq]#i~0~j'~0~#, 167 [eq]#i~1~j'~0~#, [eq]#i~0~j'~1~#, and [eq]#i~1~j'~1~#. 168 169 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 170 [NOTE] 171 .Note 172 ==== 173 For formats with reduced-resolution channels, [eq]#{DeltaUpper}~i~# and 174 [eq]#{DeltaUpper}~j~# are relative to the resolution of the 175 highest-resolution channel, and therefore may be divided by two relative to 176 the unnormalized coordinate space of the lower-resolution channels. 177 ==== 178 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 179 180 image::{images}/vulkantexture1-ll.svg[align="center",title="Texel Coordinate Systems, Nearest Filtering",opts="{imageopts}"] 181 182 The Texel Coordinate Systems - For the example shown of an 8{times}4 texel 183 two dimensional image. 184 185 * Texel coordinates as above. 186 Also shown for nearest filtering: 187 ** Given the unnormalized coordinates [eq]#(u,v)#, the texel selected is 188 [eq]#ij#. 189 ** Given the offset [eq]#{DeltaUpper}~i~# and [eq]#{DeltaUpper}~j~#, the 190 texel selected by the offset is [eq]#ij'#. 191 192 ifdef::VK_NV_corner_sampled_image[] 193 For corner-sampled images, the texel samples are located at the grid 194 intersections instead of the texel centers. 195 196 image::{images}/vulkantexture0-corner-alternative-a-ll.svg[align="center",title="Texel Coordinate Systems, Corner Sampling",opts="{imageopts}"] 197 198 endif::VK_NV_corner_sampled_image[] 199 200 == Conversion Formulas 201 202 ifdef::editing-notes[] 203 [NOTE] 204 .editing-note 205 ==== 206 (Bill) These Conversion Formulas will likely move to Section 2.7 Fixed-Point 207 Data Conversions (RGB to sRGB and sRGB to RGB) and section 2.6 Numeric 208 Representation and Computation (RGB to Shared Exponent and Shared Exponent 209 to RGB) 210 ==== 211 endif::editing-notes[] 212 213 [[textures-RGB-sexp]] 214 === RGB to Shared Exponent Conversion 215 216 An RGB color [eq]#(red, green, blue)# is transformed to a shared exponent 217 color [eq]#(red~shared~, green~shared~, blue~shared~, exp~shared~)# as 218 follows: 219 220 First, the components [eq]#(red, green, blue)# are clamped to 221 [eq]#(red~clamped~, green~clamped~, blue~clamped~)# as: 222 223 :: [eq]#red~clamped~ = max(0, min(sharedexp~max~, red))# 224 :: [eq]#green~clamped~ = max(0, min(sharedexp~max~, green))# 225 :: [eq]#blue~clamped~ = max(0, min(sharedexp~max~, blue))# 226 227 where: 228 229 [latexmath] 230 +++++++++++++++++++ 231 \begin{aligned} 232 N & = 9 & \text{number of mantissa bits per component} \\ 233 B & = 15 & \text{exponent bias} \\ 234 E_{max} & = 31 & \text{maximum possible biased exponent value} \\ 235 sharedexp_{max} & = \frac{(2^N-1)}{2^N} \times 2^{(E_{max}-B)} 236 \end{aligned} 237 +++++++++++++++++++ 238 239 [NOTE] 240 .Note 241 ==== 242 [eq]#NaN#, if supported, is handled as in <<ieee-754,IEEE 754-2008>> 243 `minNum()` and `maxNum()`. 244 That is the result is a [eq]#NaN# is mapped to zero. 245 ==== 246 247 The largest clamped component, [eq]#max~clamped~# is determined: 248 249 :: [eq]#max~clamped~ = max(red~clamped~, green~clamped~, blue~clamped~)# 250 251 A preliminary shared exponent [eq]#exp'# is computed: 252 [latexmath] 253 +++++++++++++++++++ 254 \begin{aligned} 255 exp' = 256 \begin{cases} 257 \left \lfloor \log_2(max_{clamped}) \right \rfloor + (B+1) 258 & \text{for}\ max_{clamped} > 2^{-(B+1)} \\ 259 0 260 & \text{for}\ max_{clamped} \leq 2^{-(B+1)} 261 \end{cases} 262 \end{aligned} 263 +++++++++++++++++++ 264 265 The shared exponent [eq]#exp~shared~# is computed: 266 267 [latexmath] 268 +++++++++++++++++++ 269 \begin{aligned} 270 max_{shared} = 271 \left \lfloor 272 { \frac{max_{clamped}}{2^{(exp'-B-N)}} + \frac{1}{2} } 273 \right \rfloor 274 \end{aligned} 275 +++++++++++++++++++ 276 277 [latexmath] 278 +++++++++++++++++++ 279 \begin{aligned} 280 exp_{shared} = 281 \begin{cases} 282 exp' & \text{for}\ 0 \leq max_{shared} < 2^N \\ 283 exp'+1 & \text{for}\ max_{shared} = 2^N 284 \end{cases} 285 \end{aligned} 286 +++++++++++++++++++ 287 288 Finally, three integer values in the range [eq]#0# to [eq]#2^N^# are 289 computed: 290 291 [latexmath] 292 +++++++++++++++++++ 293 \begin{aligned} 294 red_{shared} & = 295 \left \lfloor 296 { \frac{red_{clamped}}{2^{(exp_{shared}-B-N)}}+ \frac{1}{2} } 297 \right \rfloor \\ 298 green_{shared} & = 299 \left \lfloor 300 { \frac{green_{clamped}}{2^{(exp_{shared}-B-N)}}+ \frac{1}{2} } 301 \right \rfloor \\ 302 blue_{shared} & = 303 \left \lfloor 304 { \frac{blue_{clamped}}{2^{(exp_{shared}-B-N)}}+ \frac{1}{2} } 305 \right \rfloor 306 \end{aligned} 307 +++++++++++++++++++ 308 309 310 [[textures-sexp-RGB]] 311 === Shared Exponent to RGB 312 313 A shared exponent color [eq]#(red~shared~, green~shared~, blue~shared~, 314 exp~shared~)# is transformed to an RGB color [eq]#(red, green, blue)# as 315 follows: 316 317 :: latexmath:[red = red_{shared} \times {2^{(exp_{shared}-B-N)}}] 318 :: latexmath:[green = green_{shared} \times {2^{(exp_{shared}-B-N)}}] 319 :: latexmath:[blue = blue_{shared} \times {2^{(exp_{shared}-B-N)}}] 320 321 where: 322 323 :: [eq]#N = 9# (number of mantissa bits per component) 324 :: [eq]#B = 15# (exponent bias) 325 326 327 == Texel Input Operations 328 329 _Texel input instructions_ are SPIR-V image instructions that read from an 330 image. 331 _Texel input operations_ are a set of steps that are performed on state, 332 coordinates, and texel values while processing a texel input instruction, 333 and which are common to some or all texel input instructions. 334 They include the following steps, which are performed in the listed order: 335 336 * <<textures-input-validation,Validation operations>> 337 ** <<textures-operation-validation,Instruction/Sampler/Image validation>> 338 ** <<textures-integer-coordinate-validation,Coordinate validation>> 339 ** <<textures-sparse-validation,Sparse validation>> 340 ** <<textures-layout-validation,Layout validation>> 341 * <<textures-format-conversion,Format conversion>> 342 * <<textures-texel-replacement,Texel replacement>> 343 * <<textures-depth-compare-operation,Depth comparison>> 344 * <<textures-conversion-to-rgba,Conversion to RGBA>> 345 * <<textures-component-swizzle,Component swizzle>> 346 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 347 * <<textures-chroma-reconstruction,Chroma reconstruction>> 348 * <<textures-sampler-YCbCr-conversion,Y'C~B~C~R~ conversion>> 349 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 350 351 For texel input instructions involving multiple texels (for sampling or 352 gathering), these steps are applied for each texel that is used in the 353 instruction. 354 Depending on the type of image instruction, other steps are conditionally 355 performed between these steps or involving multiple coordinate or texel 356 values. 357 358 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 359 If <<textures-chroma-reconstruction,Chroma Reconstruction>> is implicit, 360 <<textures-texel-filtering, Texel Filtering>> instead takes place during 361 chroma reconstruction, before <<textures-sampler-YCbCr-conversion,sampler 362 Y'C~B~C~R~ conversion>> occurs. 363 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 364 365 366 [[textures-input-validation]] 367 === Texel Input Validation Operations 368 369 _Texel input validation operations_ inspect instruction/image/sampler state 370 or coordinates, and in certain circumstances cause the texel value to be 371 replaced or become undefined:. 372 There are a series of validations that the texel undergoes. 373 374 [[textures-operation-validation]] 375 ==== Instruction/Sampler/Image View Validation 376 377 There are a number of cases where a SPIR-V instruction can: mismatch with 378 the sampler, the image view, or both. 379 There are a number of cases where the sampler can: mismatch with the image 380 view. 381 In such cases the value of the texel returned is undefined:. 382 383 These cases include: 384 385 386 * The sampler pname:borderColor is an integer type and the image view 387 pname:format is not one of the elink:VkFormat integer types or a stencil 388 component of a depth/stencil format. 389 * The sampler pname:borderColor is a float type and the image view 390 pname:format is not one of the elink:VkFormat float types or a depth 391 component of a depth/stencil format. 392 * The sampler pname:borderColor is one of the opaque black colors 393 (ename:VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK or 394 ename:VK_BORDER_COLOR_INT_OPAQUE_BLACK) and the image view 395 elink:VkComponentSwizzle for any of the slink:VkComponentMapping 396 components is not ename:VK_COMPONENT_SWIZZLE_IDENTITY. 397 * The elink:VkImageLayout of any subresource in the image view does not 398 match that specified in slink:VkDescriptorImageInfo::pname:imageLayout 399 used to write the image descriptor. 400 * If the instruction is code:OpImageRead or code:OpImageSparseRead and the 401 pname:shaderStorageImageReadWithoutFormat feature is not enabled, or the 402 instruction is code:OpImageWrite and the 403 pname:shaderStorageImageWriteWithoutFormat feature is not enabled, then 404 the SPIR-V Image Format must: be <<spirvenv-image-formats,compatible>> 405 with the image view's pname:format. 406 * The sampler pname:unnormalizedCoordinates is ename:VK_TRUE and any of 407 the <<samplers-unnormalizedCoordinates,limitations of unnormalized 408 coordinates>> are violated. 409 ifdef::VK_EXT_fragment_density_map[] 410 * The sampler was created with pname:flags containing 411 ename:VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT and the image was not created 412 with pname:flags containing ename:VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT. 413 * The sampler was not created with pname:flags containing 414 ename:VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT and the image was created 415 with pname:flags containing ename:VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT. 416 * The sampler was created with pname:flags containing 417 ename:VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT and is used with a function 418 that is not code:OpImageSampleImplicitLod or 419 code:OpImageSampleExplicitLod, or is used with operands code:Offset or 420 code:ConstOffsets. 421 endif::VK_EXT_fragment_density_map[] 422 * The SPIR-V instruction is one of the code:OpImage*code:Dref* 423 instructions and the sampler pname:compareEnable is ename:VK_FALSE 424 * The SPIR-V instruction is not one of the code:OpImage*code:Dref* 425 instructions and the sampler pname:compareEnable is ename:VK_TRUE 426 * The SPIR-V instruction is one of the code:OpImage*code:Dref* 427 instructions and the image view pname:format is not one of the 428 depth/stencil formats with a depth component, or the image view aspect 429 is not ename:VK_IMAGE_ASPECT_DEPTH_BIT. 430 * The SPIR-V instruction's image variable's properties are not compatible 431 with the image view: 432 ** Rules for pname:viewType: 433 *** ename:VK_IMAGE_VIEW_TYPE_1D must: have code:Dim = 1D, code:Arrayed = 434 0, code:MS = 0. 435 *** ename:VK_IMAGE_VIEW_TYPE_2D must: have code:Dim = 2D, code:Arrayed = 436 0. 437 *** ename:VK_IMAGE_VIEW_TYPE_3D must: have code:Dim = 3D, code:Arrayed = 438 0, code:MS = 0. 439 *** ename:VK_IMAGE_VIEW_TYPE_CUBE must: have code:Dim = Cube, code:Arrayed 440 = 0, code:MS = 0. 441 *** ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY must: have code:Dim = 1D, 442 code:Arrayed = 1, code:MS = 0. 443 *** ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY must: have code:Dim = 2D, 444 code:Arrayed = 1. 445 *** ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY must: have code:Dim = Cube, 446 code:Arrayed = 1, code:MS = 0. 447 ** If the image was created with slink:VkImageCreateInfo::pname:samples 448 equal to ename:VK_SAMPLE_COUNT_1_BIT, the instruction must: have 449 code:MS = 0. 450 ** If the image was created with slink:VkImageCreateInfo::pname:samples 451 not equal to ename:VK_SAMPLE_COUNT_1_BIT, the instruction must: have 452 code:MS = 1. 453 ifdef::VK_NV_corner_sampled_image[] 454 * If the image was created with slink:VkImageCreateInfo::pname:flags 455 containing ename:VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV, the sampler 456 addressing modes must: only use a elink:VkSamplerAddressMode of 457 ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. 458 endif::VK_NV_corner_sampled_image[] 459 ifdef::VK_NV_shader_image_footprint[] 460 * The SPIR-V instruction is code:OpImageSampleFootprintNV with code:Dim = 461 2D and pname:addressModeU or pname:addressModeV in the sampler is not 462 ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. 463 * The SPIR-V instruction is code:OpImageSampleFootprintNV with code:Dim = 464 3D and pname:addressModeU, pname:addressModeV, or pname:addressModeW in 465 the sampler is not ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. 466 endif::VK_NV_shader_image_footprint[] 467 468 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 469 Only code:OpImageSample* and code:OpImageSparseSample* can: be used with a 470 sampler that enables <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ 471 conversion>>. 472 473 code:OpImageFetch, code:OpImageSparseFetch, code:OpImage*code:Gather, and 474 code:OpImageSparse*code:Gather must: not be used with a sampler that enables 475 <<samplers-YCbCr-conversion,sampler Y\'C~B~C~R~ conversion>>. 476 477 The code:ConstOffset and code:Offset operands must: not be used with a 478 sampler that enables <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ 479 conversion>>. 480 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 481 482 483 [[textures-integer-coordinate-validation]] 484 ==== Integer Texel Coordinate Validation 485 486 Integer texel coordinates are validated against the size of the image level, 487 and the number of layers and number of samples in the image. 488 For SPIR-V instructions that use integer texel coordinates, this is 489 performed directly on the integer coordinates. 490 For instructions that use normalized or unnormalized texel coordinates, this 491 is performed on the coordinates that result after 492 <<textures-unnormalized-to-integer,conversion>> to integer texel 493 coordinates. 494 495 If the integer texel coordinates do not satisfy all of the conditions 496 497 :: [eq]#0 {leq} i < w~s~# 498 :: [eq]#0 {leq} j < h~s~# 499 :: [eq]#0 {leq} k < d~s~# 500 :: [eq]#0 {leq} l < layers# 501 :: [eq]#0 {leq} n < samples# 502 503 where: 504 505 :: [eq]#w~s~ =# width of the image level 506 :: [eq]#h~s~ =# height of the image level 507 :: [eq]#d~s~ =# depth of the image level 508 :: [eq]#layers =# number of layers in the image 509 :: [eq]#samples =# number of samples per texel in the image 510 511 then the texel fails integer texel coordinate validation. 512 513 There are four cases to consider: 514 515 . Valid Texel Coordinates 516 + 517 * If the texel coordinates pass validation (that is, the coordinates lie 518 within the image), 519 + 520 then the texel value comes from the value in image memory. 521 522 . Border Texel 523 + 524 * If the texel coordinates fail validation, and 525 * If the read is the result of an image sample instruction or image gather 526 instruction, and 527 * If the image is not a cube image, 528 + 529 then the texel is a border texel and <<textures-texel-replacement,texel 530 replacement>> is performed. 531 532 . Invalid Texel 533 + 534 * If the texel coordinates fail validation, and 535 * If the read is the result of an image fetch instruction, image read 536 instruction, or atomic instruction, 537 + 538 then the texel is an invalid texel and <<textures-texel-replacement,texel 539 replacement>> is performed. 540 541 . Cube Map Edge or Corner 542 + 543 Otherwise the texel coordinates lie beyond the edges or corners of the 544 selected cube map face, and <<textures-cubemapedge, Cube map edge handling>> 545 is performed. 546 547 548 [[textures-cubemapedge]] 549 ==== Cube Map Edge Handling 550 551 If the texel coordinates lie beyond the edges or corners of the selected 552 cube map face, the following steps are performed. 553 Note that this does not occur when using ename:VK_FILTER_NEAREST filtering 554 within a mip level, since ename:VK_FILTER_NEAREST is treated as using 555 ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. 556 557 * Cube Map Edge Texel 558 + 559 ** If the texel lies beyond the selected cube map face in either only 560 [eq]#i# or only [eq]#j#, then the coordinates [eq]#(i,j)# and the array 561 layer [eq]#l# are transformed to select the adjacent texel from the 562 appropriate neighboring face. 563 564 * Cube Map Corner Texel 565 + 566 ** If the texel lies beyond the selected cube map face in both [eq]#i# and 567 [eq]#j#, then there is no unique neighboring face from which to read 568 that texel. 569 The texel should: be replaced by the average of the three values of the 570 adjacent texels in each incident face. 571 However, implementations may: replace the cube map corner texel by 572 other methods. 573 ifndef::VK_EXT_filter_cubic[] 574 The methods are subject to the constraint that if the three available texels 575 have the same value, the resulting filtered texel must: have that value. 576 endif::VK_EXT_filter_cubic[] 577 ifdef::VK_EXT_filter_cubic[] 578 The methods are subject to the constraint that for linear filtering if the 579 three available texels have the same value, the resulting filtered texel 580 must: have that value, and for cubic filtering if the twelve available 581 samples have the same value, the resulting filtered texel must: have that 582 value. 583 endif::VK_EXT_filter_cubic[] 584 585 [[textures-sparse-validation]] 586 ==== Sparse Validation 587 588 If the texel reads from an unbound region of a sparse image, the texel is a 589 _sparse unbound texel_, and processing continues with 590 <<textures-texel-replacement,texel replacement>>. 591 592 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 593 594 [[textures-layout-validation]] 595 ==== Layout Validation 596 597 If all planes of a _disjoint_ _multi-planar_ image are not in the same 598 <<resources-image-layouts,image layout>>, the image must: not be sampled 599 with <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ conversion>> enabled. 600 601 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 602 603 [[textures-format-conversion]] 604 === Format Conversion 605 606 Texels undergo a format conversion from the elink:VkFormat of the image view 607 to a vector of either floating point or signed or unsigned integer 608 components, with the number of components based on the number of components 609 present in the format. 610 611 * Color formats have one, two, three, or four components, according to the 612 format. 613 * Depth/stencil formats are one component. 614 The depth or stencil component is selected by the pname:aspectMask of 615 the image view. 616 617 Each component is converted based on its type and size (as defined in the 618 <<formats-definition,Format Definition>> section for each elink:VkFormat), 619 using the appropriate equations in <<fundamentals-fp16,16-Bit Floating-Point 620 Numbers>>, <<fundamentals-fp11,Unsigned 11-Bit Floating-Point Numbers>>, 621 <<fundamentals-fp10,Unsigned 10-Bit Floating-Point Numbers>>, 622 <<fundamentals-fixedconv,Fixed-Point Data Conversion>>, and 623 <<textures-sexp-RGB,Shared Exponent to RGB>>. 624 Signed integer components smaller than 32 bits are sign-extended. 625 626 If the image view format is sRGB, the color components are first converted 627 as if they are UNORM, and then sRGB to linear conversion is applied to the 628 R, G, and B components as described in the "`sRGB EOTF`" section of the 629 <<data-format,Khronos Data Format Specification>>. 630 The A component, if present, is unchanged. 631 632 If the image view format is block-compressed, then the texel value is first 633 decoded, then converted based on the type and number of components defined 634 by the compressed format. 635 636 637 [[textures-texel-replacement]] 638 === Texel Replacement 639 640 A texel is replaced if it is one (and only one) of: 641 642 * a border texel, 643 * an invalid texel, or 644 * a sparse unbound texel. 645 646 Border texels are replaced with a value based on the image format and the 647 pname:borderColor of the sampler. 648 The border color is: 649 650 [[textures-border-replacement-color]] 651 .Border Color [eq]#B# 652 [options="header",cols="60%,40%"] 653 |==== 654 | Sampler pname:borderColor | Corresponding Border Color 655 | ename:VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK | [eq]#[B~r~, B~g~, B~b~, B~a~] = [0.0, 0.0, 0.0, 0.0]# 656 | ename:VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK | [eq]#[B~r~, B~g~, B~b~, B~a~] = [0.0, 0.0, 0.0, 1.0]# 657 | ename:VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE | [eq]#[B~r~, B~g~, B~b~, B~a~] = [1.0, 1.0, 1.0, 1.0]# 658 | ename:VK_BORDER_COLOR_INT_TRANSPARENT_BLACK | [eq]#[B~r~, B~g~, B~b~, B~a~] = [0, 0, 0, 0]# 659 | ename:VK_BORDER_COLOR_INT_OPAQUE_BLACK | [eq]#[B~r~, B~g~, B~b~, B~a~] = [0, 0, 0, 1]# 660 | ename:VK_BORDER_COLOR_INT_OPAQUE_WHITE | [eq]#[B~r~, B~g~, B~b~, B~a~] = [1, 1, 1, 1]# 661 |==== 662 663 [NOTE] 664 .Note 665 ==== 666 The names etext:VK_BORDER_COLOR_*\_TRANSPARENT_BLACK, 667 etext:VK_BORDER_COLOR_*\_OPAQUE_BLACK, and 668 etext:VK_BORDER_COLOR_*_OPAQUE_WHITE are meant to describe which components 669 are zeros and ones in the vocabulary of compositing, and are not meant to 670 imply that the numerical value of ename:VK_BORDER_COLOR_INT_OPAQUE_WHITE is 671 a saturating value for integers. 672 ==== 673 674 This is substituted for the texel value by replacing the number of 675 components in the image format 676 677 [[textures-border-replacement-table]] 678 .Border Texel Components After Replacement 679 [width="100%",options="header"] 680 |==== 681 | Texel Aspect or Format | Component Assignment 682 | Depth aspect | [eq]#D = B~r~# 683 | Stencil aspect | [eq]#S = B~r~# 684 | One component color format | [eq]#Color~r~ = B~r~# 685 | Two component color format | [eq]#[Color~r~,Color~g~] = [B~r~,B~g~]# 686 | Three component color format| [eq]#[Color~r~,Color~g~,Color~b~] = [B~r~,B~g~,B~b~]# 687 | Four component color format | [eq]#[Color~r~,Color~g~,Color~b~,Color~a~] = [B~r~,B~g~,B~b~,B~a~]# 688 |==== 689 690 The value returned by a read of an invalid texel is undefined:, unless that 691 read operation is from a buffer resource and the pname:robustBufferAccess 692 feature is enabled. 693 In that case, an invalid texel is replaced as described by the 694 <<features-robustBufferAccess,pname:robustBufferAccess feature>>. 695 696 If the 697 slink:VkPhysicalDeviceSparseProperties::pname:residencyNonResidentStrict 698 property is ename:VK_TRUE, a sparse unbound texel is replaced with 0 or 0.0 699 values for integer and floating-point components of the image format, 700 respectively. 701 702 If pname:residencyNonResidentStrict is ename:VK_FALSE, the value of the 703 sparse unbound texel is undefined:. 704 705 706 [[textures-depth-compare-operation]] 707 === Depth Compare Operation 708 709 If the image view has a depth/stencil format, the depth component is 710 selected by the pname:aspectMask, and the operation is a code:Dref 711 instruction, a depth comparison is performed. 712 The value of the result [eq]#D# is [eq]#1.0# if the result of the compare 713 operation is [eq]#true#, and [eq]#0.0# otherwise. 714 The compare operation is selected by the pname:compareOp member of the 715 sampler. 716 717 [latexmath] 718 +++++++++++++++++++ 719 \begin{aligned} 720 D & = 1.0 & 721 \begin{cases} 722 D_{\textit{ref}} \leq D & \text{for LEQUAL} \\ 723 D_{\textit{ref}} \geq D & \text{for GEQUAL} \\ 724 D_{\textit{ref}} < D & \text{for LESS} \\ 725 D_{\textit{ref}} > D & \text{for GREATER} \\ 726 D_{\textit{ref}} = D & \text{for EQUAL} \\ 727 D_{\textit{ref}} \neq D & \text{for NOTEQUAL} \\ 728 \textit{true} & \text{for ALWAYS} \\ 729 \textit{false} & \text{for NEVER} 730 \end{cases} \\ 731 D & = 0.0 & \text{otherwise} 732 \end{aligned} 733 +++++++++++++++++++ 734 735 where, in the depth comparison: 736 737 :: [eq]#D~ref~ = shaderOp.D~ref~# (from optional: SPIR-V operand) 738 :: [eq]#D# (texel depth value) 739 740 741 [[textures-conversion-to-rgba]] 742 === Conversion to RGBA 743 744 The texel is expanded from one, two, or three components to four components 745 based on the image base color: 746 747 [[textures-texel-color-rgba-conversion-table]] 748 .Texel Color After Conversion To RGBA 749 [width="100%", options="header", cols="<4,<6"] 750 |==== 751 | Texel Aspect or Format | RGBA Color 752 | Depth aspect | [eq]#[Color~r~,Color~g~,Color~b~, Color~a~] = [D,0,0,one]# 753 | Stencil aspect | [eq]#[Color~r~,Color~g~,Color~b~, Color~a~] = [S,0,0,one]# 754 | One component color format | [eq]#[Color~r~,Color~g~,Color~b~, Color~a~] = [Color~r~,0,0,one]# 755 | Two component color format | [eq]#[Color~r~,Color~g~,Color~b~, Color~a~] = [Color~r~,Color~g~,0,one]# 756 | Three component color format| [eq]#[Color~r~,Color~g~,Color~b~, Color~a~] = [Color~r~,Color~g~,Color~b~,one]# 757 | Four component color format | [eq]#[Color~r~,Color~g~,Color~b~, Color~a~] = [Color~r~,Color~g~,Color~b~,Color~a~]# 758 |==== 759 760 where [eq]#one = 1.0f# for floating-point formats and depth aspects, and 761 [eq]#one = 1# for integer formats and stencil aspects. 762 763 764 [[textures-component-swizzle]] 765 === Component Swizzle 766 767 ifndef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 768 All texel input instructions apply a _swizzle_ based on the 769 elink:VkComponentSwizzle enums in the pname:components member of the 770 slink:VkImageViewCreateInfo structure for the image being read. 771 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 772 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 773 All texel input instructions apply a _swizzle_ based on: 774 775 * the elink:VkComponentSwizzle enums in the pname:components member of the 776 slink:VkImageViewCreateInfo structure for the image being read if 777 <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ conversion>> is not 778 enabled, and 779 * the elink:VkComponentSwizzle enums in the pname:components member of the 780 slink:VkSamplerYcbcrConversionCreateInfo structure for the 781 <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ conversion>> if sampler 782 Y'C~B~C~R~ conversion is enabled. 783 784 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 785 786 The swizzle can: rearrange the components of the texel, or substitute zero 787 or one for any components. 788 It is defined as follows for each color [eq]#component#: 789 790 791 [latexmath] 792 +++++++++++++++++++ 793 \begin{aligned} 794 Color'_{component} & = 795 \begin{cases} 796 Color_r & \text{for RED swizzle} \\ 797 Color_g & \text{for GREEN swizzle} \\ 798 Color_b & \text{for BLUE swizzle} \\ 799 Color_a & \text{for ALPHA swizzle} \\ 800 0 & \text{for ZERO swizzle} \\ 801 one & \text{for ONE swizzle} \\ 802 identity & \text{for IDENTITY swizzle} 803 \end{cases} 804 \end{aligned} 805 +++++++++++++++++++ 806 807 where: 808 809 [latexmath] 810 +++++++++++++++++++ 811 \begin{aligned} 812 one & = 813 \begin{cases} 814 & 1.0\text{f} & \text{for floating point components} \\ 815 & 1 & \text{for integer components} \\ 816 \end{cases} 817 \\ 818 identity & = 819 \begin{cases} 820 & Color_r & \text{for}\ component = r \\ 821 & Color_g & \text{for}\ component = g \\ 822 & Color_b & \text{for}\ component = b \\ 823 & Color_a & \text{for}\ component = a \\ 824 \end{cases} 825 \end{aligned} 826 +++++++++++++++++++ 827 828 If the border color is one of the etext:VK_BORDER_COLOR_*_OPAQUE_BLACK enums 829 and the elink:VkComponentSwizzle is not ename:VK_COMPONENT_SWIZZLE_IDENTITY 830 for all components (or the 831 <<resources-image-views-identity-mappings,equivalent identity mapping>>), 832 the value of the texel after swizzle is undefined:. 833 834 [[textures-sparse-residency]] 835 === Sparse Residency 836 837 code:OpImageSparse* instructions return a structure which includes a 838 _residency code_ indicating whether any texels accessed by the instruction 839 are sparse unbound texels. 840 This code can: be interpreted by the code:OpImageSparseTexelsResident 841 instruction which converts the residency code to a boolean value. 842 843 844 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 845 [[textures-chroma-reconstruction]] 846 === Chroma Reconstruction 847 848 In some color models, the color representation is defined in terms of 849 monochromatic light intensity (often called "`luma`") and color differences 850 relative to this intensity, often called "`chroma`". 851 It is common for color models other than RGB to represent the chroma 852 channels at lower spatial resolution than the luma channel. 853 This approach is used to take advantage of the eye's lower spatial 854 sensitivity to color compared with its sensitivity to brightness. 855 Less commonly, the same approach is used with additive color, since the 856 green channel dominates the eye's sensitivity to light intensity and the 857 spatial sensitivity to color introduced by red and blue is lower. 858 859 Lower-resolution channels are "`downsampled`" by resizing them to a lower 860 spatial resolution than the channel representing luminance. 861 The process of reconstructing a full color value for texture access involves 862 accessing both chroma and luma values at the same location. 863 To generate the color accurately, the values of the lower-resolution 864 channels at the location of the luma samples must be reconstructed from the 865 lower-resolution sample locations, an operation known here as "`chroma 866 reconstruction`" irrespective of the actual color model. 867 868 The location of the chroma samples relative to the luma coordinates is 869 determined by the pname:xChromaOffset and pname:yChromaOffset members of the 870 slink:VkSamplerYcbcrConversionCreateInfo structure used to create the 871 sampler Y'C~B~C~R~ conversion. 872 873 The following diagrams show the relationship between unnormalized (_u_,_v_) 874 coordinates and (_i_,_j_) integer texel positions in the luma channel (shown 875 in black, with circles showing integer sample positions) and the texel 876 coordinates of reduced-resolution chroma channels, shown as crosses in red. 877 878 [NOTE] 879 .Note 880 ==== 881 If the chroma values are reconstructed at the locations of the luma samples 882 by means of interpolation, chroma samples from outside the image bounds are 883 needed; these are determined according to <<textures-wrapping-operation>>. 884 These diagrams represent this by showing the bounds of the "`chroma texel`" 885 extending beyond the image bounds, and including additional chroma sample 886 positions where required for interpolation. 887 The limits of a sample for etext:NEAREST sampling is shown as a grid. 888 ==== 889 890 image::{images}/chromasamples_422_cosited.svg[align="center",title="422 downsampling, xChromaOffset=COSITED_EVEN",opts="{imageopts}"] 891 892 image::{images}/chromasamples_422_midpoint.svg[align="center",title="422 downsampling, xChromaOffset=MIDPOINT",opts="{imageopts}"] 893 894 image::{images}/chromasamples_420_xcosited_ycosited.svg[align="center",title="420 downsampling, xChromaOffset=COSITED_EVEN, yChromaOffset=COSITED_EVEN",opts="{imageopts}"] 895 896 image::{images}/chromasamples_420_xmidpoint_ycosited.svg[align="center",title="420 downsampling, xChromaOffset=MIDPOINT, yChromaOffset=COSITED_EVEN",opts="{imageopts}"] 897 898 image::{images}/chromasamples_420_xcosited_ymidpoint.svg[align="center",title="420 downsampling, xChromaOffset=COSITED_EVEN, yChromaOffset=MIDPOINT",opts="{imageopts}"] 899 900 image::{images}/chromasamples_420_xmidpoint_ymidpoint.svg[align="center",title="420 downsampling, xChromaOffset=MIDPOINT, yChromaOffset=MIDPOINT",opts="{imageopts}"] 901 902 Reconstruction is implemented in one of two ways: 903 904 If the format of the image that is to be sampled sets 905 ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, 906 or the sname:VkSamplerYcbcrConversionCreateInfo's 907 pname:forceExplicitReconstruction is set to ename:VK_TRUE, reconstruction is 908 performed as an explicit step independent of filtering, described in the 909 <<textures-explicit-reconstruction>> section. 910 911 If the format of the image that is to be sampled does not set 912 ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT 913 and if the sname:VkSamplerYcbcrConversionCreateInfo's 914 pname:forceExplicitReconstruction is set to ename:VK_FALSE, reconstruction 915 is performed as an implicit part of filtering prior to color model 916 conversion, with no separate post-conversion texel filtering step, as 917 described in the <<textures-implict-reconstruction,Implicit Reconstruction>> 918 section. 919 920 [[textures-explicit-reconstruction]] 921 ==== Explicit Reconstruction 922 923 * If the pname:chromaFilter member of the 924 slink:VkSamplerYcbcrConversionCreateInfo structure is 925 ename:VK_FILTER_NEAREST: 926 ** If the format's R and B channels are reduced in resolution in just 927 width by a factor of two relative to the G channel (i.e. this is a 928 "`etext:_422`" format), the latexmath:[\tau_{ijk}[level\]] values 929 accessed by <<textures-texel-filtering,texel filtering>> are 930 reconstructed as follows: 931 + 932 [latexmath] 933 ++++++++++++++ 934 \begin{aligned} 935 \tau_R'(i, j) & = \tau_R(\lfloor{i\times 0.5}\rfloor, j)[level] \\ 936 \tau_B'(i, j) & = \tau_B(\lfloor{i\times 0.5}\rfloor, j)[level] 937 \end{aligned} 938 ++++++++++++++ 939 940 ** If the format's R and B channels are reduced in resolution in width and 941 height by a factor of two relative to the G channel (i.e. this is a 942 "`etext:_420`" format), the latexmath:[\tau_{ijk}[level\]] values 943 accessed by <<textures-texel-filtering,texel filtering>> are 944 reconstructed as follows: 945 + 946 [latexmath] 947 ++++++++++++++ 948 \begin{aligned} 949 \tau_R'(i, j) & = \tau_R(\lfloor{i\times 0.5}\rfloor, \lfloor{j\times 0.5}\rfloor)[level] \\ 950 \tau_B'(i, j) & = \tau_B(\lfloor{i\times 0.5}\rfloor, \lfloor{j\times 0.5}\rfloor)[level] 951 \end{aligned} 952 ++++++++++++++ 953 + 954 [NOTE] 955 .Note 956 ==== 957 pname:xChromaOffset and pname:yChromaOffset have no effect if 958 pname:chromaFilter is ename:VK_FILTER_NEAREST for explicit reconstruction. 959 ==== 960 961 * If the pname:chromaFilter member of the 962 slink:VkSamplerYcbcrConversionCreateInfo structure is 963 ename:VK_FILTER_LINEAR: 964 ** If the format's R and B channels are reduced in resolution in just 965 width by a factor of two relative to the G channel (i.e. this is a 966 "`422`" format): 967 *** If pname:xChromaOffset is ename:VK_CHROMA_LOCATION_COSITED_EVEN: 968 + 969 [latexmath] 970 +++++ 971 \tau_{RB}'(i,j) = \begin{cases} 972 \tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level], & 0.5 \times i = \lfloor{0.5 \times i}\rfloor\\ 973 0.5\times\tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level] + \\ 974 0.5\times\tau_{RB}(\lfloor{i\times 0.5}\rfloor + 1,j)[level], & 0.5 \times i \neq \lfloor{0.5 \times i}\rfloor 975 \end{cases} 976 +++++ 977 + 978 *** If pname:xChromaOffset is ename:VK_CHROMA_LOCATION_MIDPOINT: 979 + 980 [latexmath] 981 +++++ 982 \tau_{RB}(i,j)' = \begin{cases} 983 0.25 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor - 1,j)[level] + \\ 984 0.75 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level], & 0.5 \times i = \lfloor{0.5 \times i}\rfloor\\ 985 0.75 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor,j)[level] + \\ 986 0.25 \times \tau_{RB}(\lfloor{i\times 0.5}\rfloor + 1,j)[level], & 0.5 \times i \neq \lfloor{0.5 \times i}\rfloor 987 \end{cases} 988 +++++ 989 990 ** If the format's R and B channels are reduced in resolution in width and 991 height by a factor of two relative to the G channel (i.e. this is a 992 "`420`" format), a similar relationship applies. 993 Due to the number of options, these formulae are expressed more 994 concisely as follows: 995 + 996 [latexmath] 997 +++++ 998 \begin{aligned} 999 i_{RB} & = 1000 \begin{cases} 1001 0.5 \times (i) & \textrm{If xChromaOffset = COSITED}\_\textrm{EVEN} \\ 1002 0.5 \times (i - 0.5) & \textrm{If xChromaOffset = MIDPOINT} 1003 \end{cases}\\ 1004 j_{RB} & = 1005 \begin{cases} 1006 0.5 \times (j) & \textrm{If yChromaOffset = COSITED}\_\textrm{EVEN} \\ 1007 0.5 \times (j - 0.5) & \textrm{If yChromaOffset = MIDPOINT} 1008 \end{cases}\\ 1009 \\ 1010 i_{floor} & = \lfloor i_{RB} \rfloor \\ 1011 j_{floor} & = \lfloor j_{RB} \rfloor \\ 1012 \\ 1013 i_{frac} & = i_{RB} - i_{floor} \\ 1014 j_{frac} & = j_{RB} - j_{floor} 1015 \end{aligned} 1016 +++++ 1017 + 1018 [latexmath] 1019 +++++ 1020 \begin{aligned} 1021 \tau_{RB}'(i,j) = 1022 & \tau_{RB}( i_{floor}, j_{floor})[level] 1023 & \times & ( 1 - i_{frac} ) & 1024 & \times & ( 1 - j_{frac} ) & + \\ 1025 & \tau_{RB}( 1 + i_{floor}, j_{floor})[level] 1026 & \times & ( i_{frac} ) & 1027 & \times & ( 1 - j_{frac} ) & + \\ 1028 & \tau_{RB}( i_{floor}, 1 + j_{floor})[level] 1029 & \times & ( 1 - i_{frac} ) & 1030 & \times & ( j_{frac} ) & + \\ 1031 & \tau_{RB}( 1 + i_{floor}, 1 + j_{floor})[level] 1032 & \times & ( i_{frac} ) & 1033 & \times & ( j_{frac} ) & 1034 \end{aligned} 1035 +++++ 1036 1037 [NOTE] 1038 .Note 1039 ==== 1040 In the case where the texture itself is bilinearly interpolated as described 1041 in <<textures-texel-filtering,Texel Filtering>>, thus requiring four 1042 full-color samples for the filtering operation, and where the reconstruction 1043 of these samples uses bilinear interpolation in the chroma channels due to 1044 pname:chromaFilter=ename:VK_FILTER_LINEAR, up to nine chroma samples may be 1045 required, depending on the sample location. 1046 ==== 1047 1048 1049 [[textures-implict-reconstruction]] 1050 ==== Implicit Reconstruction 1051 1052 Implicit reconstruction takes place by the samples being interpolated, as 1053 required by the filter settings of the sampler, except that 1054 pname:chromaFilter takes precedence for the chroma samples. 1055 1056 If pname:chromaFilter is ename:VK_FILTER_NEAREST, an implementation may: 1057 behave as if pname:xChromaOffset and pname:yChromaOffset were both 1058 ename:VK_CHROMA_LOCATION_MIDPOINT, irrespective of the values set. 1059 1060 [NOTE] 1061 .Note 1062 ==== 1063 This will not have any visible effect if the locations of the luma samples 1064 coincide with the location of the samples used for rasterization. 1065 ==== 1066 1067 The sample coordinates are adjusted by the downsample factor of the channel 1068 (such that, for example, the sample coordinates are divided by two if the 1069 channel has a downsample factor of two relative to the luma channel): 1070 1071 [latexmath] 1072 ++++++ 1073 \begin{aligned} 1074 u_{RB}' (422/420) &= 1075 \begin{cases} 1076 0.5\times (u + 0.5), & \textrm{xChromaOffset = COSITED}\_\textrm{EVEN} \\ 1077 0.5\times u, & \textrm{xChromaOffset = MIDPOINT} 1078 \end{cases} \\ 1079 v_{RB}' (420) &= 1080 \begin{cases} 1081 0.5\times (v + 0.5), & \textrm{yChromaOffset = COSITED}\_\textrm{EVEN} \\ 1082 0.5\times v, & \textrm{yChromaOffset = MIDPOINT} 1083 \end{cases} 1084 \end{aligned} 1085 ++++++ 1086 1087 1088 [[textures-sampler-YCbCr-conversion]] 1089 === Sampler Y'C~B~C~R~ Conversion 1090 1091 Sampler Y'C~B~C~R~ conversion performs the following operations, which an 1092 implementation may: combine into a single mathematical operation: 1093 1094 * <<textures-sampler-YCbCr-conversion-rangeexpand,Sampler Y'C~B~C~R~ Range 1095 Expansion>> 1096 * <<textures-sampler-YCbCr-conversion-modelconversion,Sampler Y'C~B~C~R~ 1097 Model Conversion>> 1098 1099 [[textures-sampler-YCbCr-conversion-rangeexpand]] 1100 ==== Sampler Y'C~B~C~R~ Range Expansion 1101 1102 Sampler Y'C~B~C~R~ range expansion is applied to color channel values after 1103 all texel input operations which are not specific to sampler Y'C~B~C~R~ 1104 conversion. 1105 For example, the input values to this stage have been converted using the 1106 normal <<textures-format-conversion,format conversion>> rules. 1107 1108 Sampler Y'C~B~C~R~ range expansion is not applied if pname:ycbcrModel is 1109 ename:VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY. 1110 That is, the shader receives the vector C'~rgba~ as output by the Component 1111 Swizzle stage without further modification. 1112 1113 For other values of pname:ycbcrModel, range expansion is applied to the 1114 texel channel values output by the <<textures-component-swizzle,Component 1115 Swizzle>> defined by the pname:components member of 1116 slink:VkSamplerYcbcrConversionCreateInfo. 1117 Range expansion applies independently to each channel of the image. 1118 For the purposes of range expansion and Y'C~B~C~R~ model conversion, the R 1119 and B channels contain color difference (chroma) values and the G channel 1120 contains luma. 1121 The A channel is not modified by sampler Y'C~B~C~R~ range expansion. 1122 1123 The range expansion to be applied is defined by the pname:ycbcrRange member 1124 of the sname:VkSamplerYcbcrConversionCreateInfo structure: 1125 1126 * If pname:ycbcrRange is ename:VK_SAMPLER_YCBCR_RANGE_ITU_FULL, the 1127 following transformations are applied: 1128 + 1129 [latexmath] 1130 +++++++++++++++++++ 1131 \begin{aligned} 1132 Y' &= C'_{rgba}[G] \\ 1133 C_B &= C'_{rgba}[B] - {{2^{(n-1)}}\over{(2^n) - 1}} \\ 1134 C_R &= C'_{rgba}[R] - {{2^{(n-1)}}\over{(2^n) - 1}} 1135 \end{aligned} 1136 +++++++++++++++++++ 1137 + 1138 [NOTE] 1139 .Note 1140 ==== 1141 These formulae correspond to the "`full range`" encoding in the 1142 <<data-format,Khronos Data Format Specification>>. 1143 1144 Should any future amendments be made to the ITU specifications from which 1145 these equations are derived, the formulae used by Vulkan may: also be 1146 updated to maintain parity. 1147 ==== 1148 * If pname:ycbcrRange is ename:VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, the 1149 following transformations are applied: 1150 + 1151 [latexmath] 1152 +++++++++++++++++++ 1153 \begin{aligned} 1154 Y' &= {{C'_{rgba}[G] \times (2^n-1) - 16\times 2^{n-8}}\over{219\times 2^{n-8}}} \\ 1155 C_B &= {{C'_{rgba}[B] \times \left(2^n-1\right) - 128\times 2^{n-8}}\over{224\times 2^{n-8}}} \\ 1156 C_R &= {{C'_{rgba}[R] \times \left(2^n-1\right) - 128\times 2^{n-8}}\over{224\times 2^{n-8}}} 1157 \end{aligned} 1158 +++++++++++++++++++ 1159 + 1160 [NOTE] 1161 .Note 1162 ==== 1163 These formulae correspond to the "`narrow range`" encoding in the 1164 <<data-format,Khronos Data Format Specification>>. 1165 ==== 1166 * _n_ is the bit-depth of the channels in the format. 1167 1168 The precision of the operations performed during range expansion must: be at 1169 least that of the source format. 1170 1171 An implementation may: clamp the results of these range expansion operations 1172 such that Y' falls in the range [0,1], and/or such that C~B~ and C~R~ fall 1173 in the range [-0.5,0.5]. 1174 1175 [[textures-sampler-YCbCr-conversion-modelconversion]] 1176 ==== Sampler Y'C~B~C~R~ Model Conversion 1177 1178 The range-expanded values are converted between color models, according to 1179 the color model conversion specified in the pname:ycbcrModel member: 1180 1181 ename:VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY:: 1182 The color channels are not modified by the color model conversion since 1183 they are assumed already to represent the desired color model in which the 1184 shader is operating; Y'C~B~C~R~ range expansion is also ignored. 1185 ename:VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY:: 1186 The color channels are not modified by the color model conversion and are 1187 assumed to be treated as though in Y'C~B~C~R~ form both in memory and in 1188 the shader; Y'C~B~C~R~ range expansion is applied to the channels as for 1189 other Y'C~B~C~R~ models, with the vector (C~R~,Y',C~B~,A) provided to the 1190 shader. 1191 ename:VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709:: 1192 The color channels are transformed from a Y'C~B~C~R~ representation to an 1193 R'G'B' representation as described in the "`BT.709 Y'C~B~C~R~ conversion`" 1194 section of the <<data-format,Khronos Data Format Specification>>. 1195 ename:VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601:: 1196 The color channels are transformed from a Y'C~B~C~R~ representation to an 1197 R'G'B' representation as described in the "`BT.601 Y'C~B~C~R~ conversion`" 1198 section of the <<data-format,Khronos Data Format Specification>>. 1199 ename:VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020:: 1200 The color channels are transformed from a Y'C~B~C~R~ representation to an 1201 R'G'B' representation as described in the "`BT.2020 Y'C~B~C~R~ 1202 conversion`" section of the <<data-format,Khronos Data Format 1203 Specification>>. 1204 1205 In this operation, each output channel is dependent on each input channel. 1206 1207 An implementation may: clamp the R'G'B' results of these conversions to the 1208 range [0,1]. 1209 1210 The precision of the operations performed during model conversion must: be 1211 at least that of the source format. 1212 1213 The alpha channel is not modified by these model conversions. 1214 1215 [NOTE] 1216 .Note 1217 ==== 1218 Sampling operations in a non-linear color space can introduce color and 1219 intensity shifts at sharp transition boundaries. 1220 To avoid this issue, the technically precise color correction sequence 1221 described in the "`Introduction to Color Conversions`" chapter of the 1222 <<data-format,Khronos Data Format Specification>> may be performed as 1223 follows: 1224 1225 * Calculate the <<textures-normalized-to-unnormalized,unnormalized texel 1226 coordinates>> corresponding to the desired sample position. 1227 * For a pname:minFilter/pname:magFilter of ename:VK_FILTER_NEAREST: 1228 . Calculate (_i_,_j_) for the sample location as described under the 1229 "`nearest filtering`" formulae in <<textures-unnormalized-to-integer>> 1230 . Calculate the normalized texel coordinates corresponding to these 1231 integer coordinates. 1232 . Sample using <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ 1233 conversion>> at this location. 1234 * For a pname:minFilter/pname:magFilter of ename:VK_FILTER_LINEAR: 1235 . Calculate (_i~[0,1]~_,_j~[0,1]~_) for the sample location as described 1236 under the "`linear filtering`" formulae in 1237 <<textures-unnormalized-to-integer>> 1238 . Calculate the normalized texel coordinates corresponding to these 1239 integer coordinates. 1240 . Sample using <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ 1241 conversion>> at each of these locations. 1242 . Convert the non-linear AR'G'B' outputs of the Y'C~B~C~R~ conversions 1243 to linear ARGB values as described in the "`Transfer Functions`" 1244 chapter of the <<data-format,Khronos Data Format Specification>>. 1245 . Interpolate the linear ARGB values using the [eq]#{alpha}# and 1246 [eq]#{beta}# values described in the "`linear filtering`" section of 1247 <<textures-unnormalized-to-integer>> and the equations in 1248 <<textures-texel-filtering>>. 1249 1250 The additional calculations and, especially, additional number of sampling 1251 operations in the ename:VK_FILTER_LINEAR case can be expected to have a 1252 performance impact compared with using the outputs directly; since the 1253 variation from "`correct`" results are subtle for most content, the 1254 application author should determine whether a more costly implementation is 1255 strictly necessary. 1256 Note that if pname:chromaFilter and pname:minFilter/pname:magFilter are both 1257 ename:VK_FILTER_NEAREST, these operations are redundant and sampling using 1258 <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ conversion>> at the desired 1259 sample coordinates will produce the "`correct`" results without further 1260 processing. 1261 ==== 1262 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 1263 1264 1265 == Texel Output Operations 1266 1267 _Texel output instructions_ are SPIR-V image instructions that write to an 1268 image. 1269 _Texel output operations_ are a set of steps that are performed on state, 1270 coordinates, and texel values while processing a texel output instruction, 1271 and which are common to some or all texel output instructions. 1272 They include the following steps, which are performed in the listed order: 1273 1274 * <<textures-output-validation,Validation operations>> 1275 ** <<textures-format-validation,Format validation>> 1276 ** <<textures-output-coordinate-validation,Coordinate validation>> 1277 ** <<textures-output-sparse-validation,Sparse validation>> 1278 * <<textures-output-format-conversion,Texel output format conversion>> 1279 1280 1281 [[textures-output-validation]] 1282 === Texel Output Validation Operations 1283 1284 _Texel output validation operations_ inspect instruction/image state or 1285 coordinates, and in certain circumstances cause the write to have no effect. 1286 There are a series of validations that the texel undergoes. 1287 1288 1289 [[textures-format-validation]] 1290 ==== Texel Format Validation 1291 1292 If the image format of the code:OpTypeImage is not compatible with the 1293 sname:VkImageView's pname:format, the write causes the contents of the 1294 image's memory to become undefined:. 1295 1296 1297 [[textures-output-coordinate-validation]] 1298 === Integer Texel Coordinate Validation 1299 1300 The integer texel coordinates are validated according to the same rules as 1301 for texel input <<textures-integer-coordinate-validation,coordinate 1302 validation>>. 1303 1304 If the texel fails integer texel coordinate validation, then the write has 1305 no effect. 1306 1307 1308 [[textures-output-sparse-validation]] 1309 === Sparse Texel Operation 1310 1311 If the texel attempts to write to an unbound region of a sparse image, the 1312 texel is a sparse unbound texel. 1313 In such a case, if the 1314 slink:VkPhysicalDeviceSparseProperties::pname:residencyNonResidentStrict 1315 property is ename:VK_TRUE, the sparse unbound texel write has no effect. 1316 If pname:residencyNonResidentStrict is ename:VK_FALSE, the write may: have a 1317 side effect that becomes visible to other accesses to unbound texels in any 1318 resource, but will not be visible to any device memory allocated by the 1319 application. 1320 1321 1322 [[textures-output-format-conversion]] 1323 === Texel Output Format Conversion 1324 1325 If the image format is sRGB, a linear to sRGB conversion is applied to the 1326 R, G, and B components as described in the "`sRGB EOTF`" section of the 1327 <<data-format,Khronos Data Format Specification>>. 1328 The A component, if present, is unchanged. 1329 1330 Texels then undergo a format conversion from the floating point, signed, or 1331 unsigned integer type of the texel data to the elink:VkFormat of the image 1332 view. 1333 Any unused components are ignored. 1334 1335 Each component is converted based on its type and size (as defined in the 1336 <<formats-definition,Format Definition>> section for each elink:VkFormat). 1337 Floating-point outputs are converted as described in 1338 <<fundamentals-fp-conversion,Floating-Point Format Conversions>> and 1339 <<fundamentals-fixedconv,Fixed-Point Data Conversion>>. 1340 Integer outputs are converted such that their value is preserved. 1341 The converted value of any integer that cannot be represented in the target 1342 format is undefined:. 1343 1344 1345 [[texture-derivatives]] 1346 == Derivative Operations 1347 1348 SPIR-V derivative instructions include code:OpDPdx, code:OpDPdy, 1349 code:OpDPdxFine, code:OpDPdyFine, code:OpDPdxCoarse, and code:OpDPdyCoarse. 1350 Derivative instructions are only available in 1351 ifdef::VK_NV_compute_shader_derivatives[] 1352 compute and 1353 endif::VK_NV_compute_shader_derivatives[] 1354 fragment shaders. 1355 1356 image::{images}/vulkantexture2-ll.svg[align="center",title="Implicit Derivatives",opts="{imageopts}"] 1357 1358 Derivatives are computed as if there is a 2{times}2 neighborhood of 1359 fragments for each fragment shader invocation. 1360 These neighboring fragments are used to compute derivatives with the 1361 assumption that the values of P in the neighborhood are piecewise linear. 1362 It is further assumed that the values of P in the neighborhood are locally 1363 continuous. 1364 Applications must: not use derivative instructions in non-uniform control 1365 flow. 1366 1367 [latexmath] 1368 +++++++++++++++++++ 1369 \begin{aligned} 1370 dPdx_0 & = P_{i_1,j_0} - P_{i_0,j_0} \\ 1371 dPdx_1 & = P_{i_1,j_1} - P_{i_0,j_1} \\ 1372 \\ 1373 dPdy_0 & = P_{i_0,j_1} - P_{i_0,j_0} \\ 1374 dPdy_1 & = P_{i_1,j_1} - P_{i_1,j_0} 1375 \end{aligned} 1376 +++++++++++++++++++ 1377 1378 For a 2{times}2 neighborhood, for the four fragments labled 0, 1, 2 and 3, 1379 the code:Fine derivative instructions must: return: 1380 1381 [latexmath] 1382 +++++++++++++++++++ 1383 \begin{aligned} 1384 dPdx & = 1385 \begin{cases} 1386 dPdx_0 & \text{for fragments labeled 0 and 1}\\ 1387 dPdx_1 & \text{for fragments labeled 2 and 3} 1388 \end{cases} \\ 1389 dPdy & = 1390 \begin{cases} 1391 dPdy_0 & \text{for fragments labeled 0 and 2}\\ 1392 dPdy_1 & \text{for fragments labeled 1 and 3} 1393 \end{cases} 1394 \end{aligned} 1395 +++++++++++++++++++ 1396 1397 Coarse derivatives may: return only two values. 1398 In this case, the values should: be: 1399 1400 [latexmath] 1401 +++++++++++++++++++ 1402 \begin{aligned} 1403 dPdx & = 1404 \begin{cases} 1405 dPdx_0 & \text{preferred}\\ 1406 dPdx_1 1407 \end{cases} \\ 1408 dPdy & = 1409 \begin{cases} 1410 dPdy_0 & \text{preferred}\\ 1411 dPdy_1 1412 \end{cases} 1413 \end{aligned} 1414 +++++++++++++++++++ 1415 1416 code:OpDPdx and code:OpDPdy must: return the same result as either 1417 code:OpDPdxFine or code:OpDPdxCoarse and either code:OpDPdyFine or 1418 code:OpDPdyCoarse, respectively. 1419 Implementations must: make the same choice of either coarse or fine for both 1420 code:OpDPdx and code:OpDPdy, and implementations should: make the choice 1421 that is more efficient to compute. 1422 1423 ifdef::VK_VERSION_1_1[] 1424 If the pname:subgroupSize field of slink:VkPhysicalDeviceSubgroupProperties 1425 is at least 4, the 2x2 neighborhood of fragments corresponds exactly to a 1426 subgroup quad. 1427 The order in which the fragments appear within the quad is implementation 1428 defined. 1429 endif::VK_VERSION_1_1[] 1430 1431 ifdef::VK_NV_compute_shader_derivatives[] 1432 [[texture-derivatives-compute]] 1433 === Compute Shader Derivatives 1434 1435 For compute shaders, derivatives are also evaluated using a 2{times}2 1436 logical neighborhood of compute shader invocations. 1437 Compute shader invocations are arranged into neighborhoods according to one 1438 of two SPIR-V execution modes. 1439 For the code:DerivativeGroupQuadsNV execution mode, each neighborhood is 1440 assembled from a 2{times}2{times}1 region of invocations based on the 1441 code:LocalInvocationId built-in. 1442 For the code:DerivativeGroupLinearNV execution mode, each neighborhood is 1443 assembled from a group of four invocations based on the 1444 code:LocalInvocationIndex built-in. 1445 The <<texture-derivatives-compute-group>> table specifies the 1446 code:LocalInvocationId or code:LocalInvocationIndex values for the four 1447 values of P in each neighborhood, where __x__ and __y__ are per-neighborhood 1448 integer values. 1449 1450 [[texture-derivatives-compute-group]] 1451 .Compute shader derivative group assignments 1452 [width="75%",frame="all",options="header",cols="^2,^6,^6"] 1453 |=== 1454 |Value 1455 |DerivativeGroupQuadsNV 1456 |DerivativeGroupLinearNV 1457 1458 |P~i0,j0~ | (2__x__ + 0, 2__y__ + 0, z) | 4__x__ + 0 1459 |P~i1,j0~ | (2__x__ + 1, 2__y__ + 0, z) | 4__x__ + 1 1460 |P~i0,j1~ | (2__x__ + 0, 2__y__ + 1, z) | 4__x__ + 2 1461 |P~i1,j1~ | (2__x__ + 1, 2__y__ + 1, z) | 4__x__ + 3 1462 |=== 1463 1464 endif::VK_NV_compute_shader_derivatives[] 1465 1466 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 1467 For multi-planar formats, the derivatives are computed based on the plane 1468 with the largest dimensions. 1469 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 1470 1471 1472 [[textures-normalized-operations]] 1473 == Normalized Texel Coordinate Operations 1474 1475 If the image sampler instruction provides normalized texel coordinates, some 1476 of the following operations are performed. 1477 1478 1479 [[textures-projection]] 1480 === Projection Operation 1481 1482 For code:Proj image operations, the normalized texel coordinates 1483 [eq]#(s,t,r,q,a)# and (if present) the [eq]#D~ref~# coordinate are 1484 transformed as follows: 1485 1486 [latexmath] 1487 +++++++++++++++++++ 1488 \begin{aligned} 1489 s & = \frac{s}{q}, & \text{for 1D, 2D, or 3D image} \\ 1490 \\ 1491 t & = \frac{t}{q}, & \text{for 2D or 3D image} \\ 1492 \\ 1493 r & = \frac{r}{q}, & \text{for 3D image} \\ 1494 \\ 1495 D_{\textit{ref}} & = \frac{D_{\textit{ref}}}{q}, & \text{if provided} 1496 \end{aligned} 1497 +++++++++++++++++++ 1498 1499 1500 [[textures-derivative-image-operations]] 1501 === Derivative Image Operations 1502 1503 Derivatives are used for LOD selection. 1504 These derivatives are either implicit (in an code:ImplicitLod image 1505 instruction in a fragment shader) or explicit (provided explicitly by shader 1506 to the image instruction in any shader). 1507 1508 For implicit derivatives image instructions, the derivatives of texel 1509 coordinates are calculated in the same manner as derivative operations 1510 above. 1511 That is: 1512 1513 [latexmath] 1514 +++++++++++++++++++ 1515 \begin{aligned} 1516 \partial{s}/\partial{x} & = dPdx(s), & \partial{s}/\partial{y} & = dPdy(s), & \text{for 1D, 2D, Cube, or 3D image} \\ 1517 \partial{t}/\partial{x} & = dPdx(t), & \partial{t}/\partial{y} & = dPdy(t), & \text{for 2D, Cube, or 3D image} \\ 1518 \partial{u}/\partial{x} & = dPdx(u), & \partial{u}/\partial{y} & = dPdy(u), & \text{for Cube or 3D image} 1519 \end{aligned} 1520 +++++++++++++++++++ 1521 1522 Partial derivatives not defined above for certain image dimensionalities are 1523 set to zero. 1524 1525 For explicit LOD image instructions, if the optional: SPIR-V operand 1526 [eq]#Grad# is provided, then the operand values are used for the 1527 derivatives. 1528 The number of components present in each derivative for a given image 1529 dimensionality matches the number of partial derivatives computed above. 1530 1531 If the optional: SPIR-V operand [eq]#Lod# is provided, then derivatives are 1532 set to zero, the cube map derivative transformation is skipped, and the 1533 scale factor operation is skipped. 1534 Instead, the floating point scalar coordinate is directly assigned to 1535 [eq]#{lambda}~base~# as described in <<textures-level-of-detail-operation, 1536 Level-of-Detail Operation>>. 1537 1538 For implicit derivative image instructions, the partial derivative values 1539 may: be computed by linear approximation using a 2{times}2 neighborhood of 1540 shader invocations (known as a _quad_), as described above. 1541 If the instruction is in control flow that is not uniform across the quad, 1542 then the derivative values and hence the implicit LOD values are undefined:. 1543 1544 ifdef::VK_EXT_descriptor_indexing[] 1545 If the image or sampler object used by an implicit derivative image 1546 instruction is not uniform across the quad and 1547 <<limits-quadDivergentImplicitLod,pname:quadDivergentImplicitLod>> is not 1548 supported, then the derivative and LOD values are undefined:. 1549 Implicit derivatives are well-defined when the image and sampler and control 1550 flow are uniform across the quad, even if they diverge between different 1551 quads. 1552 1553 If <<limits-quadDivergentImplicitLod,pname:quadDivergentImplicitLod>> is 1554 supported, then derivatives and implicit LOD values are well-defined even if 1555 the image or sampler object are not uniform within a quad. 1556 The derivatives are computed as specified above, and the implicit LOD 1557 calculation proceeds for each shader invocation using its respective image 1558 and sampler object. 1559 1560 For the purposes of implicit derivatives, code:Flat fragment input variables 1561 are uniform within a quad. 1562 endif::VK_EXT_descriptor_indexing[] 1563 1564 1565 === Cube Map Face Selection and Transformations 1566 1567 For cube map image instructions, the [eq]#(s,t,r)# coordinates are treated 1568 as a direction vector [eq]#(r~x~,r~y~,r~z~)#. 1569 The direction vector is used to select a cube map face. 1570 The direction vector is transformed to a per-face texel coordinate system 1571 [eq]#(s~face~,t~face~)#, The direction vector is also used to transform the 1572 derivatives to per-face derivatives. 1573 1574 1575 === Cube Map Face Selection 1576 1577 The direction vector selects one of the cube map's faces based on the 1578 largest magnitude coordinate direction (the major axis direction). 1579 Since two or more coordinates can: have identical magnitude, the 1580 implementation must: have rules to disambiguate this situation. 1581 1582 The rules should: have as the first rule that [eq]#r~z~# wins over 1583 [eq]#r~y~# and [eq]#r~x~#, and the second rule that [eq]#r~y~# wins over 1584 [eq]#r~x~#. 1585 An implementation may: choose other rules, but the rules must: be 1586 deterministic and depend only on [eq]#(r~x~,r~y~,r~z~)#. 1587 1588 The layer number (corresponding to a cube map face), the coordinate 1589 selections for [eq]#s~c~#, [eq]#t~c~#, [eq]#r~c~#, and the selection of 1590 derivatives, are determined by the major axis direction as specified in the 1591 following two tables. 1592 1593 .Cube map face and coordinate selection 1594 [width="75%",frame="all",options="header"] 1595 |==== 1596 | Major Axis Direction | Layer Number | Cube Map Face | [eq]#s~c~# | [eq]#t~c~# | [eq]#r~c~# 1597 | [eq]#+r~x~# | [eq]#0# | Positive X | [eq]#-r~z~# | [eq]#-r~y~# | [eq]#r~x~# 1598 | [eq]#-r~x~# | [eq]#1# | Negative X | [eq]#+r~z~# | [eq]#-r~y~# | [eq]#r~x~# 1599 | [eq]#+r~y~# | [eq]#2# | Positive Y | [eq]#+r~x~# | [eq]#+r~z~# | [eq]#r~y~# 1600 | [eq]#-r~y~# | [eq]#3# | Negative Y | [eq]#+r~x~# | [eq]#-r~z~# | [eq]#r~y~# 1601 | [eq]#+r~z~# | [eq]#4# | Positive Z | [eq]#+r~x~# | [eq]#-r~y~# | [eq]#r~z~# 1602 | [eq]#-r~z~# | [eq]#5# | Negative Z | [eq]#-r~x~# | [eq]#-r~y~# | [eq]#r~z~# 1603 |==== 1604 1605 1606 .Cube map derivative selection 1607 [width="75%",frame="all",options="header"] 1608 |==== 1609 | Major Axis Direction | [eq]#{partial}s~c~ / {partial}x# | [eq]#{partial}s~c~ / {partial}y# | [eq]#{partial}t~c~ / {partial}x# | [eq]#{partial}t~c~ / {partial}y# | [eq]#{partial}r~c~ / {partial}x# | [eq]#{partial}r~c~ / {partial}y# 1610 1611 | [eq]#+r~x~# 1612 | [eq]#-{partial}r~z~ / {partial}x# | [eq]#-{partial}r~z~ / {partial}y# 1613 | [eq]#-{partial}r~y~ / {partial}x# | [eq]#-{partial}r~y~ / {partial}y# 1614 | [eq]#+{partial}r~x~ / {partial}x# | [eq]#+{partial}r~x~ / {partial}y# 1615 1616 | [eq]#-r~x~# 1617 | [eq]#+{partial}r~z~ / {partial}x# | [eq]#+{partial}r~z~ / {partial}y# 1618 | [eq]#-{partial}r~y~ / {partial}x# | [eq]#-{partial}r~y~ / {partial}y# 1619 | [eq]#-{partial}r~x~ / {partial}x# | [eq]#-{partial}r~x~ / {partial}y# 1620 1621 | [eq]#+r~y~# 1622 | [eq]#+{partial}r~x~ / {partial}x# | [eq]#+{partial}r~x~ / {partial}y# 1623 | [eq]#+{partial}r~z~ / {partial}x# | [eq]#+{partial}r~z~ / {partial}y# 1624 | [eq]#+{partial}r~y~ / {partial}x# | [eq]#+{partial}r~y~ / {partial}y# 1625 1626 | [eq]#-r~y~# 1627 | [eq]#+{partial}r~x~ / {partial}x# | [eq]#+{partial}r~x~ / {partial}y# 1628 | [eq]#-{partial}r~z~ / {partial}x# | [eq]#-{partial}r~z~ / {partial}y# 1629 | [eq]#-{partial}r~y~ / {partial}x# | [eq]#-{partial}r~y~ / {partial}y# 1630 1631 | [eq]#+r~z~# 1632 | [eq]#+{partial}r~x~ / {partial}x# | [eq]#+{partial}r~x~ / {partial}y# 1633 | [eq]#-{partial}r~y~ / {partial}x# | [eq]#-{partial}r~y~ / {partial}y# 1634 | [eq]#+{partial}r~z~ / {partial}x# | [eq]#+{partial}r~z~ / {partial}y# 1635 1636 | [eq]#-r~z~# 1637 | [eq]#-{partial}r~x~ / {partial}x# | [eq]#-{partial}r~x~ / {partial}y# 1638 | [eq]#-{partial}r~y~ / {partial}x# | [eq]#-{partial}r~y~ / {partial}y# 1639 | [eq]#-{partial}r~z~ / {partial}x# | [eq]#-{partial}r~z~ / {partial}y# 1640 |==== 1641 1642 1643 === Cube Map Coordinate Transformation 1644 1645 [latexmath] 1646 ++++++++++++++++++++++++ 1647 \begin{aligned} 1648 s_{\textit{face}} & = 1649 \frac{1}{2} \times \frac{s_c}{|r_c|} + \frac{1}{2} \\ 1650 t_{\textit{face}} & = 1651 \frac{1}{2} \times \frac{t_c}{|r_c|} + \frac{1}{2} \\ 1652 \end{aligned} 1653 ++++++++++++++++++++++++ 1654 1655 1656 === Cube Map Derivative Transformation 1657 1658 [latexmath] 1659 ++++++++++++++++++++++++ 1660 \begin{aligned} 1661 \frac{\partial{s_{\textit{face}}}}{\partial{x}} &= 1662 \frac{\partial}{\partial{x}} \left ( \frac{1}{2} \times \frac{s_{c}}{|r_{c}|} 1663 + \frac{1}{2}\right ) \\ 1664 \frac{\partial{s_{\textit{face}}}}{\partial{x}} &= 1665 \frac{1}{2} \times \frac{\partial}{\partial{x}} 1666 \left ( \frac{s_{c}}{|r_{c}|} \right ) \\ 1667 \frac{\partial{s_{\textit{face}}}}{\partial{x}} &= 1668 \frac{1}{2} \times 1669 \left ( 1670 \frac{ 1671 |r_{c}| \times \partial{s_c}/\partial{x} 1672 -s_c \times {\partial{r_{c}}}/{\partial{x}}} 1673 {\left ( r_{c} \right )^2} 1674 \right ) 1675 \end{aligned} 1676 ++++++++++++++++++++++++ 1677 1678 [latexmath] 1679 ++++++++++++++++++++++++ 1680 \begin{aligned} 1681 \frac{\partial{s_{\textit{face}}}}{\partial{y}} &= 1682 \frac{1}{2} \times 1683 \left ( 1684 \frac{ 1685 |r_{c}| \times \partial{s_c}/\partial{y} 1686 -s_c \times {\partial{r_{c}}}/{\partial{y}}} 1687 {\left ( r_{c} \right )^2} 1688 \right )\\ 1689 \frac{\partial{t_{\textit{face}}}}{\partial{x}} &= 1690 \frac{1}{2} \times 1691 \left ( 1692 \frac{ 1693 |r_{c}| \times \partial{t_c}/\partial{x} 1694 -t_c \times {\partial{r_{c}}}/{\partial{x}}} 1695 {\left ( r_{c} \right )^2} 1696 \right ) \\ 1697 \frac{\partial{t_{\textit{face}}}}{\partial{y}} &= 1698 \frac{1}{2} \times 1699 \left ( 1700 \frac{ 1701 |r_{c}| \times \partial{t_c}/\partial{y} 1702 -t_c \times {\partial{r_{c}}}/{\partial{y}}} 1703 {\left ( r_{c} \right )^2} 1704 \right ) 1705 \end{aligned} 1706 ++++++++++++++++++++++++ 1707 1708 ifdef::editing-notes[] 1709 [NOTE] 1710 .editing-note 1711 ==== 1712 (Bill) Note that we never revisited ARB_texture_cubemap after we introduced 1713 dependent texture fetches (ARB_fragment_program and ARB_fragment_shader). 1714 1715 The derivatives of [eq]#s~face~# and [eq]#t~face~# are only valid for 1716 non-dependent texture fetches (pre OpenGL 2.0). 1717 ==== 1718 endif::editing-notes[] 1719 1720 1721 === Scale Factor Operation, Level-of-Detail Operation and Image Level(s) Selection 1722 1723 LOD selection can: be either explicit (provided explicitly by the image 1724 instruction) or implicit (determined from a scale factor calculated from the 1725 derivatives). 1726 The implicit LOD selected can: be queried using the SPIR-V instruction 1727 code:OpImageQueryLod, which gives access to the [eq]#{lambda}#' and 1728 [eq]#d~l~# values, defined below. 1729 These values must: be computed with pname:mipmapPrecisionBits of accuracy 1730 and may: be subject to implementation-specific maxima and minima for very 1731 large, out-of-range values. 1732 1733 1734 [[textures-scale-factor]] 1735 ==== Scale Factor Operation 1736 1737 The magnitude of the derivatives are calculated by: 1738 1739 :: [eq]#m~ux~ = {vert}{partial}s/{partial}x{vert} {times} w~base~# 1740 :: [eq]#m~vx~ = {vert}{partial}t/{partial}x{vert} {times} h~base~# 1741 :: [eq]#m~wx~ = {vert}{partial}r/{partial}x{vert} {times} d~base~# 1742 1743 :: [eq]#m~uy~ = {vert}{partial}s/{partial}y{vert} {times} w~base~# 1744 :: [eq]#m~vy~ = {vert}{partial}t/{partial}y{vert} {times} h~base~# 1745 :: [eq]#m~wy~ = {vert}{partial}r/{partial}y{vert} {times} d~base~# 1746 1747 1748 where: 1749 1750 :: [eq]#{partial}t/{partial}x = {partial}t/{partial}y = 0# (for 1D images) 1751 :: [eq]#{partial}r/{partial}x = {partial}r/{partial}y = 0# (for 1D, 2D or 1752 Cube images) 1753 1754 and: 1755 1756 :: [eq]#w~base~ = image.w# 1757 :: [eq]#h~base~ = image.h# 1758 :: [eq]#d~base~ = image.d# 1759 1760 (for the pname:baseMipLevel, from the image descriptor). 1761 1762 ifdef::VK_NV_corner_sampled_image[] 1763 1764 For corner-sampled images, the [eq]#w~base~#, [eq]#h~base~#, and 1765 [eq]#d~base~# are instead: 1766 1767 :: [eq]#w~base~ = image.w - 1# 1768 :: [eq]#h~base~ = image.h - 1# 1769 :: [eq]#d~base~ = image.d - 1# 1770 1771 endif::VK_NV_corner_sampled_image[] 1772 1773 A point sampled in screen space has an elliptical footprint in texture 1774 space. 1775 The minimum and maximum scale factors [eq]#({rho}~min~, {rho}~max~)# should: 1776 be the minor and major axes of this ellipse. 1777 1778 The _scale factors_ [eq]#{rho}~x~# and [eq]#{rho}~y~#, calculated from the 1779 magnitude of the derivatives in x and y, are used to compute the minimum and 1780 maximum scale factors. 1781 1782 [eq]#{rho}~x~# and [eq]#{rho}~y~# may: be approximated with functions 1783 [eq]#f~x~# and [eq]#f~y~#, subject to the following constraints: 1784 1785 [latexmath] 1786 ++++++++++++++++++++++++ 1787 \begin{aligned} 1788 & f_x \text{\ is\ continuous\ and\ monotonically\ increasing\ in\ each\ of\ } 1789 m_{ux}, 1790 m_{vx}, \text{\ and\ } 1791 m_{wx} \\ 1792 & f_y \text{\ is\ continuous\ and\ monotonically\ increasing\ in\ each\ of\ } 1793 m_{uy}, 1794 m_{vy}, \text{\ and\ } 1795 m_{wy} 1796 \end{aligned} 1797 ++++++++++++++++++++++++ 1798 1799 [latexmath] 1800 ++++++++++++++++++++++++ 1801 \begin{aligned} 1802 \max(|m_{ux}|, |m_{vx}|, |m_{wx}|) \leq f_{x} 1803 \leq \sqrt{2} (|m_{ux}| + |m_{vx}| + |m_{wx}|) \\ 1804 \max(|m_{uy}|, |m_{vy}|, |m_{wy}|) \leq f_{y} 1805 \leq \sqrt{2} (|m_{uy}| + |m_{vy}| + |m_{wy}|) 1806 \end{aligned} 1807 ++++++++++++++++++++++++ 1808 1809 1810 ifdef::editing-notes[] 1811 [NOTE] 1812 .editing-note 1813 ==== 1814 (Bill) For reviewers only - anticipating questions. 1815 1816 We only support implicit derivatives for normalized texel coordinates. 1817 1818 So we are documenting the derivatives in s,t,r (normalized texel 1819 coordinates) rather than u,v,w (unnormalized texel coordinates) as in OpenGL 1820 and OpenGL ES specifications. 1821 (I know, u,v,w is the way it has been documented since OpenGL V1.0.) 1822 1823 Also there is no reason to have conditional application of [eq]#w~base~, 1824 h~base~, d~base~# for rectangle textures either, since they do not support 1825 implicit derivatives. 1826 ==== 1827 endif::editing-notes[] 1828 1829 1830 The minimum and maximum scale factors [eq]#({rho}~min~,{rho}~max~)# are 1831 determined by: 1832 1833 :: [eq]#{rho}~max~ = max({rho}~x~, {rho}~y~)# 1834 :: [eq]#{rho}~min~ = min({rho}~x~, {rho}~y~)# 1835 1836 The ratio of anisotropy is determined by: 1837 1838 :: [eq]#{eta} = min({rho}~max~/{rho}~min~, max~Aniso~)# 1839 1840 where: 1841 1842 :: [eq]#sampler.max~Aniso~ = pname:maxAnisotropy# (from sampler 1843 descriptor) 1844 :: [eq]#limits.max~Aniso~ = pname:maxSamplerAnisotropy# (from physical 1845 device limits) 1846 :: [eq]#max~Aniso~ = min(sampler.max~Aniso~, limits.max~Aniso~)# 1847 1848 If [eq]#{rho}~max~ = {rho}~min~ = 0#, then all the partial derivatives are 1849 zero, the fragment's footprint in texel space is a point, and [eq]#N# 1850 should: be treated as 1. 1851 If [eq]#{rho}~max~ {neq} 0# and [eq]#{rho}~min~ = 0# then all partial 1852 derivatives along one axis are zero, the fragment's footprint in texel space 1853 is a line segment, and [eq]#{eta}# should: be treated as [eq]#max~Aniso~#. 1854 However, anytime the footprint is small in texel space the implementation 1855 may: use a smaller value of [eq]#{eta}#, even when [eq]#{rho}~min~# is zero 1856 or close to zero. 1857 If either slink:VkPhysicalDeviceFeatures::pname:samplerAnisotropy or 1858 slink:VkSamplerCreateInfo::pname:anisotropyEnable are ename:VK_FALSE, 1859 [eq]#max~Aniso~# is set to 1. 1860 1861 If [eq]#{eta} = 1#, sampling is isotropic. 1862 If [eq]#{eta} > 1#, sampling is anisotropic. 1863 1864 The sampling rate ([eq]#N#) is derived as: 1865 1866 :: [eq]#N = {lceil}{eta}{rceil}# 1867 1868 An implementation may: round [eq]#N# up to the nearest supported sampling 1869 rate. 1870 An implementation may: use the value of [eq]#N# as an approximation of 1871 [eq]#{eta}#. 1872 1873 1874 [[textures-level-of-detail-operation]] 1875 ==== Level-of-Detail Operation 1876 1877 The LOD parameter [eq]#{lambda}# is computed as follows: 1878 1879 [latexmath] 1880 ++++++++++++++++++++++++ 1881 \begin{aligned} 1882 \lambda_{base}(x,y) & = 1883 \begin{cases} 1884 shaderOp.Lod & \text{(from optional SPIR-V operand)} \\ 1885 \log_2 \left ( \frac{\rho_{max}}{\eta} \right ) & \text{otherwise} 1886 \end{cases} \\ 1887 \lambda'(x,y) & = \lambda_{base} + \mathbin{clamp}(sampler.bias + shaderOp.bias,-maxSamplerLodBias,maxSamplerLodBias) \\ 1888 \lambda & = 1889 \begin{cases} 1890 lod_{max}, & \lambda' > lod_{max} \\ 1891 \lambda', & lod_{min} \leq \lambda' \leq lod_{max} \\ 1892 lod_{min}, & \lambda' < lod_{min} \\ 1893 \textit{undefined}, & lod_{min} > lod_{max} 1894 \end{cases} 1895 \end{aligned} 1896 ++++++++++++++++++++++++ 1897 1898 where: 1899 1900 [latexmath] 1901 ++++++++++++++++++++++++ 1902 \begin{aligned} 1903 sampler.bias & = mipLodBias & \text{(from sampler descriptor)} \\ 1904 shaderOp.bias & = 1905 \begin{cases} 1906 Bias & \text{(from optional SPIR-V operand)} \\ 1907 0 & \text{otherwise} 1908 \end{cases} \\ 1909 sampler.lod_{min} & = minLod & \text{(from sampler descriptor)} \\ 1910 shaderOp.lod_{min} & = 1911 \begin{cases} 1912 MinLod & \text{(from optional SPIR-V operand)} \\ 1913 0 & \text{otherwise} 1914 \end{cases} \\ 1915 \\ 1916 lod_{min} & = \max(sampler.lod_{min}, shaderOp.lod_{min}) \\ 1917 lod_{max} & = maxLod & \text{(from sampler descriptor)} 1918 \end{aligned} 1919 ++++++++++++++++++++++++ 1920 1921 and [eq]#maxSamplerLodBias# is the value of the slink:VkPhysicalDeviceLimits 1922 feature <<limits-maxSamplerLodBias,pname:maxSamplerLodBias>>. 1923 1924 1925 [[textures-image-level-selection]] 1926 ==== Image Level(s) Selection 1927 1928 The image level(s) [eq]#d#, [eq]#d~hi~#, and [eq]#d~lo~# which texels are 1929 read from are determined by an image-level parameter [eq]#d~l~#, which is 1930 computed based on the LOD parameter, as follows: 1931 1932 [latexmath] 1933 ++++++++++++++++++++++++ 1934 \begin{aligned} 1935 d_{l} = 1936 \begin{cases} 1937 nearest(d'), & \text{mipmapMode is VK\_SAMPLER\_MIPMAP\_MODE\_NEAREST} \\ 1938 d', & \text{otherwise} 1939 \end{cases} 1940 \end{aligned} 1941 ++++++++++++++++++++++++ 1942 1943 where: 1944 1945 [latexmath] 1946 ++++++++++++++++++++++++ 1947 \begin{aligned} 1948 d' = level_{base} + \text{clamp}(\lambda, 0, q) 1949 \end{aligned} 1950 ++++++++++++++++++++++++ 1951 1952 [latexmath] 1953 ++++++++++++++++++++++++ 1954 \begin{aligned} 1955 nearest(d') & = 1956 \begin{cases} 1957 \left \lceil d' + 0.5\right \rceil - 1, & 1958 \text{preferred} \\ 1959 \left \lfloor d' + 0.5\right \rfloor, & 1960 \text{alternative} 1961 \end{cases} 1962 \end{aligned} 1963 ++++++++++++++++++++++++ 1964 1965 and: 1966 1967 :: [eq]#level~base~ = pname:baseMipLevel# 1968 :: [eq]#q = pname:levelCount - 1# 1969 1970 pname:baseMipLevel and pname:levelCount are taken from the 1971 pname:subresourceRange of the image view. 1972 1973 If the sampler's pname:mipmapMode is ename:VK_SAMPLER_MIPMAP_MODE_NEAREST, 1974 then the level selected is [eq]#d = d~l~#. 1975 1976 If the sampler's pname:mipmapMode is ename:VK_SAMPLER_MIPMAP_MODE_LINEAR, 1977 two neighboring levels are selected: 1978 1979 [latexmath] 1980 ++++++++++++++++++++++++ 1981 \begin{aligned} 1982 d_{hi} & = \lfloor d_{l} \rfloor \\ 1983 d_{lo} & = min( d_{hi} + 1, q ) \\ 1984 \delta & = d_{l} - d_{hi} 1985 \end{aligned} 1986 ++++++++++++++++++++++++ 1987 1988 [eq]#{delta}# is the fractional value, quantized to the number of 1989 <<limits-mipmapPrecisionBits,mipmap precision bits>>, used for 1990 <<textures-texel-filtering, linear filtering>> between levels. 1991 1992 [[textures-normalized-to-unnormalized]] 1993 === (s,t,r,q,a) to (u,v,w,a) Transformation 1994 1995 The normalized texel coordinates are scaled by the image level dimensions 1996 and the array layer is selected. 1997 1998 This transformation is performed once for each level used in 1999 <<textures-texel-filter,filtering>> (either [eq]#d#, or [eq]#d~hi~# and 2000 [eq]#d~lo~#). 2001 2002 [latexmath] 2003 ++++++++++++++++++++++++ 2004 \begin{aligned} 2005 u(x,y) & = s(x,y) \times width_{scale} + \Delta_i\\ 2006 v(x,y) & = 2007 \begin{cases} 2008 0 & \text{for 1D images} \\ 2009 t(x,y) \times height_{scale} + \Delta_j & \text{otherwise} 2010 \end{cases} \\ 2011 w(x,y) & = 2012 \begin{cases} 2013 0 & \text{for 2D or Cube images} \\ 2014 r(x,y) \times depth_{scale} + \Delta_k & \text{otherwise} 2015 \end{cases} \\ 2016 \\ 2017 a(x,y) & = 2018 \begin{cases} 2019 a(x,y) & \text{for array images} \\ 2020 0 & \text{otherwise} 2021 \end{cases} 2022 \end{aligned} 2023 ++++++++++++++++++++++++ 2024 2025 where: 2026 2027 :: [eq]#width~scale~ = width~level~# 2028 :: [eq]#height~scale~ = height~level~# 2029 :: [eq]#depth~scale~ = depth~level~# 2030 2031 ifdef::VK_NV_corner_sampled_image[] 2032 for conventional images, and: 2033 2034 :: [eq]#width~scale~ = width~level~ - 1# 2035 :: [eq]#height~scale~ = height~level~ - 1# 2036 :: [eq]#depth~scale~ = depth~level~ - 1# 2037 2038 for corner-sampled images. 2039 endif::VK_NV_corner_sampled_image[] 2040 2041 and where [eq]#({DeltaUpper}~i~, {DeltaUpper}~j~, {DeltaUpper}~k~)# are 2042 taken from the image instruction if it includes a code:ConstOffset or 2043 code:Offset operand, otherwise they are taken to be zero. 2044 2045 2046 Operations then proceed to Unnormalized Texel Coordinate Operations. 2047 2048 2049 == Unnormalized Texel Coordinate Operations 2050 2051 2052 [[textures-unnormalized-to-integer]] 2053 === (u,v,w,a) to (i,j,k,l,n) Transformation And Array Layer Selection 2054 2055 The unnormalized texel coordinates are transformed to integer texel 2056 coordinates relative to the selected mipmap level. 2057 2058 The layer index [eq]#l# is computed as: 2059 2060 :: [eq]#l = clamp(RNE(a), 0, pname:layerCount - 1) {plus} 2061 pname:baseArrayLayer# 2062 2063 where pname:layerCount is the number of layers in the image subresource 2064 range of the image view, pname:baseArrayLayer is the first layer from the 2065 subresource range, and where: 2066 2067 [latexmath] 2068 ++++++++++++++++++++++++ 2069 \begin{aligned} 2070 \mathbin{RNE}(a) & = 2071 \begin{cases} 2072 \mathbin{roundTiesToEven}(a) & \text{preferred, from IEEE Std 754-2008 Floating-Point Arithmetic} \\ 2073 \left \lfloor a + 0.5 \right \rfloor & \text{alternative} 2074 \end{cases} 2075 \end{aligned} 2076 ++++++++++++++++++++++++ 2077 2078 The sample index n is assigned the value zero. 2079 2080 Nearest filtering (ename:VK_FILTER_NEAREST) computes the integer texel 2081 coordinates that the unnormalized coordinates lie within: 2082 2083 [latexmath] 2084 ++++++++++++++++++++++++ 2085 \begin{aligned} 2086 i &= \lfloor u + shift \rfloor \\ 2087 j &= \lfloor v + shift \rfloor \\ 2088 k &= \lfloor w + shift \rfloor 2089 \end{aligned} 2090 ++++++++++++++++++++++++ 2091 where: 2092 2093 :: [eq]#shift = 0.0# 2094 2095 ifdef::VK_NV_corner_sampled_image[] 2096 for conventional images, and: 2097 2098 :: [eq]#shift = 0.5# 2099 2100 for corner-sampled images. 2101 endif::VK_NV_corner_sampled_image[] 2102 2103 Linear filtering (ename:VK_FILTER_LINEAR) computes a set of neighboring 2104 coordinates which bound the unnormalized coordinates. 2105 The integer texel coordinates are combinations of [eq]#i~0~# or [eq]#i~1~#, 2106 [eq]#j~0~# or [eq]#j~1~#, [eq]#k~0~# or [eq]#k~1~#, as well as weights 2107 [eq]#{alpha}, {beta}#, and [eq]#{gamma}#. 2108 2109 [latexmath] 2110 ++++++++++++++++++++++++ 2111 \begin{aligned} 2112 i_0 &= \lfloor u - shift \rfloor \\ 2113 i_1 &= i_0 + 1 \\ 2114 j_0 &= \lfloor v - shift \rfloor \\ 2115 j_1 &= j_0 + 1 \\ 2116 k_0 &= \lfloor w - shift \rfloor 2117 k_1 &= k_0 + 1 2118 \end{aligned} 2119 ++++++++++++++++++++++++ 2120 2121 [latexmath] 2122 ++++++++++++++++++++++++ 2123 \begin{aligned} 2124 \alpha &= \mathbin{frac}\left(u - shift\right) \\[1em] 2125 \beta &= \mathbin{frac}\left(v - shift\right) \\[1em] 2126 \gamma &= \mathbin{frac}\left(w - shift\right) 2127 \end{aligned} 2128 ++++++++++++++++++++++++ 2129 2130 where: 2131 2132 :: [eq]#shift = 0.5# 2133 2134 ifdef::VK_NV_corner_sampled_image[] 2135 for conventional images, and: 2136 2137 :: [eq]#shift = 0.0# 2138 2139 for corner-sampled images, 2140 endif::VK_NV_corner_sampled_image[] 2141 and where: 2142 2143 [latexmath] 2144 ++++++++++++++++++++++++ 2145 \mathbin{frac}(x) = x - \lfloor x \rfloor 2146 ++++++++++++++++++++++++ 2147 where the number of fraction bits retained is specified by 2148 sname:VkPhysicalDeviceLimits::pname:subTexelPrecisionBits. 2149 2150 ifdef::VK_IMG_filter_cubic,VK_EXT_filter_cubic[] 2151 Cubic filtering (ename:VK_FILTER_CUBIC_EXT) computes a set of neighboring 2152 coordinates which bound the unnormalized coordinates. 2153 The integer texel coordinates are combinations of [eq]#i~0~#, [eq]#i~1~#, 2154 [eq]#i~2~# or [eq]#i~3~#, [eq]#j~0~#, [eq]#j~1~#, [eq]#j~2~# or [eq]#j~3~#, 2155 ifndef::VK_EXT_filter_cubic[] 2156 as well as weights [eq]#{alpha}# and [eq]#{beta}#. 2157 endif::VK_EXT_filter_cubic[] 2158 ifdef::VK_EXT_filter_cubic[] 2159 [eq]#k~0~#, [eq]#k~1~#, [eq]#k~2~# or [eq]#k~3~#, as well as weights 2160 [eq]#{alpha}#, [eq]#{beta}#, and [eq]#{gamma}#. 2161 endif::VK_EXT_filter_cubic[] 2162 2163 ifndef::VK_EXT_filter_cubic[] 2164 [latexmath] 2165 ++++++++++++++++++++++++ 2166 \begin{aligned} 2167 i_{0} & = {\left \lfloor {u - \frac{3}{2}} \right \rfloor} & i_{1} & = i_{0} + 1 & i_{2} & = i_{1} + 1 & i_{3} & = i_{2} + 1 \\[1em] 2168 j_{0} & = {\left \lfloor {v - \frac{3}{2}} \right \rfloor} & j_{1} & = j_{0} + 1 & j_{2} & = j_{1} + 1 & j_{3} & = j_{2} + 1 2169 \end{aligned} 2170 ++++++++++++++++++++++++ 2171 2172 [latexmath] 2173 ++++++++++++++++++++++++ 2174 \begin{aligned} 2175 alpha &= \mathbin{frac}\left(u - \frac{1}{2}\right) \\[1em] 2176 \beta &= \mathbin{frac}\left(v - \frac{1}{2}\right) 2177 \end{aligned} 2178 ++++++++++++++++++++++++ 2179 2180 endif::VK_EXT_filter_cubic[] 2181 2182 ifdef::VK_EXT_filter_cubic[] 2183 [latexmath] 2184 ++++++++++++++++++++++++ 2185 \begin{aligned} 2186 i_{0} & = {\left \lfloor {u - \frac{3}{2}} \right \rfloor} & i_{1} & = i_{0} + 1 & i_{2} & = i_{1} + 1 & i_{3} & = i_{2} + 1 \\[1em] 2187 j_{0} & = {\left \lfloor {v - \frac{3}{2}} \right \rfloor} & j_{1} & = j_{0} + 1 & j_{2} & = j_{1} + 1 & j_{3} & = j_{2} + 1 \\[1em] 2188 k_{0} & = {\left \lfloor {w - \frac{3}{2}} \right \rfloor} & k_{1} & = k_{0} + 1 & k_{2} & = k_{1} + 1 & k_{3} & = k_{2} + 1 2189 \end{aligned} 2190 ++++++++++++++++++++++++ 2191 2192 [latexmath] 2193 ++++++++++++++++++++++++ 2194 \begin{aligned} 2195 \alpha &= \mathbin{frac}\left(u - \frac{1}{2}\right) \\[1em] 2196 \beta &= \mathbin{frac}\left(v - \frac{1}{2}\right) \\[1em] 2197 \gamma &= \mathbin{frac}\left(w - \frac{1}{2}\right) 2198 \end{aligned} 2199 ++++++++++++++++++++++++ 2200 2201 endif::VK_EXT_filter_cubic[] 2202 2203 where: 2204 2205 [latexmath] 2206 ++++++++++++++++++++++++ 2207 \mathbin{frac}(x) = x - \lfloor x \rfloor 2208 ++++++++++++++++++++++++ 2209 2210 where the number of fraction bits retained is specified by 2211 sname:VkPhysicalDeviceLimits::pname:subTexelPrecisionBits. 2212 endif::VK_IMG_filter_cubic,VK_EXT_filter_cubic[] 2213 2214 2215 [[textures-integer-coordinate-operations]] 2216 == Integer Texel Coordinate Operations 2217 2218 ifdef::VK_AMD_shader_image_load_store_lod[] 2219 Integer texel coordinate operations may: supply a LOD which texels are to be 2220 read from or written to using the optional SPIR-V operand code:Lod. 2221 endif::VK_AMD_shader_image_load_store_lod[] 2222 ifndef::VK_AMD_shader_image_load_store_lod[] 2223 The code:OpImageFetch and code:OpImageFetchSparse SPIR-V instructions may: 2224 supply a LOD from which texels are to be fetched using the optional SPIR-V 2225 operand code:Lod. 2226 Other integer-coordinate operations must: not. 2227 endif::VK_AMD_shader_image_load_store_lod[] 2228 If the code:Lod is provided then it must: be an integer. 2229 2230 The image level selected is: 2231 [latexmath] 2232 ++++++++++++++++++++++++ 2233 \begin{aligned} 2234 d & = level_{base} + 2235 \begin{cases} 2236 Lod & \text{(from optional SPIR-V operand)} \\ 2237 0 & \text{otherwise} 2238 \end{cases} \\ 2239 \end{aligned} 2240 ++++++++++++++++++++++++ 2241 2242 If [eq]#d# does not lie in the range [eq]#[pname:baseMipLevel, 2243 pname:baseMipLevel {plus} pname:levelCount)# then any values fetched are 2244 ifndef::VK_AMD_shader_image_load_store_lod[undefined:.] 2245 ifdef::VK_AMD_shader_image_load_store_lod[] 2246 undefined:, and any writes are discarded. 2247 endif::VK_AMD_shader_image_load_store_lod[] 2248 2249 2250 [[textures-sample-operations]] 2251 == Image Sample Operations 2252 2253 2254 [[textures-wrapping-operation]] 2255 === Wrapping Operation 2256 2257 code:Cube images ignore the wrap modes specified in the sampler. 2258 Instead, if ename:VK_FILTER_NEAREST is used within a mip level then 2259 ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE is used, and if 2260 ename:VK_FILTER_LINEAR is used within a mip level then sampling at the edges 2261 is performed as described earlier in the <<textures-cubemapedge,Cube map 2262 edge handling>> section. 2263 2264 The first integer texel coordinate i is transformed based on the 2265 pname:addressModeU parameter of the sampler. 2266 2267 [latexmath] 2268 ++++++++++++++++++++++++ 2269 \begin{aligned} 2270 i &= 2271 \begin{cases} 2272 i \bmod size & \text{for repeat} \\ 2273 (size - 1) - \mathbin{mirror} 2274 ((i \bmod (2 \times size)) - size) & \text{for mirrored repeat} \\ 2275 \mathbin{clamp}(i,0,size-1) & \text{for clamp to edge} \\ 2276 \mathbin{clamp}(i,-1,size) & \text{for clamp to border} \\ 2277 \mathbin{clamp}(\mathbin{mirror}(i),0,size-1) & \text{for mirror clamp to edge} 2278 \end{cases} 2279 \end{aligned} 2280 ++++++++++++++++++++++++ 2281 2282 where: 2283 2284 [latexmath] 2285 ++++++++++++++++++++++++ 2286 \begin{aligned} 2287 & \mathbin{mirror}(n) = 2288 \begin{cases} 2289 n & \text{for}\ n \geq 0 \\ 2290 -(1+n) & \text{otherwise} 2291 \end{cases} 2292 \end{aligned} 2293 ++++++++++++++++++++++++ 2294 2295 [eq]#j# (for 2D and Cube image) and [eq]#k# (for 3D image) are similarly 2296 transformed based on the pname:addressModeV and pname:addressModeW 2297 parameters of the sampler, respectively. 2298 2299 2300 [[textures-gather]] 2301 === Texel Gathering 2302 2303 SPIR-V instructions with code:Gather in the name return a vector derived 2304 from a 2{times}2 rectangular region of texels in the base level of the image 2305 view. 2306 The rules for the ename:VK_FILTER_LINEAR minification filter are applied to 2307 identify the four selected texels. 2308 Each texel is then converted to an RGBA value according to 2309 <<textures-conversion-to-rgba,conversion to RGBA>> and then 2310 <<textures-component-swizzle,swizzled>>. 2311 A four-component vector is then assembled by taking the component indicated 2312 by the code:Component value in the instruction from the swizzled color value 2313 of the four texels: 2314 2315 [latexmath] 2316 ++++++++++++++++++++++++ 2317 \begin{aligned} 2318 \tau[R] &= \tau_{i0j1}[level_{base}][comp] \\ 2319 \tau[G] &= \tau_{i1j1}[level_{base}][comp] \\ 2320 \tau[B] &= \tau_{i1j0}[level_{base}][comp] \\ 2321 \tau[A] &= \tau_{i0j0}[level_{base}][comp] 2322 \end{aligned} 2323 ++++++++++++++++++++++++ 2324 2325 where: 2326 2327 [latexmath] 2328 ++++++++++++++++++++++++ 2329 \begin{aligned} 2330 \tau[level_{base}][comp] &= 2331 \begin{cases} 2332 \tau[level_{base}][R], & \text{for}\ comp = 0 \\ 2333 \tau[level_{base}][G], & \text{for}\ comp = 1 \\ 2334 \tau[level_{base}][B], & \text{for}\ comp = 2 \\ 2335 \tau[level_{base}][A], & \text{for}\ comp = 3 2336 \end{cases}\\ 2337 comp & \,\text{from SPIR-V operand Component} 2338 \end{aligned} 2339 ++++++++++++++++++++++++ 2340 2341 ifdef::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 2342 code:OpImage*code:Gather must: not be used on a sampled image with 2343 <<samplers-YCbCr-conversion,sampler Y'C~B~C~R~ conversion>> enabled. 2344 endif::VK_VERSION_1_1,VK_KHR_sampler_ycbcr_conversion[] 2345 2346 2347 [[textures-texel-filtering]] 2348 === Texel Filtering 2349 2350 Texel filtering is first performed for each level (either [eq]#d# or 2351 [eq]#d~hi~# and [eq]#d~lo~#). 2352 2353 If [eq]#{lambda}# is less than or equal to zero, the texture is said to be 2354 _magnified_, and the filter mode within a mip level is selected by the 2355 pname:magFilter in the sampler. 2356 If [eq]#{lambda}# is greater than zero, the texture is said to be 2357 _minified_, and the filter mode within a mip level is selected by the 2358 pname:minFilter in the sampler. 2359 2360 [[textures-texel-nearest-filtering]] 2361 ==== Texel Nearest Filtering 2362 2363 Within a mip level, ename:VK_FILTER_NEAREST filtering selects a single value 2364 using the [eq]#(i, j, k)# texel coordinates, with all texels taken from 2365 layer l. 2366 2367 [latexmath] 2368 ++++++++++++++++++++++++ 2369 \begin{aligned} 2370 \tau[level] &= 2371 \begin{cases} 2372 \tau_{ijk}[level], & \text{for 3D image} \\ 2373 \tau_{ij}[level], & \text{for 2D or Cube image} \\ 2374 \tau_{i}[level], & \text{for 1D image} 2375 \end{cases} 2376 \end{aligned} 2377 ++++++++++++++++++++++++ 2378 2379 [[textures-texel-linear-filtering]] 2380 ==== Texel Linear Filtering 2381 2382 Within a mip level, ename:VK_FILTER_LINEAR filtering combines 8 (for 3D), 4 2383 (for 2D or Cube), or 2 (for 1D) texel values, together with their linear 2384 weights. 2385 The linear weights are derived from the fractions computed earlier: 2386 2387 [latexmath] 2388 2389 ++++++++++++++++++++++++ 2390 \begin{aligned} 2391 w_{i_0} &= (1-\alpha) \\ 2392 w_{i_1} &= (\alpha) \\ 2393 w_{j_0} &= (1-\beta) \\ 2394 w_{j_1} &= (\beta) \\ 2395 w_{k_0} &= (1-\gamma) \\ 2396 w_{k_1} &= (\gamma) 2397 \end{aligned} 2398 ++++++++++++++++++++++++ 2399 2400 ifndef::VK_EXT_sampler_filter_minmax[] 2401 The values of multiple texels, together with their weights, are combined 2402 using a weighted average to produce a filtered value: 2403 endif::VK_EXT_sampler_filter_minmax[] 2404 2405 ifdef::VK_EXT_sampler_filter_minmax[] 2406 The values of multiple texels, together with their weights, are combined to 2407 produce a filtered value. 2408 2409 The slink:VkSamplerReductionModeCreateInfoEXT::pname:reductionMode can: 2410 control the process by which multiple texels, together with their weights, 2411 are combined to produce a filtered texture value. 2412 2413 When the pname:reductionMode is set (explicitly or implicitly) to 2414 ename:VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, a weighted average is 2415 computed: 2416 endif::VK_EXT_sampler_filter_minmax[] 2417 2418 [latexmath] 2419 ++++++++++++++++++++++++ 2420 \begin{aligned} 2421 \tau_{3D} &= \sum_{k=k_0}^{k_1}\sum_{j=j_0}^{j_1}\sum_{i=i_0}^{i_1}(w_{i})(w_{j})(w_{k})\tau_{ijk} \\ 2422 \tau_{2D} &= \sum_{j=j_0}^{j_1}\sum_{i=i_0}^{i_1}(w_{i})(w_{j})\tau_{ij} \\ 2423 \tau_{1D} &= \sum_{i=i_0}^{i_1}(w_{i})\tau_{i} 2424 \end{aligned} 2425 ++++++++++++++++++++++++ 2426 2427 ifdef::VK_EXT_sampler_filter_minmax[] 2428 However, if the reduction mode is ename:VK_SAMPLER_REDUCTION_MODE_MIN_EXT or 2429 ename:VK_SAMPLER_REDUCTION_MODE_MAX_EXT, the process operates on the above 2430 set of multiple texels, together with their weights, computing a 2431 component-wise minimum or maximum, respectively, of the components of the 2432 set of texels with non-zero weights. 2433 endif::VK_EXT_sampler_filter_minmax[] 2434 2435 ifdef::VK_IMG_filter_cubic,VK_EXT_filter_cubic[] 2436 2437 [[textures-texel-cubic-filtering]] 2438 ==== Texel Cubic Filtering 2439 2440 Within a mip level, ename:VK_FILTER_CUBIC_EXT, filtering computes a weighted 2441 average of 2442 ifdef::VK_EXT_filter_cubic[] 2443 64 (for 3D), 2444 endif::VK_EXT_filter_cubic[] 2445 16 (for 2D), or 4 (for 1D) texel values, together with their Catmull-Rom 2446 weights. 2447 2448 Catmull-Rom weights are derived from the fractions computed earlier. 2449 2450 ifndef::VK_EXT_filter_cubic[] 2451 [latexmath] 2452 ++++++++++++++++++++++++ 2453 \begin{aligned} 2454 \begin{bmatrix} 2455 w_{i_0}\phantom{,} w_{i_1}\phantom{,} w_{i_2}\phantom{,} w_{i_3} 2456 \end{bmatrix} 2457 = \frac{1}{2} 2458 \begin{bmatrix} 2459 1 & \alpha & \alpha^2 & \alpha^3 2460 \end{bmatrix} 2461 \begin{bmatrix} 2462 \phantom{-}0 & \phantom{-}2 & \phantom{-}0 & \phantom{-}0 \\ 2463 -1 & \phantom{-}0 & \phantom{-}1 & \phantom{-}0 \\ 2464 \phantom{-}2 & -5 & \phantom{-}4 & \phantom{-}1 \\ 2465 -1 & \phantom{-}3 & -3 & \phantom{-}1 2466 \end{bmatrix} 2467 \\ 2468 \begin{bmatrix} 2469 w_{j_0}\phantom{,} w_{j_1}\phantom{,} w_{j_2}\phantom{,} w_{j_3} 2470 \end{bmatrix} 2471 = \frac{1}{2} 2472 \begin{bmatrix} 2473 1 & \beta & \beta^2 & \beta^3 2474 \end{bmatrix} 2475 \begin{bmatrix} 2476 \phantom{-}0 & \phantom{-}2 & \phantom{-}0 & \phantom{-}0 \\ 2477 -1 & \phantom{-}0 & \phantom{-}1 & \phantom{-}0 \\ 2478 \phantom{-}2 & -5 & \phantom{-}4 & \phantom{-}1 \\ 2479 -1 & \phantom{-}3 & -3 & \phantom{-}1 2480 \end{bmatrix} 2481 \end{aligned} 2482 ++++++++++++++++++++++++ 2483 2484 The values of multiple texels, together with their weights, are combined 2485 using a weighted average to produce a filtered value: 2486 2487 [latexmath] 2488 ++++++++++++++++++++++++ 2489 \begin{aligned} 2490 \tau_{2D} &= \sum_{j=j_0}^{j_3}\sum_{i=i_0}^{i_3}(w_{i})(w_{j})\tau_{ij} \\ 2491 \tau_{1D} &= \sum_{i=i_0}^{i_3}(w_{i})\tau_{i} 2492 \end{aligned} 2493 ++++++++++++++++++++++++ 2494 endif::VK_EXT_filter_cubic[] 2495 2496 ifdef::VK_EXT_filter_cubic[] 2497 2498 [latexmath] 2499 ++++++++++++++++++++++++ 2500 \begin{aligned} 2501 \begin{bmatrix} 2502 w_{i_0}\phantom{,} w_{i_1}\phantom{,} w_{i_2}\phantom{,} w_{i_3} 2503 \end{bmatrix} 2504 = \frac{1}{2} 2505 \begin{bmatrix} 2506 1 & \alpha & \alpha^2 & \alpha^3 2507 \end{bmatrix} 2508 \begin{bmatrix} 2509 \phantom{-}0 & \phantom{-}2 & \phantom{-}0 & \phantom{-}0 \\ 2510 -1 & \phantom{-}0 & \phantom{-}1 & \phantom{-}0 \\ 2511 \phantom{-}2 & -5 & \phantom{-}4 & \phantom{-}1 \\ 2512 -1 & \phantom{-}3 & -3 & \phantom{-}1 2513 \end{bmatrix} 2514 \\ 2515 \begin{bmatrix} 2516 w_{j_0}\phantom{,} w_{j_1}\phantom{,} w_{j_2}\phantom{,} w_{j_3} 2517 \end{bmatrix} 2518 = \frac{1}{2} 2519 \begin{bmatrix} 2520 1 & \beta & \beta^2 & \beta^3 2521 \end{bmatrix} 2522 \begin{bmatrix} 2523 \phantom{-}0 & \phantom{-}2 & \phantom{-}0 & \phantom{-}0 \\ 2524 -1 & \phantom{-}0 & \phantom{-}1 & \phantom{-}0 \\ 2525 \phantom{-}2 & -5 & \phantom{-}4 & \phantom{-}1 \\ 2526 -1 & \phantom{-}3 & -3 & \phantom{-}1 2527 \end{bmatrix} 2528 \\ 2529 \begin{bmatrix} 2530 w_{k_0}\phantom{,} w_{k_1}\phantom{,} w_{k_2}\phantom{,} w_{k_3} 2531 \end{bmatrix} 2532 = \frac{1}{2} 2533 \begin{bmatrix} 2534 1 & \gamma & \gamma^2 & \gamma^3 2535 \end{bmatrix} 2536 \begin{bmatrix} 2537 \phantom{-}0 & \phantom{-}2 & \phantom{-}0 & \phantom{-}0 \\ 2538 -1 & \phantom{-}0 & \phantom{-}1 & \phantom{-}0 \\ 2539 \phantom{-}2 & -5 & \phantom{-}4 & \phantom{-}1 \\ 2540 -1 & \phantom{-}3 & -3 & \phantom{-}1 2541 \end{bmatrix} 2542 \end{aligned} 2543 ++++++++++++++++++++++++ 2544 2545 The values of multiple texels, together with their weights, are combined to 2546 produce a filtered value. 2547 2548 The slink:VkSamplerReductionModeCreateInfoEXT::pname:reductionMode can: 2549 control the process by which multiple texels, together with their weights, 2550 are combined to produce a filtered texture value. 2551 2552 When the pname:reductionMode is set (explicitly or implicitly) to 2553 ename:VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, a weighted average is 2554 computed: 2555 2556 [latexmath] 2557 ++++++++++++++++++++++++ 2558 \begin{aligned} 2559 \tau_{3D} &= \sum_{k=j_0}^{k_3}\sum_{j=j_0}^{j_3}\sum_{i=i_0}^{i_3}(w_{i})(w_{j})(w_{k})\tau_{ijk} \\ 2560 \tau_{2D} &= \sum_{j=j_0}^{j_3}\sum_{i=i_0}^{i_3}(w_{i})(w_{j})\tau_{ij} \\ 2561 \tau_{1D} &= \sum_{i=i_0}^{i_3}(w_{i})\tau_{i} 2562 \end{aligned} 2563 ++++++++++++++++++++++++ 2564 2565 ifdef::VK_EXT_sampler_filter_minmax[] 2566 However, if the reduction mode is ename:VK_SAMPLER_REDUCTION_MODE_MIN_EXT or 2567 ename:VK_SAMPLER_REDUCTION_MODE_MAX_EXT, the process operates on the above 2568 set of multiple texels, together with their weights, computing a 2569 component-wise minimum or maximum, respectively, of the components of the 2570 set of texels with non-zero weights. 2571 endif::VK_EXT_sampler_filter_minmax[] 2572 2573 endif::VK_EXT_filter_cubic[] 2574 endif::VK_IMG_filter_cubic,VK_EXT_filter_cubic[] 2575 2576 [[textures-texel-mipmap-filtering]] 2577 2578 ==== Texel Mipmap Filtering 2579 2580 ename:VK_SAMPLER_MIPMAP_MODE_NEAREST filtering returns the value of a single 2581 mipmap level, 2582 2583 [eq]#{tau} = {tau}[d]#. 2584 2585 ename:VK_SAMPLER_MIPMAP_MODE_LINEAR filtering combines the values of 2586 multiple mipmap levels ({tau}[hi] and {tau}[lo]), together with their linear 2587 weights. 2588 2589 The linear weights are derived from the fraction computed earlier: 2590 2591 [latexmath] 2592 2593 ++++++++++++++++++++++++ 2594 \begin{aligned} 2595 w_{hi} &= (1-\delta) \\ 2596 w_{lo} &= (\delta) \\ 2597 \end{aligned} 2598 ++++++++++++++++++++++++ 2599 2600 ifndef::VK_EXT_sampler_filter_minmax[] 2601 The values of multiple mipmap levels together with their linear weights, are 2602 combined using a weighted average to produce a final filtered value: 2603 endif::VK_EXT_sampler_filter_minmax[] 2604 ifdef::VK_EXT_sampler_filter_minmax[] 2605 The values of multiple mipmap levels, together with their weights, are 2606 combined to produce a final filtered value. 2607 2608 The slink:VkSamplerReductionModeCreateInfoEXT::pname:reductionMode can: 2609 control the process by which multiple texels, together with their weights, 2610 are combined to produce a filtered texture value. 2611 2612 When the pname:reductionMode is set (explicitly or implicitly) to 2613 ename:VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, a weighted average is 2614 computed: 2615 endif::VK_EXT_sampler_filter_minmax[] 2616 2617 [latexmath] 2618 ++++++++++++++++++++++++ 2619 \begin{aligned} 2620 \tau &= (w_{hi})\tau[hi]+(w_{lo})\tau[lo] 2621 \end{aligned} 2622 ++++++++++++++++++++++++ 2623 2624 [[textures-texel-anisotropic-filtering]] 2625 ==== Texel Anisotropic Filtering 2626 2627 Anisotropic filtering is enabled by the pname:anisotropyEnable in the 2628 sampler. 2629 When enabled, the image filtering scheme accounts for a degree of 2630 anisotropy. 2631 2632 The particular scheme for anisotropic texture filtering is implementation 2633 dependent. 2634 Implementations should: consider the pname:magFilter, pname:minFilter and 2635 pname:mipmapMode of the sampler to control the specifics of the anisotropic 2636 filtering scheme used. 2637 In addition, implementations should: consider pname:minLod and pname:maxLod 2638 of the sampler. 2639 2640 The following describes one particular approach to implementing anisotropic 2641 filtering for the 2D Image case, implementations may: choose other methods: 2642 2643 Given a pname:magFilter, pname:minFilter of ename:VK_FILTER_LINEAR and a 2644 pname:mipmapMode of ename:VK_SAMPLER_MIPMAP_MODE_NEAREST: 2645 2646 Instead of a single isotropic sample, N isotropic samples are be sampled 2647 within the image footprint of the image level [eq]#d# to approximate an 2648 anisotropic filter. 2649 The sum [eq]#{tau}~2Daniso~# is defined using the single isotropic 2650 [eq]#{tau}~2D~(u,v)# at level [eq]#d#. 2651 2652 [latexmath] 2653 ++++++++++++++++++++++++ 2654 \begin{aligned} 2655 \tau_{2Daniso} & = 2656 \frac{1}{N}\sum_{i=1}^{N} 2657 {\tau_{2D}\left ( 2658 u \left ( x - \frac{1}{2} + \frac{i}{N+1} , y \right ), 2659 \left ( v \left (x-\frac{1}{2}+\frac{i}{N+1} \right ), y 2660 \right ) 2661 \right )}, 2662 & \text{when}\ \rho_{x} > \rho_{y} \\ 2663 \tau_{2Daniso} &= 2664 \frac{1}{N}\sum_{i=1}^{N} 2665 {\tau_{2D}\left ( 2666 u \left ( x, y - \frac{1}{2} + \frac{i}{N+1} \right ), 2667 \left ( v \left (x,y-\frac{1}{2}+\frac{i}{N+1} \right ) 2668 \right ) 2669 \right )}, 2670 & \text{when}\ \rho_{y} \geq \rho_{x} 2671 \end{aligned} 2672 ++++++++++++++++++++++++ 2673 2674 ifdef::VK_EXT_sampler_filter_minmax[] 2675 When slink:VkSamplerReductionModeCreateInfoEXT::pname:reductionMode is set 2676 to ename:VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT, the above summation 2677 is used. 2678 However, if the reduction mode is ename:VK_SAMPLER_REDUCTION_MODE_MIN_EXT or 2679 ename:VK_SAMPLER_REDUCTION_MODE_MAX_EXT, the process operates on the above 2680 values, together with their weights, computing a component-wise minimum or 2681 maximum, respectively, of the components of the values with non-zero 2682 weights. 2683 endif::VK_EXT_sampler_filter_minmax[] 2684 2685 ifdef::VK_NV_shader_image_footprint[] 2686 [[textures-footprint]] 2687 == Texel Footprint Evaluation 2688 2689 The SPIR-V instruction code:OpImageSampleFootprintNV evaluates the set of 2690 texels from a single mip level that would be accessed during a 2691 <<textures-texel-filtering, texel filtering>> operation. 2692 In addition to the inputs that would be accepted by an equivalent 2693 code:OpImageSample* instruction, code:OpImageSampleFootprintNV accepts two 2694 additional inputs. 2695 The code:Granularity input is an integer identifying the size of texel 2696 groups used to evaluate the footprint. 2697 Each bit in the returned footprint mask corresponds to an aligned block of 2698 texels whose size is given by the following table: 2699 2700 .Texel footprint granularity values 2701 [width="50%",options="header"] 2702 |===== 2703 | code:Granularity | code:Dim = 2D | code:Dim = 3D 2704 | 0 | unsupported | unsupported 2705 | 1 | 2x2 | 2x2x2 2706 | 2 | 4x2 | unsupported 2707 | 3 | 4x4 | 4x4x2 2708 | 4 | 8x4 | unsupported 2709 | 5 | 8x8 | unsupported 2710 | 6 | 16x8 | unsupported 2711 | 7 | 16x16 | unsupported 2712 | 8 | unsupported | unsupported 2713 | 9 | unsupported | unsupported 2714 | 10 | unsupported | 16x16x16 2715 | 11 | 64x64 | 32x16x16 2716 | 12 | 128x64 | 32x32x16 2717 | 13 | 128x128 | 32x32x32 2718 | 14 | 256x128 | 64x32x32 2719 | 15 | 256x256 | unsupported 2720 |===== 2721 2722 The code:Coarse input is used to select between the two mip levels that may: 2723 be accessed during texel filtering when using a pname:mipmapMode of 2724 ename:VK_SAMPLER_MIPMAP_MODE_LINEAR. 2725 When filtering between two mip levels, a code:Coarse value of code:true 2726 requests the footprint in the lower-resolution mip level (higher level 2727 number), while code:false requests the footprint in the higher-resolution 2728 mip level. 2729 If texel filtering would access only a single mip level, the footprint in 2730 that level would be returned when code:Coarse is set to code:false; an empty 2731 footprint would be returned when code:Coarse is set to code:true. 2732 2733 The footprint for code:OpImageSampleFootprintNV is returned in a structure 2734 with six members: 2735 2736 * The first member is a boolean value that is true if the texel filtering 2737 operation would access only a single mip level. 2738 * The second member is a two- or three-component integer vector holding 2739 the footprint anchor location. 2740 For two-dimensional images, the returned components are in units of 2741 eight texel groups. 2742 For three-dimensional images, the returned components are in units of 2743 four texel groups. 2744 * The third member is a two- or three-component integer vector holding a 2745 footprint offset relative to the anchor. 2746 All returned components are in units of texel groups. 2747 * The fourth member is a two-component integer vector mask, which holds a 2748 bitfield identifying the set of texel groups in an 8x8 or 4x4x4 2749 neighborhood relative to the anchor and offset. 2750 * The fifth member is an integer identifying the mip level containing the 2751 footprint identified by the anchor, offset, and mask. 2752 * The sixth member is an integer identifying the granularity of the 2753 returned footprint. 2754 2755 For footprints in two-dimensional images (code:Dim2D), the mask returned by 2756 code:OpImageSampleFootprintNV indicates whether each texel group in a 8x8 2757 local neighborhood of texel groups would have one or more texels accessed 2758 during texel filtering. 2759 In the mask, the texel group with local group coordinates 2760 latexmath:[(lgx,lgy)] is considered covered if and only if 2761 2762 [latexmath] 2763 +++++++++++++++++++ 2764 \begin{aligned} 2765 0 \neq ((mask.x + (mask.y << 32)) \text{ \& } (1 << (lgy \times 8 + lgx))) 2766 \end{aligned} 2767 +++++++++++++++++++ 2768 2769 where: 2770 2771 * latexmath:[0<=lgx<8] and latexmath:[0<=lgy<8]; and 2772 * latexmath:[mask] is the returned two-component mask. 2773 2774 The local group with coordinates latexmath:[(lgx,lgy)] in the mask is 2775 considered covered if and only if the texel filtering operation would access 2776 one or more texels latexmath:[\tau_{ij}] in the returned miplevel where: 2777 [latexmath] 2778 +++++++++++++++++++ 2779 \begin{aligned} 2780 i0 & = 2781 \begin{cases} 2782 gran.x \times (8 \times anchor.x + lgx), & \text{if } lgx + offset.x < 8 \\ 2783 gran.x \times (8 \times (anchor.x - 1) + lgx), & \text{otherwise} 2784 \end{cases} \\ 2785 i1 & = i0 + gran.x - 1 \\ 2786 j0 & = 2787 \begin{cases} 2788 gran.y \times (8 \times anchor.y + lgy), & \text{if } lgy + offset.y < 8 \\ 2789 gran.y \times (8 \times (anchor.y - 1) + lgy), & otherwise 2790 \end{cases} \\ 2791 j1 & = j0 + gran.y - 1 2792 \end{aligned} 2793 +++++++++++++++++++ 2794 and 2795 2796 * latexmath:[i0<=i<=i1] and latexmath:[j0<=j<=j1]; 2797 * latexmath:[gran] is a two-component vector holding the width and height 2798 of the texel group identified by the granularity; 2799 * latexmath:[anchor] is the returned two-component anchor vector; and 2800 * latexmath:[offset] is the returned two-component offset vector. 2801 2802 For footprints in three-dimensional images (code:Dim3D), the mask returned 2803 by code:OpImageSampleFootprintNV indicates whether each texel group in a 2804 4x4x4 local neighborhood of texel groups would have one or more texels 2805 accessed during texel filtering. 2806 In the mask, the texel group with local group coordinates 2807 latexmath:[(lgx,lgy,lgz)], is considered covered if and only if: 2808 [latexmath] 2809 +++++++++++++++++++ 2810 \begin{aligned} 2811 0 \neq ((mask.x + (mask.y << 32)) \text{ \& } (1 << (lgz \times 16 + lgy \times 4 + lgx))) 2812 \end{aligned} 2813 +++++++++++++++++++ 2814 where: 2815 2816 * latexmath:[0<=lgx<4], latexmath:[0<=lgy<4], and latexmath:[0<=lgz<4]; 2817 and 2818 * latexmath:[mask] is the returned two-component mask. 2819 2820 The local group with coordinates latexmath:[(lgx,lgy,lgz)] in the mask is 2821 considered covered if and only if the texel filtering operation would access 2822 one or more texels latexmath:[\tau_{ijk}] in the returned miplevel where: 2823 [latexmath] 2824 +++++++++++++++++++ 2825 \begin{aligned} 2826 i0 & = 2827 \begin{cases} 2828 gran.x \times (4 \times anchor.x + lgx), & \text{if } lgx + offset.x < 4 \\ 2829 gran.x \times (4 \times (anchor.x - 1) + lgx), & \text{otherwise} 2830 \end{cases} \\ 2831 i1 & = i0 + gran.x - 1 \\ 2832 j0 & = 2833 \begin{cases} 2834 gran.y \times (4 \times anchor.y + lgy), & \text{if } lgy + offset.y < 4 \\ 2835 gran.y \times (4 \times (anchor.y - 1) + lgy), & otherwise 2836 \end{cases} \\ 2837 j1 & = j0 + gran.y - 1 \\ 2838 k0 & = 2839 \begin{cases} 2840 gran.z \times (4 \times anchor.z + lgz), & \text{if } lgz + offset.z < 4 \\ 2841 gran.z \times (4 \times (anchor.z - 1) + lgz), & otherwise 2842 \end{cases} \\ 2843 k1 & = k0 + gran.z - 1 2844 \end{aligned} 2845 +++++++++++++++++++ 2846 and 2847 2848 * latexmath:[i0<=i<=i1], latexmath:[j0<=j<=j1], latexmath:[k0<=k<=k1]; 2849 * latexmath:[gran] is a three-component vector holding the width, height, 2850 and depth of the texel group identified by the granularity; 2851 * latexmath:[anchor] is the returned three-component anchor vector; and 2852 * latexmath:[offset] is the returned three-component offset vector. 2853 2854 If the sampler used by code:OpImageSampleFootprintNV enables anisotropic 2855 texel filtering via pname:anisotropyEnable, it is possible that the set of 2856 texel groups accessed in a mip level may be too large to be expressed using 2857 an 8x8 or 4x4x4 mask using the granularity requested in the instruction. 2858 In this case, the implementation uses a texel group larger than the 2859 requested granularity. 2860 When a larger texel group size is used, code:OpImageSampleFootprintNV 2861 returns an integer granularity value that can: be interpreted in the same 2862 manner as the granularity value provided to the instruction to determine the 2863 texel group size used. 2864 If anisotropic texel filtering is disabled in the sampler, or if an 2865 anisotropic footprint can be represented as an 8x8 or 4x4x4 mask with the 2866 requested granularity, code:OpImageSampleFootprintNV will use the requested 2867 granularity as-is and return a granularity value of zero. 2868 2869 code:OpImageSampleFootprintNV supports only two- and three-dimensional image 2870 accesses (code:Dim2D and code:Dim3D) and the footprint returned is undefined 2871 if a sampler uses an addressing mode other than 2872 ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE. 2873 2874 endif::VK_NV_shader_image_footprint[] 2875 2876 2877 [[textures-instructions]] 2878 == Image Operation Steps 2879 2880 Each step described in this chapter is performed by a subset of the image 2881 instructions: 2882 2883 * Texel Input Validation Operations, Format Conversion, Texel Replacement, 2884 Conversion to RGBA, and Component Swizzle: Performed by all instructions 2885 except code:OpImageWrite. 2886 * Depth Comparison: Performed by code:OpImage*code:Dref instructions. 2887 * All Texel output operations: Performed by code:OpImageWrite. 2888 * Projection: Performed by all code:OpImage*code:Proj instructions. 2889 * Derivative Image Operations, Cube Map Operations, Scale Factor 2890 Operation, Level-of-Detail Operation and Image Level(s) Selection, and 2891 Texel Anisotropic Filtering: Performed by all code:OpImageSample* and 2892 code:OpImageSparseSample* instructions. 2893 * (s,t,r,q,a) to (u,v,w,a) Transformation, Wrapping, and (u,v,w,a) to 2894 (i,j,k,l,n) Transformation And Array Layer Selection: Performed by all 2895 code:OpImageSample, code:OpImageSparseSample, and 2896 code:OpImage*code:Gather instructions. 2897 * Texel Gathering: Performed by code:OpImage*code:Gather instructions. 2898 ifdef::VK_NV_shader_image_footprint[] 2899 * Texel Footprint Evaluation: Performed by code:OpImageSampleFootprint 2900 instructions. 2901 endif::VK_NV_shader_image_footprint[] 2902 * Texel Filtering: Performed by all code:OpImageSample* and 2903 code:OpImageSparseSample* instructions. 2904 * Sparse Residency: Performed by all code:OpImageSparse* instructions.