Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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.          for (i = 0; i < imm_count; i++) {
  152.             next_token(ctx, &imm->u[i].Float);
  153.          }
  154.          break;
  155.  
  156.       case TGSI_IMM_UINT32:
  157.          for (i = 0; i < imm_count; i++) {
  158.             next_token(ctx, &imm->u[i].Uint);
  159.          }
  160.          break;
  161.  
  162.       case TGSI_IMM_INT32:
  163.          for (i = 0; i < imm_count; i++) {
  164.             next_token(ctx, &imm->u[i].Int);
  165.          }
  166.          break;
  167.  
  168.       default:
  169.          assert( 0 );
  170.       }
  171.  
  172.       break;
  173.    }
  174.  
  175.    case TGSI_TOKEN_TYPE_INSTRUCTION:
  176.    {
  177.       struct tgsi_full_instruction *inst = &ctx->FullToken.FullInstruction;
  178.  
  179.       memset(inst, 0, sizeof *inst);
  180.       copy_token(&inst->Instruction, &token);
  181.  
  182.       if (inst->Instruction.Predicate) {
  183.          next_token(ctx, &inst->Predicate);
  184.       }
  185.  
  186.       if (inst->Instruction.Label) {
  187.          next_token( ctx, &inst->Label);
  188.       }
  189.  
  190.       if (inst->Instruction.Texture) {
  191.          next_token( ctx, &inst->Texture);
  192.          for( i = 0; i < inst->Texture.NumOffsets; i++ ) {
  193.             next_token( ctx, &inst->TexOffsets[i] );
  194.          }
  195.       }
  196.  
  197.       assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
  198.  
  199.       for(  i = 0; i < inst->Instruction.NumDstRegs; i++ ) {
  200.  
  201.          next_token( ctx, &inst->Dst[i].Register );
  202.  
  203.          if( inst->Dst[i].Register.Indirect )
  204.             next_token( ctx, &inst->Dst[i].Indirect );
  205.  
  206.          if( inst->Dst[i].Register.Dimension ) {
  207.             next_token( ctx, &inst->Dst[i].Dimension );
  208.  
  209.             /*
  210.              * No support for multi-dimensional addressing.
  211.              */
  212.             assert( !inst->Dst[i].Dimension.Dimension );
  213.  
  214.             if( inst->Dst[i].Dimension.Indirect )
  215.                next_token( ctx, &inst->Dst[i].DimIndirect );
  216.          }
  217.       }
  218.  
  219.       assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
  220.  
  221.       for( i = 0; i < inst->Instruction.NumSrcRegs; i++ ) {
  222.  
  223.          next_token( ctx, &inst->Src[i].Register );
  224.  
  225.          if( inst->Src[i].Register.Indirect )
  226.             next_token( ctx, &inst->Src[i].Indirect );
  227.  
  228.          if( inst->Src[i].Register.Dimension ) {
  229.             next_token( ctx, &inst->Src[i].Dimension );
  230.  
  231.             /*
  232.              * No support for multi-dimensional addressing.
  233.              */
  234.             assert( !inst->Src[i].Dimension.Dimension );
  235.  
  236.             if( inst->Src[i].Dimension.Indirect )
  237.                next_token( ctx, &inst->Src[i].DimIndirect );
  238.          }
  239.       }
  240.  
  241.       break;
  242.    }
  243.  
  244.    case TGSI_TOKEN_TYPE_PROPERTY:
  245.    {
  246.       struct tgsi_full_property *prop = &ctx->FullToken.FullProperty;
  247.       uint prop_count;
  248.  
  249.       memset(prop, 0, sizeof *prop);
  250.       copy_token(&prop->Property, &token);
  251.  
  252.       prop_count = prop->Property.NrTokens - 1;
  253.       for (i = 0; i < prop_count; i++) {
  254.          next_token(ctx, &prop->u[i]);
  255.       }
  256.  
  257.       break;
  258.    }
  259.  
  260.    default:
  261.       assert( 0 );
  262.    }
  263. }
  264.  
  265.  
  266.  
  267.  
  268. /**
  269.  * Make a new copy of a token array.
  270.  */
  271. struct tgsi_token *
  272. tgsi_dup_tokens(const struct tgsi_token *tokens)
  273. {
  274.    unsigned n = tgsi_num_tokens(tokens);
  275.    unsigned bytes = n * sizeof(struct tgsi_token);
  276.    struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes);
  277.    if (new_tokens)
  278.       memcpy(new_tokens, tokens, bytes);
  279.    return new_tokens;
  280. }
  281.  
  282.  
  283. /**
  284.  * Allocate memory for num_tokens tokens.
  285.  */
  286. struct tgsi_token *
  287. tgsi_alloc_tokens(unsigned num_tokens)
  288. {
  289.    unsigned bytes = num_tokens * sizeof(struct tgsi_token);
  290.    return (struct tgsi_token *) MALLOC(bytes);
  291. }
  292.  
  293.  
  294. void
  295. tgsi_dump_tokens(const struct tgsi_token *tokens)
  296. {
  297.    const unsigned *dwords = (const unsigned *)tokens;
  298.    int nr = tgsi_num_tokens(tokens);
  299.    int i;
  300.    
  301.    assert(sizeof(*tokens) == sizeof(unsigned));
  302.  
  303.    debug_printf("const unsigned tokens[%d] = {\n", nr);
  304.    for (i = 0; i < nr; i++)
  305.       debug_printf("0x%08x,\n", dwords[i]);
  306.    debug_printf("};\n");
  307. }
  308.