190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák/************************************************************************** 290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * Copyright 2009 Marek Olšák <maraeo@gmail.com> 490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining a 690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * copy of this software and associated documentation files (the 790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * "Software"), to deal in the Software without restriction, including 890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * without limitation the rights to use, copy, modify, merge, publish, 990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * distribute, sub license, and/or sell copies of the Software, and to 1090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * permit persons to whom the Software is furnished to do so, subject to 1190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * the following conditions: 1290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 1390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * The above copyright notice and this permission notice (including the 1490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * next paragraph) shall be included in all copies or substantial portions 1590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * of the Software. 1690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 1790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 2590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák **************************************************************************/ 2690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 2790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák/* This file contains the vertex shader tranformations for SW TCL needed 2890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * to overcome the limitations of the r300 rasterizer. 2990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 3090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * Transformations: 3190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 1) If the secondary color output is present, the primary color must be 3275f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák * present too. 3390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 2) If any back-face color output is present, there must be all 4 color 3490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * outputs and missing ones must be inserted. 3590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 3) Insert a trailing texcoord output containing a copy of POS, for WPOS. 3690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * 3790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * I know this code is cumbersome, but I don't know of any nicer way 3890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * of transforming TGSI shaders. ~ M. 3990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák */ 4090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 4190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák#include "r300_vs.h" 4290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 4390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák#include <stdio.h> 4490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 4590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák#include "tgsi/tgsi_transform.h" 4690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák#include "tgsi/tgsi_dump.h" 4790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 4890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák#include "draw/draw_context.h" 4990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 5090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšákstruct vs_transform_context { 5190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct tgsi_transform_context base; 5290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 5390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák boolean color_used[2]; 5490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák boolean bcolor_used[2]; 5590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 5690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Index of the pos output, typically 0. */ 5790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned pos_output; 5890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Index of the pos temp where all writes of pos are redirected to. */ 5990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned pos_temp; 6090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* The index of the last generic output, after which we insert a new 6190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * output for WPOS. */ 6290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák int last_generic; 6390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 6490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned num_outputs; 6590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Used to shift output decl. indices when inserting new ones. */ 6690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned decl_shift; 6790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Used to remap writes to output decls if their indices changed. */ 6890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned out_remap[32]; 6990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 7090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* First instruction processed? */ 7190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák boolean first_instruction; 7290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* End instruction processed? */ 7390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák boolean end_instruction; 7475f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 7575f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák boolean temp_used[1024]; 7690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák}; 7790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 7890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšákstatic void emit_temp(struct tgsi_transform_context *ctx, unsigned reg) 7990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák{ 8090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct tgsi_full_declaration decl; 8190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 8290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl = tgsi_default_full_declaration(); 8390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl.Declaration.File = TGSI_FILE_TEMPORARY; 8490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl.Range.First = decl.Range.Last = reg; 8590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ctx->emit_declaration(ctx, &decl); 8690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák} 8790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 8890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšákstatic void emit_output(struct tgsi_transform_context *ctx, 8990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned name, unsigned index, unsigned interp, 9090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned reg) 9190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák{ 9290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 9390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct tgsi_full_declaration decl; 9490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 9590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl = tgsi_default_full_declaration(); 9690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl.Declaration.File = TGSI_FILE_OUTPUT; 971279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez decl.Declaration.Interpolate = 1; 9890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl.Declaration.Semantic = TRUE; 9990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl.Semantic.Name = name; 10090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl.Semantic.Index = index; 10190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl.Range.First = decl.Range.Last = reg; 1021279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez decl.Interp.Interpolate = interp; 10390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ctx->emit_declaration(ctx, &decl); 10490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ++vsctx->num_outputs; 10590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák} 10690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 10775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšákstatic void insert_output_before(struct tgsi_transform_context *ctx, 10875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák struct tgsi_full_declaration *before, 10975f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák unsigned name, unsigned index, unsigned interp) 11090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák{ 11190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 11290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned i; 11390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 11490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Make a place for the new output. */ 11590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák for (i = before->Range.First; i < Elements(vsctx->out_remap); i++) { 11690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ++vsctx->out_remap[i]; 11790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 11890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 11990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Insert the new output. */ 12075f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák emit_output(ctx, name, index, interp, 12175f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák before->Range.First + vsctx->decl_shift); 12290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 12390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ++vsctx->decl_shift; 12490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák} 12590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 12675f8990547903f7dde5d98319cc813f94a15aa78Marek Olšákstatic void insert_output_after(struct tgsi_transform_context *ctx, 12775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák struct tgsi_full_declaration *after, 12875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák unsigned name, unsigned index, unsigned interp) 12990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák{ 13090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 13175f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák unsigned i; 13290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 13375f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák /* Make a place for the new output. */ 13475f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák for (i = after->Range.First+1; i < Elements(vsctx->out_remap); i++) { 13575f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák ++vsctx->out_remap[i]; 13690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 13775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 13875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák /* Insert the new output. */ 13975f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák emit_output(ctx, name, index, interp, 14075f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák after->Range.First + 1); 14175f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 14275f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák ++vsctx->decl_shift; 14390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák} 14490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 14590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšákstatic void transform_decl(struct tgsi_transform_context *ctx, 14690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct tgsi_full_declaration *decl) 14790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák{ 14890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 14990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned i; 15090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 15190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (decl->Declaration.File == TGSI_FILE_OUTPUT) { 15290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák switch (decl->Semantic.Name) { 15390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák case TGSI_SEMANTIC_POSITION: 15490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->pos_output = decl->Range.First; 15590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák break; 15690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 15790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák case TGSI_SEMANTIC_COLOR: 15890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák assert(decl->Semantic.Index < 2); 15990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 16090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* We must rasterize the first color if the second one is 16190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * used, otherwise the rasterizer doesn't do the color 16290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * selection correctly. Declare it, but don't write to it. */ 16390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (decl->Semantic.Index == 1 && !vsctx->color_used[0]) { 16475f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0, 16575f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák TGSI_INTERPOLATE_LINEAR); 16690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->color_used[0] = TRUE; 16790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 16890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák break; 16990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 17090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák case TGSI_SEMANTIC_BCOLOR: 17190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák assert(decl->Semantic.Index < 2); 17290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 17390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* We must rasterize all 4 colors if back-face colors are 17490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * used, otherwise the rasterizer doesn't do the color 17590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * selection correctly. Declare it, but don't write to it. */ 17690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (!vsctx->color_used[0]) { 17775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0, 17875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák TGSI_INTERPOLATE_LINEAR); 17990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->color_used[0] = TRUE; 18090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 18190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (!vsctx->color_used[1]) { 18275f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 1, 18375f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák TGSI_INTERPOLATE_LINEAR); 18490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->color_used[1] = TRUE; 18590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 18690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (decl->Semantic.Index == 1 && !vsctx->bcolor_used[0]) { 18775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák insert_output_before(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0, 18875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák TGSI_INTERPOLATE_LINEAR); 18975d0e95a3ad188ae1c4cc38a73241c6b227c0733Marek Olšák vsctx->bcolor_used[0] = TRUE; 19090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 19190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák break; 19290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 19390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák case TGSI_SEMANTIC_GENERIC: 19490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->last_generic = MAX2(vsctx->last_generic, decl->Semantic.Index); 19590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák break; 19690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 19790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 19890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Since we're inserting new outputs in between, the following outputs 19990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * should be moved to the right so that they don't overlap with 20090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * the newly added ones. */ 20190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl->Range.First += vsctx->decl_shift; 20290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák decl->Range.Last += vsctx->decl_shift; 20390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 20490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ++vsctx->num_outputs; 20590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { 20690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák for (i = decl->Range.First; i <= decl->Range.Last; i++) { 20790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->temp_used[i] = TRUE; 20890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 20990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 21090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 21190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ctx->emit_declaration(ctx, decl); 21275f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 21375f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák /* Insert BCOLOR1 if needed. */ 21475f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák if (decl->Declaration.File == TGSI_FILE_OUTPUT && 21575f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák decl->Semantic.Name == TGSI_SEMANTIC_BCOLOR && 21675f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák !vsctx->bcolor_used[1]) { 21775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák insert_output_after(ctx, decl, TGSI_SEMANTIC_BCOLOR, 1, 21875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák TGSI_INTERPOLATE_LINEAR); 21975f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák } 22090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák} 22190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 22290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšákstatic void transform_inst(struct tgsi_transform_context *ctx, 22390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct tgsi_full_instruction *inst) 22490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák{ 22590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct vs_transform_context *vsctx = (struct vs_transform_context *) ctx; 22690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct tgsi_full_instruction new_inst; 22790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned i; 22890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 22990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (!vsctx->first_instruction) { 23090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->first_instruction = TRUE; 23190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 23290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Insert the generic output for WPOS. */ 23390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák emit_output(ctx, TGSI_SEMANTIC_GENERIC, vsctx->last_generic + 1, 23490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák TGSI_INTERPOLATE_PERSPECTIVE, vsctx->num_outputs); 23590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 23690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Find a free temp for POSITION. */ 23790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák for (i = 0; i < Elements(vsctx->temp_used); i++) { 23890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (!vsctx->temp_used[i]) { 23990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák emit_temp(ctx, i); 24090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->pos_temp = i; 24190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák break; 24290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 24390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 24490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 24590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 24690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (inst->Instruction.Opcode == TGSI_OPCODE_END) { 24790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* MOV OUT[pos_output], TEMP[pos_temp]; */ 24890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst = tgsi_default_full_instruction(); 24990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 25090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Instruction.NumDstRegs = 1; 25190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT; 25290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Dst[0].Register.Index = vsctx->pos_output; 25390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW; 25490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Instruction.NumSrcRegs = 1; 25590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 25690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Src[0].Register.Index = vsctx->pos_temp; 25790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ctx->emit_instruction(ctx, &new_inst); 25890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 25990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* MOV OUT[n-1], TEMP[pos_temp]; */ 26090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst = tgsi_default_full_instruction(); 26190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 26290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Instruction.NumDstRegs = 1; 26390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT; 26490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Dst[0].Register.Index = vsctx->num_outputs - 1; 26590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW; 26690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Instruction.NumSrcRegs = 1; 26790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 26890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_inst.Src[0].Register.Index = vsctx->pos_temp; 26990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ctx->emit_instruction(ctx, &new_inst); 27090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 27190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vsctx->end_instruction = TRUE; 27290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } else { 27390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Not an END instruction. */ 27490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Fix writes to outputs. */ 27590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák for (i = 0; i < inst->Instruction.NumDstRegs; i++) { 27690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct tgsi_full_dst_register *dst = &inst->Dst[i]; 27790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (dst->Register.File == TGSI_FILE_OUTPUT) { 27890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (dst->Register.Index == vsctx->pos_output) { 27990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Replace writes to OUT[pos_output] with TEMP[pos_temp]. */ 28090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák dst->Register.File = TGSI_FILE_TEMPORARY; 28190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák dst->Register.Index = vsctx->pos_temp; 28290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } else { 28390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Not a position, good... 28490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * Since we were changing the indices of output decls, 28590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * we must redirect writes into them too. */ 28690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák dst->Register.Index = vsctx->out_remap[dst->Register.Index]; 28790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 28890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 28990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 29090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 29190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Inserting 2 instructions before the END opcode moves all following 29290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * labels by 2. Subroutines are always after the END opcode so 29390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * they're always moved. */ 29490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (inst->Instruction.Opcode == TGSI_OPCODE_CAL) { 29590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák inst->Label.Label += 2; 29690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 29790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* The labels of the following opcodes are moved only after 29890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák * the END opcode. */ 29990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (vsctx->end_instruction && 30090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák (inst->Instruction.Opcode == TGSI_OPCODE_IF || 30190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák inst->Instruction.Opcode == TGSI_OPCODE_ELSE || 30290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP || 30390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP)) { 30490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák inst->Label.Label += 2; 30590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 30690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 30790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 30890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák ctx->emit_instruction(ctx, inst); 30990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák} 31090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 3115ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšákvoid r300_draw_init_vertex_shader(struct r300_context *r300, 31290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct r300_vertex_shader *vs) 31390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák{ 3145ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák struct draw_context *draw = r300->draw; 31590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct pipe_shader_state new_vs; 31675f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák struct tgsi_shader_info info; 31790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák struct vs_transform_context transform; 31890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák const uint newLen = tgsi_num_tokens(vs->state.tokens) + 100 /* XXX */; 31990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák unsigned i; 32090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 32175f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák tgsi_scan_shader(vs->state.tokens, &info); 32275f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 32390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák new_vs.tokens = tgsi_alloc_tokens(newLen); 32490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák if (new_vs.tokens == NULL) 32590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák return; 32690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 32790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák memset(&transform, 0, sizeof(transform)); 32890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák for (i = 0; i < Elements(transform.out_remap); i++) { 32990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák transform.out_remap[i] = i; 33090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák } 33190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák transform.last_generic = -1; 33290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák transform.base.transform_instruction = transform_inst; 33390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák transform.base.transform_declaration = transform_decl; 33490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 33575f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák for (i = 0; i < info.num_outputs; i++) { 33675f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák unsigned index = info.output_semantic_index[i]; 33775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 33875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák switch (info.output_semantic_name[i]) { 33975f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák case TGSI_SEMANTIC_COLOR: 34075f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák assert(index < 2); 34175f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák transform.color_used[index] = TRUE; 34275f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák break; 34375f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 34475f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák case TGSI_SEMANTIC_BCOLOR: 34575f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák assert(index < 2); 34675f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák transform.bcolor_used[index] = TRUE; 34775f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák break; 34875f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák } 34975f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák } 35075f8990547903f7dde5d98319cc813f94a15aa78Marek Olšák 35190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák tgsi_transform_shader(vs->state.tokens, 35290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák (struct tgsi_token*)new_vs.tokens, 35390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák newLen, &transform.base); 35490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 35590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák#if 0 35690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák printf("----------------------------------------------\norig shader:\n"); 35790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák tgsi_dump(vs->state.tokens, 0); 35890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák printf("----------------------------------------------\nnew shader:\n"); 35990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák tgsi_dump(new_vs.tokens, 0); 36090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák printf("----------------------------------------------\n"); 36190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák#endif 36290e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 36390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Free old tokens. */ 36490e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák FREE((void*)vs->state.tokens); 36590e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 36690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vs->draw_vs = draw_create_vertex_shader(draw, &new_vs); 36790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 36890e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Instead of duplicating and freeing the tokens, copy the pointer directly. */ 36990e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vs->state.tokens = new_vs.tokens; 37090e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 37190e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák /* Init the VS output table for the rasterizer. */ 3725ce0598a034179eaacff96f39eaebf0ba0f30d4cMarek Olšák r300_init_vs_outputs(r300, vs); 37390e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák 3743262554bb375230a39e155ad712740bdcd657d4cMarek Olšák /* Make the last generic be WPOS. */ 3753262554bb375230a39e155ad712740bdcd657d4cMarek Olšák vs->outputs.wpos = vs->outputs.generic[transform.last_generic + 1]; 37690e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák vs->outputs.generic[transform.last_generic + 1] = ATTR_UNUSED; 37790e5a37d128efaca9e89434ab103826ee82cb911Marek Olšák} 378