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