Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 1
#!/usr/bin/env python
2
 
3
'''
4
/**************************************************************************
5
 *
6
 * Copyright 2009-2010 VMware, Inc.
7
 * All Rights Reserved.
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a
10
 * copy of this software and associated documentation files (the
11
 * "Software"), to deal in the Software without restriction, including
12
 * without limitation the rights to use, copy, modify, merge, publish,
13
 * distribute, sub license, and/or sell copies of the Software, and to
14
 * permit persons to whom the Software is furnished to do so, subject to
15
 * the following conditions:
16
 *
17
 * The above copyright notice and this permission notice (including the
18
 * next paragraph) shall be included in all copies or substantial portions
19
 * of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
25
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
 *
29
 **************************************************************************/
30
 
31
/**
32
 * @file
33
 * Pixel format packing and unpacking functions.
34
 *
35
 * @author Jose Fonseca 
36
 */
37
'''
38
 
39
 
40
from u_format_parse import *
41
 
42
 
43
def generate_format_type(format):
44
    '''Generate a structure that describes the format.'''
45
 
46
    assert format.layout == PLAIN
47
 
48
    print 'union util_format_%s {' % format.short_name()
49
 
50
    if format.block_size() in (8, 16, 32, 64):
51
        print '   uint%u_t value;' % (format.block_size(),)
52
 
53
    use_bitfields = False
54
    for channel in format.channels:
55
        if channel.size % 8 or not is_pot(channel.size):
56
            use_bitfields = True
57
 
58
    print '   struct {'
59
    for channel in format.channels:
60
        if use_bitfields:
61
            if channel.type == VOID:
62
                if channel.size:
63
                    print '      unsigned %s:%u;' % (channel.name, channel.size)
64
            elif channel.type == UNSIGNED:
65
                print '      unsigned %s:%u;' % (channel.name, channel.size)
66
            elif channel.type in (SIGNED, FIXED):
67
                print '      int %s:%u;' % (channel.name, channel.size)
68
            elif channel.type == FLOAT:
69
                if channel.size == 64:
70
                    print '      double %s;' % (channel.name)
71
                elif channel.size == 32:
72
                    print '      float %s;' % (channel.name)
73
                else:
74
                    print '      unsigned %s:%u;' % (channel.name, channel.size)
75
            else:
76
                assert 0
77
        else:
78
            assert channel.size % 8 == 0 and is_pot(channel.size)
79
            if channel.type == VOID:
80
                if channel.size:
81
                    print '      uint%u_t %s;' % (channel.size, channel.name)
82
            elif channel.type == UNSIGNED:
83
                print '      uint%u_t %s;' % (channel.size, channel.name)
84
            elif channel.type in (SIGNED, FIXED):
85
                print '      int%u_t %s;' % (channel.size, channel.name)
86
            elif channel.type == FLOAT:
87
                if channel.size == 64:
88
                    print '      double %s;' % (channel.name)
89
                elif channel.size == 32:
90
                    print '      float %s;' % (channel.name)
91
                elif channel.size == 16:
92
                    print '      uint16_t %s;' % (channel.name)
93
                else:
94
                    assert 0
95
            else:
96
                assert 0
97
    print '   } chan;'
98
    print '};'
99
    print
100
 
101
 
102
def is_format_supported(format):
103
    '''Determines whether we actually have the plumbing necessary to generate the
104
    to read/write to/from this format.'''
105
 
106
    # FIXME: Ideally we would support any format combination here.
107
 
108
    if format.layout != PLAIN:
109
        return False
110
 
111
    for i in range(4):
112
        channel = format.channels[i]
113
        if channel.type not in (VOID, UNSIGNED, SIGNED, FLOAT, FIXED):
114
            return False
115
        if channel.type == FLOAT and channel.size not in (16, 32, 64):
116
            return False
117
 
118
    return True
119
 
120
def is_format_pure_unsigned(format):
121
    for i in range(4):
122
        channel = format.channels[i]
123
        if channel.type not in (VOID, UNSIGNED):
124
            return False
125
        if channel.type == UNSIGNED and channel.pure == False:
126
            return False
127
 
128
    return True
129
 
130
 
131
def is_format_pure_signed(format):
132
    for i in range(4):
133
        channel = format.channels[i]
134
        if channel.type not in (VOID, SIGNED):
135
            return False
136
        if channel.type == SIGNED and channel.pure == False:
