xref: /aosp_15_r20/external/mesa3d/docs/isl/formats.rst (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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