1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* This file contains the vertex shader tranformations for SW TCL needed 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to overcome the limitations of the r300 rasterizer. 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Transformations: 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1) If the secondary color output is present, the primary color must be 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * present too. 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 2) If any back-face color output is present, there must be all 4 color 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * outputs and missing ones must be inserted. 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3) Insert a trailing texcoord output containing a copy of POS, for WPOS. 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * I know this code is cumbersome, but I don't know of any nicer way 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of transforming TGSI shaders. ~ M. 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "r300_vs.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h> 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_transform.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_dump.h" 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "draw/draw_context.h" 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct vs_transform_context { 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_transform_context base; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean color_used[2]; 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean bcolor_used[2]; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Index of the pos output, typically 0. */ 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned pos_output; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Index of the pos temp where all writes of pos are redirected to. */ 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned pos_temp; 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The index of the last generic output, after which we insert a new 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * output for WPOS. */ 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int last_generic; 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_outputs; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Used to shift output decl. indices when inserting new ones. */ 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned decl_shift; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Used to remap writes to output decls if their indices changed. */ 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned out_remap[32]; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* First instruction processed? */ 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean first_instruction; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* End instruction processed? */ 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean end_instruction; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean temp_used[1024]; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_temp(struct tgsi_transform_context *ctx, unsigned reg) 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_declaration decl; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl = tgsi_default_full_declaration(); 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Declaration.File = TGSI_FILE_TEMPORARY; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Range.First = decl.Range.Last = reg; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->emit_declaration(ctx, &decl); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_output(struct tgsi_transform_context *ctx, 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned name, unsigned index, unsigned interp, 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned reg) 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_declaration decl; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl = tgsi_default_full_declaration(); 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Declaration.File = TGSI_FILE_OUTPUT; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Declaration.Interpolate = 1; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Declaration.Semantic = TRUE; 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Semantic.Name = name; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Semantic.Index = index; 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Range.First = decl.Range.Last = reg; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl.Interp.Interpolate = interp; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->emit_declaration(ctx, &decl); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++vsctx->num_outputs; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void insert_output_before(struct tgsi_transform_context *ctx, 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_declaration *before, 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned name, unsigned index, unsigned interp) 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make a place for the new output. */ 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = before->Range.First; i < Elements(vsctx->out_remap); i++) { 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++vsctx->out_remap[i]; 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Insert the new output. */ 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_output(ctx, name, index, interp, 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org before->Range.First + vsctx->decl_shift); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++vsctx->decl_shift; 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void insert_output_after(struct tgsi_transform_context *ctx, 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_declaration *after, 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned name, unsigned index, unsigned interp) 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make a place for the new output. */ 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = after->Range.First+1; i < Elements(vsctx->out_remap); i++) { 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++vsctx->out_remap[i]; 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Insert the new output. */ 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_output(ctx, name, index, interp, 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org after->Range.First + 1); 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++vsctx->decl_shift; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void transform_decl(struct tgsi_transform_context *ctx, 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_declaration *decl) 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl->Declaration.File == TGSI_FILE_OUTPUT) { 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (decl->Semantic.Name) { 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_POSITION: 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->pos_output = decl->Range.First; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_COLOR: 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(decl->Semantic.Index < 2); 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We must rasterize the first color if the second one is 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * used, otherwise the rasterizer doesn't do the color 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * selection correctly. Declare it, but don't write to it. */ 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl->Semantic.Index == 1 && !vsctx->color_used[0]) { 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0, 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_INTERPOLATE_LINEAR); 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->color_used[0] = TRUE; 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_BCOLOR: 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(decl->Semantic.Index < 2); 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We must rasterize all 4 colors if back-face colors are 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * used, otherwise the rasterizer doesn't do the color 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * selection correctly. Declare it, but don't write to it. */ 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!vsctx->color_used[0]) { 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 0, 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_INTERPOLATE_LINEAR); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->color_used[0] = TRUE; 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!vsctx->color_used[1]) { 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insert_output_before(ctx, decl, TGSI_SEMANTIC_COLOR, 1, 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_INTERPOLATE_LINEAR); 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->color_used[1] = TRUE; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl->Semantic.Index == 1 && !vsctx->bcolor_used[0]) { 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insert_output_before(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0, 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_INTERPOLATE_LINEAR); 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->bcolor_used[0] = TRUE; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_GENERIC: 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->last_generic = MAX2(vsctx->last_generic, decl->Semantic.Index); 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Since we're inserting new outputs in between, the following outputs 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * should be moved to the right so that they don't overlap with 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the newly added ones. */ 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->Range.First += vsctx->decl_shift; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->Range.Last += vsctx->decl_shift; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++vsctx->num_outputs; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = decl->Range.First; i <= decl->Range.Last; i++) { 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->temp_used[i] = TRUE; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->emit_declaration(ctx, decl); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Insert BCOLOR1 if needed. */ 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (decl->Declaration.File == TGSI_FILE_OUTPUT && 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org decl->Semantic.Name == TGSI_SEMANTIC_BCOLOR && 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !vsctx->bcolor_used[1]) { 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insert_output_after(ctx, decl, TGSI_SEMANTIC_BCOLOR, 1, 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_INTERPOLATE_LINEAR); 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void transform_inst(struct tgsi_transform_context *ctx, 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_instruction *inst) 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vs_transform_context *vsctx = (struct vs_transform_context *) ctx; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_instruction new_inst; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!vsctx->first_instruction) { 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->first_instruction = TRUE; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Insert the generic output for WPOS. */ 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_output(ctx, TGSI_SEMANTIC_GENERIC, vsctx->last_generic + 1, 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_INTERPOLATE_PERSPECTIVE, vsctx->num_outputs); 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Find a free temp for POSITION. */ 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < Elements(vsctx->temp_used); i++) { 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!vsctx->temp_used[i]) { 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_temp(ctx, i); 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->pos_temp = i; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Instruction.Opcode == TGSI_OPCODE_END) { 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MOV OUT[pos_output], TEMP[pos_temp]; */ 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst = tgsi_default_full_instruction(); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Instruction.NumDstRegs = 1; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Dst[0].Register.Index = vsctx->pos_output; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Instruction.NumSrcRegs = 1; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Src[0].Register.Index = vsctx->pos_temp; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->emit_instruction(ctx, &new_inst); 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* MOV OUT[n-1], TEMP[pos_temp]; */ 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst = tgsi_default_full_instruction(); 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Instruction.Opcode = TGSI_OPCODE_MOV; 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Instruction.NumDstRegs = 1; 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT; 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Dst[0].Register.Index = vsctx->num_outputs - 1; 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW; 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Instruction.NumSrcRegs = 1; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_inst.Src[0].Register.Index = vsctx->pos_temp; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->emit_instruction(ctx, &new_inst); 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsctx->end_instruction = TRUE; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Not an END instruction. */ 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Fix writes to outputs. */ 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < inst->Instruction.NumDstRegs; i++) { 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_dst_register *dst = &inst->Dst[i]; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst->Register.File == TGSI_FILE_OUTPUT) { 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dst->Register.Index == vsctx->pos_output) { 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Replace writes to OUT[pos_output] with TEMP[pos_temp]. */ 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Register.File = TGSI_FILE_TEMPORARY; 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Register.Index = vsctx->pos_temp; 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Not a position, good... 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Since we were changing the indices of output decls, 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we must redirect writes into them too. */ 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dst->Register.Index = vsctx->out_remap[dst->Register.Index]; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Inserting 2 instructions before the END opcode moves all following 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * labels by 2. Subroutines are always after the END opcode so 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * they're always moved. */ 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->Instruction.Opcode == TGSI_OPCODE_CAL) { 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Label.Label += 2; 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The labels of the following opcodes are moved only after 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the END opcode. */ 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vsctx->end_instruction && 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (inst->Instruction.Opcode == TGSI_OPCODE_IF || 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Instruction.Opcode == TGSI_OPCODE_ELSE || 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP || 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP)) { 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->Label.Label += 2; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->emit_instruction(ctx, inst); 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid r300_draw_init_vertex_shader(struct r300_context *r300, 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct r300_vertex_shader *vs) 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct draw_context *draw = r300->draw; 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_shader_state new_vs; 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_shader_info info; 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vs_transform_context transform; 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const uint newLen = tgsi_num_tokens(vs->state.tokens) + 100 /* XXX */; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_scan_shader(vs->state.tokens, &info); 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_vs.tokens = tgsi_alloc_tokens(newLen); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_vs.tokens == NULL) 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&transform, 0, sizeof(transform)); 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < Elements(transform.out_remap); i++) { 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform.out_remap[i] = i; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform.last_generic = -1; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform.base.transform_instruction = transform_inst; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform.base.transform_declaration = transform_decl; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < info.num_outputs; i++) { 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index = info.output_semantic_index[i]; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (info.output_semantic_name[i]) { 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_COLOR: 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index < 2); 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform.color_used[index] = TRUE; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_SEMANTIC_BCOLOR: 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(index < 2); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform.bcolor_used[index] = TRUE; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_transform_shader(vs->state.tokens, 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (struct tgsi_token*)new_vs.tokens, 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org newLen, &transform.base); 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("----------------------------------------------\norig shader:\n"); 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_dump(vs->state.tokens, 0); 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("----------------------------------------------\nnew shader:\n"); 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_dump(new_vs.tokens, 0); 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("----------------------------------------------\n"); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Free old tokens. */ 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE((void*)vs->state.tokens); 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vs->draw_vs = draw_create_vertex_shader(draw, &new_vs); 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Instead of duplicating and freeing the tokens, copy the pointer directly. */ 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vs->state.tokens = new_vs.tokens; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Init the VS output table for the rasterizer. */ 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org r300_init_vs_outputs(r300, vs); 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make the last generic be WPOS. */ 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vs->outputs.wpos = vs->outputs.generic[transform.last_generic + 1]; 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vs->outputs.generic[transform.last_generic + 1] = ATTR_UNUSED; 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 378