137
            return False
138
 
139
    return True
140
 
141
def native_type(format):
142
    '''Get the native appropriate for a format.'''
143
 
144
    if format.name == 'PIPE_FORMAT_R11G11B10_FLOAT':
145
        return 'uint32_t'
146
    if format.name == 'PIPE_FORMAT_R9G9B9E5_FLOAT':
147
        return 'uint32_t'
148
 
149
    if format.layout == PLAIN:
150
        if not format.is_array():
151
            # For arithmetic pixel formats return the integer type that matches the whole pixel
152
            return 'uint%u_t' % format.block_size()
153
        else:
154
            # For array pixel formats return the integer type that matches the color channel
155
            channel = format.channels[0]
156
            if channel.type in (UNSIGNED, VOID):
157
                return 'uint%u_t' % channel.size
158
            elif channel.type in (SIGNED, FIXED):
159
                return 'int%u_t' % channel.size
160
            elif channel.type == FLOAT:
161
                if channel.size == 16:
162
                    return 'uint16_t'
163
                elif channel.size == 32:
164
                    return 'float'
165
                elif channel.size == 64:
166
                    return 'double'
167
                else:
168
                    assert False
169
            else:
170
                assert False
171
    else:
172
        assert False
173
 
174
 
175
def intermediate_native_type(bits, sign):
176
    '''Find a native type adequate to hold intermediate results of the request bit size.'''
177
 
178
    bytes = 4 # don't use anything smaller than 32bits
179
    while bytes * 8 < bits:
180
        bytes *= 2
181
    bits = bytes*8
182
 
183
    if sign:
184
        return 'int%u_t' % bits
185
    else:
186
        return 'uint%u_t' % bits
187
 
188
 
189
def get_one_shift(type):
190
    '''Get the number of the bit that matches unity for this type.'''
191
    if type.type == 'FLOAT':
192
        assert False
193
    if not type.norm:
194
        return 0
195
    if type.type == UNSIGNED:
196
        return type.size
197
    if type.type == SIGNED:
198
        return type.size - 1
199
    if type.type == FIXED:
200
        return type.size / 2
201
    assert False
202
 
203
 
204
def value_to_native(type, value):
205
    '''Get the value of unity for this type.'''
206
    if type.type == FLOAT:
207
        return value
208
    if type.type == FIXED:
209
        return int(value * (1 << (type.size/2)))
210
    if not type.norm:
211
        return int(value)
212
    if type.type == UNSIGNED:
213
        return int(value * ((1 << type.size) - 1))
214
    if type.type == SIGNED:
215
        return int(value * ((1 << (type.size - 1)) - 1))
216
    assert False
217
 
218
 
219
def native_to_constant(type, value):
220
    '''Get the value of unity for this type.'''
221
    if type.type == FLOAT:
222
        if type.size <= 32:
223
            return "%ff" % value
224
        else:
225
            return "%ff" % value
226
    else:
227
        return str(int(value))
228
 
229
 
230
def get_one(type):
231
    '''Get the value of unity for this type.'''
232
    return value_to_native(type, 1)
233
 
234
 
235
def clamp_expr(src_channel, dst_channel, dst_native_type, value):
236
    '''Generate the expression to clamp the value in the source type to the
237
    destination type range.'''
238
 
239
    if src_channel == dst_channel:
240
        return value
241
 
242
    src_min = src_channel.min()
243
    src_max = src_channel.max()
244
    dst_min = dst_channel.min()
245
    dst_max = dst_channel.max()
246
 
247
    # Translate the destination range to the src native value
248
    dst_min_native = value_to_native(src_channel, dst_min)
249
    dst_max_native = value_to_native(src_channel, dst_max)
250
 
251
    if src_min < dst_min and src_max > dst_max:
252
        return 'CLAMP(%s, %s, %s)' % (value, dst_min_native, dst_max_native)
253
 
254
    if src_max > dst_max:
255
        return 'MIN2(%s, %s)' % (value, dst_max_native)
256
 
257
    if src_min < dst_min:
258
        return 'MAX2(%s, %s)' % (value, dst_min_native)
259
 
260
    return value
261
 
262
 
263
def conversion_expr(src_channel,
264
                    dst_channel, dst_native_type,
265
                    value,
266
                    clamp=True,
267
                    src_colorspace = RGB,
268
                    dst_colorspace = RGB):
269
    '''Generate the expression to convert a value between two types.'''
