Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 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. /**
  29.  * TGSI program transformation utility.
  30.  *
  31.  * Authors:  Brian Paul
  32.  */
  33.  
  34. #include "util/u_debug.h"
  35.  
  36. #include "tgsi_transform.h"
  37.  
  38.  
  39.  
  40. static void
  41. emit_instruction(struct tgsi_transform_context *ctx,
  42.                  const struct tgsi_full_instruction *inst)
  43. {
  44.    uint ti = ctx->ti;
  45.  
  46.    ti += tgsi_build_full_instruction(inst,
  47.                                      ctx->tokens_out + ti,
  48.                                      ctx->header,
  49.                                      ctx->max_tokens_out - ti);
  50.    ctx->ti = ti;
  51. }
  52.  
  53.  
  54. static void
  55. emit_declaration(struct tgsi_transform_context *ctx,
  56.                  const struct tgsi_full_declaration *decl)
  57. {
  58.    uint ti = ctx->ti;
  59.  
  60.    ti += tgsi_build_full_declaration(decl,
  61.                                      ctx->tokens_out + ti,
  62.                                      ctx->header,
  63.                                      ctx->max_tokens_out - ti);
  64.    ctx->ti = ti;
  65. }
  66.  
  67.  
  68. static void
  69. emit_immediate(struct tgsi_transform_context *ctx,
  70.                const struct tgsi_full_immediate *imm)
  71. {
  72.    uint ti = ctx->ti;
  73.  
  74.    ti += tgsi_build_full_immediate(imm,
  75.                                    ctx->tokens_out + ti,
  76.                                    ctx->header,
  77.                                    ctx->max_tokens_out - ti);
  78.    ctx->ti = ti;
  79. }
  80.  
  81.  
  82. static void
  83. emit_property(struct tgsi_transform_context *ctx,
  84.               const struct tgsi_full_property *prop)
  85. {
  86.    uint ti = ctx->ti;
  87.  
  88.    ti += tgsi_build_full_property(prop,
  89.                                   ctx->tokens_out + ti,
  90.                                   ctx->header,
  91.                                   ctx->max_tokens_out - ti);
  92.    ctx->ti = ti;
  93. }
  94.  
  95.  
  96. /**
  97.  * Apply user-defined transformations to the input shader to produce
  98.  * the output shader.
  99.  * For example, a register search-and-replace operation could be applied
  100.  * by defining a transform_instruction() callback that examined and changed
  101.  * the instruction src/dest regs.
  102.  *
  103.  * \return number of tokens emitted
  104.  */
  105. int
  106. tgsi_transform_shader(const struct tgsi_token *tokens_in,
  107.                       struct tgsi_token *tokens_out,
  108.                       uint max_tokens_out,
  109.                       struct tgsi_transform_context *ctx)
  110. {
  111.    uint procType;
  112.  
  113.    /* input shader */
  114.    struct tgsi_parse_context parse;
  115.  
  116.    /* output shader */
  117.    struct tgsi_processor *processor;
  118.  
  119.  
  120.    /**
  121.     ** callback context init
  122.     **/
  123.    ctx->emit_instruction = emit_instruction;
  124.    ctx->emit_declaration = emit_declaration;
  125.    ctx->emit_immediate = emit_immediate;
  126.    ctx->emit_property = emit_property;
  127.    ctx->tokens_out = tokens_out;
  128.    ctx->max_tokens_out = max_tokens_out;
  129.  
  130.  
  131.    /**
  132.     ** Setup to begin parsing input shader
  133.     **/
  134.    if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) {
  135.       debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n");
  136.       return -1;
  137.    }
  138.    procType = parse.FullHeader.Processor.Processor;
  139.    assert(procType == TGSI_PROCESSOR_FRAGMENT ||
  140.           procType == TGSI_PROCESSOR_VERTEX ||
  141.           procType == TGSI_PROCESSOR_GEOMETRY);
  142.  
  143.  
  144.    /**
  145.     **  Setup output shader
  146.     **/
  147.    ctx->header = (struct tgsi_header *)tokens_out;
  148.    *ctx->header = tgsi_build_header();
  149.  
  150.    processor = (struct tgsi_processor *) (tokens_out + 1);
  151.    *processor = tgsi_build_processor( procType, ctx->header );
  152.  
  153.    ctx->ti = 2;
  154.  
  155.  
  156.    /**
  157.     ** Loop over incoming program tokens/instructions
  158.     */
  159.    while( !tgsi_parse_end_of_tokens( &parse ) ) {
  160.  
  161.       tgsi_parse_token( &parse );
  162.  
  163.       switch( parse.FullToken.Token.Type ) {
  164.       case TGSI_TOKEN_TYPE_INSTRUCTION:
  165.          {
  166.             struct tgsi_full_instruction *fullinst
  167.                = &parse.FullToken.FullInstruction;
  168.  
  169.             if (ctx->transform_instruction)
  170.                ctx->transform_instruction(ctx, fullinst);
  171.             else
  172.                ctx->emit_instruction(ctx, fullinst);
  173.          }
  174.          break;
  175.  
  176.       case TGSI_TOKEN_TYPE_DECLARATION:
  177.          {
  178.             struct tgsi_full_declaration *fulldecl
  179.                = &parse.FullToken.FullDeclaration;
  180.  
  181.             if (ctx->transform_declaration)
  182.                ctx->transform_declaration(ctx, fulldecl);
  183.             else
  184.                ctx->emit_declaration(ctx, fulldecl);
  185.          }
  186.          break;
  187.  
  188.       case TGSI_TOKEN_TYPE_IMMEDIATE:
  189.          {
  190.             struct tgsi_full_immediate *fullimm
  191.                = &parse.FullToken.FullImmediate;
  192.  
  193.             if (ctx->transform_immediate)
  194.                ctx->transform_immediate(ctx, fullimm);
  195.             else
  196.                ctx->emit_immediate(ctx, fullimm);
  197.          }
  198.          break;
  199.       case TGSI_TOKEN_TYPE_PROPERTY:
  200.          {
  201.             struct tgsi_full_property *fullprop
  202.                = &parse.FullToken.FullProperty;
  203.  
  204.             if (ctx->transform_property)
  205.                ctx->transform_property(ctx, fullprop);
  206.             else
  207.                ctx->emit_property(ctx, fullprop);
  208.          }
  209.          break;
  210.  
  211.       default:
  212.          assert( 0 );
  213.       }
  214.    }
  215.  
  216.    if (ctx->epilog) {
  217.       ctx->epilog(ctx);
  218.    }
  219.  
  220.    tgsi_parse_free (&parse);
  221.  
  222.    return ctx->ti;
  223. }
  224.  
  225.  
  226. #include "tgsi_text.h"
  227.  
  228. extern int tgsi_transform_foo( struct tgsi_token *tokens_out,
  229.                                uint max_tokens_out );
  230.  
  231. /* This function exists only so that tgsi_text_translate() doesn't get
  232.  * magic-ed out of the libtgsi.a archive by the build system.  Don't
  233.  * remove unless you know this has been fixed - check on mingw/scons
  234.  * builds as well.
  235.  */
  236. int
  237. tgsi_transform_foo( struct tgsi_token *tokens_out,
  238.                     uint max_tokens_out )
  239. {
  240.    const char *text =
  241.       "FRAG\n"
  242.       "DCL IN[0], COLOR, CONSTANT\n"
  243.       "DCL OUT[0], COLOR\n"
  244.       "  0: MOV OUT[0], IN[0]\n"
  245.       "  1: END";
  246.        
  247.    return tgsi_text_translate( text,
  248.                                tokens_out,
  249.                                max_tokens_out );
  250. }
  251.