-
Notifications
You must be signed in to change notification settings - Fork 98
/
GL_EXT_shader_explicit_arithmetic_types.txt
1176 lines (1036 loc) · 66.5 KB
/
GL_EXT_shader_explicit_arithmetic_types.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Name
EXT_shader_explicit_arithmetic_types
Name Strings
GL_EXT_shader_explicit_arithmetic_types
GL_EXT_shader_explicit_arithmetic_types_int8
GL_EXT_shader_explicit_arithmetic_types_int16
GL_EXT_shader_explicit_arithmetic_types_int32
GL_EXT_shader_explicit_arithmetic_types_int64
GL_EXT_shader_explicit_arithmetic_types_float16
GL_EXT_shader_explicit_arithmetic_types_float32
GL_EXT_shader_explicit_arithmetic_types_float64
Contact
Alexander Galazin (alexander.galazin 'at' arm.com)
Contributors
Alexander Galazin, Arm
Jan-Harald Fredriksen, Arm
Hans-Kristian Arntzen, Arm
Neil Henning, AMD
Contributors to ARB_gpu_shader_int64
Contributors to AMD_gpu_shader_half_float
Contributors to NV_gpu_shader5
Contributors to AMD_gpu_shader_int16
Notice
Copyright (c) 2018 The Khronos Group Inc. Copyright terms at
http://www.khronos.org/registry/speccopyright.html
Status
Number
TBD
Dependencies
This extension can be applied to OpenGL GLSL versions 1.40
(#version 140) and higher.
This extension can be applied to OpenGL ES ESSL versions 3.10
(#version 310) and higher.
All these versions map GLSL/ESSL semantics to the same SPIR-V 1.0
semantics (approximating the most recent versions of GLSL/ESSL).
This extension is written against the OpenGL Shading Language
specification, Language Version 4.50, Document Revision 6.
This extension interacts with ARB_gpu_shader_int64.
This extension interacts with AMD_gpu_shader_half_float.
This extension interacts with AMD_gpu_shader_int16.
Overview
This extension modifies GLSL to expose explicit 8-bit integer, and 16-bit
integer and floating-point types. It also aliases existing float, double,
int, and uint types with more explicit type names.
This extension can be used together with GL_KHR_vulkan_glsl extension to
enable these types to be used in a high-level language for the Vulkan API.
This extension document adds support for the following extensions to be used
within GLSL:
- GL_EXT_shader_explicit_arithmetic_types_int8 - enables explicit 8-bit
signed and unsigned integer types.
- GL_EXT_shader_explicit_arithmetic_types_int16 - enables explicit 16-bit
signed and unsigned integer types
- GL_EXT_shader_explicit_arithmetic_types_int32 - enables explicit 32-bit
signed and unsigned integer types.
- GL_EXT_shader_explicit_arithmetic_types_int64 - enables explicit 64-bit
signed and unsigned integer types.
- GL_EXT_shader_explicit_arithmetic_types_float16 - enables explicit 16-bit
floating-point types.
- GL_EXT_shader_explicit_arithmetic_types_float32 - enables explicit 32-bit
floating-point types.
- GL_EXT_shader_explicit_arithmetic_types_float64 - enables explicit 64-bit
floating-point types.
Modifications to the OpenGL Shading Language Specification, Version 4.50
Including the following line in a shader can be used to control the language
features described in this extension:
#extension GL_EXT_shader_explicit_arithmetic_types : <behavior>
#extension GL_EXT_shader_explicit_arithmetic_types_int8 : <behavior>
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : <behavior>
#extension GL_EXT_shader_explicit_arithmetic_types_int32 : <behavior>
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : <behavior>
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : <behavior>
#extension GL_EXT_shader_explicit_arithmetic_types_float32 : <behavior>
#extension GL_EXT_shader_explicit_arithmetic_types_float64 : <behavior>
where <behavior> is as specified in section 3.3. If any of
- GL_EXT_shader_explicit_arithmetic_types_int8
- GL_EXT_shader_explicit_arithmetic_types_int16
- GL_EXT_shader_explicit_arithmetic_types_int32
- GL_EXT_shader_explicit_arithmetic_types_int64
- GL_EXT_shader_explicit_arithmetic_types_float16
- GL_EXT_shader_explicit_arithmetic_types_float32
- GL_EXT_shader_explicit_arithmetic_types_float64
extension are enabled, the GL_EXT_shader_explicit_arithmetic_types extension is
also implicitly enabled.
New preprocessor #defines are added:
#define GL_EXT_shader_explicit_arithmetic_types_int8 1
#define GL_EXT_shader_explicit_arithmetic_types_int16 1
#define GL_EXT_shader_explicit_arithmetic_types_int32 1
#define GL_EXT_shader_explicit_arithmetic_types_int64 1
#define GL_EXT_shader_explicit_arithmetic_types_float16 1
#define GL_EXT_shader_explicit_arithmetic_types_float32 1
#define GL_EXT_shader_explicit_arithmetic_types_float64 1
Such that if using a GL_EXT_shader_explicit_arithmetic_types_* extension is
supported, the corresponding
GL_EXT_shader_explicit_arithmetic_types_* #define is defined.
Changes to Chapter 3 of the OpenGL Shading Language Specification
If the extension GL_EXT_shader_explicit_arithmetic_types_float64 is supported,
add the following keywords to section 3.6 Keywords:
float64_t f64vec2 f64vec3 f64vec4
f64mat2 f64mat3 f64mat4
f64mat2x2 f64mat2x3 f64mat2x4
f64mat3x2 f64mat3x3 f64mat3x4
f64mat4x2 f64mat4x3 f64mat4x4
If the extension GL_EXT_shader_explicit_arithmetic_types_float32 is supported,
add the following keywords to section 3.6 Keywords:
float32_t f32vec2 f32vec3 f32vec4
f32mat2 f32mat3 f32mat4
f32mat2x2 f32mat2x3 f32mat2x4
f32mat3x2 f32mat3x3 f32mat3x4
f32mat4x2 f32mat4x3 f32mat4x4
If the extension GL_EXT_shader_explicit_arithmetic_types_float16 is supported,
add the following keywords to section 3.6 Keywords:
float16_t f16vec2 f16vec3 f16vec4
f16mat2 f16mat3 f16mat4
f16mat2x2 f16mat2x3 f16mat2x4
f16mat3x2 f16mat3x3 f16mat3x4
f16mat4x2 f16mat4x3 f16mat4x4
If the extension GL_EXT_shader_explicit_arithmetic_types_int64 is supported,
add the following keywords to section 3.6 Keywords:
int64_t i64vec2 i64vec3 i64vec4
uint64_t u64vec2 u64vec3 u64vec4
If the extension GL_EXT_shader_explicit_arithmetic_types_int32 is supported,
add the following keywords to section 3.6 Keywords:
int32_t i32vec2 i32vec3 i32vec4
uint32_t u32vec2 u32vec3 u32vec4
If the extension GL_EXT_shader_explicit_arithmetic_types_int16 is supported,
add the following keywords to section 3.6 Keywords:
int16_t i16vec2 i16vec3 i16vec4
uint16_t u16vec2 u16vec3 u16vec4
If the extension GL_EXT_shader_explicit_arithmetic_types_int8 is supported,
add the following keywords to section 3.6 Keywords:
int8_t i8vec2 i8vec3 i8vec4
uint8_t u8vec2 u8vec3 u8vec4
Changes to Chapter 4 of the OpenGL Shading Language Specification
Add into the tables in section 4.1 a new table interleaved with the existing
tables:
Transparent types with explicit bit size
--------------------------------------------------------------------------
| Type | Meaning |
| | |
--------------------------------------------------------------------------
(if GL_EXT_shader_explicit_arithmetic_types_float64 is supported)
| float64_t | a 64-bit floating-point scalar |
| f64vec2 | a two-component 64-bit floating-point vector |
| f64vec3 | a three-component 64-bit floating-point vector |
| f64vec4 | a four-component 64-bit floating-point vector |
| f64mat2 | a 2x2 64-bit floating-point matrix |
| f64mat3 | a 3x3 64-bit floating-point matrix |
| f64mat4 | a 4x4 64-bit floating-point matrix |
| f64mat2x2 | same as f64mat2 |
| f64mat2x3 | a 64-bit floating point matrix with 2 columns and 3 rows |
| f64mat2x4 | a 64-bit floating point matrix with 2 columns and 4 rows |
| f64mat3x2 | a 64-bit floating point matrix with 3 columns and 2 rows |
| f64mat3x3 | same as f64mat3 |
| f64mat3x4 | a 64-bit floating point matrix with 3 columns and 4 rows |
| f64mat4x2 | a 64-bit floating point matrix with 4 columns and 2 rows |
| f64mat4x3 | a 64-bit floating point matrix with 2 columns and 3 rows |
| f64mat4x4 | same as f64mat4 |
(if GL_EXT_shader_explicit_arithmetic_types_float32 is supported)
| float32_t | a 32-bit floating-point scalar |
| f32vec2 | a two-component 32-bit floating-point vector |
| f32vec3 | a three-component 32-bit floating-point vector |
| f32vec4 | a four-component 32-bit floating-point vector |
| f32mat2 | a 2x2 32-bit floating-point matrix |
| f32mat3 | a 3x3 32-bit floating-point matrix |
| f32mat4 | a 4x4 32-bit floating-point matrix |
| f32mat2x2 | same as f32mat2 |
| f32mat2x3 | a 32-bit floating point matrix with 2 columns and 3 rows |
| f32mat2x4 | a 32-bit floating point matrix with 2 columns and 4 rows |
| f32mat3x2 | a 32-bit floating point matrix with 3 columns and 2 rows |
| f32mat3x3 | same as f32mat3 |
| f32mat3x4 | a 32-bit floating point matrix with 3 columns and 4 rows |
| f32mat4x2 | a 32-bit floating point matrix with 4 columns and 2 rows |
| f32mat4x3 | a 32-bit floating point matrix with 2 columns and 3 rows |
| f32mat4x4 | same as f32mat4 |
(if GL_EXT_shader_explicit_arithmetic_types_float16 is supported)
| float16_t | a 16-bit floating-point scalar |
| f16vec2 | a two-component 16-bit floating-point vector |
| f16vec3 | a three-component 16-bit floating-point vector |
| f16vec4 | a four-component 16-bit floating-point vector |
| f16mat2 | a 2x2 16-bit floating-point matrix |
| f16mat3 | a 3x3 16-bit floating-point matrix |
| f16mat4 | a 4x4 16-bit floating-point matrix |
| f16mat2x2 | same as f16mat2 |
| f16mat2x3 | a 16-bit floating point matrix with 2 columns and 3 rows |
| f16mat2x4 | a 16-bit floating point matrix with 2 columns and 4 rows |
| f16mat3x2 | a 16-bit floating point matrix with 3 columns and 2 rows |
| f16mat3x3 | same as f16mat3 |
| f16mat3x4 | a 16-bit floating point matrix with 3 columns and 4 rows |
| f16mat4x2 | a 16-bit floating point matrix with 4 columns and 2 rows |
| f16mat4x3 | a 16-bit floating point matrix with 2 columns and 3 rows |
| f16mat4x4 | same as f16mat4 |
(if GL_EXT_shader_explicit_arithmetic_types_int64 is supported)
| int64_t | a 64-bit signed integer scalar |
| uint64_t | a 64-bit unsigned integer scalar |
| i64vec2 | a two-component 64-bit signed integer vector |
| i64vec3 | a three-component 64-bit signed integer vector |
| i64vec4 | a four-component 64-bit signed integer vector |
| u64vec2 | a two-component 64-bit unsigned integer vector |
| u64vec3 | a three-component 64bit unsigned integer vector |
| u64vec4 | a four-component 64-bit unsigned integer vector |
(if GL_EXT_shader_explicit_arithmetic_types_int32 is supported)
| int32_t | a 32-bit signed integer scalar |
| uint32_t | a 32-bit unsigned integer scalar |
| i32vec2 | a two-component 32-bit signed integer vector |
| i32vec3 | a three-component 32-bit signed integer vector |
| i32vec4 | a four-component 32-bit signed integer vector |
| u32vec2 | a two-component 32-bit unsigned integer vector |
| u32vec3 | a three-component 32-bit unsigned integer vector |
| u32vec4 | a four-component 32-bit unsigned integer vector |
(if GL_EXT_shader_explicit_arithmetic_types_int16 is supported)
| int16_t | a 16-bit signed integer scalar |
| uint16_t | a 16-bit unsigned integer scalar |
| i16vec2 | a two-component 16-bit signed integer vector |
| i16vec3 | a three-component 16-bit signed integer vector |
| i16vec4 | a four-component 16-bit signed integer vector |
| u16vec2 | a two-component 16-bit unsigned integer vector |
| u16vec3 | a three-component 16-bit unsigned integer vector |
| u16vec4 | a four-component 16-bit unsigned integer vector |
(if GL_EXT_shader_explicit_arithmetic_types_int8 is supported)
| int8_t | a 8-bit signed integer scalar |
| uint8_t | a 8-bit unsigned integer scalar |
| i8vec2 | a two-component 8-bit signed integer vector |
| i8vec3 | a three-component 8-bit signed integer vector |
| i8vec4 | a four-component 8-bit signed integer vector |
| u8vec2 | a two-component 8-bit unsigned integer vector |
| u8vec3 | a three-component 8-bit unsigned integer vector |
| u8vec4 | a four-component 8-bit unsigned integer vector |
--------------------------------------------------------------------------
Modify subsection 4.1.3 Integers
Modify the first paragraph to say:
"Signed and unsigned integer variables are fully supported. In this
document, the term integer is meant to generally include both signed
and unsigned integers. Variables with the types "int8_t", "int16_t",
"int32_t", and "int64_t" represent signed integer values with exactly
8, 16, 32, or 64 bits, respectively, including a sign bit, in two's
complement form. Variables with the type "uint8_t", "uint16_t",
"uint32_t", and "uint64_t" represent unsigned integer values with
exactly 8, 16, 32, or 64 bits, respectively. Variables with the type
"int32_t" and "uint32_t" are equivalent to "int" and "uint" types,
respectively. Addition, subtraction, and shift operations resulting in
overflow or underflow will not cause any exception, nor will they
saturate, rather they will "wrap" to yield the low-order 8, 16 32, or 64
bits (for respective types) the result.
Division and multiplication operations resulting in overflow or underflow
will not cause any exception but will result in an undefined value."
Change "integer-suffix" definition:
"integer-suffix:
unsigned-suffix long-suffixopt
unsigned-suffix short-suffixopt
long-suffix
short-suffix
unsigned-suffix: one of
u U
long-suffix: one of
l L
short-suffix: one of
s S"
Modify the next paragraph to say:
"No white space is allowed between the digits of an integer constant,
including after the leading 0 or after the leading 0x or 0X of a constant,
or before the integer-suffix. When tokenizing, the maximal token matching
the above will be recognized before a new token is started.
When the suffix is present, the literal type is determined as follows:
-------------------------------------
| suffix | type |
-------------------------------------
| no suffix | int, int32_t |
| u or U | uint, uint32_t |
| s or S | int16_t |
| both u/U and s/S | uint16_t |
| l or L | int64_t |
| both u/U and l/L | uint64_t |
-------------------------------------
A leading unary minus sign (-) is interpreted as an arithmetic
unary negation, not as part of the constant. Hence, literals themselves
are always expressed with non-negative syntax, though they could result
in a negative value. A suffix corresponding to a particular type must be
supported only if the extension enabling this type is supported."
Modify subsection 4.1.4 Floating-Point Variables:
Modify the first four sentences of the first paragraph to say:
"Half-precision, single-precision, and double-precision floating-point
variables are available for use in a variety of scalar calculations.
Generally, the term floating-point will refer to half-, single-,
and double-precision floating point. Floating-point variables are
defined as in the following examples:
float a, b = 1.5; // single-precision floating-point
double c, d = 2.0LF; // double-precision floating-point
float16_t e, f = 0.5HF; // half-precision floating-point
As an input value to one of the processing units, a half-precision,
single-precision, or double-precision floating-point variable is expected
to match the corresponding IEEE 754-2008 floating-point definition for
precision and dynamic range."
Modify the second paragraph to say:
"floating-suffix:
half-suffix single-suffix
double-suffix single-suffix
single-suffix
single-suffix: one of
f F
half-suffix: one of
h H
double-suffix: one of
L L"
(insert after second paragraph)
"Variables of type "float16_t" represent floating-point using
exactly 16 bits and are stored using the 16-bit floating-point
representation described in IEEE 754-2008.
Variables of type "float32_t" and "float" are equivalent and represent
floating-point with 32-bits floating-point representation
described in IEEE 754-2008.
Variables of type "float64_t" and "double" are equivalent and represent
floating-point with 64-bits floating-point representation
described in IEEE 754-2008.
Add the following sentences to the third paragraph:
"When the suffix is present, the literal type is determined as follows:
----------------------------------------
| suffix | type |
----------------------------------------
| no suffix | float32_t, float |
| f or F | float32_t, float |
| both l/L and f/F | float64_t, double|
| both h/H and f/F | float16_t |
----------------------------------------
A suffix corresponding to a particular type must be
supported only if the extension enabling this type is supported."
Modify the second sentence of subsection 4.1.6 Matrices to say:
"Matrix types beginning with "mat" or "f32mat" have single-precision
components, with "f16mat" have half-precision components, while matrix
types beginning with "dmat" of "f64mat" have double-precision components"
Modify subsection 4.1.10 Implicit Conversions to say:
"In some situations, an expression and its type will be implicitly
converted to a different type. Such conversion are classified into the
following types: integral promotions, floating point promotion,
integral conversions, floating point conversions, and
floating-integral conversions.
(Note: Expressions of type "int32_t", "uint32_t", "float32_t",
and "float64_t" are treated as identical to those of type "int", "uint",
"float", and "double" respectively. Implicit conversions to and from
these explicitly-sized types are allowed whenever conversions involving
the equivalent base type are allowed.)
The following table shows allowed integral promotions:
--------------------------------------------------------
| Type of | Can be implicitly promoted to |
| expression | |
--------------------------------------------------------
| int8_t | int32_t |
| int16_t | |
| uint8_t | |
| uint16_t | |
--------------------------------------------------------
| i8vec2 | i32vec2 |
| i16vec2 | |
| u8vec2 | |
| u16vec2 | |
--------------------------------------------------------
| i8vec3 | i32vec3 |
| i16vec3 | |
| u8vec3 | |
| u16vec3 | |
--------------------------------------------------------
| i8vec4 | i32vec4 |
| i16vec4 | |
| u8vec4 | |
| u16vec4 | |
--------------------------------------------------------
The following table shows allowed floating-point promotions:
--------------------------------------------------------
| Type of | Can be implicitly promoted to |
| expression | |
--------------------------------------------------------
| float16_t | float64_t |
| float32_t | |
--------------------------------------------------------
| f16vec2 | f64vec2 |
| f32vec2 | |
--------------------------------------------------------
| f16vec3 | f64vec3 |
| f32vec3 | |
--------------------------------------------------------
| f16vec4 | f64vec4 |
| f32vec4 | |
--------------------------------------------------------
| f16mat2 | f64mat2 |
| f32mat2 | |
--------------------------------------------------------
| f16mat3 | f64mat3 |
| f32mat3 | |
--------------------------------------------------------
| f16mat4 | f64mat4 |
| f32mat4 | |
--------------------------------------------------------
| f16mat2x3 | f64mat2x3 |
| f32mat2x3 | |
--------------------------------------------------------
| f16mat2x4 | f64mat2x4 |
| f32mat2x4 | |
--------------------------------------------------------
| f16mat3x2 | f64mat3x2 |
| f32mat3x2 | |
--------------------------------------------------------
| f16mat3x4 | f64mat3x4 |
| f32mat3x4 | |
--------------------------------------------------------
| f16mat4x2 | f64mat4x2 |
| f32mat4x2 | |
--------------------------------------------------------
| f16mat4x3 | f64mat4x3 |
| f32mat4x3 | |
--------------------------------------------------------
The following table shows allowed integral conversions:
-------------------------------------------------------------------------
| Type of | Can be implicitly converted to |
| expression | |
-------------------------------------------------------------------------
| int8_t | uint8_t, int16_t, uint16_t, uint32_t, int64_t, uint64_t |
| i8vec2 | u8vec2, i16vec2, u16vec2, u32vec2, i64vec2, u64vec2 |
| i8vec3 | u8vec3, i16vec3, u16vec3, u32vec3, i64vec3, u64vec3 |
| i8vec4 | u8vec4, i16vec4, u16vec4, u32vec4, i64vec4, u64vec4 |
| int16_t | uint16_t, uint32_t, int64_t, uint64_t |
| i16vec2 | u16vec2, u32vec2, i64vec2, u64vec2 |
| i16vec3 | u16vec3, u32vec3, i64vec3, u64vec3, |
| i16vec4 | u16vec4, u32vec4, i64vec4, u64vec4, |
| uint8_t | int16_t, uint16_t, uint32_t, int64_t, uint64_t |
| u8vec2 | i16vec2, u16vec2, u32vec2, i64vec2, u64vec2 |
| u8vec3 | i16vec3, u16vec3, u32vec3, i64vec3, u64vec3 |
| u8vec4 | i16vec4, u16vec4, u32vec4, i64vec4, u64vec4 |
| uint16_t | uint32_t, int64_t, uint64_t |
| u16vec2 | u32vec2, i64vec2, u64vec2 |
| u16vec3 | u32vec3, i64vec3, u64vec3 |
| u16vec4 | u32vec4, i64vec4, u64vec4 |
| int32_t | uint32_t, int64_t, uint64_t |
| i32vec2 | u32vec2, i64vec2, u64vec2 |
| i32vec3 | u32vec3, i64vec3, u64vec3 |
| i32vec4 | u32vec4, i64vec4, u64vec4 |
| uint32_t | int64_t, uint64_t |
| u32vec2 | i64vec2, u64vec2 |
| u32vec3 | i64vec3, u64vec3 |
| u32vec4 | i64vec4, u64vec4 |
| int64_t | uint64_t |
| i64vec2 | u64vec2 |
| i64vec3 | u64vec3 |
| i64vec4 | u64vec4 |
-------------------------------------------------------------------------
The following table shows allowed floating-point conversions:
--------------------------------------------------------
| Type of | Can be implicitly converted to |
| expression | |
--------------------------------------------------------
| float16_t | float32_t |
| f16vec2 | f32vec2 |
| f16vec3 | f32vec3 |
| f16vec4 | f32vec4 |
| f16mat2 | f32mat2 |
| f16mat3 | f32mat3 |
| f16mat4 | f32mat4 |
| f16mat2x3 | f32mat2x3 |
| f16mat2x4 | f32mat2x4 |
| f16mat3x2 | f32mat3x2 |
| f16mat3x4 | f32mat3x4 |
| f16mat4x2 | f32mat4x2 |
| f16mat4x3 | f32mat4x3 |
--------------------------------------------------------
The following table shows allowed floating-integral conversions:
--------------------------------------------------------
| Type of | Can be implicitly converted to |
| expression | |
--------------------------------------------------------
| int8_t | float16_t, float32_t, float64_t |
| i8vec2 | f16vec2, f32vec2, f64vec2 |
| i8vec3 | f16vec3, f32vec3, f64vec3 |
| i8vec4 | f16vec4, f32vec4, f64vecv4 |
| int16_t | float16_t, float32_t, float64_t |
| i16vec2 | f16vec2, f32vec2, f64vec2 |
| i16vec3 | f16vec3, f32vec3, f64vec3 |
| i16vec4 | f16vec4, f32vec4, f64vec4 |
| uint8_t | float16_t, float32_t, float64_t |
| u8vec2 | f16vec2, f32vec2, f64vec2 |
| u8vec3 | f16vec3, f32vec3, f64vec3 |
| u8vec4 | f16vec4, f32vec4, f64vec4 |
| uint16_t | float16_t, float32_t, float64_t |
| u16vec2 | f16vec2, f32vec2, f64vec2 |
| u16vec3 | f16vec3, f32vec3, f64vec3 |
| u16vec4 | f16vec4, f32vec4, f64vec4 |
| int32_t | float32_t, float64_t |
| i32vec2 | f32vec2, f64vec2 |
| i32vec3 | f32vec3, f64vec3 |
| i32vec4 | f32vec4, f64vec4 |
| uint32_t | float32_t, float64_t |
| u32vec2 | f32vec2, f64vec2 |
| u32vec3 | f32vec3, f64vec3 |
| u32vec4 | f32vec4, f64vec4 |
| int64_t | float64_t |
| i64vec2 | f64vec2 |
| i64vec3 | f64vec3 |
| i64vec4 | f64vec4 |
| uint64_t | float64_t |
| u64vec2 | f64vec2 |
| u64vec3 | f64vec3 |
| u64vec4 | f64vec4 |
--------------------------------------------------------
No implicit conversions are provided to convert from unsigned to signed
integer types of the same rank, from floating-point to integer types,
from higher-precision to lower-precision types, from larger types to
smaller types, from scalars to vectors, from vectors to scalars, or
between matrix types with non-matching number of columns and rows. There
are no implicit array or structure conversions. For example, an array of
int32_t cannot be implicitly converted to an array of float32_t.
When an implicit conversion is done, it is not a re-interpretation of the
expression's bit pattern, but a conversion of its value to an equivalent
value in the new type. For example, the integer value -5 will be
converted to the floating-point value -5.0.
When converting integer values to floating-point values the result is
exact if possible. If the value being converted is in the range of
values that can be represented but the value cannot be represented
exactly, then choice of either the next lower or higher representable
value:
* is determined by the rounding mode requested through the API, or
* is implementation-defined if no rounding mode is requested.
Integer values having more bits of precision than a floating-point
mantissa will lose precision when converted to float. If the value being
converted is outside the range of values that can be represented,
the behavior is undefined.
When performing implicit conversion for binary operators, there may be
multiple data types to which the two operands can be converted. For
example, when adding an int32_t value to a uint32_t value, both values
can be implicitly converted to uint32_t, float32_t, and float64_t. In
such cases conversion happens as defined as follows:
(Note: In this paragraph vector and matrix types are referred to as
types derived from scalar types with the same bit width and bit
interpretation)
- If either operand has type float64_t or derived from float64_t,
the other shall be converted to float64_t or derived type.
- Otherwise, if either operand has type float32_t or derived from
float32_t, the other shall be converted to float32_t or derived type.
- Otherwise, if either operand has type float16_t or derived from
float16_t, the other shall be converted to float16_t or derived type.
- Otherwise, if both operands have integer types the following rules
shall be applied to the operands:
- If both operands have the same type, no further conversion
is needed.
- If both operands have signed integer types or both
have unsigned integer types, the operand with the type of lesser
integer conversion rank shall be converted to the type of the
operand with greater rank.
- Otherwise, if the operand that has unsigned integer type has rank
greater than to the rank of the type of the other
operand, the operand with signed integer type shall be converted
to the type of the operand with unsigned integer type.
- Otherwise, if the type of the operand with signed integer type can
represent all of the values of the type of the operand with
unsigned integer type, the operand with unsigned integer type
shall be converted to the type of the operand with signed
integer type.
- Otherwise, both operands shall be converted to the unsigned
integer type corresponding to the type of the operand with signed
integer type.
(Note: Unlike C++, in case both operands have integer types the above
rules do not require to perform integral promotions before any other
conversion is considered)
The conversions listed in the following subsections are done only as
indicated by other sections of this specification.
Every integer type has an integer conversion rank defined as follows:
- No two signed integer types have the same rank.
- The rank of a scalar signed integer type shall be greater than the rank
of any scalar signed integer type with a smaller size.
- The rank of int64_t shall be greater than the rank of int32_t, which
shall be greater than the rank of int16_t, which shall be greater
than the rank of int8_t.
- The rank of any vector signed integer type is equal to the rank of the
base scalar signed integer type.
- The rank of any scalar unsigned integer type shall equal the rank of
the corresponding scalar signed integer type.
- The rank of any vector unsigned integer type is equal to the rank of
the respective scalar unsigned integer type.
Modify Section 4.3.6, Output Variables
(add new bullet to the list in the second paragraph on p. 51)
"It is a compile-time error to declare a fragment shader output that
contains any of the following:
...
* A 64-bit integer scalar or vector (int64_t, uint64_t, i64vec2, i64vec3,
i64vec4, u64vec2, u64vec3, u64vec4)"
Modify subsection 4.4.2.1 Transform Feedback Layout Qualifiers
(insert after the fourth paragraph in the section on p. 70)
"... will be a multiple of 8; if applied to an aggregrate containing a
float16_t, the offset must also be a multiple of 2, and the space taken in
he buffer will be a multiple of 2.""
Modify subsection 4.7.1 Range and Precision.
Modify the first sentence of the first paragraph to say:
"The precision of stored half-, single-, and double-precision
floating-point variables is defined by the IEEE 754-2008 standard for
16-bit, 32-bit, and 64-bit floating-point numbers."
Modify the first sentence of the second paragraph to say:
"The following rules apply to half, single and double-precision operations:
Positive and negative Infs and positive and negative zeros are generated as
dictated by IEEE 754-2008, but subject to the precisions
allowed in the following table."
For half precision operations, precisions are required as follows:
-----------------------------------------------------------------------
| Operation | Precision |
-----------------------------------------------------------------------
| a + b, a - b, a * b | Correctly rounded. |
| <, <=, ==, >, >= | Correct result. |
| a / b, 1.0 / b | 2.5 ULP for b in the range [2^(-14), 2^(14)]. |
| a * b + c | Correctly rounded single operation or |
| | sequence of two correctly rounded operations. |
| fma() | Inherited from a * b + c. |
| pow(x, y) | Inherited from exp2 (y * log2 (x)). |
| exp (x), exp2 (x) | (1 + 2 * |x|) ULP. |
| log (), log2() | 3 ULP outside the range [0.5, 2.0]. |
| | Absolute error < 2^(-7) inside |
| | the range [0.5, 2.0]. |
| sqrt () | Inherited from 1.0 / inversesqrt(). |
| inversesqrt () | 2 ULP. |
| implicit and | |
| explicit conversions| |
| between types | Correctly rounded |
-----------------------------------------------------------------------
Add the following sentence after the table with precision requirements for
single precision operations:
"The rounding mode is not defined but must not affect the result by more
than 1 ULP."
Add the following paragraph at the end of the subsection:
"Storage requirements are defined by variable type. The precision of
operations and built-in functions must preserve the storage precision
requirements of the variables involved."
Modify subsection 4.7.2 Precision Qualifiers.
Modify the first sentence to say:
"Only single-precision floating-point declaration without explicit bit size,
integer declaration without explicit bit size, or any opaque-type
declaration can have the type preceded by one of these precision
qualifiers:..."
Modify subsection 4.7.3 Default Precision Qualifiers.
Add the following paragraph after the first paragraph:
"Types with explicit bit size can not bit used in default precision
declarations."
Changes to Chapter 5 of the OpenGL Shading Language Specification
Modify subsection 5.4.1, Conversion and Scalar Constructors
(add after the first list of constructor examples on p. 97)
int8_t(bool) // convert a Boolean value to a int8_t
int8_t(uint8_t) // convert a uint8_t value to a int8_t
int8_t(int16_t) // convert a int16_t value to a int8_t
int8_t(uint16_t) // convert a uint16_t value to a int8_t
int8_t(int32_t) // convert a int32_t value to a int8_t
int8_t(uint32_t) // convert a uint32_t value to a int8_t
int8_t(int64_t) // convert a int64_t value to a int8_t
int8_t(uint64_t) // convert a uint64_t value to a int8_t
int8_t(float16_t) // convert a float16_t value to a int8_t
int8_t(float32_t) // convert a float32_t value to a int8_t
int8_t(float64_t) // convert a float64_t value to a int8_t
uint8_t(bool) // convert a Boolean value to a uint8_t
uint8_t(int8_t) // convert a int8_t value to a uint8_t
uint8_t(int16_t) // convert a int16_t value to a uint8_t
uint8_t(uint16_t) // convert a uint16_t value to a uint8_t
uint8_t(int32_t) // convert a int32_t value to a uint8_t
uint8_t(uint32_t) // convert a uint32_t value to a uint8_t
uint8_t(int64_t) // convert a int64_t value to a uint8_t
uint8_t(uint64_t) // convert a uint64_t value to a uint8_t
uint8_t(float16_t) // convert a float16_t value to a uint8_t
uint8_t(float32_t) // convert a float32_t value to a uint8_t
uint8_t(float64_t) // convert a float64_t value to a uint8_t
int16_t(bool) // convert a Boolean value to a int16_t
int16_t(int8_t) // convert a int8_t value to a int16_t
int16_t(uint8_t) // convert a uint8_t value to a int16_t
int16_t(uint16_t) // convert a uint16_t value to a int16_t
int16_t(int32_t) // convert a int32_t value to a int16_t
int16_t(uint32_t) // convert a uint32_t value to a int16_t
int16_t(int64_t) // convert a int64_t value to a int16_t
int16_t(uint64_t) // convert a uint64_t value to a int16_t
int16_t(float16_t) // convert a float16_t value to a int16_t
int16_t(float32_t) // convert a float32_t value to a int16_t
int16_t(float64_t) // convert a float64_t value to a int16_t
uint16_t(bool) // convert a Boolean value to a uint16_t
uint16_t(int8_t) // convert a int8_t value to a uint16_t
uint16_t(uint8_t) // convert a uint8_t value to a uint16_t
uint16_t(int16_t) // convert a int16_t value to a uint16_t
uint16_t(int32_t) // convert a int32_t value to a uint16_t
uint16_t(uint32_t) // convert a uint32_t value to a uint16_t
uint16_t(int64_t) // convert a int64_t value to a uint16_t
uint16_t(uint64_t) // convert a uint64_t value to a uint16_t
uint16_t(float16_t) // convert a float16_t value to a uint16_t
uint16_t(float32_t) // convert a float32_t value to a uint16_t
uint16_t(float64_t) // convert a float64_t value to a uint16_t
int32_t(bool) // convert a Boolean value to a int32_t
int32_t(int8_t) // convert a int8_t value to a int32_t
int32_t(uint8_t) // convert a uint8_t value to a int32_t
int32_t(int16_t) // convert a int16_t value to a int32_t
int32_t(uint16_t) // convert a uint16_t value to a int32_t
int32_t(uint32_t) // convert a uint32_t value to a int32_t
int32_t(int64_t) // convert a int64_t value to a int32_t
int32_t(uint64_t) // convert a uint64_t value to a int32_t
int32_t(float16_t) // convert a float16_t value to a int32_t
int32_t(float32_t) // convert a float32_t value to a int32_t
int32_t(float64_t) // convert a float64_t value to a int32_t
uint32_t(bool) // convert a Boolean value to a uint32_t
uint32_t(int8_t) // convert a int8_t value to a uint32_t
uint32_t(uint8_t) // convert a uint8_t value to a uint32_t
uint32_t(int16_t) // convert a int16_t value to a uint32_t
uint32_t(uint16_t) // convert a uint16_t value to a uint32_t
uint32_t(int32_t) // convert a int32_t value to a uint32_t
uint32_t(int64_t) // convert a int64_t value to a uint32_t
uint32_t(uint64_t) // convert a uint64_t value to a uint32_t
uint32_t(float16_t) // convert a float16_t value to a uint32_t
uint32_t(float32_t) // convert a float32_t value to a uint32_t
uint32_t(float64_t) // convert a float64_t value to a uint32_t
int64_t(bool) // convert a Boolean value to a int64_t
int64_t(int8_t) // convert a int8_t value to a int64_t
int64_t(uint8_t) // convert a uint8_t value to a int64_t
int64_t(int16_t) // convert a int16_t value to a int64_t
int64_t(uint16_t) // convert a uint16_t value to a int64_t
int64_t(int32_t) // convert a int32_t value to a int64_t
int64_t(uint32_t) // convert a uint32_t value to a int64_t
int64_t(uint64_t) // convert a uint64_t value to a int64_t
int64_t(float16_t) // convert a float16_t value to a int64_t
int64_t(float32_t) // convert a float32_t value to a int64_t
int64_t(float64_t) // convert a float64_t value to a int64_t
uint64_t(bool) // convert a Boolean value to a uint64_t
uint64_t(int8_t) // convert a int8_t value to a uint64_t
uint64_t(uint8_t) // convert a uint8_t value to a uint64_t
uint64_t(int16_t) // convert a int16_t value to a uint64_t
uint64_t(uint16_t) // convert a uint16_t value to a uint64_t
uint64_t(int32_t) // convert a int32_t value to a uint64_t
uint64_t(uint32_t) // convert a uint32_t value to a uint64_t
uint64_t(int64_t) // convert a int64_t value to a uint64_t
uint64_t(float16_t) // convert a float16_t value to a uint64_t
uint64_t(float32_t) // convert a float32_t value to a uint64_t
uint64_t(float64_t) // convert a float64_t value to a uint64_t
float16_t(bool) // convert a Boolean value to a float16_t
float16_t(int8_t) // convert a int8_t value to a float16_t
float16_t(uint8_t) // convert a uint8_t value to a float16_t
float16_t(int16_t) // convert a int16_t value to a float16_t
float16_t(uint16_t) // convert a uint16_t value to a float16_t
float16_t(int32_t) // convert a int32_t value to a float16_t
float16_t(uint32_t) // convert a uint32_t value to a float16_t
float16_t(int64_t) // convert a int64_t value to a float16_t
float16_t(uint64_t) // convert a uint64_t value to a float16_t
float16_t(float32_t) // convert a float32_t value to a float16_t
float16_t(float64_t) // convert a float64_t value to a float16_t
float32_t(bool) // convert a Boolean value to a float32_t
float32_t(int8_t) // convert a int8_t value to a float32_t
float32_t(uint8_t) // convert a uint8_t value to a float32_t
float32_t(int16_t) // convert a int16_t value to a float32_t
float32_t(uint16_t) // convert a uint16_t value to a float32_t
float32_t(int32_t) // convert a int32_t value to a float32_t
float32_t(uint32_t) // convert a uint32_t value to a float32_t
float32_t(int64_t) // convert a int64_t value to a float32_t
float32_t(uint64_t) // convert a uint64_t value to a float32_t
float32_t(float16_t) // convert a float16_t value to a float32_t
float32_t(float64_t) // convert a float64_t value to a float32_t
float64_t(bool) // convert a Boolean value to a float64_t
float64_t(int8_t) // convert a int8_t value to a float64_t
float64_t(uint8_t) // convert a uint8_t value to a float64_t
float64_t(int16_t) // convert a int16_t value to a float64_t
float64_t(uint16_t) // convert a uint16_t value to a float64_t
float64_t(int32_t) // convert a int32_t value to a float64_t
float64_t(uint32_t) // convert a uint32_t value to a float64_t
float64_t(int64_t) // convert a int64_t value to a float64_t
float64_t(uint64_t) // convert a uint64_t value to a float64_t
float64_t(float16_t) // convert a float16_t value to a float64_t
float64_t(float32_t) // convert a float64_t value to a float64_t
bool(int8_t) // convert a int8_t value to a Boolean
bool(uint8_t) // convert a uint8_t value to a Boolean
bool(int16_t) // convert a int16_t value to a Boolean
bool(uint16_t) // convert a uint16_t value to a Boolean
bool(int32_t) // convert a int32_t value to a Boolean
bool(uint32_t) // convert a uint32_t value to a Boolean
bool(int64_t) // convert a int64_t value to a Boolean
bool(uint64_t) // convert a uint64_t value to a Boolean
bool(float16_t) // convert a float16_t value to a Boolean
bool(float32_t) // convert a float32_t value to a Boolean
bool(float64_t) // convert a float64_t value to a Boolean
(modify the first sentence of last paragraph on p. 98)
"... other arguments.
If the basic type (bool, int8_t, uint8_t, int16_t, uint16_t, int32_t,
uint32_t, int, int64_t, uint64_t, float16_t, float32_t, float, float64_t,
or double) of a parameter to a constructor does not match the basic type of
the object being constructed the scalar construction rules (above) are used
to convert the parameters.""
Modify subsection 5.8 Assignments
Modify the third sentence of the second paragraph to say:
"The lvalue-expression and rvalue-expression must have the same type, or
the expression must have a type in the tables in section
4.1.10 "Implicit Conversions" that converts to the type of
lvalue-expression, in which case an implicit conversion will be done on
the rvalue-expression before the assignment is done."
Modify subsection 5.9 Expressions
Modify the third sentence in the description of the arithmetic binary
operators to say:
"All arithmetic binary operators result in the same fundamental type
(signed integer, unsigned integer, half-precision floating point,
single-precision floating point, or double-precision floating point) as
the operands they operate on, after operand type conversion."
Add the following sentence after the first sentence in the description of
the arithmetic binary operators:
"If the fundamental types in the operands match the operators must operate
exactly on the type defined by the involved operands, conversion to
larger types is not allowed."
Add the following sentence after the first sentence in the description of
the modulus operator:
"If the fundamental types in the operands match the operator must operate
exactly on the type defined by the involved operands, conversion to
larger types is not allowed."
Add the following sentence after the first sentence in the description of
the arithmetic unary operators:
"The operators must operate exactly on the type defined by the operand,
conversion to larger types is not allowed."
Add the following sentence after the first sentence in the description of
the one's complement operator:
"The operator must operate exactly on the type defined by the operand,
conversion to larger types is not allowed."
Modify the third and the fourth sentences in the description of the shift
operators to say:
"If the fundamental types in the operands match the operator must operate
exactly on the type defined by the involved operands, conversion to
larger types is not allowed. One operand can be signed while the other is
unsigned. If the fundamental types in the operands do not match,
then the conversions from section 4.1.10 "Implicit Conversions" are
applied to create matching types.
In all cases, the resulting type will be the same type as the converted
left operand."
Changes to Chapter 6 of the OpenGL Shading Language Specification
Modify subsection 6.1 Function Definitions
Modify the fifteenth paragraph of the subsection to say:
(overloading resolution rules)
"To determine whether the conversion for a single argument in one match
is better than that for another match, the conversion is assigned of the
three ranks ordered from best to worst:
1. Exact match: no conversion.
2. Promotion: integral or floating-point promotion.
3. Conversion: integral conversion, floating-point conversion,
floating-integral conversion.
A conversion C1 is better than a conversion C2 if the rank of C1 is
better than the rank of C2."
Changes to Chapter 8 of the OpenGL Shading Language Specification:
Modify the sixth paragraph to say:
"When the built-in functions are specified below, where the
input arguments (and corresponding output) can be
float32_t, f32vec2, f32vec3, f32vec4, genF32Type is used as the argument.
When the built-in functions are specified below, where the
input arguments (and corresponding output) can be
float16_t, f16vec2, f16vec3, f16vec4, genF16Type is used as the argument.
When the built-in functions are specified below, where the
input arguments (and corresponding output) can be
genF16Type or genF32Type, genType is used as the argument.
Where the input arguments (and corresponding output) can be
int64_t, i64vec2, i64vec3, i64vec4, genI64Type is used as
the argument.
Where the input arguments (and corresponding output) can be
int32_t, i32vec2, i32vec3, i32vec4, genI32Type is used as
the argument.
Where the input arguments (and corresponding output) can be
int16_t, i16vec2, i16vec3, i16vec4, genI16Type is used as
the argument.
Where the input arguments (and corresponding output) can be
int8_t, i8vec2, i8vec3, i8vec4, genI8Type is used as
the argument.
Where the input arguments (and corresponding output) can be
genI64Type, genI32Type, genI16Type, genI8Type,
genIType is used as the argument.
Where the input arguments (and corresponding output) can be
uint64_t, u64vec2, u64vec3, u64vec4, genU64Type is used as
the argument.
Where the input arguments (and corresponding output) can be
uint32_t, u32vec2, u32vec3, u32vec4, genU32Type is used as
the argument.
Where the input arguments (and corresponding output) can be
uint16_t, u16vec2, u16vec3, u16vec4, genU16Type is used as
the argument.
Where the input arguments (and corresponding output) can be
uint8_t, u8vec2, u8vec3, u8vec4, genU8Type is used as
the argument.
Where the input arguments (and corresponding output) can be
genU64Type, genU32Type, genU16Type, genU8Type,
genUType is used as the argument.
Where the input arguments (or corresponding output) can be
bool, bvec2, bvec3, or bvec4, genBType is used as the argument.
Where the input arguments (and corresponding output) can be
float64_t, f64vec2, f64vec3, f64vec4,
double, dvec2, dvec3, dvec4, genDType is used as the argument.
For any specific use of a function, the actual types substituted for
genDType, genType, genIType, genUType, or genBType have to have the
same number of components and bits per component for all arguments and
for the return type. Similarly, hmat is used for any matrix basic type