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
35 #ifdef __GNUC__
36 /* The warning missing-field-initializers is misleading: If at least one field
37 * is initialized, then the un-initialized fields will be filled with zero.
38 * Silencing the warning by manually adding the zeros that the compiler will add
39 * anyway doesn't improve the code, and initializing the files by using a named
40 * notation will make it worse, because then he remaining fields truely be
41 * un-initialized.
42 */
43 #ifdef __clang__
44 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
45 #else
46 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
47 #endif
48 #endif
49
50 /* fill the format table */
51 static struct vrend_format_table base_rgba_formats[] =
52 {
53 { VIRGL_FORMAT_B8G8R8X8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
54 { VIRGL_FORMAT_B8G8R8A8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
55
56 { VIRGL_FORMAT_R8G8B8X8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
57 { VIRGL_FORMAT_R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
58
59 { VIRGL_FORMAT_A8R8G8B8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NO_SWIZZLE },
60 { VIRGL_FORMAT_X8R8G8B8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, NO_SWIZZLE },
61
62 { VIRGL_FORMAT_A8B8G8R8_UNORM, GL_RGBA8, GL_ABGR_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE },
63
64 { VIRGL_FORMAT_B4G4R4X4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, RGB1_SWIZZLE },
65 { VIRGL_FORMAT_A4B4G4R4_UNORM, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, NO_SWIZZLE },
66 { VIRGL_FORMAT_B5G5R5X1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, RGB1_SWIZZLE },
67
68 { VIRGL_FORMAT_B5G6R5_UNORM, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NO_SWIZZLE },
69 { VIRGL_FORMAT_B2G3R3_UNORM, GL_R3_G3_B2, GL_RGB, GL_UNSIGNED_BYTE_3_3_2, NO_SWIZZLE },
70
71 { VIRGL_FORMAT_R16G16B16X16_UNORM, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, RGB1_SWIZZLE },
72
73 { VIRGL_FORMAT_R16G16B16A16_UNORM, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, NO_SWIZZLE },
74 };
75
76 static struct vrend_format_table gl_base_rgba_formats[] =
77 {
78 { VIRGL_FORMAT_B4G4R4A4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, NO_SWIZZLE },
79 { VIRGL_FORMAT_B5G5R5A1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NO_SWIZZLE },
80 };
81
82 static struct vrend_format_table base_depth_formats[] =
83 {
84 { VIRGL_FORMAT_Z16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NO_SWIZZLE },
85 { VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE },
86 { VIRGL_FORMAT_S8_UINT_Z24_UNORM, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NO_SWIZZLE },
87 { VIRGL_FORMAT_Z24X8_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE },
88 { VIRGL_FORMAT_Z32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, NO_SWIZZLE },
89 /* this is probably a separate format */
90 { VIRGL_FORMAT_Z32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NO_SWIZZLE },
91 { VIRGL_FORMAT_X24S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, NO_SWIZZLE },
92 };
93
94 static struct vrend_format_table base_la_formats[] = {
95 { VIRGL_FORMAT_A8_UNORM, GL_ALPHA8, GL_ALPHA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
96 { VIRGL_FORMAT_L8_UNORM, GL_R8, GL_RED, GL_UNSIGNED_BYTE, RRR1_SWIZZLE },
97 { VIRGL_FORMAT_L8A8_UNORM, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NO_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 { VIRGL_FORMAT_L16A16_UNORM, GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT, NO_SWIZZLE },
101 };
102
103 static struct vrend_format_table rg_base_formats[] = {
104 { VIRGL_FORMAT_R8_UNORM, GL_R8, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE },
105 { VIRGL_FORMAT_R8G8_UNORM, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE },
106 { VIRGL_FORMAT_R16_UNORM, GL_R16, GL_RED, GL_UNSIGNED_SHORT, NO_SWIZZLE },
107 { VIRGL_FORMAT_R16G16_UNORM, GL_RG16, GL_RG, GL_UNSIGNED_SHORT, NO_SWIZZLE },
108 };
109
110 static struct vrend_format_table integer_base_formats[] = {
111 { VIRGL_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE },
112 { VIRGL_FORMAT_R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, NO_SWIZZLE },
113
114 { VIRGL_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE },
115 { VIRGL_FORMAT_R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, NO_SWIZZLE },
116
117 { VIRGL_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
118 { VIRGL_FORMAT_R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT, NO_SWIZZLE },
119 };
120
121 static struct vrend_format_table integer_3comp_formats[] = {
122 { VIRGL_FORMAT_R8G8B8X8_UINT, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
123 { VIRGL_FORMAT_R8G8B8X8_SINT, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, RGB1_SWIZZLE },
124 { VIRGL_FORMAT_R16G16B16X16_UINT, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, RGB1_SWIZZLE },
125 { VIRGL_FORMAT_R16G16B16X16_SINT, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, RGB1_SWIZZLE },
126 { VIRGL_FORMAT_R32G32B32_UINT, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
127 { VIRGL_FORMAT_R32G32B32_SINT, GL_RGB32I, GL_RGB_INTEGER, GL_INT, NO_SWIZZLE },
128 };
129
130 static struct vrend_format_table float_base_formats[] = {
131 { VIRGL_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, NO_SWIZZLE },
132 { VIRGL_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA, GL_FLOAT, NO_SWIZZLE },
133 };
134
135 static struct vrend_format_table float_la_formats[] = {
136 { VIRGL_FORMAT_A16_FLOAT, GL_ALPHA16F_ARB, GL_ALPHA, GL_HALF_FLOAT, NO_SWIZZLE },
137 { VIRGL_FORMAT_L16_FLOAT, GL_R16F, GL_RED, GL_HALF_FLOAT, RRR1_SWIZZLE },
138 { VIRGL_FORMAT_L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_ARB, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, NO_SWIZZLE },
139
140 { VIRGL_FORMAT_A32_FLOAT, GL_ALPHA32F_ARB, GL_ALPHA, GL_FLOAT, NO_SWIZZLE },
141 { VIRGL_FORMAT_L32_FLOAT, GL_R32F, GL_RED, GL_FLOAT, RRR1_SWIZZLE },
142 { VIRGL_FORMAT_L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_ARB, GL_LUMINANCE_ALPHA, GL_FLOAT, NO_SWIZZLE },
143 };
144
145 static struct vrend_format_table integer_rg_formats[] = {
146 { VIRGL_FORMAT_R8_UINT, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE },
147 { VIRGL_FORMAT_R8G8_UINT, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE },
148 { VIRGL_FORMAT_R8_SINT, GL_R8I, GL_RED_INTEGER, GL_BYTE, NO_SWIZZLE },
149 { VIRGL_FORMAT_R8G8_SINT, GL_RG8I, GL_RG_INTEGER, GL_BYTE, NO_SWIZZLE },
150
151 { VIRGL_FORMAT_R16_UINT, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE },
152 { VIRGL_FORMAT_R16G16_UINT, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE },
153 { VIRGL_FORMAT_R16_SINT, GL_R16I, GL_RED_INTEGER, GL_SHORT, NO_SWIZZLE },
154 { VIRGL_FORMAT_R16G16_SINT, GL_RG16I, GL_RG_INTEGER, GL_SHORT, NO_SWIZZLE },
155
156 { VIRGL_FORMAT_R32_UINT, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
157 { VIRGL_FORMAT_R32G32_UINT, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
158 { VIRGL_FORMAT_R32_SINT, GL_R32I, GL_RED_INTEGER, GL_INT, NO_SWIZZLE },
159 { VIRGL_FORMAT_R32G32_SINT, GL_RG32I, GL_RG_INTEGER, GL_INT, NO_SWIZZLE },
160 };
161
162 static struct vrend_format_table float_rg_formats[] = {
163 { VIRGL_FORMAT_R16_FLOAT, GL_R16F, GL_RED, GL_HALF_FLOAT, NO_SWIZZLE },
164 { VIRGL_FORMAT_R16G16_FLOAT, GL_RG16F, GL_RG, GL_HALF_FLOAT, NO_SWIZZLE },
165 { VIRGL_FORMAT_R32_FLOAT, GL_R32F, GL_RED, GL_FLOAT, NO_SWIZZLE },
166 { VIRGL_FORMAT_R32G32_FLOAT, GL_RG32F, GL_RG, GL_FLOAT, NO_SWIZZLE },
167 };
168
169 static struct vrend_format_table float_3comp_formats[] = {
170 { VIRGL_FORMAT_R16G16B16X16_FLOAT, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, RGB1_SWIZZLE },
171 { VIRGL_FORMAT_R32G32B32_FLOAT, GL_RGB32F, GL_RGB, GL_FLOAT, NO_SWIZZLE },
172 };
173
174
175 static struct vrend_format_table integer_la_formats[] = {
176 { VIRGL_FORMAT_A8_UINT, GL_ALPHA8UI_EXT, GL_ALPHA_INTEGER, GL_UNSIGNED_BYTE, NO_SWIZZLE },
177 { VIRGL_FORMAT_L8_UINT, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, RRR1_SWIZZLE },
178 { VIRGL_FORMAT_L8A8_UINT, GL_LUMINANCE_ALPHA8UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE },
179 { VIRGL_FORMAT_A8_SINT, GL_ALPHA8I_EXT, GL_ALPHA_INTEGER, GL_BYTE, NO_SWIZZLE },
180 { VIRGL_FORMAT_L8_SINT, GL_R8I, GL_RED_INTEGER, GL_BYTE, RRR1_SWIZZLE },
181 { VIRGL_FORMAT_L8A8_SINT, GL_LUMINANCE_ALPHA8I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_BYTE, NO_SWIZZLE },
182
183 { VIRGL_FORMAT_A16_UINT, GL_ALPHA16UI_EXT, GL_ALPHA_INTEGER, GL_UNSIGNED_SHORT, NO_SWIZZLE },
184 { VIRGL_FORMAT_L16_UINT, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, RRR1_SWIZZLE },
185 { VIRGL_FORMAT_L16A16_UINT, GL_LUMINANCE_ALPHA16UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_SHORT, NO_SWIZZLE },
186
187 { VIRGL_FORMAT_A16_SINT, GL_ALPHA16I_EXT, GL_ALPHA_INTEGER, GL_SHORT, NO_SWIZZLE },
188 { VIRGL_FORMAT_L16_SINT, GL_R16I, GL_RED_INTEGER, GL_SHORT, RRR1_SWIZZLE },
189 { VIRGL_FORMAT_L16A16_SINT, GL_LUMINANCE_ALPHA16I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_SHORT, NO_SWIZZLE },
190
191 { VIRGL_FORMAT_A32_UINT, GL_ALPHA32UI_EXT, GL_ALPHA_INTEGER, GL_UNSIGNED_INT, NO_SWIZZLE },
192 { VIRGL_FORMAT_L32_UINT, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, RRR1_SWIZZLE },
193 { VIRGL_FORMAT_L32A32_UINT, GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_UNSIGNED_INT, NO_SWIZZLE },
194
195 { VIRGL_FORMAT_A32_SINT, GL_ALPHA32I_EXT, GL_ALPHA_INTEGER, GL_INT, NO_SWIZZLE },
196 { VIRGL_FORMAT_L32_SINT, GL_R32I, GL_RED_INTEGER, GL_INT, RRR1_SWIZZLE },
197 { VIRGL_FORMAT_L32A32_SINT, GL_LUMINANCE_ALPHA32I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, GL_INT, NO_SWIZZLE },
198
199
200 };
201
202 static struct vrend_format_table snorm_formats[] = {
203 { VIRGL_FORMAT_R8_SNORM, GL_R8_SNORM, GL_RED, GL_BYTE, NO_SWIZZLE },
204 { VIRGL_FORMAT_R8G8_SNORM, GL_RG8_SNORM, GL_RG, GL_BYTE, NO_SWIZZLE },
205
206 { VIRGL_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, NO_SWIZZLE },
207 { VIRGL_FORMAT_R8G8B8X8_SNORM, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, RGB1_SWIZZLE },
208
209 { VIRGL_FORMAT_R16_SNORM, GL_R16_SNORM, GL_RED, GL_SHORT, NO_SWIZZLE },
210 { VIRGL_FORMAT_R16G16_SNORM, GL_RG16_SNORM, GL_RG, GL_SHORT, NO_SWIZZLE },
211 { VIRGL_FORMAT_R16G16B16A16_SNORM, GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, NO_SWIZZLE },
212
213 { VIRGL_FORMAT_R16G16B16X16_SNORM, GL_RGBA16_SNORM, GL_RGBA, GL_SHORT, RGB1_SWIZZLE },
214 };
215
216 static struct vrend_format_table snorm_la_formats[] = {
217 { VIRGL_FORMAT_A8_SNORM, GL_ALPHA8_SNORM, GL_ALPHA, GL_BYTE, NO_SWIZZLE },
218 { VIRGL_FORMAT_L8_SNORM, GL_R8_SNORM, GL_RED, GL_BYTE, RRR1_SWIZZLE },
219 { VIRGL_FORMAT_L8A8_SNORM, GL_LUMINANCE8_ALPHA8_SNORM, GL_LUMINANCE_ALPHA, GL_BYTE, NO_SWIZZLE },
220 { VIRGL_FORMAT_A16_SNORM, GL_ALPHA16_SNORM, GL_ALPHA, GL_SHORT, NO_SWIZZLE },
221 { VIRGL_FORMAT_L16_SNORM, GL_R16_SNORM, GL_RED, GL_SHORT, RRR1_SWIZZLE },
222 { VIRGL_FORMAT_L16A16_SNORM, GL_LUMINANCE16_ALPHA16_SNORM, GL_LUMINANCE_ALPHA, GL_SHORT, NO_SWIZZLE },
223 };
224
225 static struct vrend_format_table dxtn_formats[] = {
226 { VIRGL_FORMAT_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
227 { VIRGL_FORMAT_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
228 { VIRGL_FORMAT_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
229 { VIRGL_FORMAT_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
230 };
231
232 static struct vrend_format_table dxtn_srgb_formats[] = {
233 { VIRGL_FORMAT_DXT1_SRGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
234 { VIRGL_FORMAT_DXT1_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
235 { VIRGL_FORMAT_DXT3_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
236 { VIRGL_FORMAT_DXT5_SRGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
237 };
238
239 static struct vrend_format_table rgtc_formats[] = {
240 { VIRGL_FORMAT_RGTC1_UNORM, GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_BYTE, NO_SWIZZLE },
241 { VIRGL_FORMAT_RGTC1_SNORM, GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_BYTE, NO_SWIZZLE },
242
243 { VIRGL_FORMAT_RGTC2_UNORM, GL_COMPRESSED_RG_RGTC2, GL_RG, GL_UNSIGNED_BYTE, NO_SWIZZLE },
244 { VIRGL_FORMAT_RGTC2_SNORM, GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_BYTE, NO_SWIZZLE },
245 };
246
247 static struct vrend_format_table srgb_formats[] = {
248 { VIRGL_FORMAT_R8G8B8X8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
249 { VIRGL_FORMAT_R8G8B8A8_SRGB, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
250
251 { VIRGL_FORMAT_L8_SRGB, GL_SR8_EXT, GL_RED, GL_UNSIGNED_BYTE, RRR1_SWIZZLE },
252 { VIRGL_FORMAT_L8A8_SRGB, GL_SLUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
253 };
254
255 static struct vrend_format_table gl_srgb_formats[] =
256 {
257 { VIRGL_FORMAT_B8G8R8X8_SRGB, GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
258 { VIRGL_FORMAT_B8G8R8A8_SRGB, GL_SRGB8_ALPHA8, GL_BGRA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
259 };
260
261 static struct vrend_format_table bit10_formats[] = {
262 { VIRGL_FORMAT_B10G10R10X2_UNORM, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, RGB1_SWIZZLE },
263 { VIRGL_FORMAT_B10G10R10A2_UNORM, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
264 { VIRGL_FORMAT_B10G10R10A2_UINT, GL_RGB10_A2UI, GL_BGRA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
265 { VIRGL_FORMAT_R10G10B10X2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, RGB1_SWIZZLE },
266 { VIRGL_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
267 { VIRGL_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, NO_SWIZZLE },
268 };
269
270 static struct vrend_format_table packed_float_formats[] = {
271 { VIRGL_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, NO_SWIZZLE },
272 };
273
274 static struct vrend_format_table exponent_float_formats[] = {
275 { VIRGL_FORMAT_R9G9B9E5_FLOAT, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, NO_SWIZZLE },
276 };
277
278 static struct vrend_format_table bptc_formats[] = {
279 { VIRGL_FORMAT_BPTC_RGBA_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
280 { VIRGL_FORMAT_BPTC_SRGBA, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, GL_RGBA, GL_UNSIGNED_BYTE, NO_SWIZZLE },
281 { VIRGL_FORMAT_BPTC_RGB_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
282 { VIRGL_FORMAT_BPTC_RGB_UFLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, GL_RGB, GL_UNSIGNED_BYTE, NO_SWIZZLE },
283 };
284
285 static struct vrend_format_table gles_bgra_formats[] = {
286 { VIRGL_FORMAT_B8G8R8X8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, RGB1_SWIZZLE },
287 { VIRGL_FORMAT_B8G8R8A8_UNORM, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NO_SWIZZLE },
288 };
289
290 static struct vrend_format_table gles_z32_format[] = {
291 { VIRGL_FORMAT_Z32_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NO_SWIZZLE },
292 };
293
vrend_add_formats(struct vrend_format_table * table,int num_entries)294 static void vrend_add_formats(struct vrend_format_table *table, int num_entries)
295 {
296 int i;
297 uint32_t binding = 0;
298 GLuint buffers;
299 GLuint tex_id, fb_id;
300
301 for (i = 0; i < num_entries; i++) {
302 GLenum status;
303 bool is_depth = false;
304 /**/
305 glGenTextures(1, &tex_id);
306 glGenFramebuffers(1, &fb_id);
307
308 glBindTexture(GL_TEXTURE_2D, tex_id);
309 glBindFramebuffer(GL_FRAMEBUFFER, fb_id);
310
311 glTexImage2D(GL_TEXTURE_2D, 0, table[i].internalformat, 32, 32, 0, table[i].glformat, table[i].gltype, NULL);
312 status = glGetError();
313 if (status == GL_INVALID_VALUE || status == GL_INVALID_ENUM || status == GL_INVALID_OPERATION) {
314 struct vrend_format_table *entry = NULL;
315 uint8_t swizzle[4];
316 binding = VIRGL_BIND_SAMPLER_VIEW | VIRGL_BIND_RENDER_TARGET | VIRGL_BIND_NEED_SWIZZLE;
317
318 switch (table[i].format) {
319 case PIPE_FORMAT_A8_UNORM:
320 entry = &rg_base_formats[0];
321 swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO;
322 swizzle[3] = PIPE_SWIZZLE_RED;
323 break;
324 case PIPE_FORMAT_A16_UNORM:
325 entry = &rg_base_formats[2];
326 swizzle[0] = swizzle[1] = swizzle[2] = PIPE_SWIZZLE_ZERO;
327 swizzle[3] = PIPE_SWIZZLE_RED;
328 break;
329 default:
330 break;
331 }
332
333 if (entry) {
334 vrend_insert_format_swizzle(table[i].format, entry, binding, swizzle);
335 }
336 glDeleteTextures(1, &tex_id);
337 glDeleteFramebuffers(1, &fb_id);
338 continue;
339 }
340
341 if (util_format_is_depth_or_stencil(table[i].format)) {
342 GLenum attachment;
343
344 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)
345 attachment = GL_DEPTH_ATTACHMENT;
346 else
347 attachment = GL_DEPTH_STENCIL_ATTACHMENT;
348 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, tex_id, 0);
349
350 is_depth = true;
351
352 buffers = GL_NONE;
353 glDrawBuffers(1, &buffers);
354 } else {
355 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex_id, 0);
356
357 buffers = GL_COLOR_ATTACHMENT0_EXT;
358 glDrawBuffers(1, &buffers);
359 }
360
361 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
362 binding = VIRGL_BIND_SAMPLER_VIEW;
363 if (status == GL_FRAMEBUFFER_COMPLETE)
364 binding |= (is_depth ? VIRGL_BIND_DEPTH_STENCIL : VIRGL_BIND_RENDER_TARGET);
365
366 glDeleteTextures(1, &tex_id);
367 glDeleteFramebuffers(1, &fb_id);
368
369 if (table[i].swizzle[0] != SWIZZLE_INVALID)
370 vrend_insert_format_swizzle(table[i].format, &table[i], binding, table[i].swizzle);
371 else
372 vrend_insert_format(&table[i], binding);
373 }
374 }
375
376 #define add_formats(x) vrend_add_formats((x), ARRAY_SIZE((x)))
377
vrend_build_format_list_common(void)378 void vrend_build_format_list_common(void)
379 {
380 add_formats(base_rgba_formats);
381 add_formats(base_depth_formats);
382 add_formats(base_la_formats);
383
384 /* float support */
385 add_formats(float_base_formats);
386 add_formats(float_la_formats);
387 add_formats(float_3comp_formats);
388
389 /* texture integer support ? */
390 add_formats(integer_base_formats);
391 add_formats(integer_la_formats);
392 add_formats(integer_3comp_formats);
393
394 /* RG support? */
395 add_formats(rg_base_formats);
396 /* integer + rg */
397 add_formats(integer_rg_formats);
398 /* float + rg */
399 add_formats(float_rg_formats);
400
401 /* snorm */
402 add_formats(snorm_formats);
403 add_formats(snorm_la_formats);
404
405 /* compressed */
406 add_formats(rgtc_formats);
407 add_formats(dxtn_formats);
408 add_formats(dxtn_srgb_formats);
409
410 add_formats(srgb_formats);
411
412 add_formats(bit10_formats);
413
414 add_formats(packed_float_formats);
415 add_formats(exponent_float_formats);
416
417 add_formats(bptc_formats);
418 }
419
420
vrend_build_format_list_gl(void)421 void vrend_build_format_list_gl(void)
422 {
423 /* GL_BGRA formats aren't as well supported in GLES as in GL, specially in
424 * transfer operations. So we only register support for it in GL.
425 */
426 add_formats(gl_base_rgba_formats);
427 add_formats(gl_srgb_formats);
428 }
429
vrend_build_format_list_gles(void)430 void vrend_build_format_list_gles(void)
431 {
432 /* The BGR[A|X] formats is required but OpenGL ES does not
433 * support rendering to it. Try to use GL_BGRA_EXT from the
434 * GL_EXT_texture_format_BGRA8888 extension. But the
435 * GL_BGRA_EXT format is not supported by OpenGL Desktop.
436 */
437 add_formats(gles_bgra_formats);
438
439
440 /* The Z32 format is required, but OpenGL ES does not support
441 * using it as a depth buffer. We just fake support with Z24
442 * and hope nobody notices.
443 */
444 add_formats(gles_z32_format);
445 }
446
447 /* glTexStorage may not support all that is supported by glTexImage,
448 * so add a flag to indicate when it can be used.
449 */
vrend_check_texture_storage(struct vrend_format_table * table)450 void vrend_check_texture_storage(struct vrend_format_table *table)
451 {
452 int i;
453 GLuint tex_id;
454 for (i = 0; i < VIRGL_FORMAT_MAX; i++) {
455
456 if (table[i].internalformat != 0) {
457 glGenTextures(1, &tex_id);
458 glBindTexture(GL_TEXTURE_2D, tex_id);
459 glTexStorage2D(GL_TEXTURE_2D, 1, table[i].internalformat, 32, 32);
460 if (glGetError() == GL_NO_ERROR)
461 table[i].bindings |= VIRGL_BIND_CAN_TEXTURE_STORAGE;
462 glDeleteTextures(1, &tex_id);
463 }
464 }
465 }
466
vrend_renderer_query_multisample_caps(unsigned max_samples,struct virgl_caps_v2 * caps)467 unsigned vrend_renderer_query_multisample_caps(unsigned max_samples, struct virgl_caps_v2 *caps)
468 {
469 GLuint tex;
470 GLuint fbo;
471 GLenum status;
472
473 uint max_samples_confirmed = 1;
474 uint test_num_samples[4] = {2,4,8,16};
475 int out_buf_offsets[4] = {0,1,2,4};
476 int lowest_working_ms_count_idx = -1;
477
478 glGenFramebuffers( 1, &fbo );
479 memset(caps->sample_locations, 0, 8 * sizeof(uint32_t));
480
481 for (int i = 3; i >= 0; i--) {
482 if (test_num_samples[i] > max_samples)
483 continue;
484 glGenTextures(1, &tex);
485 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
486 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, test_num_samples[i], GL_RGBA32F, 64, 64, GL_TRUE);
487 status = glGetError();
488 if (status == GL_NO_ERROR) {
489 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
490 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex, 0);
491 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
492 if (status == GL_FRAMEBUFFER_COMPLETE) {
493 if (max_samples_confirmed < test_num_samples[i])
494 max_samples_confirmed = test_num_samples[i];
495
496 for (uint k = 0; k < test_num_samples[i]; ++k) {
497 float msp[2];
498 uint32_t compressed;
499 glGetMultisamplefv(GL_SAMPLE_POSITION, k, msp);
500 compressed = ((unsigned)(floor(msp[0] * 16.0f)) & 0xf) << 4;
501 compressed |= ((unsigned)(floor(msp[1] * 16.0f)) & 0xf);
502 caps->sample_locations[out_buf_offsets[i] + (k >> 2)] |= compressed << (8 * (k & 3));
503 }
504 lowest_working_ms_count_idx = i;
505 } else {
506 /* If a framebuffer doesn't support low sample counts,
507 * use the sample position from the last working larger count. */
508 if (lowest_working_ms_count_idx > 0) {
509 for (uint k = 0; k < test_num_samples[i]; ++k) {
510 caps->sample_locations[out_buf_offsets[i] + (k >> 2)] =
511 caps->sample_locations[out_buf_offsets[lowest_working_ms_count_idx] + (k >> 2)];
512 }
513 }
514 }
515 glBindFramebuffer(GL_FRAMEBUFFER, 0);
516 }
517 glDeleteTextures(1, &tex);
518 }
519 glDeleteFramebuffers(1, &fbo);
520 return max_samples_confirmed;
521 }
522
523 /* returns: 1 = compatible, -1 = not compatible, 0 = undecided */
format_uncompressed_compressed_copy_compatible(enum pipe_format src,enum pipe_format dst)524 static int format_uncompressed_compressed_copy_compatible(enum pipe_format src,
525 enum pipe_format dst)
526 {
527 switch (src) {
528 case PIPE_FORMAT_R32G32B32A32_UINT:
529 case PIPE_FORMAT_R32G32B32A32_SINT:
530 case PIPE_FORMAT_R32G32B32A32_FLOAT:
531 case PIPE_FORMAT_R32G32B32A32_SNORM:
532 case PIPE_FORMAT_R32G32B32A32_UNORM:
533 switch (dst) {
534 case PIPE_FORMAT_DXT3_RGBA:
535 case PIPE_FORMAT_DXT3_SRGBA:
536 case PIPE_FORMAT_DXT5_RGBA:
537 case PIPE_FORMAT_DXT5_SRGBA:
538 case PIPE_FORMAT_RGTC2_UNORM:
539 case PIPE_FORMAT_RGTC2_SNORM:
540 case PIPE_FORMAT_BPTC_RGBA_UNORM:
541 case PIPE_FORMAT_BPTC_SRGBA:
542 case PIPE_FORMAT_BPTC_RGB_FLOAT:
543 case PIPE_FORMAT_BPTC_RGB_UFLOAT:
544 return 1;
545 default:
546 return -1;
547 }
548 case PIPE_FORMAT_R16G16B16A16_UINT:
549 case PIPE_FORMAT_R16G16B16A16_SINT:
550 case PIPE_FORMAT_R16G16B16A16_FLOAT:
551 case PIPE_FORMAT_R16G16B16A16_SNORM:
552 case PIPE_FORMAT_R16G16B16A16_UNORM:
553 case PIPE_FORMAT_R32G32_UINT:
554 case PIPE_FORMAT_R32G32_SINT:
555 case PIPE_FORMAT_R32G32_FLOAT:
556 case PIPE_FORMAT_R32G32_UNORM:
557 case PIPE_FORMAT_R32G32_SNORM:
558 switch (dst) {
559 case PIPE_FORMAT_DXT1_RGBA:
560 case PIPE_FORMAT_DXT1_SRGBA:
561 case PIPE_FORMAT_DXT1_RGB:
562 case PIPE_FORMAT_DXT1_SRGB:
563 case PIPE_FORMAT_RGTC1_UNORM:
564 case PIPE_FORMAT_RGTC1_SNORM:
565 return 1;
566 default:
567 return -1;
568 }
569 default:
570 return 0;
571 }
572 }
573
format_compressed_compressed_copy_compatible(enum pipe_format src,enum pipe_format dst)574 static boolean format_compressed_compressed_copy_compatible(enum pipe_format src, enum pipe_format dst)
575 {
576 if ((src == PIPE_FORMAT_RGTC1_UNORM && dst == PIPE_FORMAT_RGTC1_SNORM) ||
577 (src == PIPE_FORMAT_RGTC2_UNORM && dst == PIPE_FORMAT_RGTC2_SNORM) ||
578 (src == PIPE_FORMAT_BPTC_RGBA_UNORM && dst == PIPE_FORMAT_BPTC_SRGBA) ||
579 (src == PIPE_FORMAT_BPTC_RGB_FLOAT && dst == PIPE_FORMAT_BPTC_RGB_UFLOAT))
580 return true;
581 return false;
582 }
583
format_is_copy_compatible(enum pipe_format src,enum pipe_format dst,boolean allow_compressed)584 boolean format_is_copy_compatible(enum pipe_format src, enum pipe_format dst,
585 boolean allow_compressed)
586 {
587 int r;
588
589 if (src == dst)
590 return true;
591
592 if (util_format_is_plain(src) && util_format_is_plain(dst)) {
593 const struct util_format_description *src_desc = util_format_description(src);
594 const struct util_format_description *dst_desc = util_format_description(dst);
595 return util_is_format_compatible(src_desc, dst_desc);
596 }
597
598 if (!allow_compressed)
599 return false;
600
601 /* compressed-uncompressed */
602 r = format_uncompressed_compressed_copy_compatible(src, dst);
603 if (r)
604 return r > 0;
605
606 r = format_uncompressed_compressed_copy_compatible(dst, src);
607 if (r)
608 return r > 0;
609
610 return format_compressed_compressed_copy_compatible(dst, src);
611 }
612