270
 
271
    if src_colorspace != dst_colorspace:
272
        if src_colorspace == SRGB:
273
            assert src_channel.type == UNSIGNED
274
            assert src_channel.norm
275
            assert src_channel.size == 8
276
            assert dst_colorspace == RGB
277
            if dst_channel.type == FLOAT:
278
                return 'util_format_srgb_8unorm_to_linear_float(%s)' % value
279
            else:
280
                assert dst_channel.type == UNSIGNED
281
                assert dst_channel.norm
282
                assert dst_channel.size == 8
283
                return 'util_format_srgb_to_linear_8unorm(%s)' % value
284
        elif dst_colorspace == SRGB:
285
            assert dst_channel.type == UNSIGNED
286
            assert dst_channel.norm
287
            assert dst_channel.size == 8
288
            assert src_colorspace == RGB
289
            if src_channel.type == FLOAT:
290
                return 'util_format_linear_float_to_srgb_8unorm(%s)' % value
291
            else:
292
                assert src_channel.type == UNSIGNED
293
                assert src_channel.norm
294
                assert src_channel.size == 8
295
                return 'util_format_linear_to_srgb_8unorm(%s)' % value
296
        elif src_colorspace == ZS:
297
            pass
298
        elif dst_colorspace == ZS:
299
            pass
300
        else:
301
            assert 0
302
 
303
    if src_channel == dst_channel:
304
        return value
305
 
306
    src_type = src_channel.type
307
    src_size = src_channel.size
308
    src_norm = src_channel.norm
309
    src_pure = src_channel.pure
310
 
311
    # Promote half to float
312
    if src_type == FLOAT and src_size == 16:
313
        value = 'util_half_to_float(%s)' % value
314
        src_size = 32
315
 
316
    # Special case for float <-> ubytes for more accurate results
317
    # Done before clamping since these functions already take care of that
318
    if src_type == UNSIGNED and src_norm and src_size == 8 and dst_channel.type == FLOAT and dst_channel.size == 32:
319
        return 'ubyte_to_float(%s)' % value
320
    if src_type == FLOAT and src_size == 32 and dst_channel.type == UNSIGNED and dst_channel.norm and dst_channel.size == 8:
321
        return 'float_to_ubyte(%s)' % value
322
 
323
    if clamp:
324
        if dst_channel.type != FLOAT or src_type != FLOAT:
325
            value = clamp_expr(src_channel, dst_channel, dst_native_type, value)
326
 
327
    if src_type in (SIGNED, UNSIGNED) and dst_channel.type in (SIGNED, UNSIGNED):
328
        if not src_norm and not dst_channel.norm:
329
            # neither is normalized -- just cast
330
            return '(%s)%s' % (dst_native_type, value)
331
 
332
        src_one = get_one(src_channel)
333
        dst_one = get_one(dst_channel)
334
 
335
        if src_one > dst_one and src_norm and dst_channel.norm:
336
            # We can just bitshift
337
            src_shift = get_one_shift(src_channel)
338
            dst_shift = get_one_shift(dst_channel)
339
            value = '(%s >> %s)' % (value, src_shift - dst_shift)
340
        else:
341
            # We need to rescale using an intermediate type big enough to hold the multiplication of both
342
            tmp_native_type = intermediate_native_type(src_size + dst_channel.size, src_channel.sign and dst_channel.sign)
343
            value = '((%s)%s)' % (tmp_native_type, value)
344
            value = '(%s * 0x%x / 0x%x)' % (value, dst_one, src_one)
345
        value = '(%s)%s' % (dst_native_type, value)
346
        return value
347
 
348
    # Promote to either float or double
349
    if src_type != FLOAT:
350
        if src_norm or src_type == FIXED:
351
            one = get_one(src_channel)
352
            if src_size <= 23:
353
                value = '(%s * (1.0f/0x%x))' % (value, one)
354
                if dst_channel.size <= 32:
355
                    value = '(float)%s' % value
356
                src_size = 32
357
            else:
358
                # bigger than single precision mantissa, use double
359
                value = '(%s * (1.0/0x%x))' % (value, one)
360
                src_size = 64
361
            src_norm = False
362
        else:
363
            if src_size <= 23 or dst_channel.size <= 32:
364
                value = '(float)%s' % value
365
                src_size = 32
366
            else:
367
                # bigger than single precision mantissa, use double
