Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/translate/translate_generic.c
4565 views
1
/**************************************************************************
2
*
3
* Copyright 2007 VMware, Inc.
4
* All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
**************************************************************************/
27
28
/*
29
* Authors:
30
* Keith Whitwell <[email protected]>
31
*/
32
33
#include "util/u_memory.h"
34
#include "util/format/u_format.h"
35
#include "util/half_float.h"
36
#include "util/u_math.h"
37
#include "pipe/p_state.h"
38
#include "translate.h"
39
40
41
#define DRAW_DBG 0
42
43
typedef void (*emit_func)(const void *attrib, void *ptr);
44
45
46
47
struct translate_generic {
48
struct translate translate;
49
50
struct {
51
enum translate_element_type type;
52
53
void (*fetch)(void *restrict dst, const uint8_t *restrict src,
54
unsigned width);
55
unsigned buffer;
56
unsigned input_offset;
57
unsigned instance_divisor;
58
59
emit_func emit;
60
unsigned output_offset;
61
62
const uint8_t *input_ptr;
63
unsigned input_stride;
64
unsigned max_index;
65
66
/* this value is set to -1 if this is a normal element with
67
* output_format != input_format: in this case, u_format is used
68
* to do a full conversion
69
*
70
* this value is set to the format size in bytes if
71
* output_format == input_format or for 32-bit instance ids:
72
* in this case, memcpy is used to copy this amount of bytes
73
*/
74
int copy_size;
75
76
} attrib[TRANSLATE_MAX_ATTRIBS];
77
78
unsigned nr_attrib;
79
};
80
81
82
static struct translate_generic *
83
translate_generic(struct translate *translate)
84
{
85
return (struct translate_generic *)translate;
86
}
87
88
89
/**
90
* Fetch a dword[4] vertex attribute from memory, doing format/type
91
* conversion as needed.
92
*
93
* This is probably needed/dupliocated elsewhere, eg format
94
* conversion, texture sampling etc.
95
*/
96
#define ATTRIB(NAME, SZ, SRCTYPE, DSTTYPE, TO) \
97
static void \
98
emit_##NAME(const void *attrib, void *ptr) \
99
{ \
100
unsigned i; \
101
SRCTYPE *in = (SRCTYPE *)attrib; \
102
DSTTYPE *out = (DSTTYPE *)ptr; \
103
\
104
for (i = 0; i < SZ; i++) { \
105
out[i] = TO(in[i]); \
106
} \
107
}
108
109
110
#define TO_64_FLOAT(x) ((double) x)
111
#define TO_32_FLOAT(x) (x)
112
#define TO_16_FLOAT(x) _mesa_float_to_half(x)
113
114
#define TO_8_USCALED(x) ((unsigned char) x)
115
#define TO_16_USCALED(x) ((unsigned short) x)
116
#define TO_32_USCALED(x) ((unsigned int) x)
117
118
#define TO_8_SSCALED(x) ((char) x)
119
#define TO_16_SSCALED(x) ((short) x)
120
#define TO_32_SSCALED(x) ((int) x)
121
122
#define TO_8_UNORM(x) ((unsigned char) (x * 255.0f))
123
#define TO_16_UNORM(x) ((unsigned short) (x * 65535.0f))
124
#define TO_32_UNORM(x) ((unsigned int) (x * 4294967295.0f))
125
126
#define TO_8_SNORM(x) ((char) (x * 127.0f))
127
#define TO_16_SNORM(x) ((short) (x * 32767.0f))
128
#define TO_32_SNORM(x) ((int) (x * 2147483647.0f))
129
130
#define TO_32_FIXED(x) ((int) (x * 65536.0f))
131
132
#define TO_INT(x) (x)
133
134
135
ATTRIB(R64G64B64A64_FLOAT, 4, float, double, TO_64_FLOAT)
136
ATTRIB(R64G64B64_FLOAT, 3, float, double, TO_64_FLOAT)
137
ATTRIB(R64G64_FLOAT, 2, float, double, TO_64_FLOAT)
138
ATTRIB(R64_FLOAT, 1, float, double, TO_64_FLOAT)
139
140
ATTRIB(R32G32B32A32_FLOAT, 4, float, float, TO_32_FLOAT)
141
ATTRIB(R32G32B32_FLOAT, 3, float, float, TO_32_FLOAT)
142
ATTRIB(R32G32_FLOAT, 2, float, float, TO_32_FLOAT)
143
ATTRIB(R32_FLOAT, 1, float, float, TO_32_FLOAT)
144
145
ATTRIB(R16G16B16A16_FLOAT, 4, float, ushort, TO_16_FLOAT)
146
ATTRIB(R16G16B16_FLOAT, 3, float, ushort, TO_16_FLOAT)
147
ATTRIB(R16G16_FLOAT, 2, float, ushort, TO_16_FLOAT)
148
ATTRIB(R16_FLOAT, 1, float, ushort, TO_16_FLOAT)
149
150
ATTRIB(R32G32B32A32_USCALED, 4, float, unsigned, TO_32_USCALED)
151
ATTRIB(R32G32B32_USCALED, 3, float, unsigned, TO_32_USCALED)
152
ATTRIB(R32G32_USCALED, 2, float, unsigned, TO_32_USCALED)
153
ATTRIB(R32_USCALED, 1, float, unsigned, TO_32_USCALED)
154
155
ATTRIB(R32G32B32A32_SSCALED, 4, float, int, TO_32_SSCALED)
156
ATTRIB(R32G32B32_SSCALED, 3, float, int, TO_32_SSCALED)
157
ATTRIB(R32G32_SSCALED, 2, float, int, TO_32_SSCALED)
158
ATTRIB(R32_SSCALED, 1, float, int, TO_32_SSCALED)
159
160
ATTRIB(R32G32B32A32_UNORM, 4, float, unsigned, TO_32_UNORM)
161
ATTRIB(R32G32B32_UNORM, 3, float, unsigned, TO_32_UNORM)
162
ATTRIB(R32G32_UNORM, 2, float, unsigned, TO_32_UNORM)
163
ATTRIB(R32_UNORM, 1, float, unsigned, TO_32_UNORM)
164
165
ATTRIB(R32G32B32A32_SNORM, 4, float, int, TO_32_SNORM)
166
ATTRIB(R32G32B32_SNORM, 3, float, int, TO_32_SNORM)
167
ATTRIB(R32G32_SNORM, 2, float, int, TO_32_SNORM)
168
ATTRIB(R32_SNORM, 1, float, int, TO_32_SNORM)
169
170
ATTRIB(R16G16B16A16_USCALED, 4, float, ushort, TO_16_USCALED)
171
ATTRIB(R16G16B16_USCALED, 3, float, ushort, TO_16_USCALED)
172
ATTRIB(R16G16_USCALED, 2, float, ushort, TO_16_USCALED)
173
ATTRIB(R16_USCALED, 1, float, ushort, TO_16_USCALED)
174
175
ATTRIB(R16G16B16A16_SSCALED, 4, float, short, TO_16_SSCALED)
176
ATTRIB(R16G16B16_SSCALED, 3, float, short, TO_16_SSCALED)
177
ATTRIB(R16G16_SSCALED, 2, float, short, TO_16_SSCALED)
178
ATTRIB(R16_SSCALED, 1, float, short, TO_16_SSCALED)
179
180
ATTRIB(R16G16B16A16_UNORM, 4, float, ushort, TO_16_UNORM)
181
ATTRIB(R16G16B16_UNORM, 3, float, ushort, TO_16_UNORM)
182
ATTRIB(R16G16_UNORM, 2, float, ushort, TO_16_UNORM)
183
ATTRIB(R16_UNORM, 1, float, ushort, TO_16_UNORM)
184
185
ATTRIB(R16G16B16A16_SNORM, 4, float, short, TO_16_SNORM)
186
ATTRIB(R16G16B16_SNORM, 3, float, short, TO_16_SNORM)
187
ATTRIB(R16G16_SNORM, 2, float, short, TO_16_SNORM)
188
ATTRIB(R16_SNORM, 1, float, short, TO_16_SNORM)
189
190
ATTRIB(R8G8B8A8_USCALED, 4, float, ubyte, TO_8_USCALED)
191
ATTRIB(R8G8B8_USCALED, 3, float, ubyte, TO_8_USCALED)
192
ATTRIB(R8G8_USCALED, 2, float, ubyte, TO_8_USCALED)
193
ATTRIB(R8_USCALED, 1, float, ubyte, TO_8_USCALED)
194
195
ATTRIB(R8G8B8A8_SSCALED, 4, float, char, TO_8_SSCALED)
196
ATTRIB(R8G8B8_SSCALED, 3, float, char, TO_8_SSCALED)
197
ATTRIB(R8G8_SSCALED, 2, float, char, TO_8_SSCALED)
198
ATTRIB(R8_SSCALED, 1, float, char, TO_8_SSCALED)
199
200
ATTRIB(R8G8B8A8_UNORM, 4, float, ubyte, TO_8_UNORM)
201
ATTRIB(R8G8B8_UNORM, 3, float, ubyte, TO_8_UNORM)
202
ATTRIB(R8G8_UNORM, 2, float, ubyte, TO_8_UNORM)
203
ATTRIB(R8_UNORM, 1, float, ubyte, TO_8_UNORM)
204
205
ATTRIB(R8G8B8A8_SNORM, 4, float, char, TO_8_SNORM)
206
ATTRIB(R8G8B8_SNORM, 3, float, char, TO_8_SNORM)
207
ATTRIB(R8G8_SNORM, 2, float, char, TO_8_SNORM)
208
ATTRIB(R8_SNORM, 1, float, char, TO_8_SNORM)
209
210
ATTRIB(R32G32B32A32_UINT, 4, uint32_t, unsigned, TO_INT)
211
ATTRIB(R32G32B32_UINT, 3, uint32_t, unsigned, TO_INT)
212
ATTRIB(R32G32_UINT, 2, uint32_t, unsigned, TO_INT)
213
ATTRIB(R32_UINT, 1, uint32_t, unsigned, TO_INT)
214
215
ATTRIB(R16G16B16A16_UINT, 4, uint32_t, ushort, TO_INT)
216
ATTRIB(R16G16B16_UINT, 3, uint32_t, ushort, TO_INT)
217
ATTRIB(R16G16_UINT, 2, uint32_t, ushort, TO_INT)
218
ATTRIB(R16_UINT, 1, uint32_t, ushort, TO_INT)
219
220
ATTRIB(R8G8B8A8_UINT, 4, uint32_t, ubyte, TO_INT)
221
ATTRIB(R8G8B8_UINT, 3, uint32_t, ubyte, TO_INT)
222
ATTRIB(R8G8_UINT, 2, uint32_t, ubyte, TO_INT)
223
ATTRIB(R8_UINT, 1, uint32_t, ubyte, TO_INT)
224
225
ATTRIB(R32G32B32A32_SINT, 4, int32_t, int, TO_INT)
226
ATTRIB(R32G32B32_SINT, 3, int32_t, int, TO_INT)
227
ATTRIB(R32G32_SINT, 2, int32_t, int, TO_INT)
228
ATTRIB(R32_SINT, 1, int32_t, int, TO_INT)
229
230
ATTRIB(R16G16B16A16_SINT, 4, int32_t, short, TO_INT)
231
ATTRIB(R16G16B16_SINT, 3, int32_t, short, TO_INT)
232
ATTRIB(R16G16_SINT, 2, int32_t, short, TO_INT)
233
ATTRIB(R16_SINT, 1, int32_t, short, TO_INT)
234
235
ATTRIB(R8G8B8A8_SINT, 4, int32_t, char, TO_INT)
236
ATTRIB(R8G8B8_SINT, 3, int32_t, char, TO_INT)
237
ATTRIB(R8G8_SINT, 2, int32_t, char, TO_INT)
238
ATTRIB(R8_SINT, 1, int32_t, char, TO_INT)
239
240
static void
241
emit_A8R8G8B8_UNORM(const void *attrib, void *ptr)
242
{
243
float *in = (float *)attrib;
244
ubyte *out = (ubyte *)ptr;
245
out[0] = TO_8_UNORM(in[3]);
246
out[1] = TO_8_UNORM(in[0]);
247
out[2] = TO_8_UNORM(in[1]);
248
out[3] = TO_8_UNORM(in[2]);
249
}
250
251
static void
252
emit_B8G8R8A8_UNORM(const void *attrib, void *ptr)
253
{
254
float *in = (float *)attrib;
255
ubyte *out = (ubyte *)ptr;
256
out[2] = TO_8_UNORM(in[0]);
257
out[1] = TO_8_UNORM(in[1]);
258
out[0] = TO_8_UNORM(in[2]);
259
out[3] = TO_8_UNORM(in[3]);
260
}
261
262
static void
263
emit_B10G10R10A2_UNORM(const void *attrib, void *ptr)
264
{
265
float *src = (float *)ptr;
266
uint32_t value = 0;
267
value |= ((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff;
268
value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10;
269
value |= (((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff) << 20;
270
value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30;
271
*(uint32_t *)attrib = util_le32_to_cpu(value);
272
}
273
274
static void
275
emit_B10G10R10A2_USCALED(const void *attrib, void *ptr)
276
{
277
float *src = (float *)ptr;
278
uint32_t value = 0;
279
value |= ((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff;
280
value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10;
281
value |= (((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff) << 20;
282
value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30;
283
*(uint32_t *)attrib = util_le32_to_cpu(value);
284
}
285
286
static void
287
emit_B10G10R10A2_SNORM(const void *attrib, void *ptr)
288
{
289
float *src = (float *)ptr;
290
uint32_t value = 0;
291
value |= (uint32_t)(((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) ;
292
value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ;
293
value |= (uint32_t)((((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) << 20) ;
294
value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ;
295
*(uint32_t *)attrib = util_le32_to_cpu(value);
296
}
297
298
static void
299
emit_B10G10R10A2_SSCALED(const void *attrib, void *ptr)
300
{
301
float *src = (float *)ptr;
302
uint32_t value = 0;
303
value |= (uint32_t)(((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) ;
304
value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ;
305
value |= (uint32_t)((((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) << 20) ;
306
value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ;
307
*(uint32_t *)attrib = util_le32_to_cpu(value);
308
}
309
310
static void
311
emit_R10G10B10A2_UNORM(const void *attrib, void *ptr)
312
{
313
float *src = (float *)ptr;
314
uint32_t value = 0;
315
value |= ((uint32_t)(CLAMP(src[0], 0, 1) * 0x3ff)) & 0x3ff;
316
value |= (((uint32_t)(CLAMP(src[1], 0, 1) * 0x3ff)) & 0x3ff) << 10;
317
value |= (((uint32_t)(CLAMP(src[2], 0, 1) * 0x3ff)) & 0x3ff) << 20;
318
value |= ((uint32_t)(CLAMP(src[3], 0, 1) * 0x3)) << 30;
319
*(uint32_t *)attrib = util_le32_to_cpu(value);
320
}
321
322
static void
323
emit_R10G10B10A2_USCALED(const void *attrib, void *ptr)
324
{
325
float *src = (float *)ptr;
326
uint32_t value = 0;
327
value |= ((uint32_t)CLAMP(src[0], 0, 1023)) & 0x3ff;
328
value |= (((uint32_t)CLAMP(src[1], 0, 1023)) & 0x3ff) << 10;
329
value |= (((uint32_t)CLAMP(src[2], 0, 1023)) & 0x3ff) << 20;
330
value |= ((uint32_t)CLAMP(src[3], 0, 3)) << 30;
331
*(uint32_t *)attrib = util_le32_to_cpu(value);
332
}
333
334
static void
335
emit_R10G10B10A2_SNORM(const void *attrib, void *ptr)
336
{
337
float *src = (float *)ptr;
338
uint32_t value = 0;
339
value |= (uint32_t)(((uint32_t)(CLAMP(src[0], -1, 1) * 0x1ff)) & 0x3ff) ;
340
value |= (uint32_t)((((uint32_t)(CLAMP(src[1], -1, 1) * 0x1ff)) & 0x3ff) << 10) ;
341
value |= (uint32_t)((((uint32_t)(CLAMP(src[2], -1, 1) * 0x1ff)) & 0x3ff) << 20) ;
342
value |= (uint32_t)(((uint32_t)(CLAMP(src[3], -1, 1) * 0x1)) << 30) ;
343
*(uint32_t *)attrib = util_le32_to_cpu(value);
344
}
345
346
static void
347
emit_R10G10B10A2_SSCALED(const void *attrib, void *ptr)
348
{
349
float *src = (float *)ptr;
350
uint32_t value = 0;
351
value |= (uint32_t)(((uint32_t)CLAMP(src[0], -512, 511)) & 0x3ff) ;
352
value |= (uint32_t)((((uint32_t)CLAMP(src[1], -512, 511)) & 0x3ff) << 10) ;
353
value |= (uint32_t)((((uint32_t)CLAMP(src[2], -512, 511)) & 0x3ff) << 20) ;
354
value |= (uint32_t)(((uint32_t)CLAMP(src[3], -2, 1)) << 30) ;
355
*(uint32_t *)attrib = util_le32_to_cpu(value);
356
}
357
358
static void
359
emit_NULL(const void *attrib, void *ptr)
360
{
361
/* do nothing is the only sensible option */
362
}
363
364
static emit_func
365
get_emit_func(enum pipe_format format)
366
{
367
switch (format) {
368
case PIPE_FORMAT_R64_FLOAT:
369
return &emit_R64_FLOAT;
370
case PIPE_FORMAT_R64G64_FLOAT:
371
return &emit_R64G64_FLOAT;
372
case PIPE_FORMAT_R64G64B64_FLOAT:
373
return &emit_R64G64B64_FLOAT;
374
case PIPE_FORMAT_R64G64B64A64_FLOAT:
375
return &emit_R64G64B64A64_FLOAT;
376
377
case PIPE_FORMAT_R32_FLOAT:
378
return &emit_R32_FLOAT;
379
case PIPE_FORMAT_R32G32_FLOAT:
380
return &emit_R32G32_FLOAT;
381
case PIPE_FORMAT_R32G32B32_FLOAT:
382
return &emit_R32G32B32_FLOAT;
383
case PIPE_FORMAT_R32G32B32A32_FLOAT:
384
return &emit_R32G32B32A32_FLOAT;
385
386
case PIPE_FORMAT_R16_FLOAT:
387
return &emit_R16_FLOAT;
388
case PIPE_FORMAT_R16G16_FLOAT:
389
return &emit_R16G16_FLOAT;
390
case PIPE_FORMAT_R16G16B16_FLOAT:
391
return &emit_R16G16B16_FLOAT;
392
case PIPE_FORMAT_R16G16B16A16_FLOAT:
393
return &emit_R16G16B16A16_FLOAT;
394
395
case PIPE_FORMAT_R32_UNORM:
396
return &emit_R32_UNORM;
397
case PIPE_FORMAT_R32G32_UNORM:
398
return &emit_R32G32_UNORM;
399
case PIPE_FORMAT_R32G32B32_UNORM:
400
return &emit_R32G32B32_UNORM;
401
case PIPE_FORMAT_R32G32B32A32_UNORM:
402
return &emit_R32G32B32A32_UNORM;
403
404
case PIPE_FORMAT_R32_USCALED:
405
return &emit_R32_USCALED;
406
case PIPE_FORMAT_R32G32_USCALED:
407
return &emit_R32G32_USCALED;
408
case PIPE_FORMAT_R32G32B32_USCALED:
409
return &emit_R32G32B32_USCALED;
410
case PIPE_FORMAT_R32G32B32A32_USCALED:
411
return &emit_R32G32B32A32_USCALED;
412
413
case PIPE_FORMAT_R32_SNORM:
414
return &emit_R32_SNORM;
415
case PIPE_FORMAT_R32G32_SNORM:
416
return &emit_R32G32_SNORM;
417
case PIPE_FORMAT_R32G32B32_SNORM:
418
return &emit_R32G32B32_SNORM;
419
case PIPE_FORMAT_R32G32B32A32_SNORM:
420
return &emit_R32G32B32A32_SNORM;
421
422
case PIPE_FORMAT_R32_SSCALED:
423
return &emit_R32_SSCALED;
424
case PIPE_FORMAT_R32G32_SSCALED:
425
return &emit_R32G32_SSCALED;
426
case PIPE_FORMAT_R32G32B32_SSCALED:
427
return &emit_R32G32B32_SSCALED;
428
case PIPE_FORMAT_R32G32B32A32_SSCALED:
429
return &emit_R32G32B32A32_SSCALED;
430
431
case PIPE_FORMAT_R16_UNORM:
432
return &emit_R16_UNORM;
433
case PIPE_FORMAT_R16G16_UNORM:
434
return &emit_R16G16_UNORM;
435
case PIPE_FORMAT_R16G16B16_UNORM:
436
return &emit_R16G16B16_UNORM;
437
case PIPE_FORMAT_R16G16B16A16_UNORM:
438
return &emit_R16G16B16A16_UNORM;
439
440
case PIPE_FORMAT_R16_USCALED:
441
return &emit_R16_USCALED;
442
case PIPE_FORMAT_R16G16_USCALED:
443
return &emit_R16G16_USCALED;
444
case PIPE_FORMAT_R16G16B16_USCALED:
445
return &emit_R16G16B16_USCALED;
446
case PIPE_FORMAT_R16G16B16A16_USCALED:
447
return &emit_R16G16B16A16_USCALED;
448
449
case PIPE_FORMAT_R16_SNORM:
450
return &emit_R16_SNORM;
451
case PIPE_FORMAT_R16G16_SNORM:
452
return &emit_R16G16_SNORM;
453
case PIPE_FORMAT_R16G16B16_SNORM:
454
return &emit_R16G16B16_SNORM;
455
case PIPE_FORMAT_R16G16B16A16_SNORM:
456
return &emit_R16G16B16A16_SNORM;
457
458
case PIPE_FORMAT_R16_SSCALED:
459
return &emit_R16_SSCALED;
460
case PIPE_FORMAT_R16G16_SSCALED:
461
return &emit_R16G16_SSCALED;
462
case PIPE_FORMAT_R16G16B16_SSCALED:
463
return &emit_R16G16B16_SSCALED;
464
case PIPE_FORMAT_R16G16B16A16_SSCALED:
465
return &emit_R16G16B16A16_SSCALED;
466
467
case PIPE_FORMAT_R8_UNORM:
468
return &emit_R8_UNORM;
469
case PIPE_FORMAT_R8G8_UNORM:
470
return &emit_R8G8_UNORM;
471
case PIPE_FORMAT_R8G8B8_UNORM:
472
return &emit_R8G8B8_UNORM;
473
case PIPE_FORMAT_R8G8B8A8_UNORM:
474
return &emit_R8G8B8A8_UNORM;
475
476
case PIPE_FORMAT_R8_USCALED:
477
return &emit_R8_USCALED;
478
case PIPE_FORMAT_R8G8_USCALED:
479
return &emit_R8G8_USCALED;
480
case PIPE_FORMAT_R8G8B8_USCALED:
481
return &emit_R8G8B8_USCALED;
482
case PIPE_FORMAT_R8G8B8A8_USCALED:
483
return &emit_R8G8B8A8_USCALED;
484
485
case PIPE_FORMAT_R8_SNORM:
486
return &emit_R8_SNORM;
487
case PIPE_FORMAT_R8G8_SNORM:
488
return &emit_R8G8_SNORM;
489
case PIPE_FORMAT_R8G8B8_SNORM:
490
return &emit_R8G8B8_SNORM;
491
case PIPE_FORMAT_R8G8B8A8_SNORM:
492
return &emit_R8G8B8A8_SNORM;
493
494
case PIPE_FORMAT_R8_SSCALED:
495
return &emit_R8_SSCALED;
496
case PIPE_FORMAT_R8G8_SSCALED:
497
return &emit_R8G8_SSCALED;
498
case PIPE_FORMAT_R8G8B8_SSCALED:
499
return &emit_R8G8B8_SSCALED;
500
case PIPE_FORMAT_R8G8B8A8_SSCALED:
501
return &emit_R8G8B8A8_SSCALED;
502
503
case PIPE_FORMAT_B8G8R8A8_UNORM:
504
return &emit_B8G8R8A8_UNORM;
505
506
case PIPE_FORMAT_A8R8G8B8_UNORM:
507
return &emit_A8R8G8B8_UNORM;
508
509
case PIPE_FORMAT_R32_UINT:
510
return &emit_R32_UINT;
511
case PIPE_FORMAT_R32G32_UINT:
512
return &emit_R32G32_UINT;
513
case PIPE_FORMAT_R32G32B32_UINT:
514
return &emit_R32G32B32_UINT;
515
case PIPE_FORMAT_R32G32B32A32_UINT:
516
return &emit_R32G32B32A32_UINT;
517
518
case PIPE_FORMAT_R16_UINT:
519
return &emit_R16_UINT;
520
case PIPE_FORMAT_R16G16_UINT:
521
return &emit_R16G16_UINT;
522
case PIPE_FORMAT_R16G16B16_UINT:
523
return &emit_R16G16B16_UINT;
524
case PIPE_FORMAT_R16G16B16A16_UINT:
525
return &emit_R16G16B16A16_UINT;
526
527
case PIPE_FORMAT_R8_UINT:
528
return &emit_R8_UINT;
529
case PIPE_FORMAT_R8G8_UINT:
530
return &emit_R8G8_UINT;
531
case PIPE_FORMAT_R8G8B8_UINT:
532
return &emit_R8G8B8_UINT;
533
case PIPE_FORMAT_R8G8B8A8_UINT:
534
return &emit_R8G8B8A8_UINT;
535
536
case PIPE_FORMAT_R32_SINT:
537
return &emit_R32_SINT;
538
case PIPE_FORMAT_R32G32_SINT:
539
return &emit_R32G32_SINT;
540
case PIPE_FORMAT_R32G32B32_SINT:
541
return &emit_R32G32B32_SINT;
542
case PIPE_FORMAT_R32G32B32A32_SINT:
543
return &emit_R32G32B32A32_SINT;
544
545
case PIPE_FORMAT_R16_SINT:
546
return &emit_R16_SINT;
547
case PIPE_FORMAT_R16G16_SINT:
548
return &emit_R16G16_SINT;
549
case PIPE_FORMAT_R16G16B16_SINT:
550
return &emit_R16G16B16_SINT;
551
case PIPE_FORMAT_R16G16B16A16_SINT:
552
return &emit_R16G16B16A16_SINT;
553
554
case PIPE_FORMAT_R8_SINT:
555
return &emit_R8_SINT;
556
case PIPE_FORMAT_R8G8_SINT:
557
return &emit_R8G8_SINT;
558
case PIPE_FORMAT_R8G8B8_SINT:
559
return &emit_R8G8B8_SINT;
560
case PIPE_FORMAT_R8G8B8A8_SINT:
561
return &emit_R8G8B8A8_SINT;
562
563
case PIPE_FORMAT_B10G10R10A2_UNORM:
564
return &emit_B10G10R10A2_UNORM;
565
case PIPE_FORMAT_B10G10R10A2_USCALED:
566
return &emit_B10G10R10A2_USCALED;
567
case PIPE_FORMAT_B10G10R10A2_SNORM:
568
return &emit_B10G10R10A2_SNORM;
569
case PIPE_FORMAT_B10G10R10A2_SSCALED:
570
return &emit_B10G10R10A2_SSCALED;
571
572
case PIPE_FORMAT_R10G10B10A2_UNORM:
573
return &emit_R10G10B10A2_UNORM;
574
case PIPE_FORMAT_R10G10B10A2_USCALED:
575
return &emit_R10G10B10A2_USCALED;
576
case PIPE_FORMAT_R10G10B10A2_SNORM:
577
return &emit_R10G10B10A2_SNORM;
578
case PIPE_FORMAT_R10G10B10A2_SSCALED:
579
return &emit_R10G10B10A2_SSCALED;
580
581
default:
582
assert(0);
583
return &emit_NULL;
584
}
585
}
586
587
static ALWAYS_INLINE void PIPE_CDECL
588
generic_run_one(struct translate_generic *tg,
589
unsigned elt,
590
unsigned start_instance,
591
unsigned instance_id,
592
void *vert)
593
{
594
unsigned nr_attrs = tg->nr_attrib;
595
unsigned attr;
596
597
for (attr = 0; attr < nr_attrs; attr++) {
598
float data[4];
599
uint8_t *dst = (uint8_t *)vert + tg->attrib[attr].output_offset;
600
601
if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) {
602
const uint8_t *src;
603
unsigned index;
604
int copy_size;
605
606
if (tg->attrib[attr].instance_divisor) {
607
index = start_instance;
608
index += (instance_id / tg->attrib[attr].instance_divisor);
609
/* XXX we need to clamp the index here too, but to a
610
* per-array max value, not the draw->pt.max_index value
611
* that's being given to us via translate->set_buffer().
612
*/
613
}
614
else {
615
index = elt;
616
/* clamp to avoid going out of bounds */
617
index = MIN2(index, tg->attrib[attr].max_index);
618
}
619
620
src = tg->attrib[attr].input_ptr +
621
(ptrdiff_t)tg->attrib[attr].input_stride * index;
622
623
copy_size = tg->attrib[attr].copy_size;
624
if (likely(copy_size >= 0)) {
625
memcpy(dst, src, copy_size);
626
} else {
627
tg->attrib[attr].fetch(data, src, 1);
628
629
if (0)
630
debug_printf("Fetch linear attr %d from %p stride %d index %d: "
631
" %f, %f, %f, %f \n",
632
attr,
633
tg->attrib[attr].input_ptr,
634
tg->attrib[attr].input_stride,
635
index,
636
data[0], data[1],data[2], data[3]);
637
638
tg->attrib[attr].emit(data, dst);
639
}
640
} else {
641
if (likely(tg->attrib[attr].copy_size >= 0)) {
642
memcpy(data, &instance_id, 4);
643
} else {
644
data[0] = (float)instance_id;
645
tg->attrib[attr].emit(data, dst);
646
}
647
}
648
}
649
}
650
651
/**
652
* Fetch vertex attributes for 'count' vertices.
653
*/
654
static void PIPE_CDECL
655
generic_run_elts(struct translate *translate,
656
const unsigned *elts,
657
unsigned count,
658
unsigned start_instance,
659
unsigned instance_id,
660
void *output_buffer)
661
{
662
struct translate_generic *tg = translate_generic(translate);
663
char *vert = output_buffer;
664
unsigned i;
665
666
for (i = 0; i < count; i++) {
667
generic_run_one(tg, *elts++, start_instance, instance_id, vert);
668
vert += tg->translate.key.output_stride;
669
}
670
}
671
672
static void PIPE_CDECL
673
generic_run_elts16(struct translate *translate,
674
const uint16_t *elts,
675
unsigned count,
676
unsigned start_instance,
677
unsigned instance_id,
678
void *output_buffer)
679
{
680
struct translate_generic *tg = translate_generic(translate);
681
char *vert = output_buffer;
682
unsigned i;
683
684
for (i = 0; i < count; i++) {
685
generic_run_one(tg, *elts++, start_instance, instance_id, vert);
686
vert += tg->translate.key.output_stride;
687
}
688
}
689
690
static void PIPE_CDECL
691
generic_run_elts8(struct translate *translate,
692
const uint8_t *elts,
693
unsigned count,
694
unsigned start_instance,
695
unsigned instance_id,
696
void *output_buffer)
697
{
698
struct translate_generic *tg = translate_generic(translate);
699
char *vert = output_buffer;
700
unsigned i;
701
702
for (i = 0; i < count; i++) {
703
generic_run_one(tg, *elts++, start_instance, instance_id, vert);
704
vert += tg->translate.key.output_stride;
705
}
706
}
707
708
static void PIPE_CDECL
709
generic_run(struct translate *translate,
710
unsigned start,
711
unsigned count,
712
unsigned start_instance,
713
unsigned instance_id,
714
void *output_buffer)
715
{
716
struct translate_generic *tg = translate_generic(translate);
717
char *vert = output_buffer;
718
unsigned i;
719
720
for (i = 0; i < count; i++) {
721
generic_run_one(tg, start + i, start_instance, instance_id, vert);
722
vert += tg->translate.key.output_stride;
723
}
724
}
725
726
727
728
static void
729
generic_set_buffer(struct translate *translate,
730
unsigned buf,
731
const void *ptr,
732
unsigned stride,
733
unsigned max_index)
734
{
735
struct translate_generic *tg = translate_generic(translate);
736
unsigned i;
737
738
for (i = 0; i < tg->nr_attrib; i++) {
739
if (tg->attrib[i].buffer == buf) {
740
tg->attrib[i].input_ptr = ((const uint8_t *)ptr +
741
tg->attrib[i].input_offset);
742
tg->attrib[i].input_stride = stride;
743
tg->attrib[i].max_index = max_index;
744
}
745
}
746
}
747
748
749
static void
750
generic_release(struct translate *translate)
751
{
752
/* Refcount?
753
*/
754
FREE(translate);
755
}
756
757
static boolean
758
is_legal_int_format_combo(const struct util_format_description *src,
759
const struct util_format_description *dst)
760
{
761
unsigned i;
762
unsigned nr = MIN2(src->nr_channels, dst->nr_channels);
763
764
for (i = 0; i < nr; i++) {
765
/* The signs must match. */
766
if (src->channel[i].type != dst->channel[i].type) {
767
return FALSE;
768
}
769
770
/* Integers must not lose precision at any point in the pipeline. */
771
if (src->channel[i].size > dst->channel[i].size) {
772
return FALSE;
773
}
774
}
775
return TRUE;
776
}
777
778
struct translate *
779
translate_generic_create(const struct translate_key *key)
780
{
781
struct translate_generic *tg = CALLOC_STRUCT(translate_generic);
782
unsigned i;
783
784
if (!tg)
785
return NULL;
786
787
assert(key->nr_elements <= TRANSLATE_MAX_ATTRIBS);
788
789
tg->translate.key = *key;
790
tg->translate.release = generic_release;
791
tg->translate.set_buffer = generic_set_buffer;
792
tg->translate.run_elts = generic_run_elts;
793
tg->translate.run_elts16 = generic_run_elts16;
794
tg->translate.run_elts8 = generic_run_elts8;
795
tg->translate.run = generic_run;
796
797
for (i = 0; i < key->nr_elements; i++) {
798
const struct util_format_description *format_desc =
799
util_format_description(key->element[i].input_format);
800
const struct util_format_unpack_description *unpack =
801
util_format_unpack_description(key->element[i].input_format);
802
803
assert(format_desc);
804
805
tg->attrib[i].type = key->element[i].type;
806
807
if (format_desc->channel[0].pure_integer) {
808
const struct util_format_description *out_format_desc =
809
util_format_description(key->element[i].output_format);
810
811
if (!is_legal_int_format_combo(format_desc, out_format_desc)) {
812
FREE(tg);
813
return NULL;
814
}
815
}
816
817
tg->attrib[i].fetch = unpack->unpack_rgba;
818
tg->attrib[i].buffer = key->element[i].input_buffer;
819
tg->attrib[i].input_offset = key->element[i].input_offset;
820
tg->attrib[i].instance_divisor = key->element[i].instance_divisor;
821
822
tg->attrib[i].output_offset = key->element[i].output_offset;
823
824
tg->attrib[i].copy_size = -1;
825
if (tg->attrib[i].type == TRANSLATE_ELEMENT_INSTANCE_ID) {
826
if (key->element[i].output_format == PIPE_FORMAT_R32_USCALED
827
|| key->element[i].output_format == PIPE_FORMAT_R32_SSCALED)
828
tg->attrib[i].copy_size = 4;
829
} else {
830
if (key->element[i].input_format == key->element[i].output_format
831
&& format_desc->block.width == 1
832
&& format_desc->block.height == 1
833
&& !(format_desc->block.bits & 7))
834
tg->attrib[i].copy_size = format_desc->block.bits >> 3;
835
}
836
837
if (tg->attrib[i].copy_size < 0)
838
tg->attrib[i].emit = get_emit_func(key->element[i].output_format);
839
else
840
tg->attrib[i].emit = NULL;
841
}
842
843
tg->nr_attrib = key->nr_elements;
844
845
return &tg->translate;
846
}
847
848
boolean
849
translate_generic_is_output_format_supported(enum pipe_format format)
850
{
851
switch(format) {
852
case PIPE_FORMAT_R64G64B64A64_FLOAT: return TRUE;
853
case PIPE_FORMAT_R64G64B64_FLOAT: return TRUE;
854
case PIPE_FORMAT_R64G64_FLOAT: return TRUE;
855
case PIPE_FORMAT_R64_FLOAT: return TRUE;
856
857
case PIPE_FORMAT_R32G32B32A32_FLOAT: return TRUE;
858
case PIPE_FORMAT_R32G32B32_FLOAT: return TRUE;
859
case PIPE_FORMAT_R32G32_FLOAT: return TRUE;
860
case PIPE_FORMAT_R32_FLOAT: return TRUE;
861
862
case PIPE_FORMAT_R16G16B16A16_FLOAT: return TRUE;
863
case PIPE_FORMAT_R16G16B16_FLOAT: return TRUE;
864
case PIPE_FORMAT_R16G16_FLOAT: return TRUE;
865
case PIPE_FORMAT_R16_FLOAT: return TRUE;
866
867
case PIPE_FORMAT_R32G32B32A32_USCALED: return TRUE;
868
case PIPE_FORMAT_R32G32B32_USCALED: return TRUE;
869
case PIPE_FORMAT_R32G32_USCALED: return TRUE;
870
case PIPE_FORMAT_R32_USCALED: return TRUE;
871
872
case PIPE_FORMAT_R32G32B32A32_SSCALED: return TRUE;
873
case PIPE_FORMAT_R32G32B32_SSCALED: return TRUE;
874
case PIPE_FORMAT_R32G32_SSCALED: return TRUE;
875
case PIPE_FORMAT_R32_SSCALED: return TRUE;
876
877
case PIPE_FORMAT_R32G32B32A32_UNORM: return TRUE;
878
case PIPE_FORMAT_R32G32B32_UNORM: return TRUE;
879
case PIPE_FORMAT_R32G32_UNORM: return TRUE;
880
case PIPE_FORMAT_R32_UNORM: return TRUE;
881
882
case PIPE_FORMAT_R32G32B32A32_SNORM: return TRUE;
883
case PIPE_FORMAT_R32G32B32_SNORM: return TRUE;
884
case PIPE_FORMAT_R32G32_SNORM: return TRUE;
885
case PIPE_FORMAT_R32_SNORM: return TRUE;
886
887
case PIPE_FORMAT_R16G16B16A16_USCALED: return TRUE;
888
case PIPE_FORMAT_R16G16B16_USCALED: return TRUE;
889
case PIPE_FORMAT_R16G16_USCALED: return TRUE;
890
case PIPE_FORMAT_R16_USCALED: return TRUE;
891
892
case PIPE_FORMAT_R16G16B16A16_SSCALED: return TRUE;
893
case PIPE_FORMAT_R16G16B16_SSCALED: return TRUE;
894
case PIPE_FORMAT_R16G16_SSCALED: return TRUE;
895
case PIPE_FORMAT_R16_SSCALED: return TRUE;
896
897
case PIPE_FORMAT_R16G16B16A16_UNORM: return TRUE;
898
case PIPE_FORMAT_R16G16B16_UNORM: return TRUE;
899
case PIPE_FORMAT_R16G16_UNORM: return TRUE;
900
case PIPE_FORMAT_R16_UNORM: return TRUE;
901
902
case PIPE_FORMAT_R16G16B16A16_SNORM: return TRUE;
903
case PIPE_FORMAT_R16G16B16_SNORM: return TRUE;
904
case PIPE_FORMAT_R16G16_SNORM: return TRUE;
905
case PIPE_FORMAT_R16_SNORM: return TRUE;
906
907
case PIPE_FORMAT_R8G8B8A8_USCALED: return TRUE;
908
case PIPE_FORMAT_R8G8B8_USCALED: return TRUE;
909
case PIPE_FORMAT_R8G8_USCALED: return TRUE;
910
case PIPE_FORMAT_R8_USCALED: return TRUE;
911
912
case PIPE_FORMAT_R8G8B8A8_SSCALED: return TRUE;
913
case PIPE_FORMAT_R8G8B8_SSCALED: return TRUE;
914
case PIPE_FORMAT_R8G8_SSCALED: return TRUE;
915
case PIPE_FORMAT_R8_SSCALED: return TRUE;
916
917
case PIPE_FORMAT_R8G8B8A8_UNORM: return TRUE;
918
case PIPE_FORMAT_R8G8B8_UNORM: return TRUE;
919
case PIPE_FORMAT_R8G8_UNORM: return TRUE;
920
case PIPE_FORMAT_R8_UNORM: return TRUE;
921
922
case PIPE_FORMAT_R8G8B8A8_SNORM: return TRUE;
923
case PIPE_FORMAT_R8G8B8_SNORM: return TRUE;
924
case PIPE_FORMAT_R8G8_SNORM: return TRUE;
925
case PIPE_FORMAT_R8_SNORM: return TRUE;
926
927
case PIPE_FORMAT_A8R8G8B8_UNORM: return TRUE;
928
case PIPE_FORMAT_B8G8R8A8_UNORM: return TRUE;
929
930
case PIPE_FORMAT_R32G32B32A32_UINT: return TRUE;
931
case PIPE_FORMAT_R32G32B32_UINT: return TRUE;
932
case PIPE_FORMAT_R32G32_UINT: return TRUE;
933
case PIPE_FORMAT_R32_UINT: return TRUE;
934
935
case PIPE_FORMAT_R16G16B16A16_UINT: return TRUE;
936
case PIPE_FORMAT_R16G16B16_UINT: return TRUE;
937
case PIPE_FORMAT_R16G16_UINT: return TRUE;
938
case PIPE_FORMAT_R16_UINT: return TRUE;
939
940
case PIPE_FORMAT_R8G8B8A8_UINT: return TRUE;
941
case PIPE_FORMAT_R8G8B8_UINT: return TRUE;
942
case PIPE_FORMAT_R8G8_UINT: return TRUE;
943
case PIPE_FORMAT_R8_UINT: return TRUE;
944
945
case PIPE_FORMAT_R32G32B32A32_SINT: return TRUE;
946
case PIPE_FORMAT_R32G32B32_SINT: return TRUE;
947
case PIPE_FORMAT_R32G32_SINT: return TRUE;
948
case PIPE_FORMAT_R32_SINT: return TRUE;
949
950
case PIPE_FORMAT_R16G16B16A16_SINT: return TRUE;
951
case PIPE_FORMAT_R16G16B16_SINT: return TRUE;
952
case PIPE_FORMAT_R16G16_SINT: return TRUE;
953
case PIPE_FORMAT_R16_SINT: return TRUE;
954
955
case PIPE_FORMAT_R8G8B8A8_SINT: return TRUE;
956
case PIPE_FORMAT_R8G8B8_SINT: return TRUE;
957
case PIPE_FORMAT_R8G8_SINT: return TRUE;
958
case PIPE_FORMAT_R8_SINT: return TRUE;
959
960
case PIPE_FORMAT_B10G10R10A2_UNORM: return TRUE;
961
case PIPE_FORMAT_B10G10R10A2_USCALED: return TRUE;
962
case PIPE_FORMAT_B10G10R10A2_SNORM: return TRUE;
963
case PIPE_FORMAT_B10G10R10A2_SSCALED: return TRUE;
964
965
case PIPE_FORMAT_R10G10B10A2_UNORM: return TRUE;
966
case PIPE_FORMAT_R10G10B10A2_USCALED: return TRUE;
967
case PIPE_FORMAT_R10G10B10A2_SNORM: return TRUE;
968
case PIPE_FORMAT_R10G10B10A2_SSCALED: return TRUE;
969
970
default: return FALSE;
971
}
972
}
973
974