Browse Source

gallium: new tgsi_transform_shader() function

Used to apply transformations to TGSI shaders, such as register search and
replace.
tags/mesa_20090313
Brian 17 years ago
parent
commit
4c1403f667
2 changed files with 292 additions and 0 deletions
  1. 199
    0
      src/mesa/pipe/tgsi/util/tgsi_transform.c
  2. 93
    0
      src/mesa/pipe/tgsi/util/tgsi_transform.h

+ 199
- 0
src/mesa/pipe/tgsi/util/tgsi_transform.c View File

@@ -0,0 +1,199 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* 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
* 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.
*
**************************************************************************/

/**
* TGSI program transformation utility.
*
* Authors: Brian Paul
*/


#include "tgsi_transform.h"



static void
emit_instruction(struct tgsi_transform_context *ctx,
const struct tgsi_full_instruction *inst)
{
uint ti = ctx->ti;

ti += tgsi_build_full_instruction(inst,
ctx->tokens_out + ti,
ctx->header,
ctx->max_tokens_out - ti);
ctx->ti = ti;
}


static void
emit_declaration(struct tgsi_transform_context *ctx,
const struct tgsi_full_declaration *decl)
{
uint ti = ctx->ti;

ti += tgsi_build_full_declaration(decl,
ctx->tokens_out + ti,
ctx->header,
ctx->max_tokens_out - ti);
ctx->ti = ti;
}


static void
emit_immediate(struct tgsi_transform_context *ctx,
const struct tgsi_full_immediate *imm)
{
uint ti = ctx->ti;

ti += tgsi_build_full_immediate(imm,
ctx->tokens_out + ti,
ctx->header,
ctx->max_tokens_out - ti);
ctx->ti = ti;
}



/**
* Apply user-defined transformations to the input shader to produce
* the output shader.
* For example, a register search-and-replace operation could be applied
* by defining a transform_instruction() callback that examined and changed
* the instruction src/dest regs.
*
* \return number of tokens emitted
*/
int
tgsi_transform_shader(const struct tgsi_token *tokens_in,
struct tgsi_token *tokens_out,
uint max_tokens_out,
struct tgsi_transform_context *ctx)
{
uint procType;

/* input shader */
struct tgsi_parse_context parse;

/* output shader */
struct tgsi_processor *processor;


/**
** callback context init
**/
ctx->emit_instruction = emit_instruction;
ctx->emit_declaration = emit_declaration;
ctx->emit_immediate = emit_immediate;
ctx->tokens_out = tokens_out;
ctx->max_tokens_out = max_tokens_out;


/**
** Setup to begin parsing input shader
**/
if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) {
debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n");
return -1;
}
procType = parse.FullHeader.Processor.Processor;
assert(procType == TGSI_PROCESSOR_FRAGMENT ||
procType == TGSI_PROCESSOR_VERTEX ||
procType == TGSI_PROCESSOR_GEOMETRY);


/**
** Setup output shader
**/
*(struct tgsi_version *) &tokens_out[0] = tgsi_build_version();

ctx->header = (struct tgsi_header *) (tokens_out + 1);
*ctx->header = tgsi_build_header();

processor = (struct tgsi_processor *) (tokens_out + 2);
*processor = tgsi_build_processor( procType, ctx->header );

ctx->ti = 3;


/**
** Loop over incoming program tokens/instructions
*/
while( !tgsi_parse_end_of_tokens( &parse ) ) {

tgsi_parse_token( &parse );

switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_INSTRUCTION:
{
struct tgsi_full_instruction *fullinst
= &parse.FullToken.FullInstruction;

if (ctx->transform_instruction)
ctx->transform_instruction(ctx, fullinst);
else
ctx->emit_instruction(ctx, fullinst);
}
break;

case TGSI_TOKEN_TYPE_DECLARATION:
{
struct tgsi_full_declaration *fulldecl
= &parse.FullToken.FullDeclaration;

if (ctx->transform_declaration)
ctx->transform_declaration(ctx, fulldecl);
else
ctx->emit_declaration(ctx, fulldecl);
}
break;

case TGSI_TOKEN_TYPE_IMMEDIATE:
{
struct tgsi_full_immediate *fullimm
= &parse.FullToken.FullImmediate;

if (ctx->transform_immediate)
ctx->transform_immediate(ctx, fullimm);
else
ctx->emit_immediate(ctx, fullimm);
}
break;

default:
assert( 0 );
}
}

if (ctx->epilog) {
ctx->epilog(ctx);
}

tgsi_parse_free (&parse);

return ctx->ti;
}

+ 93
- 0
src/mesa/pipe/tgsi/util/tgsi_transform.h View File

@@ -0,0 +1,93 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* 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
* 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.
*
**************************************************************************/

#ifndef TGSI_TRANSFORM_H
#define TGSI_TRANSFORM_H


#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/tgsi/util/tgsi_parse.h"
#include "pipe/tgsi/util/tgsi_build.h"



/**
* Subclass this to add caller-specific data
*/
struct tgsi_transform_context
{
/**** PUBLIC ***/

/**
* User-defined callbacks invoked per instruction.
*/
void (*transform_instruction)(struct tgsi_transform_context *ctx,
struct tgsi_full_instruction *inst);

void (*transform_declaration)(struct tgsi_transform_context *ctx,
struct tgsi_full_declaration *decl);

void (*transform_immediate)(struct tgsi_transform_context *ctx,
struct tgsi_full_immediate *imm);

/**
* Called at end of input program to allow caller to append extra
* instructions. Return number of tokens emitted.
*/
void (*epilog)(struct tgsi_transform_context *ctx);


/*** PRIVATE ***/

/**
* These are setup by tgsi_transform_shader() and cannot be overridden.
* Meant to be called from in the above user callback functions.
*/
void (*emit_instruction)(struct tgsi_transform_context *ctx,
const struct tgsi_full_instruction *inst);
void (*emit_declaration)(struct tgsi_transform_context *ctx,
const struct tgsi_full_declaration *decl);
void (*emit_immediate)(struct tgsi_transform_context *ctx,
const struct tgsi_full_immediate *imm);

struct tgsi_header *header;
uint max_tokens_out;
struct tgsi_token *tokens_out;
uint ti;
};



extern int
tgsi_transform_shader(const struct tgsi_token *tokens_in,
struct tgsi_token *tokens_out,
uint max_tokens_out,
struct tgsi_transform_context *ctx);


#endif /* TGSI_TRANSFORM_H */

Loading…
Cancel
Save