368
                value = '(double)%s' % value
369
                src_size = 64
370
        src_type = FLOAT
371
 
372
    # Convert double or float to non-float
373
    if dst_channel.type != FLOAT:
374
        if dst_channel.norm or dst_channel.type == FIXED:
375
            dst_one = get_one(dst_channel)
376
            if dst_channel.size <= 23:
377
                value = 'util_iround(%s * 0x%x)' % (value, dst_one)
378
            else:
379
                # bigger than single precision mantissa, use double
380
                value = '(%s * (double)0x%x)' % (value, dst_one)
381
        value = '(%s)%s' % (dst_native_type, value)
382
    else:
383
        # Cast double to float when converting to either half or float
384
        if dst_channel.size <= 32 and src_size > 32:
385
            value = '(float)%s' % value
386
            src_size = 32
387
 
388
        if dst_channel.size == 16:
389
            value = 'util_float_to_half(%s)' % value
390
        elif dst_channel.size == 64 and src_size < 64:
391
            value = '(double)%s' % value
392
 
393
    return value
394
 
395
 
396
def generate_unpack_kernel(format, dst_channel, dst_native_type):
397
 
398
    if not is_format_supported(format):
399
        return
400
 
401
    assert format.layout == PLAIN
402
 
403
    src_native_type = native_type(format)
404
 
405
    if format.is_bitmask():
406
        depth = format.block_size()
407
        print '         uint%u_t value = *(const uint%u_t *)src;' % (depth, depth)
408
 
409
        # Declare the intermediate variables
410
        for i in range(format.nr_channels()):
411
            src_channel = format.channels[i]
412
            if src_channel.type == UNSIGNED:
413
                print '         uint%u_t %s;' % (depth, src_channel.name)
414
            elif src_channel.type == SIGNED:
415
                print '         int%u_t %s;' % (depth, src_channel.name)
416
 
417
        # Compute the intermediate unshifted values
418
        for i in range(format.nr_channels()):
419
            src_channel = format.channels[i]
420
            value = 'value'
421
            shift = src_channel.shift
422
            if src_channel.type == UNSIGNED:
423
                if shift:
424
                    value = '%s >> %u' % (value, shift)
425
                if shift + src_channel.size < depth:
426
                    value = '(%s) & 0x%x' % (value, (1 << src_channel.size) - 1)
427
            elif src_channel.type == SIGNED:
428
                if shift + src_channel.size < depth:
429
                    # Align the sign bit
430
                    lshift = depth - (shift + src_channel.size)
431
                    value = '%s << %u' % (value, lshift)
432
                # Cast to signed
433
                value = '(int%u_t)(%s) ' % (depth, value)
434
                if src_channel.size < depth:
435
                    # Align the LSB bit
436
                    rshift = depth - src_channel.size
437
                    value = '(%s) >> %u' % (value, rshift)
438
            else:
439
                value = None
440
 
441
            if value is not None:
442
                print '         %s = %s;' % (src_channel.name, value)
443
 
444
        # Convert, swizzle, and store final values
445
        for i in range(4):
446
            swizzle = format.swizzles[i]
447
            if swizzle < 4:
448
                src_channel = format.channels[swizzle]
449
                src_colorspace = format.colorspace
450
                if src_colorspace == SRGB and i == 3:
451
                    # Alpha channel is linear
452
                    src_colorspace = RGB
453
                value = src_channel.name
454
                value = conversion_expr(src_channel,
455
                                        dst_channel, dst_native_type,
456
                                        value,
457
                                        src_colorspace = src_colorspace)
458
            elif swizzle == SWIZZLE_0:
459
                value = '0'
460
            elif swizzle == SWIZZLE_1:
461
                value = get_one(dst_channel)
462
            elif swizzle == SWIZZLE_NONE:
463
                value = '0'
464
            else:
465
                assert False
466
            print '         dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
467
 
468
    else:
469
        print '         union util_format_%s pixel;' % format.short_name()
470
        print '         memcpy(&pixel, src, sizeof pixel);'
471
 
472
        for i in range(4):
473
            swizzle = format.swizzles[i]
474
            if swizzle < 4:
475
                src_channel = format.channels[swizzle]
476
                src_colorspace = format.colorspace
477
                if src_colorspace == SRGB and i == 3:
478
                    # Alpha channel is linear
479
                    src_colorspace = RGB
480
                value = 'pixel.chan.%s' % src_channel.name
