1 /**************************************************************************
2 *
3 * Copyright (C) 2014 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24 #include <epoxy/gl.h>
25
26 #include "vrend_renderer.h"
27 #include "util/u_memory.h"
28 #include "util/u_format.h"
29
30 #define SWIZZLE_INVALID 0xff
31 #define NO_SWIZZLE { SWIZZLE_INVALID, SWIZZLE_INVALID, SWIZZLE_INVALID, SWIZZLE_INVALID }
32 #define RRR1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ONE }
33 #define RGB1_SWIZZLE { PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ONE }
34 #define OOOR_SWIZZLE { PIPE_SWIZZLE_ZERO, PIPE_SWIZZLE_ZERO, PIPE_SWIZZLE_ZERO, PIPE_SWIZZLE_RED }
35
36 #define BGR1_SWIZZLE { PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ONE }
37 #define BGRA_SWIZZLE { PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_GREEN, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_ALPHA }
38
39 #ifdef __GNUC__
40 /* The warning missing-field-initializers is misleading: If at least one field
41 * is initialized, then the un-initialized fields will be filled with zero.
42 * Silencing the warning by manually adding the zeros that the compiler will add
43 * anyway doesn't improve the code, and initializing the files by using a named
44 * notation will make it worse, because then he remaining fields truely be
45 * un-initialized.
46 */
47 #ifdef __clang__
48 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
49 #else
50 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
51 #endif
52 #endif
53
54 /* fill the format table */
55 static struct vrend_format_table base_rgba_formats[] =
56 {
57 { VIRGL_FORMAT_R8G8B8X8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
58 { VIRGL_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
59
60 { VIRGL_FORMAT_A8R8G8B8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NO_SWIZZLE },
61 { VIRGL_FORMAT_X8R8G8B8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NO_SWIZZLE },
62
63 { VIRGL_FORMAT_A8B8G8R8_UNORM, GL_RGBA8, GL_ABGR_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE },
64
65 { VIRGL_FORMAT_B4G4R4X4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, RGB1_SWIZZLE },
66 { VIRGL_FORMAT_A4B4G4R4_UNORM, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NO_SWIZZLE },
67 { VIRGL_FORMAT_B5G5R5X1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, RGB1_SWIZZLE },
68
69 { VIRGL_FORMAT_B5G6R5_UNORM, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NO_SWIZZLE },
70 { VIRGL_FORMAT_B2G3R3_UNORM, GL_R3_G3_B2, GL_RGB, GL_UNSIGNED_BYTE_3_3_2, NO_SWIZZLE },
71
72 { VIRGL_FORMAT_R16G16B16X16_UNORM, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, RGB1_SWIZZLE },
73
74 { VIRGL_FORMAT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, NO_SWIZZLE },
75 };
76
77 static struct vrend_format_table gl_base_rgba_formats[] =
78 {
79 { VIRGL_FORMAT_B4G4R4A4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, NO_SWIZZLE },
80 { VIRGL_FORMAT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NO_SWIZZLE },
81 };
82
83 static struct vrend_format_table base_depth_formats[] =
84 {
85 { VIRGL_FORMAT_Z16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NO_SWIZZLE },
86 { VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE },
87 { VIRGL_FORMAT_S8_UINT_Z24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NO_SWIZZLE },
88 { VIRGL_FORMAT_Z24X8_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE },
89 { VIRGL_FORMAT_Z32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, NO_SWIZZLE },
90 /* this is probably a separate format */
91 { VIRGL_FORMAT_Z32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NO_SWIZZLE },
92 { VIRGL_FORMAT_X24S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, NO_SWIZZLE },
93 };
94
95 static struct vrend_format_table base_la_formats[] = {
96 { VIRGL_FORMAT_A8_UNORM, GL_ALPHA8, GL_ALPHA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
97 { VIRGL_FORMAT_L8_UNORM, GL_R8, GL_RED, GL_UNSIGNED_BYTE, RRR1_SWIZZLE },
98 { VIRGL_FORMAT_A16_UNORM, GL_ALPHA16, GL_ALPHA, GL_UNSIGNED_SHORT, NO_SWIZZLE },
99 { VIRGL_FORMAT_L16_UNORM, GL_R16, GL_RED, GL_UNSIGNED_SHORT, RRR1_SWIZZLE },
100 };
101
102 static struct vrend_format_table rg_base_formats[] = {
103 { VIRGL_FORMAT_R8_UNORM, GL_R8, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE },
104 { VIRGL_FORMAT_R8G8_UNORM, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE },
105 { VIRGL_FORMAT_R16_UNORM, GL_R16, GL_RED, GL_UNSIGNED_SHORT, NO_SWIZZLE },
106 { VIRGL_FORMAT_R16G16_UNORM, GL_RG16, GL_RG, GL_UNSIGNED_SHORT, NO_SWIZZLE },
107 };
108
109 static struct vrend_format_table integer_base_formats[] = {
110 { VIRGL_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE },
111 { VIRGL_FORMAT_R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, NO_SWIZZLE },
112
113 { VIRGL_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE },
114 { VIRGL_FORMAT_R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, NO_SWIZZLE },
115
116 { VIRGL_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
117 { VIRGL_FORMAT_R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT, NO_SWIZZLE },
118 };
119
120 static struct vrend_format_table integer_3comp_formats[] = {
121 { VIRGL_FORMAT_R8G8B8X8_UINT, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
122 { VIRGL_FORMAT_R8G8B8X8_SINT, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, RGB1_SWIZZLE },
123 { VIRGL_FORMAT_R16G16B16X16_UINT, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, RGB1_SWIZZLE },
124 { VIRGL_FORMAT_R16G16B16X16_SINT, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, RGB1_SWIZZLE },
125 { VIRGL_FORMAT_R32G32B32_UINT, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
126 { VIRGL_FORMAT_R32G32B32_SINT, GL_RGB32I, GL_RGB_INTEGER, GL_INT, NO_SWIZZLE },
127 };
128
129 static struct vrend_format_table float_base_formats[] = {
130 { VIRGL_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, NO_SWIZZLE },
131 { VIRGL_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA, GL_FLOAT, NO_SWIZZLE },
132 };
133
134 static struct vrend_format_table float_la_formats[] = {
135 { VIRGL_FORMAT_A16_FLOAT, GL_R16F, GL_RED, GL_HALF_FLOAT, OOOR_SWIZZLE },
136 { VIRGL_FORMAT_L16_FLOAT, GL_R16F, GL_RED, GL_HALF_FLOAT, RRR1_SWIZZLE },
137 { VIRGL_FORMAT_L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_ARB, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, NO_SWIZZLE },
138
139 { VIRGL_FORMAT_A32_FLOAT, GL_R32F, GL_RED, GL_FLOAT, OOOR_SWIZZLE },
140 { VIRGL_FORMAT_L32_FLOAT, GL_R32F, GL_RED, GL_FLOAT, RRR1_SWIZZLE },
141 { VIRGL_FORMAT_L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_ARB, GL_LUMINANCE_ALPHA, GL_FLOAT, NO_SWIZZLE },
142 };
143
144 static struct vrend_format_table integer_rg_formats[] = {
145 { VIRGL_FORMAT_R8_UINT, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE },
146 { VIRGL_FORMAT_R8G8_UINT, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE },
147 { VIRGL_FORMAT_R8_SINT, GL_R8I, GL_RED_INTEGER, GL_BYTE, NO_SWIZZLE },
148 { VIRGL_FORMAT_R8G8_SINT, GL_RG8I, GL_RG_INTEGER, GL_BYTE, NO_SWIZZLE },
149
150 { VIRGL_FORMAT_R16_UINT, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE },
151 { VIRGL_FORMAT_R16G16_UINT, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE },
152 { VIRGL_FORMAT_R16_SINT, GL_R16I, GL_RED_INTEGER, GL_SHORT, NO_SWIZZLE },
153 { VIRGL_FORMAT_R16G16_SINT, GL_RG16I, GL_RG_INTEGER, GL_SHORT, NO_SWIZZLE },
154
155 { VIRGL_FORMAT_R32_UINT, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
156 { VIRGL_FORMAT_R32G32_UINT, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
157 { VIRGL_FORMAT_R32_SINT, GL_R32I, GL_RED_INTEGER, GL_INT, NO_SWIZZLE },
158 { VIRGL_FORMAT_R32G32_SINT, GL_RG32I, GL_RG_INTEGER, GL_INT, NO_SWIZZLE },
159 };
160
161 static struct vrend_format_table float_rg_formats[] = {
162 { VIRGL_FORMAT_R16_FLOAT, GL_R16F, GL_RED, GL_HALF_FLOAT, NO_SWIZZLE },
163 { VIRGL_FORMAT_R16G16_FLOAT, GL_RG16F, GL_RG, GL_HALF_FLOAT, NO_SWIZZLE },
164 { VIRGL_FORMAT_R32_FLOAT, GL_R32F, GL_RED, GL_FLOAT, NO_SWIZZLE },
165 { VIRGL_FORMAT_R32G32_FLOAT, GL_RG32F, GL_RG, GL_FLOAT, NO_SWIZZLE },
166 };
167
168 static struct vrend_format_table float_3comp_formats[] = {
169 { VIRGL_FORMAT_R16G16B16X16_FLOAT, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, RGB1_SWIZZLE },
170 { VIRGL_FORMAT_R32G32B32_FLOAT, GL_RGB32F, GL_RGB, GL_FLOAT, NO_SWIZZLE },
171 };
172
173
174 static struct vrend_format_table integer_la_formats[] = {
175 { VIRGL_FORMAT_A8_UINT, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, OOOR_SWIZZLE },
176 { VIRGL_FORMAT_L8_UINT, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, RRR1_SWIZZLE },
177 { VIRGL_FORMAT_L8A8_UINT, GL_LUMINANCE_ALPHA8UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE },
178 { VIRGL_FORMAT_A8_SINT, GL_R8I, GL_RED_INTEGER, GL_BYTE, OOOR_SWIZZLE },
179 { VIRGL_FORMAT_L8_SINT, GL_R8I, GL_RED_INTEGER, GL_BYTE, RRR1_SWIZZLE },
180 { VIRGL_FORMAT_L8A8_SINT, GL_LUMINANCE_ALPHA8I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_BYTE, NO_SWIZZLE },
181
182 { VIRGL_FORMAT_A16_UINT, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, OOOR_SWIZZLE },
183 { VIRGL_FORMAT_L16_UINT, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, RRR1_SWIZZLE },
184 { VIRGL_FORMAT_L16A16_UINT, GL_LUMINANCE_ALPHA16UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_SHORT, NO_SWIZZLE },
185
186 { VIRGL_FORMAT_A16_SINT, GL_R16I, GL_RED_INTEGER, GL_SHORT, OOOR_SWIZZLE },
187 { VIRGL_FORMAT_L16_SINT, GL_R16I, GL_RED_INTEGER, GL_SHORT, RRR1_SWIZZLE },
188 { VIRGL_FORMAT_L16A16_SINT, GL_LUMINANCE_ALPHA16I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_SHORT, NO_SWIZZLE },
189
190 { VIRGL_FORMAT_A32_UINT, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, OOOR_SWIZZLE },
191 { VIRGL_FORMAT_L32_UINT, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, RRR1_SWIZZLE },
192 { VIRGL_FORMAT_L32A32_UINT, GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, NO_SWIZZLE },
193
194 { VIRGL_FORMAT_A32_SINT, GL_R32I, GL_RED_INTEGER, GL_INT, OOOR_SWIZZLE },
195 { VIRGL_FORMAT_L32_SINT, GL_R32I, GL_RED_INTEGER, GL_INT, RRR1_SWIZZLE },
196 { VIRGL_FORMAT_L32A32_SINT, GL_LUMINANCE_ALPHA32I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_INT, NO_SWIZZLE },
197
198
199 };
200
201 static struct vrend_format_table snorm_formats[] = {
202 { VIRGL_FORMAT_R8_SNORM, GL_R8_SNORM, GL_RED, GL_BYTE, NO_SWIZZLE },
203 { VIRGL_FORMAT_R8G8_SNORM, GL_RG8_SNORM, GL_RG, GL_BYTE, NO_SWIZZLE },
204
205 { VIRGL_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, NO_SWIZZLE },
206 { VIRGL_FORMAT_R8G8B8X8_SNORM, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, RGB1_SWIZZLE },
207
208 { VIRGL_FORMAT_R16_SNORM, GL_R16_SNORM, GL_RED, GL_SHORT, NO_SWIZZLE },
209 { VIRGL_FORMAT_R16G16_SNORM, GL_RG16_SNORM, GL_RG, GL_SHORT, NO_SWIZZLE },
210 { VIRGL_FORMAT_R16G16B16A16_SNORM, GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, NO_SWIZZLE },
211
212 { VIRGL_FORMAT_R16G16B16X16_SNORM, GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, RGB1_SWIZZLE },
213 };
214
215 static struct vrend_format_table snorm_la_formats[] = {
216 { VIRGL_FORMAT_A8_SNORM, GL_ALPHA8_SNORM, GL_ALPHA, GL_BYTE, NO_SWIZZLE },
217 { VIRGL_FORMAT_L8_SNORM, GL_R8_SNORM, GL_RED, GL_BYTE, RRR1_SWIZZLE },
218 { VIRGL_FORMAT_L8A8_SNORM, GL_LUMINANCE8_ALPHA8_SNORM, GL_LUMINANCE_ALPHA, GL_BYTE, NO_SWIZZLE },
219 { VIRGL_FORMAT_A16_SNORM, GL_ALPHA16_SNORM, GL_ALPHA, GL_SHORT, NO_SWIZZLE },
220 { VIRGL_FORMAT_L16_SNORM, GL_R16_SNORM, GL_RED, GL_SHORT, RRR1_SWIZZLE },
221 { VIRGL_FORMAT_L16A16_SNORM, GL_LUMINANCE16_ALPHA16_SNORM, GL_LUMINANCE_ALPHA, GL_SHORT, NO_SWIZZLE },
222 };
223
224 static struct vrend_format_table dxtn_formats[] = {
225 { VIRGL_FORMAT_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
226 { VIRGL_FORMAT_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
227 { VIRGL_FORMAT_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
228 { VIRGL_FORMAT_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
229 };
230
231 static struct vrend_format_table dxtn_srgb_formats[] = {
232 { VIRGL_FORMAT_DXT1_SRGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
233 { VIRGL_FORMAT_DXT1_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
234 { VIRGL_FORMAT_DXT3_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
235 { VIRGL_FORMAT_DXT5_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
236 };
237
238 static struct vrend_format_table etc2_formats[] = {
239 {VIRGL_FORMAT_ETC2_RGB8, GL_COMPRESSED_RGB8_ETC2, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
240 {VIRGL_FORMAT_ETC2_SRGB8, GL_COMPRESSED_SRGB8_ETC2, GL_RGB, GL_BYTE, NO_SWIZZLE },
241 {VIRGL_FORMAT_ETC2_RGB8A1, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
242 {VIRGL_FORMAT_ETC2_SRGB8A1, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_RGBA, GL_BYTE, NO_SWIZZLE },
243 {VIRGL_FORMAT_ETC2_RGBA8, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
244 {VIRGL_FORMAT_ETC2_SRGBA8, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_RGBA, GL_BYTE, NO_SWIZZLE },
245 {VIRGL_FORMAT_ETC2_R11_UNORM, GL_COMPRESSED_R11_EAC, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE},
246 {VIRGL_FORMAT_ETC2_R11_SNORM, GL_COMPRESSED_SIGNED_R11_EAC, GL_RED, GL_BYTE, NO_SWIZZLE},
247 {VIRGL_FORMAT_ETC2_RG11_UNORM, GL_COMPRESSED_RG11_EAC, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE},
248 {VIRGL_FORMAT_ETC2_RG11_SNORM, GL_COMPRESSED_SIGNED_RG11_EAC, GL_RG, GL_BYTE, NO_SWIZZLE},
249 };
250 static struct vrend_format_table astc_formats[] = {
251 {VIRGL_FORMAT_ASTC_4x4, GL_COMPRESSED_RGBA_ASTC_4x4, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
252 {VIRGL_FORMAT_ASTC_5x4, GL_COMPRESSED_RGBA_ASTC_5x4, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
253 {VIRGL_FORMAT_ASTC_5x5, GL_COMPRESSED_RGBA_ASTC_5x5, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
254 {VIRGL_FORMAT_ASTC_6x5, GL_COMPRESSED_RGBA_ASTC_6x5, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
255 {VIRGL_FORMAT_ASTC_6x6, GL_COMPRESSED_RGBA_ASTC_6x6, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
256 {VIRGL_FORMAT_ASTC_8x5, GL_COMPRESSED_RGBA_ASTC_8x5, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
257 {VIRGL_FORMAT_ASTC_8x6, GL_COMPRESSED_RGBA_ASTC_8x6, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
258 {VIRGL_FORMAT_ASTC_8x8, GL_COMPRESSED_RGBA_ASTC_8x8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
259 {VIRGL_FORMAT_ASTC_10x5, GL_COMPRESSED_RGBA_ASTC_10x5, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
260 {VIRGL_FORMAT_ASTC_10x6, GL_COMPRESSED_RGBA_ASTC_10x6, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
261 {VIRGL_FORMAT_ASTC_10x8, GL_COMPRESSED_RGBA_ASTC_10x8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
262 {VIRGL_FORMAT_ASTC_10x10, GL_COMPRESSED_RGBA_ASTC_10x10, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
263 {VIRGL_FORMAT_ASTC_12x10, GL_COMPRESSED_RGBA_ASTC_12x10, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
264 {VIRGL_FORMAT_ASTC_12x12, GL_COMPRESSED_RGBA_ASTC_12x12, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
265 {VIRGL_FORMAT_ASTC_4x4_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4, GL_RGBA, GL_BYTE, NO_SWIZZLE },
266 {VIRGL_FORMAT_ASTC_5x4_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4, GL_RGBA, GL_BYTE, NO_SWIZZLE },
267 {VIRGL_FORMAT_ASTC_5x5_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5, GL_RGBA, GL_BYTE, NO_SWIZZLE },
268 {VIRGL_FORMAT_ASTC_6x5_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5, GL_RGBA, GL_BYTE, NO_SWIZZLE },
269 {VIRGL_FORMAT_ASTC_6x6_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6, GL_RGBA, GL_BYTE, NO_SWIZZLE },
270 {VIRGL_FORMAT_ASTC_8x5_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5, GL_RGBA, GL_BYTE, NO_SWIZZLE },
271 {VIRGL_FORMAT_ASTC_8x6_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6, GL_RGBA, GL_BYTE, NO_SWIZZLE },
272 {VIRGL_FORMAT_ASTC_8x8_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8, GL_RGBA, GL_BYTE, NO_SWIZZLE },
273 {VIRGL_FORMAT_ASTC_10x5_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5, GL_RGBA, GL_BYTE, NO_SWIZZLE },
274 {VIRGL_FORMAT_ASTC_10x6_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6, GL_RGBA, GL_BYTE, NO_SWIZZLE },
275 {VIRGL_FORMAT_ASTC_10x8_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8, GL_RGBA, GL_BYTE, NO_SWIZZLE },
276 {VIRGL_FORMAT_ASTC_10x10_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10, GL_RGBA, GL_BYTE, NO_SWIZZLE },
277 {VIRGL_FORMAT_ASTC_12x10_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10, GL_RGBA, GL_BYTE, NO_SWIZZLE },
278 {VIRGL_FORMAT_ASTC_12x12_SRGB, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12, GL_RGBA, GL_BYTE, NO_SWIZZLE },
279 };
280
281 static struct vrend_format_table rgtc_formats[] = {
282 { VIRGL_FORMAT_RGTC1_UNORM, GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE },
283 { VIRGL_FORMAT_RGTC1_SNORM, GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_BYTE, NO_SWIZZLE },
284
285 { VIRGL_FORMAT_RGTC2_UNORM, GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE },
286 { VIRGL_FORMAT_RGTC2_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_BYTE, NO_SWIZZLE },
287 };
288
289 static struct vrend_format_table srgb_formats[] = {
290 { VIRGL_FORMAT_R8G8B8X8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
291 { VIRGL_FORMAT_R8G8B8A8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
292
293 { VIRGL_FORMAT_L8_SRGB, GL_SR8_EXT, GL_RED, GL_UNSIGNED_BYTE, RRR1_SWIZZLE },
294 { VIRGL_FORMAT_R8_SRGB, GL_SR8_EXT, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE },
295
296 { VIRGL_FORMAT_R8G8_SRGB, GL_SRG8_EXT, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE },
297 };
298
299 static struct vrend_format_table bit10_formats[] = {
300 { VIRGL_FORMAT_B10G10R10X2_UNORM, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, RGB1_SWIZZLE },
301 { VIRGL_FORMAT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
302 { VIRGL_FORMAT_B10G10R10A2_UINT, GL_RGB10_A2UI, GL_BGRA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
303 { VIRGL_FORMAT_R10G10B10X2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, RGB1_SWIZZLE },
304 { VIRGL_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
305 { VIRGL_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
306 };
307
308 static struct vrend_format_table packed_float_formats[] = {
309 { VIRGL_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, NO_SWIZZLE },
310 };
311
312 static struct vrend_format_table exponent_float_formats[] = {
313 { VIRGL_FORMAT_R9G9B9E5_FLOAT, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, NO_SWIZZLE },
314 };
315
316 static struct vrend_format_table bptc_formats[] = {
317 { VIRGL_FORMAT_BPTC_RGBA_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
318 { VIRGL_FORMAT_BPTC_SRGBA, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
319 { VIRGL_FORMAT_BPTC_RGB_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
320 { VIRGL_FORMAT_BPTC_RGB_UFLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
321 };
322
323 static struct vrend_format_table gl_bgra_formats[] = {
324 { VIRGL_FORMAT_B8G8R8X8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
325 { VIRGL_FORMAT_B8G8R8A8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
326 { VIRGL_FORMAT_B8G8R8X8_SRGB, GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
327 { VIRGL_FORMAT_B8G8R8A8_SRGB, GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
328 };
329
330 static struct vrend_format_table gles_bgra_formats[] = {
331 { VIRGL_FORMAT_B8G8R8X8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
332 { VIRGL_FORMAT_B8G8R8A8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
333 { VIRGL_FORMAT_B8G8R8X8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
334 { VIRGL_FORMAT_B8G8R8A8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
335 };
336
337
338
339 static struct vrend_format_table gles_z32_format[] = {
340 { VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE },
341 };
342
343 static struct vrend_format_table gles_bit10_formats[] = {
344 { VIRGL_FORMAT_B10G10R10X2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, RGB1_SWIZZLE },
345 { VIRGL_FORMAT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
346 };
347
color_format_can_readback(struct vrend_format_table * virgl_format,int gles_ver)348 static bool color_format_can_readback(struct vrend_format_table *virgl_format, int gles_ver)
349 {
350 GLint imp = 0;
351
352 if (virgl_format->format == VIRGL_FORMAT_R8G8B8A8_UNORM)
353 return true;
354
355 if (gles_ver >= 30 &&
356 (virgl_format->format == VIRGL_FORMAT_R32G32B32A32_SINT ||
357 virgl_format->format == VIRGL_FORMAT_R32G32B32A32_UINT))
358 return true;
359
360 if ((virgl_format->format == VIRGL_FORMAT_R32G32B32A32_FLOAT) &&
361 (gles_ver >= 32 || epoxy_has_gl_extension("GL_EXT_color_buffer_float")))
362 return true;
363
364 /* Hotfix for the CI, on GLES these formats are defined like
365 * VIRGL_FORMAT_R10G10B10.2_UNORM, and seems to be incorrect for direct
366 * readback but the blit workaround seems to work, so disable the
367 * direct readback for these two formats. */
368 if (virgl_format->format == VIRGL_FORMAT_B10G10R10A2_UNORM ||
369 virgl_format->format == VIRGL_FORMAT_B10G10R10X2_UNORM)
370 return false;
371
372
373 /* Check implementation specific readback formats */
374 glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &imp);
375 if (imp == (GLint)virgl_format->gltype) {
376 glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &imp);
377 if (imp == (GLint)virgl_format->glformat)
378 return true;
379 }
380 return false;
381 }
382
depth_stencil_formats_can_readback(enum virgl_formats format)383 static bool depth_stencil_formats_can_readback(enum virgl_formats format)
384 {
385 switch (format) {
386 case VIRGL_FORMAT_Z16_UNORM:
387 case VIRGL_FORMAT_Z32_UNORM:
388 case VIRGL_FORMAT_Z32_FLOAT:
389 case VIRGL_FORMAT_Z24X8_UNORM:
390 return epoxy_has_gl_extension("GL_NV_read_depth");
391
392 case VIRGL_FORMAT_Z24_UNORM_S8_UINT:
393 case VIRGL_FORMAT_S8_UINT_Z24_UNORM:
394 case VIRGL_FORMAT_Z32_FLOAT_S8X24_UINT:
395 return epoxy_has_gl_extension("GL_NV_read_depth_stencil");
396
397 case VIRGL_FORMAT_X24S8_UINT:
398 case VIRGL_FORMAT_S8X24_UINT:
399 case VIRGL_FORMAT_S8_UINT:
400 return epoxy_has_gl_extension("GL_NV_read_stencil");
401
402 default:
403 return false;
404 }
405 }
406
vrend_add_formats(struct vrend_format_table * table,int num_entries)407 static void vrend_add_formats(struct vrend_format_table *table, int num_entries)
408 {
409 int i;
410
411 const bool is_desktop_gl = epoxy_is_desktop_gl();
412 const int gles_ver = is_desktop_gl ? 0 : epoxy_gl_version();
413
414 for (i = 0; i < num_entries; i++) {
415 GLenum status;
416 bool is_depth = false;
417 uint32_t flags = 0;
418 uint32_t binding = 0;
419 GLuint buffers;
420 GLuint tex_id, fb_id;
421
422 /**/
423 glGenTextures(1, &tex_id);
424 glGenFramebuffers(1, &fb_id);
425
426 glBindTexture(GL_TEXTURE_2D, tex_id);
427 glBindFramebuffer(GL_FRAMEBUFFER, fb_id);
428
429 /* The error state should be clear here */
430 status = glGetError();
431 assert(status == GL_NO_ERROR);
432
433 glTexImage2D(GL_TEXTURE_2D, 0, table[i].internalformat, 32, 32, 0, table[i].glformat, table[i].gltype, NULL);
434 status = glGetError();
435 /* Currently possible errors are:
436 * * GL_INVALID_VALUE
437 * * GL_INVALID_ENUM
438 * * GL_INVALID_OPERATION
439 * * GL_OUT_OF_MEMORY
440 */
441 if (status != GL_NO_ERROR) {
442 struct vrend_format_table *entry = NULL;
443 uint8_t swizzle[4];
444 binding = VIRGL_BIND_SAMPLER_VIEW | VIRGL_BIND_RENDER_TARGET;
445
446 switch (table[i].format) {
447 case VIRGL_FORMAT_A8_UNORM:
448 entry = &rg_base_formats[0];
449 swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO;
450 swizzle[3] = PIPE_SWIZZLE_RED;
451 flags |= VIRGL_TEXTURE_NEED_SWIZZLE;
452 break;
453 case VIRGL_FORMAT_A16_UNORM:
454 entry = &rg_base_formats[2];
455 swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO;
456 swizzle[3] = PIPE_SWIZZLE_RED;
457 flags |= VIRGL_TEXTURE_NEED_SWIZZLE;
458 break;
459 default:
460 break;
461 }
462
463 if (entry) {
464 vrend_insert_format_swizzle(table[i].format, entry, binding, swizzle, flags);
465 }
466 glDeleteTextures(1, &tex_id);
467 glDeleteFramebuffers(1, &fb_id);
468 continue;
469 }
470
471 if (is_desktop_gl) {
472 glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, table[i].internalformat, 32, 32, 0, table[i].glformat, table[i].gltype, NULL);
473 status = glGetError();
474 if (status == GL_NO_ERROR) {
475 flags |= VIRGL_TEXTURE_CAN_TARGET_RECTANGLE;
476 }
477 }
478
479 if (table[i].format < VIRGL_FORMAT_MAX && util_format_is_depth_or_stencil(table[i].format)) {
480 GLenum attachment;
481
482 if (table[i].format == VIRGL_FORMAT_Z24X8_UNORM || table[i].format == VIRGL_FORMAT_Z32_UNORM || table[i].format == VIRGL_FORMAT_Z16_UNORM || table[i].format == VIRGL_FORMAT_Z32_FLOAT)
483 attachment = GL_DEPTH_ATTACHMENT;
484 else
485 attachment = GL_DEPTH_STENCIL_ATTACHMENT;
486 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex_id, 0);
487
488 is_depth = true;
489
490 buffers = GL_NONE;
491 glDrawBuffers(1, &buffers);
492 } else {
493 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0);
494
495 buffers = GL_COLOR_ATTACHMENT0;
496 glDrawBuffers(1, &buffers);
497 }
498
499 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
500 binding = VIRGL_BIND_SAMPLER_VIEW;
501 if (status == GL_FRAMEBUFFER_COMPLETE)
502 binding |= is_depth ? VIRGL_BIND_DEPTH_STENCIL : VIRGL_BIND_RENDER_TARGET;
503
504 /* On OpenGL all textures can be read back using glGetTexImage, but on GLES
505 we have to be able to bind textures to framebuffers, and use glReadPixels
506 to get the data. And apart from a few formats where support is required
507 (by the GLES version), we have to query the driver to identify additional
508 formats that are supported as destination formats by glReadPixels. */
509 if (is_desktop_gl ||
510 (status == GL_FRAMEBUFFER_COMPLETE &&
511 (is_depth ? depth_stencil_formats_can_readback(table[i].format) :
512 color_format_can_readback(&table[i], gles_ver))))
513 flags |= VIRGL_TEXTURE_CAN_READBACK;
514
515 glDeleteTextures(1, &tex_id);
516 glDeleteFramebuffers(1, &fb_id);
517
518 if (table[i].swizzle[0] != SWIZZLE_INVALID)
519 vrend_insert_format_swizzle(table[i].format, &table[i], binding, table[i].swizzle, flags);
520 else
521 vrend_insert_format(&table[i], binding, flags);
522 }
523 }
524
vrend_add_compressed_formats(struct vrend_format_table * table,int num_entries)525 static void vrend_add_compressed_formats(struct vrend_format_table *table, int num_entries)
526 {
527 int flags = epoxy_is_desktop_gl() ? VIRGL_TEXTURE_CAN_READBACK : 0;
528 for (int i = 0; i < num_entries; i++) {
529 vrend_insert_format(&table[i], VIRGL_BIND_SAMPLER_VIEW, flags);
530 }
531 }
532
533
534 #define add_formats(x) vrend_add_formats((x), ARRAY_SIZE((x)))
535 #define add_compressed_formats(x) vrend_add_compressed_formats((x), ARRAY_SIZE((x)))
536
vrend_build_format_list_common(void)537 void vrend_build_format_list_common(void)
538 {
539 add_formats(base_rgba_formats);
540 add_formats(base_depth_formats);
541 add_formats(base_la_formats);
542
543 /* float support */
544 add_formats(float_base_formats);
545 add_formats(float_la_formats);
546 add_formats(float_3comp_formats);
547
548 /* texture integer support ? */
549 add_formats(integer_base_formats);
550 add_formats(integer_la_formats);
551 add_formats(integer_3comp_formats);
552
553 /* RG support? */
554 add_formats(rg_base_formats);
555 /* integer + rg */
556 add_formats(integer_rg_formats);
557 /* float + rg */
558 add_formats(float_rg_formats);
559
560 /* snorm */
561 add_formats(snorm_formats);
562 add_formats(snorm_la_formats);
563
564 /* compressed */
565 if (epoxy_has_gl_extension("GL_S3_s3tc") ||
566 epoxy_has_gl_extension("GL_EXT_texture_compression_s3tc") ||
567 epoxy_has_gl_extension("GL_ANGLE_texture_compression_dxt")) {
568 add_compressed_formats(dxtn_formats);
569 add_compressed_formats(dxtn_srgb_formats);
570 }
571
572 if (epoxy_has_gl_extension("GL_ARB_texture_compression_rgtc") ||
573 epoxy_has_gl_extension("GL_EXT_texture_compression_rgtc") )
574 add_compressed_formats(rgtc_formats);
575
576 if (epoxy_has_gl_extension("GL_ARB_texture_compression_bptc") ||
577 epoxy_has_gl_extension("GL_EXT_texture_compression_bptc"))
578 add_compressed_formats(bptc_formats);
579
580 add_formats(srgb_formats);
581
582 add_formats(bit10_formats);
583
584 add_formats(packed_float_formats);
585 add_formats(exponent_float_formats);
586 }
587
588
vrend_build_format_list_gl(void)589 void vrend_build_format_list_gl(void)
590 {
591 /* GL_BGRA formats aren't as well supported in GLES as in GL, specially in
592 * transfer operations. So we only register support for it in GL.
593 */
594 add_formats(gl_base_rgba_formats);
595 add_formats(gl_bgra_formats);
596 }
597
vrend_build_format_list_gles(void)598 void vrend_build_format_list_gles(void)
599 {
600 /* The BGR[A|X] formats is required but OpenGL ES does not
601 * support it as nicely as OpenGL. We could try to use BGRA_EXT from
602 * EXT_texture_format_BGRA8888, but it becomes error prone when mixed
603 * with BGR*_SRGB formats and framebuffer multisampling. Instead, on
604 * GLES hosts, we always emulate BGR* as GL_RGB* with a swizzle on
605 * transfers to/from the host.
606 */
607 add_formats(gles_bgra_formats);
608
609 /* The Z32 format is required, but OpenGL ES does not support
610 * using it as a depth buffer. We just fake support with Z24
611 * and hope nobody notices.
612 */
613 add_formats(gles_z32_format);
614 add_formats(gles_bit10_formats);
615
616 if (epoxy_has_gl_extension("GL_KHR_texture_compression_astc_ldr"))
617 add_compressed_formats(astc_formats);
618
619 if (epoxy_gl_version() >= 30) {
620 add_compressed_formats(etc2_formats);
621 }
622
623 }
624
625 /* glTexStorage may not support all that is supported by glTexImage,
626 * so add a flag to indicate when it can be used.
627 */
vrend_check_texture_storage(struct vrend_format_table * table)628 void vrend_check_texture_storage(struct vrend_format_table *table)
629 {
630 int i;
631 GLuint tex_id;
632 for (i = 0; i < VIRGL_FORMAT_MAX_EXTENDED; i++) {
633
634 if (table[i].internalformat != 0 &&
635 !(table[i].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE)) {
636 glGenTextures(1, &tex_id);
637 glBindTexture(GL_TEXTURE_2D, tex_id);
638 glTexStorage2D(GL_TEXTURE_2D, 1, table[i].internalformat, 32, 32);
639 if (glGetError() == GL_NO_ERROR)
640 table[i].flags |= VIRGL_TEXTURE_CAN_TEXTURE_STORAGE;
641 glDeleteTextures(1, &tex_id);
642 }
643 }
644 }
645
vrend_check_texture_multisample(struct vrend_format_table * table,bool enable_storage)646 void vrend_check_texture_multisample(struct vrend_format_table *table,
647 bool enable_storage)
648 {
649 bool is_desktop_gl = epoxy_is_desktop_gl();
650 for (int i = 0; i < VIRGL_FORMAT_MAX_EXTENDED; i++) {
651 bool function_available =
652 (table[i].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE) ? enable_storage : is_desktop_gl;
653
654 if (table[i].internalformat != 0 &&
655 !(table[i].flags & VIRGL_TEXTURE_CAN_MULTISAMPLE) &&
656 function_available) {
657 GLuint tex_id;
658 glGenTextures(1, &tex_id);
659 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_id);
660 if (table[i].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE) {
661 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,
662 table[i].internalformat, 32, 32, GL_TRUE);
663 } else {
664 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,
665 table[i].internalformat, 32, 32, GL_TRUE);
666 }
667 if (glGetError() == GL_NO_ERROR)
668 table[i].flags |= VIRGL_TEXTURE_CAN_MULTISAMPLE;
669 glDeleteTextures(1, &tex_id);
670 }
671 }
672 }
673
vrend_check_framebuffer_mixed_color_attachements(void)674 bool vrend_check_framebuffer_mixed_color_attachements(void)
675 {
676 GLuint tex_id[2];
677 GLuint fb_id;
678 bool retval = false;
679
680 glGenTextures(2, tex_id);
681 glGenFramebuffers(1, &fb_id);
682
683 glBindTexture(GL_TEXTURE_2D, tex_id[0]);
684 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
685
686 glBindFramebuffer(GL_FRAMEBUFFER, fb_id);
687 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id[0], 0);
688
689 glBindTexture(GL_TEXTURE_2D, tex_id[1]);
690 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 32, 32, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
691 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex_id[1], 0);
692
693
694 retval = glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
695
696 glDeleteFramebuffers(1, &fb_id);
697 glDeleteTextures(2, tex_id);
698
699 return retval;
700 }
701
702
vrend_renderer_query_multisample_caps(unsigned max_samples,struct virgl_caps_v2 * caps)703 unsigned vrend_renderer_query_multisample_caps(unsigned max_samples, struct virgl_caps_v2 *caps)
704 {
705 GLuint tex;
706 GLuint fbo;
707 GLenum status;
708
709 uint max_samples_confirmed = 1;
710 uint test_num_samples[4] = {2,4,8,16};
711 int out_buf_offsets[4] = {0,1,2,4};
712 int lowest_working_ms_count_idx = -1;
713
714 assert(glGetError() == GL_NO_ERROR &&
715 "Stale error state detected, please check for failures in initialization");
716
717 glGenFramebuffers( 1, &fbo );
718 memset(caps->sample_locations, 0, 8 * sizeof(uint32_t));
719
720 for (int i = 3; i >= 0; i--) {
721 if (test_num_samples[i] > max_samples)
722 continue;
723 glGenTextures(1, &tex);
724 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
725 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, test_num_samples[i], GL_RGBA32F, 64, 64, GL_TRUE);
726 status = glGetError();
727 if (status == GL_NO_ERROR) {
728 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
729 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
730 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
731 if (status == GL_FRAMEBUFFER_COMPLETE) {
732 if (max_samples_confirmed < test_num_samples[i])
733 max_samples_confirmed = test_num_samples[i];
734
735 for (uint k = 0; k < test_num_samples[i]; ++k) {
736 float msp[2];
737 uint32_t compressed;
738 glGetMultisamplefv(GL_SAMPLE_POSITION, k, msp);
739 compressed = ((unsigned)(floor(msp[0] * 16.0f)) & 0xf) << 4;
740 compressed |= ((unsigned)(floor(msp[1] * 16.0f)) & 0xf);
741 caps->sample_locations[out_buf_offsets[i] + (k >> 2)] |= compressed << (8 * (k & 3));
742 }
743 lowest_working_ms_count_idx = i;
744 } else {
745 /* If a framebuffer doesn't support low sample counts,
746 * use the sample position from the last working larger count. */
747 if (lowest_working_ms_count_idx > 0) {
748 for (uint k = 0; k < test_num_samples[i]; ++k) {
749 caps->sample_locations[out_buf_offsets[i] + (k >> 2)] =
750 caps->sample_locations[out_buf_offsets[lowest_working_ms_count_idx] + (k >> 2)];
751 }
752 }
753 }
754 glBindFramebuffer(GL_FRAMEBUFFER, 0);
755 }
756 glDeleteTextures(1, &tex);
757 }
758 glDeleteFramebuffers(1, &fbo);
759 return max_samples_confirmed;
760 }
761
762 /* returns: 1 = compatible, -1 = not compatible, 0 = undecided */
format_uncompressed_compressed_copy_compatible(enum virgl_formats src,enum virgl_formats dst)763 static int format_uncompressed_compressed_copy_compatible(enum virgl_formats src,
764 enum virgl_formats dst)
765 {
766
767 switch (src) {
768 case VIRGL_FORMAT_R32G32B32A32_UINT:
769 case VIRGL_FORMAT_R32G32B32A32_SINT:
770 case VIRGL_FORMAT_R32G32B32A32_FLOAT:
771 case VIRGL_FORMAT_R32G32B32A32_SNORM:
772 case VIRGL_FORMAT_R32G32B32A32_UNORM:
773 switch (dst) {
774 case VIRGL_FORMAT_DXT3_RGBA:
775 case VIRGL_FORMAT_DXT3_SRGBA:
776 case VIRGL_FORMAT_DXT5_RGBA:
777 case VIRGL_FORMAT_DXT5_SRGBA:
778 case VIRGL_FORMAT_RGTC2_UNORM:
779 case VIRGL_FORMAT_RGTC2_SNORM:
780 case VIRGL_FORMAT_BPTC_RGBA_UNORM:
781 case VIRGL_FORMAT_BPTC_SRGBA:
782 case VIRGL_FORMAT_BPTC_RGB_FLOAT:
783 case VIRGL_FORMAT_BPTC_RGB_UFLOAT:
784 case VIRGL_FORMAT_ETC2_RGBA8:
785 case VIRGL_FORMAT_ETC2_SRGBA8:
786 case VIRGL_FORMAT_ETC2_RG11_UNORM:
787 case VIRGL_FORMAT_ETC2_RG11_SNORM:
788 return 1;
789 case VIRGL_FORMAT_ASTC_4x4:
790 case VIRGL_FORMAT_ASTC_5x4:
791 case VIRGL_FORMAT_ASTC_5x5:
792 case VIRGL_FORMAT_ASTC_6x5:
793 case VIRGL_FORMAT_ASTC_6x6:
794 case VIRGL_FORMAT_ASTC_8x5:
795 case VIRGL_FORMAT_ASTC_8x6:
796 case VIRGL_FORMAT_ASTC_8x8:
797 case VIRGL_FORMAT_ASTC_10x5:
798 case VIRGL_FORMAT_ASTC_10x6:
799 case VIRGL_FORMAT_ASTC_10x8:
800 case VIRGL_FORMAT_ASTC_10x10:
801 case VIRGL_FORMAT_ASTC_12x10:
802 case VIRGL_FORMAT_ASTC_12x12:
803 case VIRGL_FORMAT_ASTC_4x4_SRGB:
804 case VIRGL_FORMAT_ASTC_5x4_SRGB:
805 case VIRGL_FORMAT_ASTC_5x5_SRGB:
806 case VIRGL_FORMAT_ASTC_6x5_SRGB:
807 case VIRGL_FORMAT_ASTC_6x6_SRGB:
808 case VIRGL_FORMAT_ASTC_8x5_SRGB:
809 case VIRGL_FORMAT_ASTC_8x6_SRGB:
810 case VIRGL_FORMAT_ASTC_8x8_SRGB:
811 case VIRGL_FORMAT_ASTC_10x5_SRGB:
812 case VIRGL_FORMAT_ASTC_10x6_SRGB:
813 case VIRGL_FORMAT_ASTC_10x8_SRGB:
814 case VIRGL_FORMAT_ASTC_10x10_SRGB:
815 case VIRGL_FORMAT_ASTC_12x10_SRGB:
816 case VIRGL_FORMAT_ASTC_12x12_SRGB:
817 return epoxy_is_desktop_gl() ? -1 : 1;
818 default:
819 return -1;
820 }
821 case VIRGL_FORMAT_R16G16B16A16_UINT:
822 case VIRGL_FORMAT_R16G16B16A16_SINT:
823 case VIRGL_FORMAT_R16G16B16A16_FLOAT:
824 case VIRGL_FORMAT_R16G16B16A16_SNORM:
825 case VIRGL_FORMAT_R16G16B16A16_UNORM:
826 case VIRGL_FORMAT_R32G32_UINT:
827 case VIRGL_FORMAT_R32G32_SINT:
828 case VIRGL_FORMAT_R32G32_FLOAT:
829 case VIRGL_FORMAT_R32G32_UNORM:
830 case VIRGL_FORMAT_R32G32_SNORM:
831 switch (dst) {
832 case VIRGL_FORMAT_DXT1_RGBA:
833 case VIRGL_FORMAT_DXT1_SRGBA:
834 case VIRGL_FORMAT_DXT1_RGB:
835 case VIRGL_FORMAT_DXT1_SRGB:
836 case VIRGL_FORMAT_RGTC1_UNORM:
837 case VIRGL_FORMAT_RGTC1_SNORM:
838 case VIRGL_FORMAT_ETC2_RGB8:
839 case VIRGL_FORMAT_ETC2_SRGB8:
840 case VIRGL_FORMAT_ETC2_RGB8A1:
841 case VIRGL_FORMAT_ETC2_SRGB8A1:
842 case VIRGL_FORMAT_ETC2_R11_UNORM:
843 case VIRGL_FORMAT_ETC2_R11_SNORM:
844 return 1;
845 default:
846 return -1;
847 }
848 default:
849 return 0;
850 }
851 }
852
format_compressed_compressed_copy_compatible(enum virgl_formats src,enum virgl_formats dst)853 static boolean format_compressed_compressed_copy_compatible(enum virgl_formats src, enum virgl_formats dst)
854 {
855 const bool is_desktop_gl = epoxy_is_desktop_gl();
856
857 if(!is_desktop_gl) {
858 if((src == VIRGL_FORMAT_ASTC_4x4 && dst == VIRGL_FORMAT_ASTC_4x4_SRGB) ||
859 (src == VIRGL_FORMAT_ASTC_5x4 && dst == VIRGL_FORMAT_ASTC_5x4_SRGB) ||
860 (src == VIRGL_FORMAT_ASTC_5x5 && dst == VIRGL_FORMAT_ASTC_5x5_SRGB) ||
861 (src == VIRGL_FORMAT_ASTC_6x5 && dst == VIRGL_FORMAT_ASTC_6x5_SRGB) ||
862 (src == VIRGL_FORMAT_ASTC_6x6 && dst == VIRGL_FORMAT_ASTC_6x6_SRGB) ||
863 (src == VIRGL_FORMAT_ASTC_8x5 && dst == VIRGL_FORMAT_ASTC_8x5_SRGB) ||
864 (src == VIRGL_FORMAT_ASTC_8x6 && dst == VIRGL_FORMAT_ASTC_8x6_SRGB) ||
865 (src == VIRGL_FORMAT_ASTC_8x8 && dst == VIRGL_FORMAT_ASTC_8x8_SRGB) ||
866 (src == VIRGL_FORMAT_ASTC_10x5 && dst == VIRGL_FORMAT_ASTC_10x5_SRGB) ||
867 (src == VIRGL_FORMAT_ASTC_10x6 && dst == VIRGL_FORMAT_ASTC_10x6_SRGB) ||
868 (src == VIRGL_FORMAT_ASTC_10x8 && dst == VIRGL_FORMAT_ASTC_10x8_SRGB) ||
869 (src == VIRGL_FORMAT_ASTC_10x10 && dst == VIRGL_FORMAT_ASTC_10x10_SRGB) ||
870 (src == VIRGL_FORMAT_ASTC_12x10 && dst == VIRGL_FORMAT_ASTC_12x10_SRGB) ||
871 (src == VIRGL_FORMAT_ASTC_12x12 && dst == VIRGL_FORMAT_ASTC_12x12_SRGB) ||
872 (src == VIRGL_FORMAT_ETC2_R11_UNORM && dst == VIRGL_FORMAT_ETC2_R11_SNORM) ||
873 (src == VIRGL_FORMAT_ETC2_RG11_UNORM && dst == VIRGL_FORMAT_ETC2_RG11_SNORM) ||
874 (src == VIRGL_FORMAT_ETC2_RGBA8 && dst == VIRGL_FORMAT_ETC2_SRGBA8) ||
875 (src == VIRGL_FORMAT_ETC2_RGB8A1 && dst == VIRGL_FORMAT_ETC2_SRGB8A1) ||
876 (src == VIRGL_FORMAT_ETC2_RGB8 && dst == VIRGL_FORMAT_ETC2_SRGB8))
877 return true;
878 }
879
880 if ((src == VIRGL_FORMAT_RGTC1_UNORM && dst == VIRGL_FORMAT_RGTC1_SNORM) ||
881 (src == VIRGL_FORMAT_RGTC2_UNORM && dst == VIRGL_FORMAT_RGTC2_SNORM) ||
882 (src == VIRGL_FORMAT_BPTC_RGBA_UNORM && dst == VIRGL_FORMAT_BPTC_SRGBA) ||
883 (src == VIRGL_FORMAT_BPTC_RGB_FLOAT && dst == VIRGL_FORMAT_BPTC_RGB_UFLOAT))
884 return true;
885
886 return false;
887 }
888
format_is_copy_compatible(enum virgl_formats src,enum virgl_formats dst,unsigned int flags)889 boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst,
890 unsigned int flags)
891 {
892 int r;
893
894 if (src == dst) {
895 /* When Mesa imports dma_buf VIRGL_FORMAT_B8G8R8X8_UNORM/DRM|GBM_FORMAT_XRGB8888
896 * it uses internal format GL_RGB8.
897 * But when virglrenderer creates VIRGL_FORMAT_B8G8R8X8_UNORM texture, it
898 * uses internal format GL_RGBA8.
899 * So the formats do not match when Mesa checks them internally.
900 */
901 if (flags & VREND_COPY_COMPAT_FLAG_ONE_IS_EGL_IMAGE &&
902 src == VIRGL_FORMAT_B8G8R8X8_UNORM)
903 return false;
904 return true;
905 }
906
907 if (util_format_is_plain(src) && util_format_is_plain(dst)) {
908 const struct util_format_description *src_desc = util_format_description(src);
909 const struct util_format_description *dst_desc = util_format_description(dst);
910 return util_is_format_compatible(src_desc, dst_desc);
911 }
912
913 if (!(flags & VREND_COPY_COMPAT_FLAG_ALLOW_COMPRESSED))
914 return false;
915
916 /* compressed-uncompressed */
917 r = format_uncompressed_compressed_copy_compatible(src, dst);
918 if (r)
919 return r > 0;
920
921 r = format_uncompressed_compressed_copy_compatible(dst, src);
922 if (r)
923 return r > 0;
924
925 return format_compressed_compressed_copy_compatible(dst, src) ||
926 format_compressed_compressed_copy_compatible(src, dst);
927 }
928