1*61046927SAndroid Build Coastguard WorkerSurface Formats 2*61046927SAndroid Build Coastguard Worker=============== 3*61046927SAndroid Build Coastguard Worker 4*61046927SAndroid Build Coastguard WorkerA surface format describes the encoding of color information into the actual 5*61046927SAndroid Build Coastguard Workerdata stored in memory. Surface formats in isl are specified via the 6*61046927SAndroid Build Coastguard Worker:c:enum:`isl_format` enum. A complete list of surface formats is included at 7*61046927SAndroid Build Coastguard Workerthe end of this chapter. 8*61046927SAndroid Build Coastguard Worker 9*61046927SAndroid Build Coastguard WorkerIn general, a surface format definition consists of two parts: encoding and 10*61046927SAndroid Build Coastguard Workerlayout. 11*61046927SAndroid Build Coastguard Worker 12*61046927SAndroid Build Coastguard WorkerData Encoding 13*61046927SAndroid Build Coastguard Worker------------- 14*61046927SAndroid Build Coastguard Worker 15*61046927SAndroid Build Coastguard WorkerThere are several different ways that one can encode a number (or vector) into 16*61046927SAndroid Build Coastguard Workera binary form, and each makes different trade-offs. By default, most color 17*61046927SAndroid Build Coastguard Workervalues lie in the range [0, 1], so one of the most common encodings for color 18*61046927SAndroid Build Coastguard Workerdata is unsigned normalized where the range of an unsigned integer of a 19*61046927SAndroid Build Coastguard Workerparticular size is mapped linearly onto the interval [0, 1]. While normalized 20*61046927SAndroid Build Coastguard Workeris certainly the most common representation for color data, not all data is 21*61046927SAndroid Build Coastguard Workercolor data, and not all values are nicely bounded. The possible data encodings 22*61046927SAndroid Build Coastguard Workerare specified by :c:enum:`isl_base_type`: 23*61046927SAndroid Build Coastguard Worker 24*61046927SAndroid Build Coastguard Worker.. c:autoenum:: isl_base_type 25*61046927SAndroid Build Coastguard Worker :file: src/intel/isl/isl.h 26*61046927SAndroid Build Coastguard Worker :members: 27*61046927SAndroid Build Coastguard Worker 28*61046927SAndroid Build Coastguard WorkerData Layout 29*61046927SAndroid Build Coastguard Worker----------- 30*61046927SAndroid Build Coastguard Worker 31*61046927SAndroid Build Coastguard WorkerThe different data layouts fall into two categories: array and packed. When an 32*61046927SAndroid Build Coastguard Workerarray layout is used, the components are stored sequentially in an array of the 33*61046927SAndroid Build Coastguard Workergiven encoding. For instance, if the data is encoded in an 8-bit RGBA array 34*61046927SAndroid Build Coastguard Workerformat the data is stored in an array of type :c:type:`uint8_t` where the blue 35*61046927SAndroid Build Coastguard Workercomponent of the ``i``'th color value is accessed as: 36*61046927SAndroid Build Coastguard Worker 37*61046927SAndroid Build Coastguard Worker.. code-block:: C 38*61046927SAndroid Build Coastguard Worker 39*61046927SAndroid Build Coastguard Worker uint8_t r = ((uint8_t *)data)[i * 4 + 0]; 40*61046927SAndroid Build Coastguard Worker uint8_t g = ((uint8_t *)data)[i * 4 + 1]; 41*61046927SAndroid Build Coastguard Worker uint8_t b = ((uint8_t *)data)[i * 4 + 2]; 42*61046927SAndroid Build Coastguard Worker uint8_t a = ((uint8_t *)data)[i * 4 + 3]; 43*61046927SAndroid Build Coastguard Worker 44*61046927SAndroid Build Coastguard WorkerArray formats are popular because of their simplicity. However, they are 45*61046927SAndroid Build Coastguard Workerlimited to formats where all components have the same size and fit in 46*61046927SAndroid Build Coastguard Workera standard C data type. 47*61046927SAndroid Build Coastguard Worker 48*61046927SAndroid Build Coastguard WorkerPacked formats, on the other hand, are encoded with the entire color value 49*61046927SAndroid Build Coastguard Workerpacked into a single 8, 16, or 32-bit value. The components are specified by 50*61046927SAndroid Build Coastguard Workerwhich bits they occupy within that value. For instance, with the popular 51*61046927SAndroid Build Coastguard Worker``RGB565`` format, each :c:type:`vec3` takes up 16 bits and the 52*61046927SAndroid Build Coastguard Worker``i``'th color value is accessed as: 53*61046927SAndroid Build Coastguard Worker 54*61046927SAndroid Build Coastguard Worker.. code-block:: C 55*61046927SAndroid Build Coastguard Worker 56*61046927SAndroid Build Coastguard Worker uint8_t r = (*(uint16_t *)data >> 0) & 0x1f; 57*61046927SAndroid Build Coastguard Worker uint8_t g = (*(uint16_t *)data >> 5) & 0x3f; 58*61046927SAndroid Build Coastguard Worker uint8_t b = (*(uint16_t *)data >> 11) & 0x1f; 59*61046927SAndroid Build Coastguard Worker 60*61046927SAndroid Build Coastguard WorkerPacked formats are useful because they allow you to specify formats with uneven 61*61046927SAndroid Build Coastguard Workercomponent sizes such as ``RGBA1010102`` or where the components are 62*61046927SAndroid Build Coastguard Workersmaller than 8 bits such as ``RGB565`` discussed above. It does, 63*61046927SAndroid Build Coastguard Workerhowever, come with the restriction that the entire vector must fit within 8, 64*61046927SAndroid Build Coastguard Worker16, or 32 bits. 65*61046927SAndroid Build Coastguard Worker 66*61046927SAndroid Build Coastguard WorkerOne has to be careful when reasoning about packed formats because it is easy to 67*61046927SAndroid Build Coastguard Workerget the color order wrong. With array formats, the channel ordering is usually 68*61046927SAndroid Build Coastguard Workerimplied directly from the format name with ``RGBA8888`` storing the 69*61046927SAndroid Build Coastguard Workerformats as in the first example and ``BGRA8888`` storing them in the BGRA 70*61046927SAndroid Build Coastguard Workerordering. Packed formats, however, are not as simple because some 71*61046927SAndroid Build Coastguard Workerspecifications choose to use a MSB to LSB ordering and others LSB to MSB. One 72*61046927SAndroid Build Coastguard Workermust be careful to pay attention to the enum in question in order to avoid 73*61046927SAndroid Build Coastguard Workergetting them backwards. 74*61046927SAndroid Build Coastguard Worker 75*61046927SAndroid Build Coastguard WorkerFrom an API perspective, both types of formats are available. In Vulkan, the 76*61046927SAndroid Build Coastguard Workerformats that are of the form ``VK_FORMAT_xxx_PACKEDn`` are packed 77*61046927SAndroid Build Coastguard Workerformats where the entire color fits in ``n`` bits and formats without the 78*61046927SAndroid Build Coastguard Worker``_PACKEDn`` suffix are array formats. In GL, if you specify one of the 79*61046927SAndroid Build Coastguard Workerbase types such as :c:enumerator:`GL_FLOAT` you get an array format but if you 80*61046927SAndroid Build Coastguard Workerspecify a packed type such as :c:enumerator:`GL_UNSIGNED_INT_8_8_8_8_REV` you 81*61046927SAndroid Build Coastguard Workerget a packed format. 82*61046927SAndroid Build Coastguard Worker 83*61046927SAndroid Build Coastguard WorkerThe following table provides a summary of the bit orderings of different packed 84*61046927SAndroid Build Coastguard Workerformat specifications. The bit ordering is relative to the reading of the enum 85*61046927SAndroid Build Coastguard Workername from left to right. 86*61046927SAndroid Build Coastguard Worker 87*61046927SAndroid Build Coastguard Worker===================== ============== 88*61046927SAndroid Build Coastguard WorkerComponent Left → Right 89*61046927SAndroid Build Coastguard Worker===================== ============== 90*61046927SAndroid Build Coastguard WorkerGL MSB → LSB 91*61046927SAndroid Build Coastguard WorkerVulkan MSB → LSB 92*61046927SAndroid Build Coastguard Workermesa_format LSB → MSB 93*61046927SAndroid Build Coastguard WorkerIntel surface format LSB → MSB 94*61046927SAndroid Build Coastguard Worker===================== ============== 95*61046927SAndroid Build Coastguard Worker 96*61046927SAndroid Build Coastguard WorkerUnderstanding sRGB 97*61046927SAndroid Build Coastguard Worker------------------ 98*61046927SAndroid Build Coastguard Worker 99*61046927SAndroid Build Coastguard WorkerThe sRGB colorspace is one of the least tractable concepts in the entire world 100*61046927SAndroid Build Coastguard Workerof surfaces and formats. Most texture formats are stored in a linear 101*61046927SAndroid Build Coastguard Workercolorspace where the floating-point value corresponds linearly to intensity 102*61046927SAndroid Build Coastguard Workervalues. The sRGB color space, on the other hand, is non-linear and provides 103*61046927SAndroid Build Coastguard Workergreater precision in the lower-intensity (darker) end of the spectrum. The 104*61046927SAndroid Build Coastguard Workerrelationship between linear and sRGB is governed by the following continuous 105*61046927SAndroid Build Coastguard Workerbijection: 106*61046927SAndroid Build Coastguard Worker 107*61046927SAndroid Build Coastguard Worker.. math:: 108*61046927SAndroid Build Coastguard Worker 109*61046927SAndroid Build Coastguard Worker c_l = 110*61046927SAndroid Build Coastguard Worker \begin{cases} 111*61046927SAndroid Build Coastguard Worker \frac{c_s}{12.92} &\text{if } c_s \le 0.04045 \\\\ 112*61046927SAndroid Build Coastguard Worker \left(\frac{c_s + 0.055}{1.055}\right)^{2.4} &\text{if } c_s > 0.04045 113*61046927SAndroid Build Coastguard Worker \end{cases} 114*61046927SAndroid Build Coastguard Worker 115*61046927SAndroid Build Coastguard Workerwhere :math:`c_l` is the linear color and :math:`c_s` is the color in sRGB. 116*61046927SAndroid Build Coastguard WorkerIt is important to note that, when an alpha channel is present, the alpha 117*61046927SAndroid Build Coastguard Workerchannel is always stored in the linear colorspace. 118*61046927SAndroid Build Coastguard Worker 119*61046927SAndroid Build Coastguard WorkerThe key to understanding sRGB is to think about it starting from the physical 120*61046927SAndroid Build Coastguard Workerdisplay. All displays work natively in sRGB. On older displays, there isn't 121*61046927SAndroid Build Coastguard Workerso much a conversion operation as a fact of how the hardware works. All 122*61046927SAndroid Build Coastguard Workerdisplay hardware has a natural gamma curve required to get from linear to the 123*61046927SAndroid Build Coastguard Workersignal level required to generate the correct color. On older CRT displays, 124*61046927SAndroid Build Coastguard Workerthe gamma curve of your average CRT is approximately the sRGB curve. More 125*61046927SAndroid Build Coastguard Workermodern display hardware has support for additional gamma curves to try and get 126*61046927SAndroid Build Coastguard Workeraccurate colors but, for the sake of compatibility, everything still operates 127*61046927SAndroid Build Coastguard Workerin sRGB. When an image is sent to the X server, X passes the pixels on to the 128*61046927SAndroid Build Coastguard Workerdisplay verbatim without doing any conversions. (Fun fact: When dealing with 129*61046927SAndroid Build Coastguard Workertranslucent windows, X blends in the wrong colorspace.) This means that the 130*61046927SAndroid Build Coastguard Workerimage into which you are rendering will always be interpreted as if it were in 131*61046927SAndroid Build Coastguard Workerthe sRGB colorspace. 132*61046927SAndroid Build Coastguard Worker 133*61046927SAndroid Build Coastguard WorkerWhen sampling from a texture, the value returned to the shader is in the linear 134*61046927SAndroid Build Coastguard Workercolorspace. The conversion from sRGB happens as part of sampling. In OpenGL, 135*61046927SAndroid Build Coastguard Workerthanks mostly to history, there are various knobs for determining when you 136*61046927SAndroid Build Coastguard Workershould or should not encode or decode sRGB. In 2007, :ext:`GL_EXT_texture_sRGB` 137*61046927SAndroid Build Coastguard Workeradded support for sRGB texture formats and was included in OpenGL 2.1. In 138*61046927SAndroid Build Coastguard Worker2010, :ext:`GL_EXT_texture_sRGB_decode` added a flag to allow you to disable 139*61046927SAndroid Build Coastguard Workertexture decoding so that the shader received the data still in the sRGB 140*61046927SAndroid Build Coastguard Workercolorspace. Then, in 2012, :ext:`GL_ARB_texture_view` came along and made 141*61046927SAndroid Build Coastguard Worker:ext:`GL_EXT_texture_sRGB_decode` simultaneously obsolete and very confusing. 142*61046927SAndroid Build Coastguard WorkerNow, thanks to the combination of extensions, you can upload a texture as 143*61046927SAndroid Build Coastguard Workerlinear, create an sRGB view of it and ask that sRGB not be decoded. What 144*61046927SAndroid Build Coastguard Workerformat is it in again? 145*61046927SAndroid Build Coastguard Worker 146*61046927SAndroid Build Coastguard WorkerThe situation with render targets is a bit different. Historically, you got 147*61046927SAndroid Build Coastguard Workeryour render target from the window system (which is always sRGB) and the spec 148*61046927SAndroid Build Coastguard Workersaid nothing whatsoever about encoding. All render targets were sRGB because 149*61046927SAndroid Build Coastguard Workerthat's how monitors worked and application writers were expected to understand 150*61046927SAndroid Build Coastguard Workerthat their final rendering needed to be in sRGB. However, with the advent of 151*61046927SAndroid Build Coastguard Worker:ext:`GL_EXT_framebuffer_object` this was no longer true. Also, sRGB was causing 152*61046927SAndroid Build Coastguard Workerproblems with blending because GL was blind to the fact that the output was 153*61046927SAndroid Build Coastguard WorkersRGB and blending was occurring in the wrong colorspace. In 2006, a set of 154*61046927SAndroid Build Coastguard Worker:ext:`GL_EXT_framebuffer_sRGB` extensions added support (on both the GL and 155*61046927SAndroid Build Coastguard Workerwindow-system sides) for detecting whether a particular framebuffer was in sRGB 156*61046927SAndroid Build Coastguard Workerand instructing GL to do the conversion into the sRGB colorspace as the final 157*61046927SAndroid Build Coastguard Workerstep prior to writing out to the render target. Enabling sRGB also implied 158*61046927SAndroid Build Coastguard Workerthat blending would occur in the linear colorspace prior to sRGB conversion and 159*61046927SAndroid Build Coastguard Workerwould therefore be more accurate. When sRGB was added to the OpenGL ES spec in 160*61046927SAndroid Build Coastguard Worker3.1, they added the query for sRGB but did not add the flag to allow you to 161*61046927SAndroid Build Coastguard Workerturn it on and off. 162*61046927SAndroid Build Coastguard Worker 163*61046927SAndroid Build Coastguard WorkerIn Vulkan, this is all much more straightforward. Your format is sRGB or it 164*61046927SAndroid Build Coastguard Workerisn't. If you have an sRGB image and you don't want sRGB decoding to happen 165*61046927SAndroid Build Coastguard Workerwhen you sample from it, you simply create a :c:struct:`VkImageView` that has 166*61046927SAndroid Build Coastguard Workerthe appropriate linear format and the data will be treated as linear and not 167*61046927SAndroid Build Coastguard Workerconverted. Similarly for render targets, blending always happens in the same 168*61046927SAndroid Build Coastguard Workercolorspace as the shader output and you determine whether or not you want sRGB 169*61046927SAndroid Build Coastguard Workerconversion by the format of the :c:struct:`VkImageView` used as the render 170*61046927SAndroid Build Coastguard Workertarget. 171*61046927SAndroid Build Coastguard Worker 172*61046927SAndroid Build Coastguard WorkerSurface Format Introspection API 173*61046927SAndroid Build Coastguard Worker-------------------------------- 174*61046927SAndroid Build Coastguard Worker 175*61046927SAndroid Build Coastguard WorkerISL provides an API for introspecting the :c:enum:`isl_format` enum and 176*61046927SAndroid Build Coastguard Workergetting various bits of information about a format. ISL provides helpers for 177*61046927SAndroid Build Coastguard Workerintrospecting both the data layout of an :c:enum:`isl_format` and the 178*61046927SAndroid Build Coastguard Workercapabilities of that format for a particular piece of Intel hardware. 179*61046927SAndroid Build Coastguard Worker 180*61046927SAndroid Build Coastguard WorkerFormat Layout Introspection 181*61046927SAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^ 182*61046927SAndroid Build Coastguard Worker 183*61046927SAndroid Build Coastguard WorkerTo get the layout of a given :c:enum:`isl_format`, call 184*61046927SAndroid Build Coastguard Worker:c:func:`isl_format_get_layout`: 185*61046927SAndroid Build Coastguard Worker 186*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_get_layout 187*61046927SAndroid Build Coastguard Worker 188*61046927SAndroid Build Coastguard Worker.. c:autostruct:: isl_format_layout 189*61046927SAndroid Build Coastguard Worker :members: 190*61046927SAndroid Build Coastguard Worker 191*61046927SAndroid Build Coastguard Worker.. c:autostruct:: isl_channel_layout 192*61046927SAndroid Build Coastguard Worker :members: 193*61046927SAndroid Build Coastguard Worker 194*61046927SAndroid Build Coastguard WorkerThere are also quite a few helpers for many of the common cases that allow you 195*61046927SAndroid Build Coastguard Workerto avoid using :c:struct:`isl_format_layout` manually. There are a lot of 196*61046927SAndroid Build Coastguard Workerthem so we won't include a full list here. Look at isl.h for more details. 197*61046927SAndroid Build Coastguard Worker 198*61046927SAndroid Build Coastguard WorkerHardware Format Support Introspection 199*61046927SAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 200*61046927SAndroid Build Coastguard Worker 201*61046927SAndroid Build Coastguard WorkerThis is provided by means of a table located in isl_format.c. Looking at the 202*61046927SAndroid Build Coastguard Workertable directly is often useful for understanding HW support for various 203*61046927SAndroid Build Coastguard Workerformats. However, for the purposes of code cleanliness, the table is not 204*61046927SAndroid Build Coastguard Workerexposed directly and, instead, hardware support information is exposed via 205*61046927SAndroid Build Coastguard Workera set of helper functions: 206*61046927SAndroid Build Coastguard Worker 207*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_rendering 208*61046927SAndroid Build Coastguard Worker 209*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_alpha_blending 210*61046927SAndroid Build Coastguard Worker 211*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_sampling 212*61046927SAndroid Build Coastguard Worker 213*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_filtering 214*61046927SAndroid Build Coastguard Worker 215*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_vertex_fetch 216*61046927SAndroid Build Coastguard Worker 217*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_typed_writes 218*61046927SAndroid Build Coastguard Worker :file: src/intel/isl/isl_format.c 219*61046927SAndroid Build Coastguard Worker 220*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_typed_reads 221*61046927SAndroid Build Coastguard Worker 222*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_ccs_d 223*61046927SAndroid Build Coastguard Worker 224*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_ccs_e 225*61046927SAndroid Build Coastguard Worker 226*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_supports_multisampling 227*61046927SAndroid Build Coastguard Worker 228*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_formats_are_ccs_e_compatible 229*61046927SAndroid Build Coastguard Worker 230*61046927SAndroid Build Coastguard WorkerSurface Format Enums 231*61046927SAndroid Build Coastguard Worker-------------------- 232*61046927SAndroid Build Coastguard Worker 233*61046927SAndroid Build Coastguard WorkerEverything in ISL is done in terms of the :c:enum:`isl_format` enum. However, 234*61046927SAndroid Build Coastguard Workerfor the sake of interacting with other parts of Mesa, we provide a helper for 235*61046927SAndroid Build Coastguard Workerconverting a :c:enum:`pipe_format` to an :c:enum:`isl_format`: 236*61046927SAndroid Build Coastguard Worker 237*61046927SAndroid Build Coastguard Worker.. c:autofunction:: isl_format_for_pipe_format 238*61046927SAndroid Build Coastguard Worker 239*61046927SAndroid Build Coastguard WorkerThe :c:enum:`isl_format` enum is as follows: 240*61046927SAndroid Build Coastguard Worker 241*61046927SAndroid Build Coastguard Worker.. c:autoenum:: isl_format 242*61046927SAndroid Build Coastguard Worker :members: 243