481
                value = conversion_expr(src_channel,
482
                                        dst_channel, dst_native_type,
483
                                        value,
484
                                        src_colorspace = src_colorspace)
485
            elif swizzle == SWIZZLE_0:
486
                value = '0'
487
            elif swizzle == SWIZZLE_1:
488
                value = get_one(dst_channel)
489
            elif swizzle == SWIZZLE_NONE:
490
                value = '0'
491
            else:
492
                assert False
493
            print '         dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
494
 
495
 
496
def generate_pack_kernel(format, src_channel, src_native_type):
497
 
498
    if not is_format_supported(format):
499
        return
500
 
501
    dst_native_type = native_type(format)
502
 
503
    assert format.layout == PLAIN
504
 
505
    inv_swizzle = format.inv_swizzles()
506
 
507
    if format.is_bitmask():
508
        depth = format.block_size()
509
        print '         uint%u_t value = 0;' % depth
510
 
511
        for i in range(4):
512
            dst_channel = format.channels[i]
513
            shift = dst_channel.shift
514
            if inv_swizzle[i] is not None:
515
                value ='src[%u]' % inv_swizzle[i]
516
                dst_colorspace = format.colorspace
517
                if dst_colorspace == SRGB and inv_swizzle[i] == 3:
518
                    # Alpha channel is linear
519
                    dst_colorspace = RGB
520
                value = conversion_expr(src_channel,
521
                                        dst_channel, dst_native_type,
522
                                        value,
523
                                        dst_colorspace = dst_colorspace)
524
                if dst_channel.type in (UNSIGNED, SIGNED):
525
                    if shift + dst_channel.size < depth:
526
                        value = '(%s) & 0x%x' % (value, (1 << dst_channel.size) - 1)
527
                    if shift:
528
                        value = '(%s) << %u' % (value, shift)
529
                    if dst_channel.type == SIGNED:
530
                        # Cast to unsigned
531
                        value = '(uint%u_t)(%s) ' % (depth, value)
532
                else:
533
                    value = None
534
                if value is not None:
535
                    print '         value |= %s;' % (value)
536
 
537
        print '         *(uint%u_t *)dst = value;' % depth
538
 
539
    else:
540
        print '         union util_format_%s pixel;' % format.short_name()
541
 
542
        for i in range(4):
543
            dst_channel = format.channels[i]
544
            width = dst_channel.size
545
            if inv_swizzle[i] is None:
546
                continue
547
            dst_colorspace = format.colorspace
548
            if dst_colorspace == SRGB and inv_swizzle[i] == 3:
549
                # Alpha channel is linear
550
                dst_colorspace = RGB
551
            value ='src[%u]' % inv_swizzle[i]
552
            value = conversion_expr(src_channel,
553
                                    dst_channel, dst_native_type,
554
                                    value,
555
                                    dst_colorspace = dst_colorspace)
556
            print '         pixel.chan.%s = %s;' % (dst_channel.name, value)
557
 
558
        print '         memcpy(dst, &pixel, sizeof pixel);'
559
 
560
 
561
def generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix):
562
    '''Generate the function to unpack pixels from a particular format'''
563
 
564
    name = format.short_name()
565
 
566
    print 'static INLINE void'
567
    print 'util_format_%s_unpack_%s(%s *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)' % (name, dst_suffix, dst_native_type)
568
    print '{'
569
 
570
    if is_format_supported(format):
571
        print '   unsigned x, y;'
572
        print '   for(y = 0; y < height; y += %u) {' % (format.block_height,)
573
        print '      %s *dst = dst_row;' % (dst_native_type)
574
        print '      const uint8_t *src = src_row;'
575
        print '      for(x = 0; x < width; x += %u) {' % (format.block_width,)
576
 
577
        generate_unpack_kernel(format, dst_channel, dst_native_type)
578
 
579
        print '         src += %u;' % (format.block_size() / 8,)
580
        print '         dst += 4;'
581
        print '      }'
582
        print '      src_row += src_stride;'
583
        print '      dst_row += dst_stride/sizeof(*dst_row);'
584
        print '   }'
585
 
586
    print '}'
587
    print
588
 
589
 
590
def generate_format_pack(format, src_channel, src_native_type, src_suffix):
591
    '''Generate the function to pack pixels to a particular format'''
592
 
593
    name = format.short_name()
594
 
595
    print 'static INLINE void'
