1848b8605Smrg/* 2848b8605Smrg * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> 3848b8605Smrg * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4848b8605Smrg * 5848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 6848b8605Smrg * copy of this software and associated documentation files (the "Software"), 7848b8605Smrg * to deal in the Software without restriction, including without limitation 8848b8605Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 9848b8605Smrg * license, and/or sell copies of the Software, and to permit persons to whom 10848b8605Smrg * the Software is furnished to do so, subject to the following conditions: 11848b8605Smrg * 12848b8605Smrg * The above copyright notice and this permission notice (including the next 13848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 14848b8605Smrg * Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20848b8605Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21848b8605Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22848b8605Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23848b8605Smrg 24848b8605Smrg#include "r300_vs.h" 25848b8605Smrg 26848b8605Smrg#include "r300_context.h" 27848b8605Smrg#include "r300_screen.h" 28848b8605Smrg#include "r300_tgsi_to_rc.h" 29848b8605Smrg#include "r300_reg.h" 30848b8605Smrg 31848b8605Smrg#include "tgsi/tgsi_dump.h" 32848b8605Smrg#include "tgsi/tgsi_parse.h" 33848b8605Smrg#include "tgsi/tgsi_ureg.h" 34848b8605Smrg 35848b8605Smrg#include "compiler/radeon_compiler.h" 36848b8605Smrg 37848b8605Smrg/* Convert info about VS output semantics into r300_shader_semantics. */ 38848b8605Smrgstatic void r300_shader_read_vs_outputs( 39848b8605Smrg struct r300_context *r300, 40848b8605Smrg struct tgsi_shader_info* info, 41848b8605Smrg struct r300_shader_semantics* vs_outputs) 42848b8605Smrg{ 43848b8605Smrg int i; 44848b8605Smrg unsigned index; 45848b8605Smrg 46848b8605Smrg r300_shader_semantics_reset(vs_outputs); 47848b8605Smrg 48848b8605Smrg for (i = 0; i < info->num_outputs; i++) { 49848b8605Smrg index = info->output_semantic_index[i]; 50848b8605Smrg 51848b8605Smrg switch (info->output_semantic_name[i]) { 52848b8605Smrg case TGSI_SEMANTIC_POSITION: 53848b8605Smrg assert(index == 0); 54848b8605Smrg vs_outputs->pos = i; 55848b8605Smrg break; 56848b8605Smrg 57848b8605Smrg case TGSI_SEMANTIC_PSIZE: 58848b8605Smrg assert(index == 0); 59848b8605Smrg vs_outputs->psize = i; 60848b8605Smrg break; 61848b8605Smrg 62848b8605Smrg case TGSI_SEMANTIC_COLOR: 63848b8605Smrg assert(index < ATTR_COLOR_COUNT); 64848b8605Smrg vs_outputs->color[index] = i; 65848b8605Smrg break; 66848b8605Smrg 67848b8605Smrg case TGSI_SEMANTIC_BCOLOR: 68848b8605Smrg assert(index < ATTR_COLOR_COUNT); 69848b8605Smrg vs_outputs->bcolor[index] = i; 70848b8605Smrg break; 71848b8605Smrg 72848b8605Smrg case TGSI_SEMANTIC_GENERIC: 73848b8605Smrg assert(index < ATTR_GENERIC_COUNT); 74848b8605Smrg vs_outputs->generic[index] = i; 75848b8605Smrg vs_outputs->num_generic++; 76848b8605Smrg break; 77848b8605Smrg 78848b8605Smrg case TGSI_SEMANTIC_FOG: 79848b8605Smrg assert(index == 0); 80848b8605Smrg vs_outputs->fog = i; 81848b8605Smrg break; 82848b8605Smrg 83848b8605Smrg case TGSI_SEMANTIC_EDGEFLAG: 84848b8605Smrg assert(index == 0); 85848b8605Smrg fprintf(stderr, "r300 VP: cannot handle edgeflag output.\n"); 86848b8605Smrg break; 87848b8605Smrg 88848b8605Smrg case TGSI_SEMANTIC_CLIPVERTEX: 89848b8605Smrg assert(index == 0); 90848b8605Smrg /* Draw does clip vertex for us. */ 91848b8605Smrg if (r300->screen->caps.has_tcl) { 92848b8605Smrg fprintf(stderr, "r300 VP: cannot handle clip vertex output.\n"); 93848b8605Smrg } 94848b8605Smrg break; 95848b8605Smrg 96848b8605Smrg default: 97848b8605Smrg fprintf(stderr, "r300 VP: unknown vertex output semantic: %i.\n", 98848b8605Smrg info->output_semantic_name[i]); 99848b8605Smrg } 100848b8605Smrg } 101848b8605Smrg 102848b8605Smrg /* WPOS is a straight copy of POSITION and it's always emitted. */ 103848b8605Smrg vs_outputs->wpos = i; 104848b8605Smrg} 105848b8605Smrg 106848b8605Smrgstatic void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c) 107848b8605Smrg{ 108848b8605Smrg struct r300_vertex_shader * vs = c->UserData; 109848b8605Smrg struct r300_shader_semantics* outputs = &vs->outputs; 110848b8605Smrg struct tgsi_shader_info* info = &vs->info; 111848b8605Smrg int i, reg = 0; 112848b8605Smrg boolean any_bcolor_used = outputs->bcolor[0] != ATTR_UNUSED || 113848b8605Smrg outputs->bcolor[1] != ATTR_UNUSED; 114848b8605Smrg 115848b8605Smrg /* Fill in the input mapping */ 116848b8605Smrg for (i = 0; i < info->num_inputs; i++) 117848b8605Smrg c->code->inputs[i] = i; 118848b8605Smrg 119848b8605Smrg /* Position. */ 120848b8605Smrg if (outputs->pos != ATTR_UNUSED) { 121848b8605Smrg c->code->outputs[outputs->pos] = reg++; 122848b8605Smrg } else { 123848b8605Smrg assert(0); 124848b8605Smrg } 125848b8605Smrg 126848b8605Smrg /* Point size. */ 127848b8605Smrg if (outputs->psize != ATTR_UNUSED) { 128848b8605Smrg c->code->outputs[outputs->psize] = reg++; 129848b8605Smrg } 130848b8605Smrg 131848b8605Smrg /* If we're writing back facing colors we need to send 132848b8605Smrg * four colors to make front/back face colors selection work. 133848b8605Smrg * If the vertex program doesn't write all 4 colors, lets 134848b8605Smrg * pretend it does by skipping output index reg so the colors 135848b8605Smrg * get written into appropriate output vectors. 136848b8605Smrg */ 137848b8605Smrg 138848b8605Smrg /* Colors. */ 139848b8605Smrg for (i = 0; i < ATTR_COLOR_COUNT; i++) { 140848b8605Smrg if (outputs->color[i] != ATTR_UNUSED) { 141848b8605Smrg c->code->outputs[outputs->color[i]] = reg++; 142848b8605Smrg } else if (any_bcolor_used || 143848b8605Smrg outputs->color[1] != ATTR_UNUSED) { 144848b8605Smrg reg++; 145848b8605Smrg } 146848b8605Smrg } 147848b8605Smrg 148848b8605Smrg /* Back-face colors. */ 149848b8605Smrg for (i = 0; i < ATTR_COLOR_COUNT; i++) { 150848b8605Smrg if (outputs->bcolor[i] != ATTR_UNUSED) { 151848b8605Smrg c->code->outputs[outputs->bcolor[i]] = reg++; 152848b8605Smrg } else if (any_bcolor_used) { 153848b8605Smrg reg++; 154848b8605Smrg } 155848b8605Smrg } 156848b8605Smrg 157848b8605Smrg /* Texture coordinates. */ 158848b8605Smrg for (i = 0; i < ATTR_GENERIC_COUNT; i++) { 159848b8605Smrg if (outputs->generic[i] != ATTR_UNUSED) { 160848b8605Smrg c->code->outputs[outputs->generic[i]] = reg++; 161848b8605Smrg } 162848b8605Smrg } 163848b8605Smrg 164848b8605Smrg /* Fog coordinates. */ 165848b8605Smrg if (outputs->fog != ATTR_UNUSED) { 166848b8605Smrg c->code->outputs[outputs->fog] = reg++; 167848b8605Smrg } 168848b8605Smrg 169848b8605Smrg /* WPOS. */ 170848b8605Smrg c->code->outputs[outputs->wpos] = reg++; 171848b8605Smrg} 172848b8605Smrg 173848b8605Smrgvoid r300_init_vs_outputs(struct r300_context *r300, 174848b8605Smrg struct r300_vertex_shader *vs) 175848b8605Smrg{ 176848b8605Smrg tgsi_scan_shader(vs->state.tokens, &vs->info); 177848b8605Smrg r300_shader_read_vs_outputs(r300, &vs->info, &vs->outputs); 178848b8605Smrg} 179848b8605Smrg 180848b8605Smrgstatic void r300_dummy_vertex_shader( 181848b8605Smrg struct r300_context* r300, 182848b8605Smrg struct r300_vertex_shader* shader) 183848b8605Smrg{ 184848b8605Smrg struct ureg_program *ureg; 185848b8605Smrg struct ureg_dst dst; 186848b8605Smrg struct ureg_src imm; 187848b8605Smrg 188848b8605Smrg /* Make a simple vertex shader which outputs (0, 0, 0, 1), 189848b8605Smrg * effectively rendering nothing. */ 190b8e80941Smrg ureg = ureg_create(PIPE_SHADER_VERTEX); 191848b8605Smrg dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 192848b8605Smrg imm = ureg_imm4f(ureg, 0, 0, 0, 1); 193848b8605Smrg 194848b8605Smrg ureg_MOV(ureg, dst, imm); 195848b8605Smrg ureg_END(ureg); 196848b8605Smrg 197848b8605Smrg shader->state.tokens = tgsi_dup_tokens(ureg_finalize(ureg)); 198848b8605Smrg ureg_destroy(ureg); 199848b8605Smrg 200848b8605Smrg shader->dummy = TRUE; 201848b8605Smrg r300_init_vs_outputs(r300, shader); 202848b8605Smrg r300_translate_vertex_shader(r300, shader); 203848b8605Smrg} 204848b8605Smrg 205848b8605Smrgvoid r300_translate_vertex_shader(struct r300_context *r300, 206848b8605Smrg struct r300_vertex_shader *vs) 207848b8605Smrg{ 208848b8605Smrg struct r300_vertex_program_compiler compiler; 209848b8605Smrg struct tgsi_to_rc ttr; 210848b8605Smrg unsigned i; 211848b8605Smrg 212848b8605Smrg /* Setup the compiler */ 213848b8605Smrg memset(&compiler, 0, sizeof(compiler)); 214848b8605Smrg rc_init(&compiler.Base, NULL); 215848b8605Smrg 216848b8605Smrg DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0; 217848b8605Smrg DBG_ON(r300, DBG_P_STAT) ? compiler.Base.Debug |= RC_DBG_STATS : 0; 218848b8605Smrg compiler.code = &vs->code; 219848b8605Smrg compiler.UserData = vs; 220848b8605Smrg compiler.Base.is_r500 = r300->screen->caps.is_r500; 221848b8605Smrg compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT); 222848b8605Smrg compiler.Base.has_half_swizzles = FALSE; 223848b8605Smrg compiler.Base.has_presub = FALSE; 224848b8605Smrg compiler.Base.has_omod = FALSE; 225848b8605Smrg compiler.Base.max_temp_regs = 32; 226848b8605Smrg compiler.Base.max_constants = 256; 227848b8605Smrg compiler.Base.max_alu_insts = r300->screen->caps.is_r500 ? 1024 : 256; 228848b8605Smrg 229848b8605Smrg if (compiler.Base.Debug & RC_DBG_LOG) { 230848b8605Smrg DBG(r300, DBG_VP, "r300: Initial vertex program\n"); 231848b8605Smrg tgsi_dump(vs->state.tokens, 0); 232848b8605Smrg } 233848b8605Smrg 234848b8605Smrg /* Translate TGSI to our internal representation */ 235848b8605Smrg ttr.compiler = &compiler.Base; 236848b8605Smrg ttr.info = &vs->info; 237848b8605Smrg ttr.use_half_swizzles = FALSE; 238848b8605Smrg 239848b8605Smrg r300_tgsi_to_rc(&ttr, vs->state.tokens); 240848b8605Smrg 241848b8605Smrg if (ttr.error) { 242848b8605Smrg fprintf(stderr, "r300 VP: Cannot translate a shader. " 243848b8605Smrg "Using a dummy shader instead.\n"); 244848b8605Smrg r300_dummy_vertex_shader(r300, vs); 245848b8605Smrg return; 246848b8605Smrg } 247848b8605Smrg 248848b8605Smrg if (compiler.Base.Program.Constants.Count > 200) { 249848b8605Smrg compiler.Base.remove_unused_constants = TRUE; 250848b8605Smrg } 251848b8605Smrg 252848b8605Smrg compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1)); 253848b8605Smrg compiler.SetHwInputOutput = &set_vertex_inputs_outputs; 254848b8605Smrg 255848b8605Smrg /* Insert the WPOS output. */ 256848b8605Smrg rc_copy_output(&compiler.Base, 0, vs->outputs.wpos); 257848b8605Smrg 258848b8605Smrg /* Invoke the compiler */ 259848b8605Smrg r3xx_compile_vertex_program(&compiler); 260848b8605Smrg if (compiler.Base.Error) { 261848b8605Smrg fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader" 262848b8605Smrg " instead.\n", compiler.Base.ErrorMsg); 263848b8605Smrg 264848b8605Smrg if (vs->dummy) { 265848b8605Smrg fprintf(stderr, "r300 VP: Cannot compile the dummy shader! " 266848b8605Smrg "Giving up...\n"); 267848b8605Smrg abort(); 268848b8605Smrg } 269848b8605Smrg 270848b8605Smrg rc_destroy(&compiler.Base); 271848b8605Smrg r300_dummy_vertex_shader(r300, vs); 272848b8605Smrg return; 273848b8605Smrg } 274848b8605Smrg 275848b8605Smrg /* Initialize numbers of constants for each type. */ 276848b8605Smrg vs->externals_count = 0; 277848b8605Smrg for (i = 0; 278848b8605Smrg i < vs->code.constants.Count && 279848b8605Smrg vs->code.constants.Constants[i].Type == RC_CONSTANT_EXTERNAL; i++) { 280848b8605Smrg vs->externals_count = i+1; 281848b8605Smrg } 282848b8605Smrg for (; i < vs->code.constants.Count; i++) { 283848b8605Smrg assert(vs->code.constants.Constants[i].Type == RC_CONSTANT_IMMEDIATE); 284848b8605Smrg } 285848b8605Smrg vs->immediates_count = vs->code.constants.Count - vs->externals_count; 286848b8605Smrg 287848b8605Smrg /* And, finally... */ 288848b8605Smrg rc_destroy(&compiler.Base); 289848b8605Smrg} 290