X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Ftgsi%2Ftgsi_text.c;h=91baa01ad8bdebad44ec44ba43f9d7a5166080d2;hb=e2a1ec5f0f0314915fdfc9a8ef93f3789f356404;hp=6b97bee8b0f67178905e81c7ec1769dd255715c7;hpb=21190fbd56ec2f12dc5a1bf1d9fc32d507e8f0a3;p=mesa.git diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 6b97bee8b0f..91baa01ad8b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -18,7 +18,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -195,8 +195,15 @@ static boolean parse_float( const char **pcur, float *val ) boolean integral_part = FALSE; boolean fractional_part = FALSE; - *val = (float) atof( cur ); + if (*cur == '0' && *(cur + 1) == 'x') { + union fi fi; + fi.ui = strtoul(cur, NULL, 16); + *val = fi.f; + cur += 10; + goto out; + } + *val = (float) atof( cur ); if (*cur == '-' || *cur == '+') cur++; if (is_digit( cur )) { @@ -228,10 +235,30 @@ static boolean parse_float( const char **pcur, float *val ) else return FALSE; } + +out: *pcur = cur; return TRUE; } +static boolean parse_double( const char **pcur, uint32_t *val0, uint32_t *val1) +{ + const char *cur = *pcur; + union { + double dval; + uint32_t uval[2]; + } v; + + v.dval = strtod(cur, (char**)pcur); + if (*pcur == cur) + return FALSE; + + *val0 = v.uval[0]; + *val1 = v.uval[1]; + + return TRUE; +} + struct translate_ctx { const char *text; @@ -241,7 +268,7 @@ struct translate_ctx struct tgsi_token *tokens_end; struct tgsi_header *header; unsigned processor : 4; - int implied_array_size : 5; + unsigned implied_array_size : 6; unsigned num_immediates; }; @@ -279,6 +306,10 @@ static boolean parse_header( struct translate_ctx *ctx ) processor = TGSI_PROCESSOR_VERTEX; else if (str_match_nocase_whole( &ctx->cur, "GEOM" )) processor = TGSI_PROCESSOR_GEOMETRY; + else if (str_match_nocase_whole( &ctx->cur, "TESS_CTRL" )) + processor = TGSI_PROCESSOR_TESS_CTRL; + else if (str_match_nocase_whole( &ctx->cur, "TESS_EVAL" )) + processor = TGSI_PROCESSOR_TESS_EVAL; else if (str_match_nocase_whole( &ctx->cur, "COMP" )) processor = TGSI_PROCESSOR_COMPUTE; else { @@ -322,7 +353,7 @@ parse_file( const char **pcur, uint *file ) for (i = 0; i < TGSI_FILE_COUNT; i++) { const char *cur = *pcur; - if (str_match_nocase_whole( &cur, tgsi_file_names[i] )) { + if (str_match_nocase_whole( &cur, tgsi_file_name(i) )) { *pcur = cur; *file = i; return TRUE; @@ -653,6 +684,9 @@ parse_register_dcl( eat_opt_white( &cur ); if (cur[0] == '[') { + bool is_in = *file == TGSI_FILE_INPUT; + bool is_out = *file == TGSI_FILE_OUTPUT; + ++cur; ctx->cur = cur; if (!parse_register_dcl_bracket( ctx, &brackets[1] )) @@ -662,7 +696,11 @@ parse_register_dcl( * input primitive. so we want to declare just * the index relevant to the semantics which is in * the second bracket */ - if (ctx->processor == TGSI_PROCESSOR_GEOMETRY && *file == TGSI_FILE_INPUT) { + + /* tessellation has similar constraints to geometry shader */ + if ((ctx->processor == TGSI_PROCESSOR_GEOMETRY && is_in) || + (ctx->processor == TGSI_PROCESSOR_TESS_EVAL && is_in) || + (ctx->processor == TGSI_PROCESSOR_TESS_CTRL && (is_in || is_out))) { brackets[0] = brackets[1]; *num_brackets = 1; } else { @@ -718,6 +756,14 @@ parse_dst_operand( dst->Dimension.Indirect = 0; dst->Dimension.Dimension = 0; dst->Dimension.Index = bracket[0].index; + + if (bracket[0].ind_file != TGSI_FILE_NULL) { + dst->Dimension.Indirect = 1; + dst->DimIndirect.File = bracket[0].ind_file; + dst->DimIndirect.Index = bracket[0].ind_index; + dst->DimIndirect.Swizzle = bracket[0].ind_comp; + dst->DimIndirect.ArrayID = bracket[0].ind_array; + } bracket[0] = bracket[1]; } dst->Register.Index = bracket[0].index; @@ -735,8 +781,9 @@ parse_dst_operand( static boolean parse_optional_swizzle( struct translate_ctx *ctx, - uint swizzle[4], - boolean *parsed_swizzle ) + uint *swizzle, + boolean *parsed_swizzle, + int components) { const char *cur = ctx->cur; @@ -748,7 +795,7 @@ parse_optional_swizzle( cur++; eat_opt_white( &cur ); - for (i = 0; i < 4; i++) { + for (i = 0; i < components; i++) { if (uprcase( *cur ) == 'X') swizzle[i] = TGSI_SWIZZLE_X; else if (uprcase( *cur ) == 'Y') @@ -803,6 +850,13 @@ parse_src_operand( src->Dimension.Indirect = 0; src->Dimension.Dimension = 0; src->Dimension.Index = bracket[0].index; + if (bracket[0].ind_file != TGSI_FILE_NULL) { + src->Dimension.Indirect = 1; + src->DimIndirect.File = bracket[0].ind_file; + src->DimIndirect.Index = bracket[0].ind_index; + src->DimIndirect.Swizzle = bracket[0].ind_comp; + src->DimIndirect.ArrayID = bracket[0].ind_array; + } bracket[0] = bracket[1]; } src->Register.Index = bracket[0].index; @@ -816,7 +870,7 @@ parse_src_operand( /* Parse optional swizzle. */ - if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) { + if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 4 )) { if (parsed_swizzle) { src->Register.SwizzleX = swizzle[0]; src->Register.SwizzleY = swizzle[1]; @@ -838,6 +892,35 @@ parse_src_operand( return TRUE; } +static boolean +parse_texoffset_operand( + struct translate_ctx *ctx, + struct tgsi_texture_offset *src ) +{ + uint file; + uint swizzle[3]; + boolean parsed_swizzle; + struct parsed_bracket bracket; + + if (!parse_register_src(ctx, &file, &bracket)) + return FALSE; + + src->File = file; + src->Index = bracket.index; + + /* Parse optional swizzle. + */ + if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 3 )) { + if (parsed_swizzle) { + src->SwizzleX = swizzle[0]; + src->SwizzleY = swizzle[1]; + src->SwizzleZ = swizzle[2]; + } + } + + return TRUE; +} + static boolean match_inst(const char **pcur, unsigned *saturate, @@ -848,7 +931,7 @@ match_inst(const char **pcur, /* simple case: the whole string matches the instruction name */ if (str_match_nocase_whole(&cur, info->mnemonic)) { *pcur = cur; - *saturate = TGSI_SAT_NONE; + *saturate = 0; return TRUE; } @@ -856,13 +939,7 @@ match_inst(const char **pcur, /* the instruction has a suffix, figure it out */ if (str_match_nocase_whole(&cur, "_SAT")) { *pcur = cur; - *saturate = TGSI_SAT_ZERO_ONE; - return TRUE; - } - - if (str_match_nocase_whole(&cur, "_SATNV")) { - *pcur = cur; - *saturate = TGSI_SAT_MINUS_PLUS_ONE; + *saturate = 1; return TRUE; } } @@ -876,7 +953,7 @@ parse_instruction( boolean has_label ) { uint i; - uint saturate = TGSI_SAT_NONE; + uint saturate = 0; const struct tgsi_opcode_info *info; struct tgsi_full_instruction inst; const char *cur; @@ -904,7 +981,7 @@ parse_instruction( if (!parse_register_1d( ctx, &file, &index )) return FALSE; - if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) { + if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle, 4 )) { if (parsed_swizzle) { inst.Predicate.SwizzleX = swizzle[0]; inst.Predicate.SwizzleY = swizzle[1]; @@ -956,13 +1033,18 @@ parse_instruction( /* * These are not considered tex opcodes here (no additional * target argument) however we're required to set the Texture - * bit so we can set the number of tex offsets (offsets aren't - * actually handled here yet in any case). + * bit so we can set the number of tex offsets. */ inst.Instruction.Texture = 1; inst.Texture.Texture = TGSI_TEXTURE_UNKNOWN; } + if ((i >= TGSI_OPCODE_LOAD && i <= TGSI_OPCODE_ATOMIMAX) || + i == TGSI_OPCODE_RESQ) { + inst.Instruction.Memory = 1; + inst.Memory.Qualifier = 0; + } + /* Parse instruction operands. */ for (i = 0; i < info->num_dst + info->num_src + info->is_tex; i++) { @@ -1001,6 +1083,40 @@ parse_instruction( } } + cur = ctx->cur; + eat_opt_white( &cur ); + for (i = 0; inst.Instruction.Texture && *cur == ','; i++) { + cur++; + eat_opt_white( &cur ); + ctx->cur = cur; + if (!parse_texoffset_operand( ctx, &inst.TexOffsets[i] )) + return FALSE; + cur = ctx->cur; + eat_opt_white( &cur ); + } + inst.Texture.NumOffsets = i; + + cur = ctx->cur; + eat_opt_white(&cur); + for (i = 0; inst.Instruction.Memory && *cur == ','; i++) { + uint j; + cur++; + eat_opt_white(&cur); + ctx->cur = cur; + for (j = 0; j < 3; j++) { + if (str_match_nocase_whole(&ctx->cur, tgsi_memory_names[j])) { + inst.Memory.Qualifier |= 1U << j; + break; + } + } + if (j == 3) { + report_error(ctx, "Expected memory qualifier"); + return FALSE; + } + cur = ctx->cur; + eat_opt_white(&cur); + } + cur = ctx->cur; eat_opt_white( &cur ); if (info->is_branch && *cur == ':') { @@ -1055,6 +1171,10 @@ static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type, } switch (type) { + case TGSI_IMM_FLOAT64: + ret = parse_double(&ctx->cur, &values[i].Uint, &values[i+1].Uint); + i++; + break; case TGSI_IMM_FLOAT32: ret = parse_float(&ctx->cur, &values[i].Float); break; @@ -1129,8 +1249,13 @@ static boolean parse_declaration( struct translate_ctx *ctx ) cur2 = cur; cur2++; eat_opt_white( &cur2 ); - if (str_match_nocase_whole( &cur2, "ARRAY(" )) { + if (str_match_nocase_whole( &cur2, "ARRAY" )) { int arrayid; + if (*cur2 != '(') { + report_error( ctx, "Expected `('" ); + return FALSE; + } + cur2++; eat_opt_white( &cur2 ); if (!parse_int( &cur2, &arrayid )) { report_error( ctx, "Expected `,'" ); @@ -1138,12 +1263,13 @@ static boolean parse_declaration( struct translate_ctx *ctx ) } eat_opt_white( &cur2 ); if (*cur2 != ')') { - report_error( ctx, "Expected `,'" ); + report_error( ctx, "Expected `)'" ); return FALSE; } + cur2++; decl.Declaration.Array = 1; decl.Array.ArrayID = arrayid; - cur = cur2; + ctx->cur = cur = cur2; } } @@ -1152,10 +1278,10 @@ static boolean parse_declaration( struct translate_ctx *ctx ) cur++; eat_opt_white( &cur ); - if (file == TGSI_FILE_RESOURCE) { + if (file == TGSI_FILE_IMAGE) { for (i = 0; i < TGSI_TEXTURE_COUNT; i++) { if (str_match_nocase_whole(&cur, tgsi_texture_names[i])) { - decl.Resource.Resource = i; + decl.Image.Resource = i; break; } } @@ -1170,13 +1296,22 @@ static boolean parse_declaration( struct translate_ctx *ctx ) cur2++; eat_opt_white(&cur2); if (str_match_nocase_whole(&cur2, "RAW")) { - decl.Resource.Raw = 1; + decl.Image.Raw = 1; } else if (str_match_nocase_whole(&cur2, "WR")) { - decl.Resource.Writable = 1; + decl.Image.Writable = 1; } else { - break; + for (i = 0; i < PIPE_FORMAT_COUNT; i++) { + const struct util_format_description *desc = + util_format_description(i); + if (desc && str_match_nocase_whole(&cur2, desc->name)) { + decl.Image.Format = i; + break; + } + } + if (i == PIPE_FORMAT_COUNT) + break; } cur = cur2; eat_opt_white(&cur2); @@ -1203,8 +1338,8 @@ static boolean parse_declaration( struct translate_ctx *ctx ) ++cur; eat_opt_white( &cur ); for (j = 0; j < 4; ++j) { - for (i = 0; i < PIPE_TYPE_COUNT; ++i) { - if (str_match_nocase_whole(&cur, tgsi_type_names[i])) { + for (i = 0; i < TGSI_RETURN_TYPE_COUNT; ++i) { + if (str_match_nocase_whole(&cur, tgsi_return_type_names[i])) { switch (j) { case 0: decl.SamplerView.ReturnTypeX = i; @@ -1224,7 +1359,7 @@ static boolean parse_declaration( struct translate_ctx *ctx ) break; } } - if (i == PIPE_TYPE_COUNT) { + if (i == TGSI_RETURN_TYPE_COUNT) { if (j == 0 || j > 2) { report_error(ctx, "Expected type name"); return FALSE; @@ -1249,6 +1384,14 @@ static boolean parse_declaration( struct translate_ctx *ctx ) decl.SamplerView.ReturnTypeX; } ctx->cur = cur; + } else if (file == TGSI_FILE_BUFFER) { + if (str_match_nocase_whole(&cur, "ATOMIC")) { + decl.Declaration.Atomic = 1; + ctx->cur = cur; + } else if (str_match_nocase_whole(&cur, "SHARED")) { + decl.Declaration.Shared = 1; + ctx->cur = cur; + } } else { if (str_match_nocase_whole(&cur, "LOCAL")) { decl.Declaration.Local = 1; @@ -1319,6 +1462,23 @@ static boolean parse_declaration( struct translate_ctx *ctx ) } } + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',' && !is_vs_input) { + uint i; + + cur++; + eat_opt_white( &cur ); + for (i = 0; i < TGSI_INTERPOLATE_LOC_COUNT; i++) { + if (str_match_nocase_whole( &cur, tgsi_interpolate_locations[i] )) { + decl.Interp.Location = i; + + ctx->cur = cur; + break; + } + } + } + advance = tgsi_build_full_declaration( &decl, ctx->tokens_cur, @@ -1531,6 +1691,10 @@ static boolean translate( struct translate_ctx *ctx ) if (!parse_header( ctx )) return FALSE; + if (ctx->processor == TGSI_PROCESSOR_TESS_CTRL || + ctx->processor == TGSI_PROCESSOR_TESS_EVAL) + ctx->implied_array_size = 32; + while (*ctx->cur != '\0') { uint label_val = 0; if (!eat_white( &ctx->cur )) { @@ -1570,7 +1734,7 @@ tgsi_text_translate( struct tgsi_token *tokens, uint num_tokens ) { - struct translate_ctx ctx; + struct translate_ctx ctx = {0}; ctx.text = text; ctx.cur = text;