Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 VMware, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #include "util/u_debug.h"
  29. #include "pipe/p_shader_tokens.h"
  30. #include "tgsi_parse.h"
  31. #include "util/u_memory.h"
  32.  
  33. unsigned
  34. tgsi_parse_init(
  35.    struct tgsi_parse_context *ctx,
  36.    const struct tgsi_token *tokens )
  37. {
  38.    ctx->FullHeader.Header = *(struct tgsi_header *) &tokens[0];
  39.    if( ctx->FullHeader.Header.HeaderSize >= 2 ) {
  40.       ctx->FullHeader.Processor = *(struct tgsi_processor *) &tokens[1];
  41.    }
  42.    else {
  43.       return TGSI_PARSE_ERROR;
  44.    }
  45.  
  46.    ctx->Tokens = tokens;
  47.    ctx->Position = ctx->FullHeader.Header.HeaderSize;
  48.  
  49.    return TGSI_PARSE_OK;
  50. }
  51.  
  52. void
  53. tgsi_parse_free(
  54.    struct tgsi_parse_context *ctx )
  55. {
  56. }
  57.  
  58. boolean
  59. tgsi_parse_end_of_tokens(
  60.    struct tgsi_parse_context *ctx )
  61. {
  62.    return ctx->Position >=
  63.       ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;
  64. }
  65.  
  66.  
  67. /**
  68.  * This function is used to avoid and work-around type punning/aliasing
  69.  * warnings.  The warnings seem harmless on x86 but on PPC they cause
  70.  * real failures.
  71.  */
  72. static INLINE void
  73. copy_token(void *dst, const void *src)
  74. {
  75.    memcpy(dst, src, 4);
  76. }
  77.  
  78.  
  79. /**
  80.  * Get next 4-byte token, return it at address specified by 'token'
  81.  */
  82. static void
  83. next_token(
  84.    struct tgsi_parse_context *ctx,
  85.    void *token )
  86. {
  87.    assert( !tgsi_parse_end_of_tokens( ctx ) );
  88.    copy_token(token, &ctx->Tokens[ctx->Position]);
  89.    ctx->Position++;
  90. }
  91.  
  92.  
  93. void
  94. tgsi_parse_token(
  95.    struct tgsi_parse_context *ctx )
  96. {
  97.    struct tgsi_token token;
  98.    unsigned i;
  99.  
  100.    next_token( ctx, &token );
  101.  
  102.    switch( token.Type ) {
  103.    case TGSI_TOKEN_TYPE_DECLARATION:
  104.    {
  105.       struct tgsi_full_declaration *decl = &ctx->FullToken.FullDeclaration;
  106.  
  107.       memset(decl, 0, sizeof *decl);
  108.       copy_token(&decl->Declaration, &token);
  109.  
  110.       next_token( ctx, &decl->Range );
  111.  
  112.       if (decl->Declaration.Dimension) {
  113.          next_token(ctx, &decl->Dim);
  114.       }
  115.  
  116.       if( decl->Declaration.Interpolate ) {
  117.          next_token( ctx, &decl->Interp );
  118.       }
  119.  
  120.       if( decl->Declaration.Semantic ) {
  121.          next_token( ctx, &decl->Semantic );
  122.       }
  123.  
  124.       if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
  125.          next_token(ctx, &decl->Resource);
  126.       }
  127.  
  128.       if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
  129.          next_token(ctx, &decl->SamplerView);
  130.       }
  131.  
  132.       if( decl->Declaration.Array ) {
  133.          next_token(ctx, &decl->Array);
  134.       }
  135.  
  136.       break;
  137.    }
  138.  
  139.    case TGSI_TOKEN_TYPE_IMMEDIATE:
  140.    {
  141.       struct tgsi_full_immediate *imm = &ctx->FullToken.FullImmediate;
  142.       uint imm_count;
  143.  
  144.       memset(imm, 0, sizeof *imm);
  145.       copy_token(&imm->Immediate, &token);
  146.  
  147.       imm_count = imm->Immediate.NrTokens - 1;
  148.  
  149.       switch (imm->Immediate.DataType) {
  150.       case TGSI_IMM_FLOAT32:
  151.       case TGSI_IMM_FLOAT64:
  152.          for (i = 0; i < imm_count; i++) {
  153.             next_token(ctx, &imm->u[i].Float);
  154.          }
  155.          break;
  156.  
  157.       case TGSI_IMM_UINT32:
  158.          for (i = 0; i < imm_count; i++) {
  159.             next_token(ctx, &imm->u[i].Uint);
  160.          }
  161.          break;
  162.  
  163.       case TGSI_IMM_INT32:
  164.          for (i = 0; i < imm_count; i++) {
  165.             next_token(ctx, &imm->u[i].Int);
  166.          }
  167.          break;
  168.  
  169.       default:
  170.          assert( 0 );
  171.       }
  172.  
  173.       break;
  174.    }
  175.  
  176.    case TGSI_TOKEN_TYPE_INSTRUCTION:
  177.    {
  178.       struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction;
  179.  
  180.       memset(inst, 0, sizeof *inst);
  181.       copy_token(&inst->Instruction, &token);
  182.  
  183.       if (inst->Instruction.Predicate) {
  184.          next_token(ctx, &inst->Predicate);
  185.       }
  186.  
  187.       if (inst->Instruction.Label) {
  188.          next_token( ctx, &inst->Label);
  189.       }
  190.  
  191.       if (inst->Instruction.Texture) {
  192.          next_token( ctx, &inst->Texture);
  193.          for( i = 0; i < inst->Texture.NumOffsets; i++ ) {
  194.             next_token( ctx, &inst->TexOffsets[i] );
  195.          }
  196.       }
  197.  
  198.       assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
  199.  
  200.       for(  i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
  201.  
  202.          next_token( ctx, &inst->Dst[i].Register );
  203.  
  204.          if( inst->Dst[i].Register.Indirect )
  205.             next_token( ctx, &inst->Dst[i].Indirect );
  206.  
  207.          if( inst->Dst[i].Register.Dimension ) {
  208.             next_token( ctx, &inst->Dst[i].Dimension );
  209.  
  210.             /*
  211.              * No support for multi-dimensional addressing.
  212.              */
  213.             assert( !inst->Dst[i].Dimension.Dimension );
  214.  
  215.             if( inst->Dst[i].Dimension.Indirect )
  216.                next_token( ctx, &inst->Dst[i].DimIndirect );
  217.          }
  218.       }
  219.  
  220.       assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
  221.  
  222.       for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
  223.  
  224.          next_token( ctx, &inst->Src[i].Register );
  225.  
  226.          if( inst->Src[i].Register.Indirect )
  227.             next_token( ctx, &inst->Src[i].Indirect );
  228.  
  229.          if( inst->Src[i].Register.Dimension ) {
  230.             next_token( ctx, &inst->Src[i].Dimension );
  231.  
  232.             /*
  233.              * No support for multi-dimensional addressing.
  234.              */
  235.             assert( !inst->Src[i].Dimension.Dimension );
  236.  
  237.             if( inst->Src[i].Dimension.Indirect )
  238.                next_token( ctx, &inst->Src[i].DimIndirect );
  239.          }
  240.       }
  241.  
  242.       break;
  243.    }
  244.  
  245.    case TGSI_TOKEN_TYPE_PROPERTY:
  246.    {
  247.       struct tgsi_full_property *prop = &ctx->FullToken.FullProperty;
  248.       uint prop_count;
  249.  
  250.       memset(prop, 0, sizeof *prop);
  251.       copy_token(&prop->Property, &token);
  252.  
  253.       prop_count = prop->Property.NrTokens - 1;
  254.       for (i = 0; i < prop_count; i++) {
  255.          next_token(ctx, &prop->u[i]);
  256.       }
  257.  
  258.       break;
  259.    }
  260.  
  261.    default:
  262.       assert( 0 );
  263.    }
  264. }
  265.  
  266.  
  267.  
  268.  
  269. /**
  270.  * Make a new copy of a token array.
  271.  */
  272. struct tgsi_token *
  273. tgsi_dup_tokens(const struct tgsi_token *tokens)
  274. {
  275.    unsigned n = tgsi_num_tokens(tokens);
  276.    unsigned bytes = n * sizeof(struct tgsi_token);
  277.    struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes);
  278.    if (new_tokens)
  279.       memcpy(new_tokens, tokens, bytes);
  280.    return new_tokens;
  281. }
  282.  
  283.  
  284. /**
  285.  * Allocate memory for num_tokens tokens.
  286.  */
  287. struct tgsi_token *
  288. tgsi_alloc_tokens(unsigned num_tokens)
  289. {
  290.    unsigned bytes = num_tokens * sizeof(struct tgsi_token);
  291.    return (struct tgsi_token *) MALLOC(bytes);
  292. }
  293.  
  294.  
  295. /**
  296.  * Free tokens allocated by tgsi_alloc_tokens() or tgsi_dup_tokens()
  297.  */
  298. void
  299. tgsi_free_tokens(const struct tgsi_token *tokens)
  300. {
  301.    FREE((void *) tokens);
  302. }
  303.  
  304.  
  305. void
  306. tgsi_dump_tokens(const struct tgsi_token *tokens)
  307. {
  308.    const unsigned *dwords = (const unsigned *)tokens;
  309.    int nr = tgsi_num_tokens(tokens);
  310.    int i;
  311.    
  312.    assert(sizeof(*tokens) == sizeof(unsigned));
  313.  
  314.    debug_printf("const unsigned tokens[%d] = {\n", nr);
  315.    for (i = 0; i < nr; i++)
  316.       debug_printf("0x%08x,\n", dwords[i]);
  317.    debug_printf("};\n");
  318. }
  319.  
  320. unsigned
  321. tgsi_get_processor_type(const struct tgsi_token *tokens)
  322. {
  323.    struct tgsi_parse_context parse;
  324.  
  325.    if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) {
  326.       debug_printf("tgsi_parse_init() failed in %s:%i!\n", __func__, __LINE__);
  327.       return ~0;
  328.    }
  329.    return parse.FullHeader.Processor.Processor;
  330. }
  331.