tgsi_transform.c revision b865501bda8f2f99bfa8ee365aa4a3da64291e6e
14c1403f667c6047a44ff494364725b3b7da82c68Brian/************************************************************************** 24c1403f667c6047a44ff494364725b3b7da82c68Brian * 34c1403f667c6047a44ff494364725b3b7da82c68Brian * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 44c1403f667c6047a44ff494364725b3b7da82c68Brian * All Rights Reserved. 54c1403f667c6047a44ff494364725b3b7da82c68Brian * 64c1403f667c6047a44ff494364725b3b7da82c68Brian * Permission is hereby granted, free of charge, to any person obtaining a 74c1403f667c6047a44ff494364725b3b7da82c68Brian * copy of this software and associated documentation files (the 84c1403f667c6047a44ff494364725b3b7da82c68Brian * "Software"), to deal in the Software without restriction, including 94c1403f667c6047a44ff494364725b3b7da82c68Brian * without limitation the rights to use, copy, modify, merge, publish, 104c1403f667c6047a44ff494364725b3b7da82c68Brian * distribute, sub license, and/or sell copies of the Software, and to 114c1403f667c6047a44ff494364725b3b7da82c68Brian * permit persons to whom the Software is furnished to do so, subject to 124c1403f667c6047a44ff494364725b3b7da82c68Brian * the following conditions: 134c1403f667c6047a44ff494364725b3b7da82c68Brian * 144c1403f667c6047a44ff494364725b3b7da82c68Brian * The above copyright notice and this permission notice (including the 154c1403f667c6047a44ff494364725b3b7da82c68Brian * next paragraph) shall be included in all copies or substantial portions 164c1403f667c6047a44ff494364725b3b7da82c68Brian * of the Software. 174c1403f667c6047a44ff494364725b3b7da82c68Brian * 184c1403f667c6047a44ff494364725b3b7da82c68Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 194c1403f667c6047a44ff494364725b3b7da82c68Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 204c1403f667c6047a44ff494364725b3b7da82c68Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 214c1403f667c6047a44ff494364725b3b7da82c68Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 224c1403f667c6047a44ff494364725b3b7da82c68Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 234c1403f667c6047a44ff494364725b3b7da82c68Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 244c1403f667c6047a44ff494364725b3b7da82c68Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254c1403f667c6047a44ff494364725b3b7da82c68Brian * 264c1403f667c6047a44ff494364725b3b7da82c68Brian **************************************************************************/ 274c1403f667c6047a44ff494364725b3b7da82c68Brian 284c1403f667c6047a44ff494364725b3b7da82c68Brian/** 294c1403f667c6047a44ff494364725b3b7da82c68Brian * TGSI program transformation utility. 304c1403f667c6047a44ff494364725b3b7da82c68Brian * 314c1403f667c6047a44ff494364725b3b7da82c68Brian * Authors: Brian Paul 324c1403f667c6047a44ff494364725b3b7da82c68Brian */ 334c1403f667c6047a44ff494364725b3b7da82c68Brian 34ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h" 354c1403f667c6047a44ff494364725b3b7da82c68Brian 364c1403f667c6047a44ff494364725b3b7da82c68Brian#include "tgsi_transform.h" 374c1403f667c6047a44ff494364725b3b7da82c68Brian 384c1403f667c6047a44ff494364725b3b7da82c68Brian 394c1403f667c6047a44ff494364725b3b7da82c68Brian 404c1403f667c6047a44ff494364725b3b7da82c68Brianstatic void 414c1403f667c6047a44ff494364725b3b7da82c68Brianemit_instruction(struct tgsi_transform_context *ctx, 424c1403f667c6047a44ff494364725b3b7da82c68Brian const struct tgsi_full_instruction *inst) 434c1403f667c6047a44ff494364725b3b7da82c68Brian{ 444c1403f667c6047a44ff494364725b3b7da82c68Brian uint ti = ctx->ti; 454c1403f667c6047a44ff494364725b3b7da82c68Brian 464c1403f667c6047a44ff494364725b3b7da82c68Brian ti += tgsi_build_full_instruction(inst, 474c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->tokens_out + ti, 484c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->header, 494c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->max_tokens_out - ti); 504c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->ti = ti; 514c1403f667c6047a44ff494364725b3b7da82c68Brian} 524c1403f667c6047a44ff494364725b3b7da82c68Brian 534c1403f667c6047a44ff494364725b3b7da82c68Brian 544c1403f667c6047a44ff494364725b3b7da82c68Brianstatic void 554c1403f667c6047a44ff494364725b3b7da82c68Brianemit_declaration(struct tgsi_transform_context *ctx, 564c1403f667c6047a44ff494364725b3b7da82c68Brian const struct tgsi_full_declaration *decl) 574c1403f667c6047a44ff494364725b3b7da82c68Brian{ 584c1403f667c6047a44ff494364725b3b7da82c68Brian uint ti = ctx->ti; 594c1403f667c6047a44ff494364725b3b7da82c68Brian 604c1403f667c6047a44ff494364725b3b7da82c68Brian ti += tgsi_build_full_declaration(decl, 614c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->tokens_out + ti, 624c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->header, 634c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->max_tokens_out - ti); 644c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->ti = ti; 654c1403f667c6047a44ff494364725b3b7da82c68Brian} 664c1403f667c6047a44ff494364725b3b7da82c68Brian 674c1403f667c6047a44ff494364725b3b7da82c68Brian 684c1403f667c6047a44ff494364725b3b7da82c68Brianstatic void 694c1403f667c6047a44ff494364725b3b7da82c68Brianemit_immediate(struct tgsi_transform_context *ctx, 704c1403f667c6047a44ff494364725b3b7da82c68Brian const struct tgsi_full_immediate *imm) 714c1403f667c6047a44ff494364725b3b7da82c68Brian{ 724c1403f667c6047a44ff494364725b3b7da82c68Brian uint ti = ctx->ti; 734c1403f667c6047a44ff494364725b3b7da82c68Brian 744c1403f667c6047a44ff494364725b3b7da82c68Brian ti += tgsi_build_full_immediate(imm, 754c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->tokens_out + ti, 764c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->header, 774c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->max_tokens_out - ti); 784c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->ti = ti; 794c1403f667c6047a44ff494364725b3b7da82c68Brian} 804c1403f667c6047a44ff494364725b3b7da82c68Brian 814c1403f667c6047a44ff494364725b3b7da82c68Brian 824c1403f667c6047a44ff494364725b3b7da82c68Brian 834c1403f667c6047a44ff494364725b3b7da82c68Brian/** 844c1403f667c6047a44ff494364725b3b7da82c68Brian * Apply user-defined transformations to the input shader to produce 854c1403f667c6047a44ff494364725b3b7da82c68Brian * the output shader. 864c1403f667c6047a44ff494364725b3b7da82c68Brian * For example, a register search-and-replace operation could be applied 874c1403f667c6047a44ff494364725b3b7da82c68Brian * by defining a transform_instruction() callback that examined and changed 884c1403f667c6047a44ff494364725b3b7da82c68Brian * the instruction src/dest regs. 894c1403f667c6047a44ff494364725b3b7da82c68Brian * 904c1403f667c6047a44ff494364725b3b7da82c68Brian * \return number of tokens emitted 914c1403f667c6047a44ff494364725b3b7da82c68Brian */ 924c1403f667c6047a44ff494364725b3b7da82c68Brianint 934c1403f667c6047a44ff494364725b3b7da82c68Briantgsi_transform_shader(const struct tgsi_token *tokens_in, 944c1403f667c6047a44ff494364725b3b7da82c68Brian struct tgsi_token *tokens_out, 954c1403f667c6047a44ff494364725b3b7da82c68Brian uint max_tokens_out, 964c1403f667c6047a44ff494364725b3b7da82c68Brian struct tgsi_transform_context *ctx) 974c1403f667c6047a44ff494364725b3b7da82c68Brian{ 984c1403f667c6047a44ff494364725b3b7da82c68Brian uint procType; 994c1403f667c6047a44ff494364725b3b7da82c68Brian 1004c1403f667c6047a44ff494364725b3b7da82c68Brian /* input shader */ 1014c1403f667c6047a44ff494364725b3b7da82c68Brian struct tgsi_parse_context parse; 1024c1403f667c6047a44ff494364725b3b7da82c68Brian 1034c1403f667c6047a44ff494364725b3b7da82c68Brian /* output shader */ 1044c1403f667c6047a44ff494364725b3b7da82c68Brian struct tgsi_processor *processor; 1054c1403f667c6047a44ff494364725b3b7da82c68Brian 1064c1403f667c6047a44ff494364725b3b7da82c68Brian 1074c1403f667c6047a44ff494364725b3b7da82c68Brian /** 1084c1403f667c6047a44ff494364725b3b7da82c68Brian ** callback context init 1094c1403f667c6047a44ff494364725b3b7da82c68Brian **/ 1104c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->emit_instruction = emit_instruction; 1114c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->emit_declaration = emit_declaration; 1124c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->emit_immediate = emit_immediate; 1134c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->tokens_out = tokens_out; 1144c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->max_tokens_out = max_tokens_out; 1154c1403f667c6047a44ff494364725b3b7da82c68Brian 1164c1403f667c6047a44ff494364725b3b7da82c68Brian 1174c1403f667c6047a44ff494364725b3b7da82c68Brian /** 1184c1403f667c6047a44ff494364725b3b7da82c68Brian ** Setup to begin parsing input shader 1194c1403f667c6047a44ff494364725b3b7da82c68Brian **/ 1204c1403f667c6047a44ff494364725b3b7da82c68Brian if (tgsi_parse_init( &parse, tokens_in ) != TGSI_PARSE_OK) { 1214c1403f667c6047a44ff494364725b3b7da82c68Brian debug_printf("tgsi_parse_init() failed in tgsi_transform_shader()!\n"); 1224c1403f667c6047a44ff494364725b3b7da82c68Brian return -1; 1234c1403f667c6047a44ff494364725b3b7da82c68Brian } 1244c1403f667c6047a44ff494364725b3b7da82c68Brian procType = parse.FullHeader.Processor.Processor; 1254c1403f667c6047a44ff494364725b3b7da82c68Brian assert(procType == TGSI_PROCESSOR_FRAGMENT || 1264c1403f667c6047a44ff494364725b3b7da82c68Brian procType == TGSI_PROCESSOR_VERTEX || 1274c1403f667c6047a44ff494364725b3b7da82c68Brian procType == TGSI_PROCESSOR_GEOMETRY); 1284c1403f667c6047a44ff494364725b3b7da82c68Brian 1294c1403f667c6047a44ff494364725b3b7da82c68Brian 1304c1403f667c6047a44ff494364725b3b7da82c68Brian /** 1314c1403f667c6047a44ff494364725b3b7da82c68Brian ** Setup output shader 1324c1403f667c6047a44ff494364725b3b7da82c68Brian **/ 1334c1403f667c6047a44ff494364725b3b7da82c68Brian *(struct tgsi_version *) &tokens_out[0] = tgsi_build_version(); 1344c1403f667c6047a44ff494364725b3b7da82c68Brian 1354c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->header = (struct tgsi_header *) (tokens_out + 1); 1364c1403f667c6047a44ff494364725b3b7da82c68Brian *ctx->header = tgsi_build_header(); 1374c1403f667c6047a44ff494364725b3b7da82c68Brian 1384c1403f667c6047a44ff494364725b3b7da82c68Brian processor = (struct tgsi_processor *) (tokens_out + 2); 1394c1403f667c6047a44ff494364725b3b7da82c68Brian *processor = tgsi_build_processor( procType, ctx->header ); 1404c1403f667c6047a44ff494364725b3b7da82c68Brian 1414c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->ti = 3; 1424c1403f667c6047a44ff494364725b3b7da82c68Brian 1434c1403f667c6047a44ff494364725b3b7da82c68Brian 1444c1403f667c6047a44ff494364725b3b7da82c68Brian /** 1454c1403f667c6047a44ff494364725b3b7da82c68Brian ** Loop over incoming program tokens/instructions 1464c1403f667c6047a44ff494364725b3b7da82c68Brian */ 1474c1403f667c6047a44ff494364725b3b7da82c68Brian while( !tgsi_parse_end_of_tokens( &parse ) ) { 1484c1403f667c6047a44ff494364725b3b7da82c68Brian 1494c1403f667c6047a44ff494364725b3b7da82c68Brian tgsi_parse_token( &parse ); 1504c1403f667c6047a44ff494364725b3b7da82c68Brian 1514c1403f667c6047a44ff494364725b3b7da82c68Brian switch( parse.FullToken.Token.Type ) { 1524c1403f667c6047a44ff494364725b3b7da82c68Brian case TGSI_TOKEN_TYPE_INSTRUCTION: 1534c1403f667c6047a44ff494364725b3b7da82c68Brian { 1544c1403f667c6047a44ff494364725b3b7da82c68Brian struct tgsi_full_instruction *fullinst 1554c1403f667c6047a44ff494364725b3b7da82c68Brian = &parse.FullToken.FullInstruction; 1564c1403f667c6047a44ff494364725b3b7da82c68Brian 1574c1403f667c6047a44ff494364725b3b7da82c68Brian if (ctx->transform_instruction) 1584c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->transform_instruction(ctx, fullinst); 1594c1403f667c6047a44ff494364725b3b7da82c68Brian else 1604c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->emit_instruction(ctx, fullinst); 1614c1403f667c6047a44ff494364725b3b7da82c68Brian } 1624c1403f667c6047a44ff494364725b3b7da82c68Brian break; 1634c1403f667c6047a44ff494364725b3b7da82c68Brian 1644c1403f667c6047a44ff494364725b3b7da82c68Brian case TGSI_TOKEN_TYPE_DECLARATION: 1654c1403f667c6047a44ff494364725b3b7da82c68Brian { 1664c1403f667c6047a44ff494364725b3b7da82c68Brian struct tgsi_full_declaration *fulldecl 1674c1403f667c6047a44ff494364725b3b7da82c68Brian = &parse.FullToken.FullDeclaration; 1684c1403f667c6047a44ff494364725b3b7da82c68Brian 1694c1403f667c6047a44ff494364725b3b7da82c68Brian if (ctx->transform_declaration) 1704c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->transform_declaration(ctx, fulldecl); 1714c1403f667c6047a44ff494364725b3b7da82c68Brian else 1724c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->emit_declaration(ctx, fulldecl); 1734c1403f667c6047a44ff494364725b3b7da82c68Brian } 1744c1403f667c6047a44ff494364725b3b7da82c68Brian break; 1754c1403f667c6047a44ff494364725b3b7da82c68Brian 1764c1403f667c6047a44ff494364725b3b7da82c68Brian case TGSI_TOKEN_TYPE_IMMEDIATE: 1774c1403f667c6047a44ff494364725b3b7da82c68Brian { 1784c1403f667c6047a44ff494364725b3b7da82c68Brian struct tgsi_full_immediate *fullimm 1794c1403f667c6047a44ff494364725b3b7da82c68Brian = &parse.FullToken.FullImmediate; 1804c1403f667c6047a44ff494364725b3b7da82c68Brian 1814c1403f667c6047a44ff494364725b3b7da82c68Brian if (ctx->transform_immediate) 1824c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->transform_immediate(ctx, fullimm); 1834c1403f667c6047a44ff494364725b3b7da82c68Brian else 1844c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->emit_immediate(ctx, fullimm); 1854c1403f667c6047a44ff494364725b3b7da82c68Brian } 1864c1403f667c6047a44ff494364725b3b7da82c68Brian break; 1874c1403f667c6047a44ff494364725b3b7da82c68Brian 1884c1403f667c6047a44ff494364725b3b7da82c68Brian default: 1894c1403f667c6047a44ff494364725b3b7da82c68Brian assert( 0 ); 1904c1403f667c6047a44ff494364725b3b7da82c68Brian } 1914c1403f667c6047a44ff494364725b3b7da82c68Brian } 1924c1403f667c6047a44ff494364725b3b7da82c68Brian 1934c1403f667c6047a44ff494364725b3b7da82c68Brian if (ctx->epilog) { 1944c1403f667c6047a44ff494364725b3b7da82c68Brian ctx->epilog(ctx); 1954c1403f667c6047a44ff494364725b3b7da82c68Brian } 1964c1403f667c6047a44ff494364725b3b7da82c68Brian 1974c1403f667c6047a44ff494364725b3b7da82c68Brian tgsi_parse_free (&parse); 1984c1403f667c6047a44ff494364725b3b7da82c68Brian 1994c1403f667c6047a44ff494364725b3b7da82c68Brian return ctx->ti; 2004c1403f667c6047a44ff494364725b3b7da82c68Brian} 201b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell 202b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell 203b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell#include "tgsi_text.h" 204b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell 205b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwellextern int tgsi_transform_foo( struct tgsi_token *tokens_out, 206b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell uint max_tokens_out ); 207b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell 208b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell/* This function exists only so that tgsi_text_translate() doesn't get 209b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell * magic-ed out of the libtgsi.a archive by the build system. Don't 210b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell * remove unless you know this has been fixed - check on mingw/scons 211b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell * builds as well. 212b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell */ 213b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwellint 214b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwelltgsi_transform_foo( struct tgsi_token *tokens_out, 215b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell uint max_tokens_out ) 216b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell{ 217b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell const char *text = 218b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell "FRAG1.1\n" 219b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell "DCL IN[0], COLOR, CONSTANT\n" 220b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell "DCL OUT[0], COLOR\n" 221b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell " 0: MOV OUT[0], IN[0]\n" 222b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell " 1: END"; 223b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell 224b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell return tgsi_text_translate( text, 225b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell tokens_out, 226b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell max_tokens_out ); 227b865501bda8f2f99bfa8ee365aa4a3da64291e6eKeith Whitwell} 228