/src/mpv/video/out/opengl/formats.c
Line | Count | Source |
1 | | #include "common/common.h" |
2 | | #include "formats.h" |
3 | | |
4 | | enum { |
5 | | // --- GL type aliases (for readability) |
6 | | T_U8 = GL_UNSIGNED_BYTE, |
7 | | T_U16 = GL_UNSIGNED_SHORT, |
8 | | T_FL = GL_FLOAT, |
9 | | }; |
10 | | |
11 | | // List of allowed formats, and their usability for bilinear filtering and FBOs. |
12 | | // This is limited to combinations that are useful for our renderer. |
13 | | const struct gl_format gl_formats[] = { |
14 | | // These are used for desktop GL 3+, and GLES 3+ with GL_EXT_texture_norm16. |
15 | | {"r8", GL_R8, GL_RED, T_U8, F_CF | F_GL3 | F_GL2F | F_ES3}, |
16 | | {"rg8", GL_RG8, GL_RG, T_U8, F_CF | F_GL3 | F_GL2F | F_ES3}, |
17 | | {"rgb8", GL_RGB8, GL_RGB, T_U8, F_CF | F_GL3 | F_GL2F | F_ES3}, |
18 | | {"rgba8", GL_RGBA8, GL_RGBA, T_U8, F_CF | F_GL3 | F_GL2F | F_ES3}, |
19 | | {"r16", GL_R16, GL_RED, T_U16, F_CF | F_GL3 | F_GL2F | F_EXT16}, |
20 | | {"rg16", GL_RG16, GL_RG, T_U16, F_CF | F_GL3 | F_GL2F | F_EXT16}, |
21 | | {"rgb16", GL_RGB16, GL_RGB, T_U16, F_CF | F_GL3 | F_GL2F}, |
22 | | {"rgba16", GL_RGBA16, GL_RGBA, T_U16, F_CF | F_GL3 | F_GL2F | F_EXT16}, |
23 | | |
24 | | // Specifically not color-renderable. |
25 | | {"rgb16", GL_RGB16, GL_RGB, T_U16, F_TF | F_EXT16}, |
26 | | |
27 | | // GL2 legacy. Ignores possibly present FBO extensions (no CF flag set). |
28 | | {"l8", GL_LUMINANCE8, GL_LUMINANCE, T_U8, F_TF | F_GL2}, |
29 | | {"la8", GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, T_U8, F_TF | F_GL2}, |
30 | | {"rgb8", GL_RGB8, GL_RGB, T_U8, F_TF | F_GL2}, |
31 | | {"rgba8", GL_RGBA8, GL_RGBA, T_U8, F_TF | F_GL2}, |
32 | | {"l16", GL_LUMINANCE16, GL_LUMINANCE, T_U16, F_TF | F_GL2}, |
33 | | {"la16", GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA, T_U16, F_TF | F_GL2}, |
34 | | {"rgb16", GL_RGB16, GL_RGB, T_U16, F_TF | F_GL2}, |
35 | | {"rgba16", GL_RGBA16, GL_RGBA, T_U16, F_TF | F_GL2}, |
36 | | |
37 | | // ES3 legacy. This is literally to compensate for Apple bugs in their iOS |
38 | | // interop (can they do anything right?). ES3 still allows these formats, |
39 | | // but they are deprecated. |
40 | | {"l" , GL_LUMINANCE,GL_LUMINANCE, T_U8, F_CF | F_ES3}, |
41 | | {"la",GL_LUMINANCE_ALPHA,GL_LUMINANCE_ALPHA, T_U8, F_CF | F_ES3}, |
42 | | |
43 | | // ES2 legacy |
44 | | {"l" , GL_LUMINANCE,GL_LUMINANCE, T_U8, F_TF | F_ES2}, |
45 | | {"la",GL_LUMINANCE_ALPHA,GL_LUMINANCE_ALPHA, T_U8, F_TF | F_ES2}, |
46 | | {"rgb", GL_RGB, GL_RGB, T_U8, F_TF | F_ES2}, |
47 | | {"rgba", GL_RGBA, GL_RGBA, T_U8, F_TF | F_ES2}, |
48 | | |
49 | | // Non-normalized integer formats. |
50 | | // Follows ES 3.0 as to which are color-renderable. |
51 | | {"r8ui", GL_R8UI, GL_RED_INTEGER, T_U8, F_CR | F_GL3 | F_ES3}, |
52 | | {"rg8ui", GL_RG8UI, GL_RG_INTEGER, T_U8, F_CR | F_GL3 | F_ES3}, |
53 | | {"rgb8ui", GL_RGB8UI, GL_RGB_INTEGER, T_U8, F_GL3 | F_ES3}, |
54 | | {"rgba8ui", GL_RGBA8UI, GL_RGBA_INTEGER, T_U8, F_CR | F_GL3 | F_ES3}, |
55 | | {"r16ui", GL_R16UI, GL_RED_INTEGER, T_U16, F_CR | F_GL3 | F_ES3}, |
56 | | {"rg16ui", GL_RG16UI, GL_RG_INTEGER, T_U16, F_CR | F_GL3 | F_ES3}, |
57 | | {"rgb16ui", GL_RGB16UI, GL_RGB_INTEGER, T_U16, F_GL3 | F_ES3}, |
58 | | {"rgba16ui",GL_RGBA16UI, GL_RGBA_INTEGER, T_U16, F_CR | F_GL3 | F_ES3}, |
59 | | |
60 | | // On GL3+ or GL2.1 with GL_ARB_texture_float, floats work fully. |
61 | | {"r16f", GL_R16F, GL_RED, T_FL, F_F16 | F_CF | F_GL3 | F_GL2F}, |
62 | | {"rg16f", GL_RG16F, GL_RG, T_FL, F_F16 | F_CF | F_GL3 | F_GL2F}, |
63 | | {"rgb16f", GL_RGB16F, GL_RGB, T_FL, F_F16 | F_CF | F_GL3 | F_GL2F}, |
64 | | {"rgba16f", GL_RGBA16F, GL_RGBA, T_FL, F_F16 | F_CF | F_GL3 | F_GL2F}, |
65 | | {"r32f", GL_R32F, GL_RED, T_FL, F_CF | F_GL3 | F_GL2F}, |
66 | | {"rg32f", GL_RG32F, GL_RG, T_FL, F_CF | F_GL3 | F_GL2F}, |
67 | | {"rgb32f", GL_RGB32F, GL_RGB, T_FL, F_CF | F_GL3 | F_GL2F}, |
68 | | {"rgba32f", GL_RGBA32F, GL_RGBA, T_FL, F_CF | F_GL3 | F_GL2F}, |
69 | | |
70 | | // Note: we simply don't support float anything on ES2, despite extensions. |
71 | | // We also don't bother with non-filterable float formats, and we ignore |
72 | | // 32 bit float formats that are not blendable when rendering to them. |
73 | | |
74 | | // On ES3.2+, both 16 bit floats work fully (except 3-component formats). |
75 | | // F_EXTF16 implies extensions that also enable 16 bit floats fully. |
76 | | {"r16f", GL_R16F, GL_RED, T_FL, F_F16 | F_CF | F_ES32 | F_EXTF16}, |
77 | | {"rg16f", GL_RG16F, GL_RG, T_FL, F_F16 | F_CF | F_ES32 | F_EXTF16}, |
78 | | {"rgb16f", GL_RGB16F, GL_RGB, T_FL, F_F16 | F_TF | F_ES32 | F_EXTF16}, |
79 | | {"rgba16f", GL_RGBA16F, GL_RGBA, T_FL, F_F16 | F_CF | F_ES32 | F_EXTF16}, |
80 | | |
81 | | // On ES3.0+, 16 bit floats are texture-filterable. |
82 | | // Don't bother with 32 bit floats; they exist but are neither CR nor TF. |
83 | | {"r16f", GL_R16F, GL_RED, T_FL, F_F16 | F_TF | F_ES3}, |
84 | | {"rg16f", GL_RG16F, GL_RG, T_FL, F_F16 | F_TF | F_ES3}, |
85 | | {"rgb16f", GL_RGB16F, GL_RGB, T_FL, F_F16 | F_TF | F_ES3}, |
86 | | {"rgba16f", GL_RGBA16F, GL_RGBA, T_FL, F_F16 | F_TF | F_ES3}, |
87 | | |
88 | | // These might be useful as FBO formats. |
89 | | {"rgb10_a2",GL_RGB10_A2, GL_RGBA, |
90 | | GL_UNSIGNED_INT_2_10_10_10_REV, F_CF | F_GL3 | F_ES3}, |
91 | | {"rgba12", GL_RGBA12, GL_RGBA, T_U16, F_CF | F_GL2 | F_GL3}, |
92 | | {"rgb10", GL_RGB10, GL_RGB, T_U16, F_CF | F_GL2 | F_GL3}, |
93 | | |
94 | | // Special formats. |
95 | | {"rgb565", GL_RGB8, GL_RGB, |
96 | | GL_UNSIGNED_SHORT_5_6_5, F_TF | F_GL2 | F_GL3}, |
97 | | // Worthless, but needed by macOS videotoolbox interop on old Apple hardware. |
98 | | {"appleyp", GL_RGB, GL_RGB_422_APPLE, |
99 | | GL_UNSIGNED_SHORT_8_8_APPLE, F_TF | F_APPL}, |
100 | | |
101 | | {0} |
102 | | }; |
103 | | |
104 | | // Return an or-ed combination of all F_ flags that apply. |
105 | | int gl_format_feature_flags(GL *gl) |
106 | 0 | { |
107 | 0 | return (gl->version == 210 ? F_GL2 : 0) |
108 | 0 | | (gl->version >= 300 ? F_GL3 : 0) |
109 | 0 | | (gl->es == 200 ? F_ES2 : 0) |
110 | 0 | | (gl->es >= 300 ? F_ES3 : 0) |
111 | 0 | | (gl->es >= 320 ? F_ES32 : 0) |
112 | 0 | | (gl->mpgl_caps & MPGL_CAP_EXT16 ? F_EXT16 : 0) |
113 | 0 | | ((gl->es >= 300 && |
114 | 0 | (gl->mpgl_caps & MPGL_CAP_EXT_CR_HFLOAT)) ? F_EXTF16 : 0) |
115 | 0 | | ((gl->version == 210 && |
116 | 0 | (gl->mpgl_caps & MPGL_CAP_ARB_FLOAT) && |
117 | 0 | (gl->mpgl_caps & MPGL_CAP_TEX_RG) && |
118 | 0 | (gl->mpgl_caps & MPGL_CAP_FB)) ? F_GL2F : 0) |
119 | 0 | | (gl->mpgl_caps & MPGL_CAP_APPLE_RGB_422 ? F_APPL : 0); |
120 | 0 | } |
121 | | |
122 | | int gl_format_type(const struct gl_format *format) |
123 | 0 | { |
124 | 0 | if (!format) |
125 | 0 | return 0; |
126 | 0 | if (format->type == GL_FLOAT) |
127 | 0 | return MPGL_TYPE_FLOAT; |
128 | 0 | if (gl_integer_format_to_base(format->format)) |
129 | 0 | return MPGL_TYPE_UINT; |
130 | 0 | return MPGL_TYPE_UNORM; |
131 | 0 | } |
132 | | |
133 | | // Return base internal format of an integer format, or 0 if it's not integer. |
134 | | // "format" is like in struct gl_format. |
135 | | GLenum gl_integer_format_to_base(GLenum format) |
136 | 0 | { |
137 | 0 | switch (format) { |
138 | 0 | case GL_RED_INTEGER: return GL_RED; |
139 | 0 | case GL_RG_INTEGER: return GL_RG; |
140 | 0 | case GL_RGB_INTEGER: return GL_RGB; |
141 | 0 | case GL_RGBA_INTEGER: return GL_RGBA; |
142 | 0 | } |
143 | 0 | return 0; |
144 | 0 | } |
145 | | |
146 | | // Return the number of bytes per component this format implies. |
147 | | // Returns 0 for formats with non-byte alignments and formats which |
148 | | // merge multiple components (like GL_UNSIGNED_SHORT_5_6_5). |
149 | | // "type" is like in struct gl_format. |
150 | | int gl_component_size(GLenum type) |
151 | 0 | { |
152 | 0 | switch (type) { |
153 | 0 | case GL_UNSIGNED_BYTE: return 1; |
154 | 0 | case GL_UNSIGNED_SHORT: return 2; |
155 | 0 | case GL_FLOAT: return 4; |
156 | 0 | } |
157 | 0 | return 0; |
158 | 0 | } |
159 | | |
160 | | // Return the number of separate color components. |
161 | | // "format" is like in struct gl_format. |
162 | | int gl_format_components(GLenum format) |
163 | 0 | { |
164 | 0 | switch (format) { |
165 | 0 | case GL_RED: |
166 | 0 | case GL_RED_INTEGER: |
167 | 0 | case GL_LUMINANCE: |
168 | 0 | return 1; |
169 | 0 | case GL_RG: |
170 | 0 | case GL_RG_INTEGER: |
171 | 0 | case GL_LUMINANCE_ALPHA: |
172 | 0 | return 2; |
173 | 0 | case GL_RGB: |
174 | 0 | case GL_RGB_INTEGER: |
175 | 0 | return 3; |
176 | 0 | case GL_RGBA: |
177 | 0 | case GL_RGBA_INTEGER: |
178 | 0 | return 4; |
179 | 0 | } |
180 | 0 | return 0; |
181 | 0 | } |
182 | | |
183 | | // Return the number of bytes per pixel for the given format. |
184 | | // Parameter names like in struct gl_format. |
185 | | int gl_bytes_per_pixel(GLenum format, GLenum type) |
186 | 0 | { |
187 | | // Formats with merged components are special. |
188 | 0 | switch (type) { |
189 | 0 | case GL_UNSIGNED_INT_2_10_10_10_REV: return 4; |
190 | 0 | case GL_UNSIGNED_SHORT_5_6_5: return 2; |
191 | 0 | case GL_UNSIGNED_SHORT_8_8_APPLE: return 2; |
192 | 0 | case GL_UNSIGNED_SHORT_8_8_REV_APPLE: return 2; |
193 | 0 | } |
194 | | |
195 | 0 | return gl_component_size(type) * gl_format_components(format); |
196 | 0 | } |