51
static boolean is_digit( const char *cur )
51
static bool is_digit( const char *cur )
53
53
return *cur >= '0' && *cur <= '9';
56
static boolean is_digit_alpha_underscore( const char *cur )
56
static bool is_digit_alpha_underscore( const char *cur )
58
58
return is_digit( cur ) || is_alpha_underscore( cur );
87
87
* The pointer to the first string is moved at end of the read word
90
static boolean str_match_no_case( const char **pcur, const char *str )
90
static bool str_match_no_case( const char **pcur, const char *str )
92
92
const char *cur = *pcur;
108
108
* The pointer to the first string is moved at end of the read word
111
static boolean str_match_nocase_whole( const char **pcur, const char *str )
111
static bool str_match_nocase_whole( const char **pcur, const char *str )
113
113
const char *cur = *pcur;
115
115
if (str_match_no_case(&cur, str) &&
116
116
!is_digit_alpha_underscore(cur)) {
123
123
/* Return the array index that matches starting at *pcur, where the string at
178
178
/* Parse unsigned integer.
179
179
* No checks for overflow.
181
static boolean parse_uint( const char **pcur, uint *val )
181
static bool parse_uint( const char **pcur, unsigned *val )
183
183
const char *cur = *pcur;
187
187
while (is_digit( cur ))
188
188
*val = *val * 10 + *cur++ - '0';
195
static boolean parse_int( const char **pcur, int *val )
195
static bool parse_int( const char **pcur, int *val )
197
197
const char *cur = *pcur;
198
198
int sign = (*cur == '-' ? -1 : 1);
200
200
if (*cur == '+' || *cur == '-')
203
if (parse_uint(&cur, (uint *)val)) {
203
if (parse_uint(&cur, (unsigned *)val)) {
212
static boolean parse_identifier( const char **pcur, char *ret, size_t len )
212
static bool parse_identifier( const char **pcur, char *ret, size_t len )
214
214
const char *cur = *pcur;
217
217
ret[i++] = *cur++;
218
218
while (is_alpha_underscore( cur ) || is_digit( cur )) {
219
219
if (i == len - 1)
221
221
ret[i++] = *cur++;
230
230
/* Parse floating point.
232
static boolean parse_float( const char **pcur, float *val )
232
static bool parse_float( const char **pcur, float *val )
234
234
const char *cur = *pcur;
235
235
*val = _mesa_strtof(cur, (char**)pcur);
236
236
if (*pcur == cur)
241
static boolean parse_double( const char **pcur, uint32_t *val0, uint32_t *val1)
241
static bool parse_double( const char **pcur, uint32_t *val0, uint32_t *val1)
243
243
const char *cur = *pcur;
249
249
v.dval = _mesa_strtod(cur, (char**)pcur);
250
250
if (*pcur == cur)
253
253
*val0 = v.uval[0];
254
254
*val1 = v.uval[1];
259
static boolean parse_int64( const char **pcur, uint32_t *val0, uint32_t *val1)
259
static bool parse_int64( const char **pcur, uint32_t *val0, uint32_t *val1)
261
261
const char *cur = *pcur;
267
267
v.i64val = strtoll(cur, (char**)pcur, 0);
268
268
if (*pcur == cur)
271
271
*val0 = v.uval[0];
272
272
*val1 = v.uval[1];
277
static boolean parse_uint64( const char **pcur, uint32_t *val0, uint32_t *val1)
277
static bool parse_uint64( const char **pcur, uint32_t *val0, uint32_t *val1)
279
279
const char *cur = *pcur;
332
static boolean parse_header( struct translate_ctx *ctx )
332
static bool parse_header( struct translate_ctx *ctx )
334
enum pipe_shader_type processor;
336
336
if (str_match_nocase_whole( &ctx->cur, "FRAG" ))
337
337
processor = PIPE_SHADER_FRAGMENT;
347
347
processor = PIPE_SHADER_COMPUTE;
349
349
report_error( ctx, "Unknown header" );
353
353
if (ctx->tokens_cur >= ctx->tokens_end)
355
355
ctx->header = (struct tgsi_header *) ctx->tokens_cur++;
356
356
*ctx->header = tgsi_build_header();
358
358
if (ctx->tokens_cur >= ctx->tokens_end)
360
360
*(struct tgsi_processor *) ctx->tokens_cur++ = tgsi_build_processor( processor, ctx->header );
361
361
ctx->processor = processor;
366
static boolean parse_label( struct translate_ctx *ctx, uint *val )
366
static bool parse_label( struct translate_ctx *ctx, unsigned *val )
368
368
const char *cur = ctx->cur;
436
436
*writemask = TGSI_WRITEMASK_XYZW;
442
442
/* <register_file_bracket> ::= <file> `['
445
445
parse_register_file_bracket(
446
446
struct translate_ctx *ctx,
447
enum tgsi_file_type *file )
449
449
if (!parse_file( &ctx->cur, file )) {
450
450
report_error( ctx, "Unknown register file" );
453
453
eat_opt_white( &ctx->cur );
454
454
if (*ctx->cur != '[') {
455
455
report_error( ctx, "Expected `['" );
462
462
/* <register_file_bracket_index> ::= <register_file_bracket> <uint>
465
465
parse_register_file_bracket_index(
466
466
struct translate_ctx *ctx,
467
enum tgsi_file_type *file,
472
472
if (!parse_register_file_bracket( ctx, file ))
474
474
eat_opt_white( &ctx->cur );
475
475
if (!parse_uint( &ctx->cur, &uindex )) {
476
476
report_error( ctx, "Expected literal unsigned integer" );
479
479
*index = (int) uindex;
483
483
/* Parse simple 1d register operand.
484
484
* <register_dst> ::= <register_file_bracket_index> `]'
487
487
parse_register_1d(struct translate_ctx *ctx,
488
enum tgsi_file_type *file,
491
491
if (!parse_register_file_bracket_index( ctx, file, index ))
493
493
eat_opt_white( &ctx->cur );
494
494
if (*ctx->cur != ']') {
495
495
report_error( ctx, "Expected `]'" );
502
502
struct parsed_bracket {
505
enum tgsi_file_type ind_file;
513
513
parse_register_bracket(
514
514
struct translate_ctx *ctx,
515
515
struct parsed_bracket *brackets)
520
520
memset(brackets, 0, sizeof(struct parsed_bracket));
525
525
if (parse_file( &cur, &brackets->ind_file )) {
526
526
if (!parse_register_1d( ctx, &brackets->ind_file,
527
527
&brackets->ind_index ))
529
529
eat_opt_white( &ctx->cur );
531
531
if (*ctx->cur == '.') {
562
562
if (!parse_uint( &ctx->cur, &uindex )) {
563
563
report_error( ctx, "Expected literal unsigned integer" );
566
566
brackets->index = (int) uindex;
567
567
brackets->ind_file = TGSI_FILE_NULL;
578
578
eat_opt_white( &ctx->cur );
579
579
if (!parse_uint( &ctx->cur, &brackets->ind_array )) {
580
580
report_error( ctx, "Expected literal unsigned integer" );
583
583
eat_opt_white( &ctx->cur );
584
584
if (*ctx->cur != ')') {
585
585
report_error( ctx, "Expected `)'" );
594
594
parse_opt_register_src_bracket(
595
595
struct translate_ctx *ctx,
596
596
struct parsed_bracket *brackets,
621
621
* <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `+' <uint> `]' |
622
622
* <register_file_bracket> <register_dst> [`.' (`x' | `y' | `z' | `w')] `-' <uint> `]'
625
625
parse_register_src(
626
626
struct translate_ctx *ctx,
627
enum tgsi_file_type *file,
628
628
struct parsed_bracket *brackets)
630
630
brackets->ind_comp = TGSI_SWIZZLE_X;
631
631
if (!parse_register_file_bracket( ctx, file ))
633
633
if (!parse_register_bracket( ctx, brackets ))
639
639
struct parsed_dcl_bracket {
645
645
parse_register_dcl_bracket(
646
646
struct translate_ctx *ctx,
647
647
struct parsed_dcl_bracket *bracket)
650
650
memset(bracket, 0, sizeof(struct parsed_dcl_bracket));
652
652
eat_opt_white( &ctx->cur );
662
662
report_error( ctx, "Expected literal unsigned integer" );
665
665
bracket->first = uindex;
667
667
eat_opt_white( &ctx->cur );
669
669
if (ctx->cur[0] == '.' && ctx->cur[1] == '.') {
673
673
eat_opt_white( &ctx->cur );
674
674
if (!parse_uint( &ctx->cur, &uindex )) {
675
675
report_error( ctx, "Expected literal integer" );
678
678
bracket->last = (int) uindex;
679
679
eat_opt_white( &ctx->cur );
686
686
if (*ctx->cur != ']') {
687
687
report_error( ctx, "Expected `]' or `..'" );
694
694
/* Parse register declaration.
695
695
* <register_dcl> ::= <register_file_bracket_index> `]' |
696
696
* <register_file_bracket_index> `..' <index> `]'
699
699
parse_register_dcl(
700
700
struct translate_ctx *ctx,
701
enum tgsi_file_type *file,
702
702
struct parsed_dcl_bracket *brackets,
703
703
int *num_brackets)
725
725
if (!parse_register_dcl_bracket( ctx, &brackets[1] ))
727
727
/* for geometry shader we don't really care about
728
728
* the first brackets it's always the size of the
729
729
* input primitive. so we want to declare just
748
748
/* Parse destination register operand.*/
750
750
parse_register_dst(
751
751
struct translate_ctx *ctx,
752
enum tgsi_file_type *file,
753
753
struct parsed_bracket *brackets)
755
755
brackets->ind_comp = TGSI_SWIZZLE_X;
756
756
if (!parse_register_file_bracket( ctx, file ))
758
758
if (!parse_register_bracket( ctx, brackets ))
765
765
parse_dst_operand(
766
766
struct translate_ctx *ctx,
767
767
struct tgsi_full_dst_register *dst )
769
enum tgsi_file_type file;
772
772
struct parsed_bracket bracket[2];
773
773
int parsed_opt_brackets;
775
775
if (!parse_register_dst( ctx, &file, &bracket[0] ))
777
777
if (!parse_opt_register_src_bracket(ctx, &bracket[1], &parsed_opt_brackets))
781
781
eat_opt_white( &cur );
783
783
if (!parse_opt_writemask( ctx, &writemask ))
786
786
dst->Register.File = file;
787
787
if (parsed_opt_brackets) {
808
808
dst->Indirect.Swizzle = bracket[0].ind_comp;
809
809
dst->Indirect.ArrayID = bracket[0].ind_array;
815
815
parse_optional_swizzle(
816
816
struct translate_ctx *ctx,
818
boolean *parsed_swizzle,
818
bool *parsed_swizzle,
821
821
const char *cur = ctx->cur;
823
*parsed_swizzle = FALSE;
823
*parsed_swizzle = false;
825
825
eat_opt_white( &cur );
826
826
if (*cur == '.') {
839
839
swizzle[i] = TGSI_SWIZZLE_W;
841
841
report_error( ctx, "Expected register swizzle component `x', `y', `z' or `w'" );
846
*parsed_swizzle = TRUE;
846
*parsed_swizzle = true;
853
853
parse_src_operand(
854
854
struct translate_ctx *ctx,
855
855
struct tgsi_full_src_register *src )
859
boolean parsed_swizzle;
857
enum tgsi_file_type file;
860
860
struct parsed_bracket bracket[2];
861
861
int parsed_opt_brackets;
875
875
if (!parse_register_src(ctx, &file, &bracket[0]))
877
877
if (!parse_opt_register_src_bracket(ctx, &bracket[1], &parsed_opt_brackets))
880
880
src->Register.File = file;
881
881
if (parsed_opt_brackets) {
916
916
eat_opt_white( &ctx->cur );
917
917
if (*ctx->cur != '|') {
918
918
report_error( ctx, "Expected `|'" );
929
929
parse_texoffset_operand(
930
930
struct translate_ctx *ctx,
931
931
struct tgsi_texture_offset *src )
935
boolean parsed_swizzle;
933
enum tgsi_file_type file;
936
936
struct parsed_bracket bracket;
938
938
if (!parse_register_src(ctx, &file, &bracket))
941
941
src->File = file;
942
942
src->Index = bracket.index;
986
986
if (!is_digit_alpha_underscore(cur))
994
994
parse_instruction(
995
995
struct translate_ctx *ctx,
999
unsigned saturate = 0;
1000
unsigned precise = 0;
1001
1001
const struct tgsi_opcode_info *info;
1002
1002
struct tgsi_full_instruction inst;
1003
1003
const char *cur;
1006
1006
inst = tgsi_default_full_instruction();
1028
1028
report_error( ctx, "Unknown opcode" );
1030
1030
report_error( ctx, "Expected `DCL', `IMM' or a label" );
1034
1034
inst.Instruction.Opcode = i;
1072
1072
if (i < info->num_dst) {
1073
1073
if (!parse_dst_operand( ctx, &inst.Dst[i] ))
1076
1076
else if (i < info->num_dst + info->num_src) {
1077
1077
if (!parse_src_operand( ctx, &inst.Src[i - info->num_dst] ))
1083
1083
for (j = 0; j < TGSI_TEXTURE_COUNT; j++) {
1084
1084
if (str_match_nocase_whole( &ctx->cur, tgsi_texture_names[j] )) {
1140
1140
ctx->cur = cur;
1141
1141
report_error(ctx, "Expected memory qualifier, texture target, or format\n");
1145
1145
cur = ctx->cur;
1146
1146
eat_opt_white( &cur );
1147
1147
if (info->is_branch && *cur == ':') {
1151
1151
eat_opt_white( &cur );
1152
1152
if (!parse_uint( &cur, &target )) {
1153
1153
report_error( ctx, "Expected a label" );
1156
1156
inst.Instruction.Label = 1;
1157
1157
inst.Label.Label = target;
1163
1163
ctx->tokens_cur,
1165
(uint) (ctx->tokens_end - ctx->tokens_cur) );
1165
(unsigned) (ctx->tokens_end - ctx->tokens_cur) );
1166
1166
if (advance == 0)
1168
1168
ctx->tokens_cur += advance;
1173
1173
/* parses a 4-touple of the form {x, y, z, w}
1174
1174
* where x, y, z, w are numbers */
1175
static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type,
1176
union tgsi_immediate_data *values)
1175
static bool parse_immediate_data(struct translate_ctx *ctx, unsigned type,
1176
union tgsi_immediate_data *values)
1227
1227
report_error( ctx, "Expected immediate constant" );
1231
1231
eat_opt_white( &ctx->cur );
1232
1232
if (*ctx->cur != '}') {
1233
1233
report_error( ctx, "Expected `}'" );
1241
static boolean parse_declaration( struct translate_ctx *ctx )
1241
static bool parse_declaration( struct translate_ctx *ctx )
1243
1243
struct tgsi_full_declaration decl;
1244
enum tgsi_file_type file;
1245
1245
struct parsed_dcl_bracket brackets[2];
1246
1246
int num_brackets;
1248
1248
const char *cur, *cur2;
1250
boolean is_vs_input;
1252
1252
if (!eat_white( &ctx->cur )) {
1253
1253
report_error( ctx, "Syntax error" );
1256
1256
if (!parse_register_dcl( ctx, &file, brackets, &num_brackets))
1258
1258
if (!parse_opt_writemask( ctx, &writemask ))
1261
1261
decl = tgsi_default_full_declaration();
1262
1262
decl.Declaration.File = file;
1287
1287
if (*cur2 != '(') {
1288
1288
report_error( ctx, "Expected `('" );
1292
1292
eat_opt_white( &cur2 );
1293
1293
if (!parse_int( &cur2, &arrayid )) {
1294
1294
report_error( ctx, "Expected `,'" );
1297
1297
eat_opt_white( &cur2 );
1298
1298
if (*cur2 != ')') {
1299
1299
report_error( ctx, "Expected `)'" );
1303
1303
decl.Declaration.Array = 1;
1357
1357
if (i == TGSI_TEXTURE_COUNT) {
1358
1358
report_error(ctx, "Expected texture target");
1361
1361
eat_opt_white( &cur );
1362
1362
if (*cur != ',') {
1363
1363
report_error( ctx, "Expected `,'" );
1367
1367
eat_opt_white( &cur );
1455
1455
eat_opt_white( &cur2 );
1456
1456
if (!parse_uint( &cur2, &index )) {
1457
1457
report_error( ctx, "Expected literal integer" );
1460
1460
eat_opt_white( &cur2 );
1461
1461
if (*cur2 != ']') {
1462
1462
report_error( ctx, "Expected `]'" );
1500
1500
eat_opt_white(&cur);
1501
1501
if (!parse_uint(&cur, &stream[i])) {
1502
1502
report_error(ctx, "Expected literal integer");
1506
1506
eat_opt_white(&cur);
1508
1508
if (*cur != ',') {
1509
1509
report_error(ctx, "Expected ','");
1582
1582
ctx->tokens_cur,
1584
(uint) (ctx->tokens_end - ctx->tokens_cur) );
1584
(unsigned) (ctx->tokens_end - ctx->tokens_cur) );
1586
1586
if (advance == 0)
1588
1588
ctx->tokens_cur += advance;
1593
static boolean parse_immediate( struct translate_ctx *ctx )
1593
static bool parse_immediate( struct translate_ctx *ctx )
1595
1595
struct tgsi_full_immediate imm;
1599
1599
if (*ctx->cur == '[') {
1604
1604
eat_opt_white( &ctx->cur );
1605
1605
if (!parse_uint( &ctx->cur, &uindex )) {
1606
1606
report_error( ctx, "Expected literal unsigned integer" );
1610
1610
if (uindex != ctx->num_immediates) {
1611
1611
report_error( ctx, "Immediates must be sorted" );
1615
1615
eat_opt_white( &ctx->cur );
1616
1616
if (*ctx->cur != ']') {
1617
1617
report_error( ctx, "Expected `]'" );
1624
1624
if (!eat_white( &ctx->cur )) {
1625
1625
report_error( ctx, "Syntax error" );
1628
1628
for (type = 0; type < ARRAY_SIZE(tgsi_immediate_type_names); ++type) {
1629
1629
if (str_match_nocase_whole(&ctx->cur, tgsi_immediate_type_names[type]))
1644
1644
ctx->tokens_cur,
1646
(uint) (ctx->tokens_end - ctx->tokens_cur) );
1646
(unsigned) (ctx->tokens_end - ctx->tokens_cur) );
1647
1647
if (advance == 0)
1649
1649
ctx->tokens_cur += advance;
1651
1651
ctx->num_immediates++;
1657
parse_primitive( const char **pcur, uint *primitive )
1657
parse_primitive( const char **pcur, unsigned *primitive )
1661
for (i = 0; i < PIPE_PRIM_MAX; i++) {
1661
for (i = 0; i < MESA_PRIM_COUNT; i++) {
1662
1662
const char *cur = *pcur;
1664
1664
if (str_match_nocase_whole( &cur, tgsi_primitive_names[i])) {
1665
1665
*primitive = i;
1674
parse_fs_coord_origin( const char **pcur, uint *fs_coord_origin )
1674
parse_fs_coord_origin( const char **pcur, unsigned *fs_coord_origin )
1678
1678
for (i = 0; i < ARRAY_SIZE(tgsi_fs_coord_origin_names); i++) {
1679
1679
const char *cur = *pcur;
1681
1681
if (str_match_nocase_whole( &cur, tgsi_fs_coord_origin_names[i])) {
1682
1682
*fs_coord_origin = i;
1691
parse_fs_coord_pixel_center( const char **pcur, uint *fs_coord_pixel_center )
1691
parse_fs_coord_pixel_center( const char **pcur, unsigned *fs_coord_pixel_center )
1695
1695
for (i = 0; i < ARRAY_SIZE(tgsi_fs_coord_pixel_center_names); i++) {
1696
1696
const char *cur = *pcur;
1698
1698
if (str_match_nocase_whole( &cur, tgsi_fs_coord_pixel_center_names[i])) {
1699
1699
*fs_coord_pixel_center = i;
1708
parse_property_next_shader( const char **pcur, uint *next_shader )
1708
parse_property_next_shader( const char **pcur, unsigned *next_shader )
1712
1712
for (i = 0; i < ARRAY_SIZE(tgsi_processor_type_names); i++) {
1713
1713
const char *cur = *pcur;
1715
1715
if (str_match_nocase_whole( &cur, tgsi_processor_type_names[i])) {
1716
1716
*next_shader = i;
1724
static boolean parse_property( struct translate_ctx *ctx )
1724
static bool parse_property( struct translate_ctx *ctx )
1726
1726
struct tgsi_full_property prop;
1727
enum tgsi_property_name property_name;
1732
1732
if (!eat_white( &ctx->cur )) {
1733
1733
report_error( ctx, "Syntax error" );
1736
1736
if (!parse_identifier( &ctx->cur, id, sizeof(id) )) {
1737
1737
report_error( ctx, "Syntax error" );
1740
1740
for (property_name = 0; property_name < TGSI_PROPERTY_COUNT;
1741
1741
++property_name) {
1754
1754
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
1755
1755
if (!parse_primitive(&ctx->cur, &values[0] )) {
1756
1756
report_error( ctx, "Unknown primitive name as property!" );
1759
1759
if (property_name == TGSI_PROPERTY_GS_INPUT_PRIM &&
1760
1760
ctx->processor == PIPE_SHADER_GEOMETRY) {
1764
1764
case TGSI_PROPERTY_FS_COORD_ORIGIN:
1765
1765
if (!parse_fs_coord_origin(&ctx->cur, &values[0] )) {
1766
1766
report_error( ctx, "Unknown coord origin as property: must be UPPER_LEFT or LOWER_LEFT!" );
1770
1770
case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
1771
1771
if (!parse_fs_coord_pixel_center(&ctx->cur, &values[0] )) {
1772
1772
report_error( ctx, "Unknown coord pixel center as property: must be HALF_INTEGER or INTEGER!" );
1776
1776
case TGSI_PROPERTY_NEXT_SHADER:
1777
1777
if (!parse_property_next_shader(&ctx->cur, &values[0] )) {
1778
1778
report_error( ctx, "Unknown next shader property value." );
1782
1782
case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
1784
1784
if (!parse_uint(&ctx->cur, &values[0] )) {
1785
1785
report_error( ctx, "Expected unsigned integer as property!" );
1797
1797
ctx->tokens_cur,
1799
(uint) (ctx->tokens_end - ctx->tokens_cur) );
1799
(unsigned) (ctx->tokens_end - ctx->tokens_cur) );
1800
1800
if (advance == 0)
1802
1802
ctx->tokens_cur += advance;
1808
static boolean translate( struct translate_ctx *ctx )
1808
static bool translate( struct translate_ctx *ctx )
1810
1810
eat_opt_white( &ctx->cur );
1811
1811
if (!parse_header( ctx ))
1814
1814
if (ctx->processor == PIPE_SHADER_TESS_CTRL ||
1815
1815
ctx->processor == PIPE_SHADER_TESS_EVAL)
1816
1816
ctx->implied_array_size = 32;
1818
1818
while (*ctx->cur != '\0') {
1819
unsigned label_val = 0;
1820
1820
if (!eat_white( &ctx->cur )) {
1821
1821
report_error( ctx, "Syntax error" );
1825
1825
if (*ctx->cur == '\0')
1827
1827
if (parse_label( ctx, &label_val )) {
1828
if (!parse_instruction( ctx, TRUE ))
1828
if (!parse_instruction( ctx, true ))
1831
1831
else if (str_match_nocase_whole( &ctx->cur, "DCL" )) {
1832
1832
if (!parse_declaration( ctx ))
1835
1835
else if (str_match_nocase_whole( &ctx->cur, "IMM" )) {
1836
1836
if (!parse_immediate( ctx ))
1839
1839
else if (str_match_nocase_whole( &ctx->cur, "PROPERTY" )) {
1840
1840
if (!parse_property( ctx ))
1843
else if (!parse_instruction( ctx, FALSE )) {
1843
else if (!parse_instruction( ctx, false )) {
1852
1852
tgsi_text_translate(
1853
1853
const char *text,
1854
1854
struct tgsi_token *tokens,
1855
unsigned num_tokens )
1857
1857
struct translate_ctx ctx = {0};