596
    print 'util_format_%s_pack_%s(uint8_t *dst_row, unsigned dst_stride, const %s *src_row, unsigned src_stride, unsigned width, unsigned height)' % (name, src_suffix, src_native_type)
597
    print '{'
598
 
599
    if is_format_supported(format):
600
        print '   unsigned x, y;'
601
        print '   for(y = 0; y < height; y += %u) {' % (format.block_height,)
602
        print '      const %s *src = src_row;' % (src_native_type)
603
        print '      uint8_t *dst = dst_row;'
604
        print '      for(x = 0; x < width; x += %u) {' % (format.block_width,)
605
 
606
        generate_pack_kernel(format, src_channel, src_native_type)
607
 
608
        print '         src += 4;'
609
        print '         dst += %u;' % (format.block_size() / 8,)
610
        print '      }'
611
        print '      dst_row += dst_stride;'
612
        print '      src_row += src_stride/sizeof(*src_row);'
613
        print '   }'
614
 
615
    print '}'
616
    print
617
 
618
 
619
def generate_format_fetch(format, dst_channel, dst_native_type, dst_suffix):
620
    '''Generate the function to unpack pixels from a particular format'''
621
 
622
    name = format.short_name()
623
 
624
    print 'static INLINE void'
625
    print 'util_format_%s_fetch_%s(%s *dst, const uint8_t *src, unsigned i, unsigned j)' % (name, dst_suffix, dst_native_type)
626
    print '{'
627
 
628
    if is_format_supported(format):
629
        generate_unpack_kernel(format, dst_channel, dst_native_type)
630
 
631
    print '}'
632
    print
633
 
634
 
635
def is_format_hand_written(format):
636
    return format.layout in ('s3tc', 'rgtc', 'etc', 'subsampled', 'other') or format.colorspace == ZS
637
 
638
 
639
def generate(formats):
640
    print
641
    print '#include "pipe/p_compiler.h"'
642
    print '#include "u_math.h"'
643
    print '#include "u_half.h"'
644
    print '#include "u_format.h"'
645
    print '#include "u_format_other.h"'
646
    print '#include "u_format_srgb.h"'
647
    print '#include "u_format_yuv.h"'
648
    print '#include "u_format_zs.h"'
649
    print
650
 
651
    for format in formats:
652
        if not is_format_hand_written(format):
653
 
654
            if is_format_supported(format):
655
                generate_format_type(format)
656
 
657
            if is_format_pure_unsigned(format):
658
                native_type = 'unsigned'
659
                suffix = 'unsigned'
660
                channel = Channel(UNSIGNED, False, True, 32)
661
 
662
                generate_format_unpack(format, channel, native_type, suffix)
663
                generate_format_pack(format, channel, native_type, suffix)
664
                generate_format_fetch(format, channel, native_type, suffix)
665
 
666
                channel = Channel(SIGNED, False, True, 32)
667
                native_type = 'int'
668
                suffix = 'signed'
669
                generate_format_unpack(format, channel, native_type, suffix)
670
                generate_format_pack(format, channel, native_type, suffix)
671
            elif is_format_pure_signed(format):
672
                native_type = 'int'
673
                suffix = 'signed'
674
                channel = Channel(SIGNED, False, True, 32)
675
 
676
                generate_format_unpack(format, channel, native_type, suffix)
677
                generate_format_pack(format, channel, native_type, suffix)
678
                generate_format_fetch(format, channel, native_type, suffix)
679
 
680
                native_type = 'unsigned'
681
                suffix = 'unsigned'
682
                channel = Channel(UNSIGNED, False, True, 32)
683
                generate_format_unpack(format, channel, native_type, suffix)
684
                generate_format_pack(format, channel, native_type, suffix)
685
            else:
686
                channel = Channel(FLOAT, False, False, 32)
687
                native_type = 'float'
688
                suffix = 'rgba_float'
689
 
690
                generate_format_unpack(format, channel, native_type, suffix)
691
                generate_format_pack(format, channel, native_type, suffix)
692
                generate_format_fetch(format, channel, native_type, suffix)
693
 
694
                channel = Channel(UNSIGNED, True, False, 8)
695
                native_type = 'uint8_t'
696
                suffix = 'rgba_8unorm'
697
 
698
                generate_format_unpack(format, channel, native_type, suffix)
699
                generate_format_pack(format, channel, native_type, suffix)
700