• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "util/format/u_format.h"
2 #include "zink_format.h"
3 #include "util/u_math.h"
4 
5 enum pipe_format
zink_decompose_vertex_format(enum pipe_format format)6 zink_decompose_vertex_format(enum pipe_format format)
7 {
8    const struct util_format_description *desc = util_format_description(format);
9    unsigned first_non_void = util_format_get_first_non_void_channel(format);
10    enum pipe_format new_format;
11    assert(first_non_void == 0);
12    if (!desc->is_array)
13       return PIPE_FORMAT_NONE;
14    if (desc->is_unorm) {
15       enum pipe_format unorm_formats[] = {
16          PIPE_FORMAT_R8_UNORM,
17          PIPE_FORMAT_R16_UNORM,
18          PIPE_FORMAT_R32_UNORM
19       };
20       return unorm_formats[desc->channel[first_non_void].size >> 4];
21    } else if (desc->is_snorm) {
22       enum pipe_format snorm_formats[] = {
23          PIPE_FORMAT_R8_SNORM,
24          PIPE_FORMAT_R16_SNORM,
25          PIPE_FORMAT_R32_SNORM
26       };
27       return snorm_formats[desc->channel[first_non_void].size >> 4];
28    } else {
29       enum pipe_format uint_formats[][3] = {
30          {PIPE_FORMAT_R8_USCALED, PIPE_FORMAT_R16_USCALED, PIPE_FORMAT_R32_USCALED},
31          {PIPE_FORMAT_R8_UINT, PIPE_FORMAT_R16_UINT, PIPE_FORMAT_R32_UINT},
32       };
33       enum pipe_format sint_formats[][3] = {
34          {PIPE_FORMAT_R8_SSCALED, PIPE_FORMAT_R16_SSCALED, PIPE_FORMAT_R32_SSCALED},
35          {PIPE_FORMAT_R8_SINT, PIPE_FORMAT_R16_SINT, PIPE_FORMAT_R32_SINT},
36       };
37       switch (desc->channel[first_non_void].type) {
38       case UTIL_FORMAT_TYPE_UNSIGNED:
39          return uint_formats[desc->channel[first_non_void].pure_integer][desc->channel[first_non_void].size >> 4];
40       case UTIL_FORMAT_TYPE_SIGNED:
41          return sint_formats[desc->channel[first_non_void].pure_integer][desc->channel[first_non_void].size >> 4];
42       case UTIL_FORMAT_TYPE_FLOAT:
43          return desc->channel[first_non_void].size == 16 ? PIPE_FORMAT_R16_FLOAT : PIPE_FORMAT_R32_FLOAT;
44          break;
45       default:
46          return PIPE_FORMAT_NONE;
47       }
48    }
49    return new_format;
50 }
51 
52 bool
zink_format_is_red_alpha(enum pipe_format format)53 zink_format_is_red_alpha(enum pipe_format format)
54 {
55    switch (format) {
56    case PIPE_FORMAT_R4A4_UNORM:
57    case PIPE_FORMAT_R8A8_SINT:
58    case PIPE_FORMAT_R8A8_SNORM:
59    case PIPE_FORMAT_R8A8_UINT:
60    case PIPE_FORMAT_R8A8_UNORM:
61    case PIPE_FORMAT_R16A16_SINT:
62    case PIPE_FORMAT_R16A16_SNORM:
63    case PIPE_FORMAT_R16A16_UINT:
64    case PIPE_FORMAT_R16A16_UNORM:
65    case PIPE_FORMAT_R16A16_FLOAT:
66    case PIPE_FORMAT_R32A32_SINT:
67    case PIPE_FORMAT_R32A32_UINT:
68    case PIPE_FORMAT_R32A32_FLOAT:
69       return true;
70    default: break;
71    }
72    return false;
73 }
74 
75 bool
zink_format_is_emulated_alpha(enum pipe_format format)76 zink_format_is_emulated_alpha(enum pipe_format format)
77 {
78    return util_format_is_alpha(format) ||
79           util_format_is_luminance(format) ||
80           util_format_is_luminance_alpha(format) ||
81           zink_format_is_red_alpha(format);
82 }
83 
84 static enum pipe_format
emulate_alpha(enum pipe_format format)85 emulate_alpha(enum pipe_format format)
86 {
87    if (format == PIPE_FORMAT_A8_UNORM)
88       return PIPE_FORMAT_R8_UNORM;
89    if (format == PIPE_FORMAT_A8_UINT)
90       return PIPE_FORMAT_R8_UINT;
91    if (format == PIPE_FORMAT_A8_SNORM)
92       return PIPE_FORMAT_R8_SNORM;
93    if (format == PIPE_FORMAT_A8_SINT)
94       return PIPE_FORMAT_R8_SINT;
95    if (format == PIPE_FORMAT_A16_UNORM)
96       return PIPE_FORMAT_R16_UNORM;
97    if (format == PIPE_FORMAT_A16_UINT)
98       return PIPE_FORMAT_R16_UINT;
99    if (format == PIPE_FORMAT_A16_SNORM)
100       return PIPE_FORMAT_R16_SNORM;
101    if (format == PIPE_FORMAT_A16_SINT)
102       return PIPE_FORMAT_R16_SINT;
103    if (format == PIPE_FORMAT_A16_FLOAT)
104       return PIPE_FORMAT_R16_FLOAT;
105    if (format == PIPE_FORMAT_A32_UINT)
106       return PIPE_FORMAT_R32_UINT;
107    if (format == PIPE_FORMAT_A32_SINT)
108       return PIPE_FORMAT_R32_SINT;
109    if (format == PIPE_FORMAT_A32_FLOAT)
110       return PIPE_FORMAT_R32_FLOAT;
111    return format;
112 }
113 
114 static enum pipe_format
emulate_red_alpha(enum pipe_format format)115 emulate_red_alpha(enum pipe_format format)
116 {
117    switch (format) {
118    case PIPE_FORMAT_R8A8_SINT:
119       return PIPE_FORMAT_R8G8_SINT;
120    case PIPE_FORMAT_R8A8_SNORM:
121       return PIPE_FORMAT_R8G8_SNORM;
122    case PIPE_FORMAT_R8A8_UINT:
123       return PIPE_FORMAT_R8G8_UINT;
124    case PIPE_FORMAT_R8A8_UNORM:
125       return PIPE_FORMAT_R8G8_UNORM;
126    case PIPE_FORMAT_R16A16_SINT:
127       return PIPE_FORMAT_R16G16_SINT;
128    case PIPE_FORMAT_R16A16_SNORM:
129       return PIPE_FORMAT_R16G16_SNORM;
130    case PIPE_FORMAT_R16A16_UINT:
131       return PIPE_FORMAT_R16G16_UINT;
132    case PIPE_FORMAT_R16A16_UNORM:
133       return PIPE_FORMAT_R16G16_UNORM;
134    case PIPE_FORMAT_R16A16_FLOAT:
135       return PIPE_FORMAT_R16G16_FLOAT;
136    case PIPE_FORMAT_R32A32_SINT:
137       return PIPE_FORMAT_R32G32_SINT;
138    case PIPE_FORMAT_R32A32_UINT:
139       return PIPE_FORMAT_R32G32_UINT;
140    case PIPE_FORMAT_R32A32_FLOAT:
141       return PIPE_FORMAT_R32G32_FLOAT;
142    default: break;
143    }
144    return format;
145 }
146 
147 enum pipe_format
zink_format_get_emulated_alpha(enum pipe_format format)148 zink_format_get_emulated_alpha(enum pipe_format format)
149 {
150    if (util_format_is_alpha(format))
151       return emulate_alpha(format);
152    if (util_format_is_luminance(format))
153       return util_format_luminance_to_red(format);
154    if (util_format_is_luminance_alpha(format)) {
155       if (util_format_is_srgb(format))
156          return format;
157       if (format == PIPE_FORMAT_LATC2_UNORM)
158          return PIPE_FORMAT_RGTC2_UNORM;
159       if (format == PIPE_FORMAT_LATC2_SNORM)
160          return PIPE_FORMAT_RGTC2_SNORM;
161 
162       format = util_format_luminance_to_red(format);
163    }
164 
165    return emulate_red_alpha(format);
166 }
167 
168 
169 enum pipe_format
zink_format_emulate_x8(enum pipe_format format)170 zink_format_emulate_x8(enum pipe_format format)
171 {
172    /* convert missing Xn variants to An */
173    switch (format) {
174    case PIPE_FORMAT_B8G8R8X8_UNORM:
175       return PIPE_FORMAT_B8G8R8A8_UNORM;
176 
177    case PIPE_FORMAT_B8G8R8X8_SRGB:
178       return PIPE_FORMAT_B8G8R8A8_SRGB;
179    case PIPE_FORMAT_R8G8B8X8_SRGB:
180       return PIPE_FORMAT_R8G8B8A8_SRGB;
181 
182    case PIPE_FORMAT_R8G8B8X8_SINT:
183       return PIPE_FORMAT_R8G8B8A8_SINT;
184    case PIPE_FORMAT_R8G8B8X8_SNORM:
185       return PIPE_FORMAT_R8G8B8A8_SNORM;
186    case PIPE_FORMAT_R8G8B8X8_UNORM:
187       return PIPE_FORMAT_R8G8B8A8_UNORM;
188 
189    case PIPE_FORMAT_R16G16B16X16_FLOAT:
190       return PIPE_FORMAT_R16G16B16A16_FLOAT;
191    case PIPE_FORMAT_R16G16B16X16_SINT:
192       return PIPE_FORMAT_R16G16B16A16_SINT;
193    case PIPE_FORMAT_R16G16B16X16_SNORM:
194       return PIPE_FORMAT_R16G16B16A16_SNORM;
195    case PIPE_FORMAT_R16G16B16X16_UNORM:
196       return PIPE_FORMAT_R16G16B16A16_UNORM;
197 
198    case PIPE_FORMAT_R32G32B32X32_FLOAT:
199       return PIPE_FORMAT_R32G32B32A32_FLOAT;
200    case PIPE_FORMAT_R32G32B32X32_SINT:
201       return PIPE_FORMAT_R32G32B32A32_SINT;
202 
203    case PIPE_FORMAT_R10G10B10X2_SINT:
204       return PIPE_FORMAT_R10G10B10A2_SINT;
205    case PIPE_FORMAT_R10G10B10X2_SNORM:
206       return PIPE_FORMAT_R10G10B10A2_SNORM;
207    case PIPE_FORMAT_R10G10B10X2_UNORM:
208       return PIPE_FORMAT_R10G10B10A2_UNORM;
209 
210    case PIPE_FORMAT_B10G10R10X2_SINT:
211       return PIPE_FORMAT_B10G10R10A2_SINT;
212    case PIPE_FORMAT_B10G10R10X2_SNORM:
213       return PIPE_FORMAT_B10G10R10A2_SNORM;
214    case PIPE_FORMAT_B10G10R10X2_UNORM:
215       return PIPE_FORMAT_B10G10R10A2_UNORM;
216 
217    case PIPE_FORMAT_R5G5B5X1_UNORM:
218       return PIPE_FORMAT_R5G5B5A1_UNORM;
219    case PIPE_FORMAT_B5G5R5X1_UNORM:
220       return PIPE_FORMAT_B5G5R5A1_UNORM;
221 
222    default:
223       return format;
224    }
225 }
226 
227 bool
zink_format_is_voidable_rgba_variant(enum pipe_format format)228 zink_format_is_voidable_rgba_variant(enum pipe_format format)
229 {
230    return format != zink_format_emulate_x8(format);
231 }
232 
233 void
zink_format_clamp_channel_color(const struct util_format_description * desc,union pipe_color_union * dst,const union pipe_color_union * src,unsigned i)234 zink_format_clamp_channel_color(const struct util_format_description *desc, union pipe_color_union *dst, const union pipe_color_union *src, unsigned i)
235 {
236    int non_void = util_format_get_first_non_void_channel(desc->format);
237    unsigned channel = desc->swizzle[i];
238 
239    if (channel > PIPE_SWIZZLE_W || desc->channel[channel].type == UTIL_FORMAT_TYPE_VOID) {
240       if (non_void != -1) {
241          if (desc->channel[non_void].type == UTIL_FORMAT_TYPE_FLOAT) {
242             dst->f[i] = uif(UINT32_MAX);
243          } else {
244             if (desc->channel[non_void].normalized)
245                dst->f[i] = 1.0;
246             else if (desc->channel[non_void].type == UTIL_FORMAT_TYPE_SIGNED)
247                dst->i[i] = INT32_MAX;
248             else
249                dst->ui[i] = UINT32_MAX;
250          }
251       } else {
252          dst->ui[i] = src->ui[i];
253       }
254       return;
255    }
256 
257    switch (desc->channel[channel].type) {
258    case UTIL_FORMAT_TYPE_VOID:
259       unreachable("handled above");
260       break;
261    case UTIL_FORMAT_TYPE_SIGNED:
262       if (desc->channel[channel].normalized)
263          dst->i[i] = src->i[i];
264       else {
265          dst->i[i] = MAX2(src->i[i], -(1<<(desc->channel[channel].size - 1)));
266          dst->i[i] = MIN2(dst->i[i], (1 << (desc->channel[channel].size - 1)) - 1);
267       }
268       break;
269    case UTIL_FORMAT_TYPE_UNSIGNED:
270       if (desc->channel[channel].normalized)
271          dst->ui[i] = src->ui[i];
272       else
273          dst->ui[i] = MIN2(src->ui[i], BITFIELD_MASK(desc->channel[channel].size));
274       break;
275    case UTIL_FORMAT_TYPE_FIXED:
276    case UTIL_FORMAT_TYPE_FLOAT:
277       dst->ui[i] = src->ui[i];
278       break;
279    }
280 }
281 
282 void
zink_format_clamp_channel_srgb(const struct util_format_description * desc,union pipe_color_union * dst,const union pipe_color_union * src,unsigned i)283 zink_format_clamp_channel_srgb(const struct util_format_description *desc, union pipe_color_union *dst, const union pipe_color_union *src, unsigned i)
284 {
285    unsigned channel = desc->swizzle[i];
286    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB &&
287        channel <= PIPE_SWIZZLE_W) {
288       switch (desc->channel[channel].type) {
289       case UTIL_FORMAT_TYPE_SIGNED:
290       case UTIL_FORMAT_TYPE_UNSIGNED:
291          dst->f[i] = CLAMP(src->f[i], 0.0, 1.0);
292          return;
293       default:
294          break;
295       }
296    }
297 
298    dst->ui[i] = src->ui[i];
299 }
300