r300_fs.c revision 6a448a525baf81173f92ee8c3074b98baa54397b
1/* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * Joakim Sindholt <opensource@zhasha.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 24#include "tgsi/tgsi_dump.h" 25 26#include "r300_context.h" 27#include "r300_screen.h" 28#include "r300_fs.h" 29#include "r300_tgsi_to_rc.h" 30 31#include "radeon_code.h" 32#include "radeon_compiler.h" 33 34static void find_output_registers(struct r300_fragment_program_compiler * compiler, 35 struct r300_fragment_shader * fs) 36{ 37 unsigned i; 38 39 /* Mark the outputs as not present initially */ 40 compiler->OutputColor = fs->info.num_outputs; 41 compiler->OutputDepth = fs->info.num_outputs; 42 43 /* Now see where they really are. */ 44 for(i = 0; i < fs->info.num_outputs; ++i) { 45 switch(fs->info.output_semantic_name[i]) { 46 case TGSI_SEMANTIC_COLOR: 47 compiler->OutputColor = i; 48 break; 49 case TGSI_SEMANTIC_POSITION: 50 compiler->OutputDepth = i; 51 break; 52 } 53 } 54} 55 56static void allocate_hardware_inputs( 57 struct r300_fragment_program_compiler * c, 58 void (*allocate)(void * data, unsigned input, unsigned hwreg), 59 void * mydata) 60{ 61 struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info; 62 int total_colors = 0; 63 int colors = 0; 64 int total_generic = 0; 65 int generic = 0; 66 int i; 67 68 for (i = 0; i < info->num_inputs; i++) { 69 switch (info->input_semantic_name[i]) { 70 case TGSI_SEMANTIC_COLOR: 71 total_colors++; 72 break; 73 case TGSI_SEMANTIC_FOG: 74 case TGSI_SEMANTIC_GENERIC: 75 total_generic++; 76 break; 77 } 78 } 79 80 for(i = 0; i < info->num_inputs; i++) { 81 switch (info->input_semantic_name[i]) { 82 case TGSI_SEMANTIC_COLOR: 83 allocate(mydata, i, colors); 84 colors++; 85 break; 86 case TGSI_SEMANTIC_FOG: 87 case TGSI_SEMANTIC_GENERIC: 88 allocate(mydata, i, total_colors + generic); 89 generic++; 90 break; 91 } 92 } 93} 94 95void r300_translate_fragment_shader(struct r300_context* r300, 96 struct r300_fragment_shader* fs) 97{ 98 struct r300_fragment_program_compiler compiler; 99 struct tgsi_to_rc ttr; 100 101 memset(&compiler, 0, sizeof(compiler)); 102 rc_init(&compiler.Base); 103 compiler.Base.Debug = DBG_ON(r300, DBG_FP); 104 105 compiler.code = &fs->code; 106 compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500; 107 compiler.AllocateHwInputs = &allocate_hardware_inputs; 108 compiler.UserData = fs; 109 110 /* TODO: Program compilation depends on texture compare modes, 111 * which are sampler state. Therefore, programs need to be recompiled 112 * depending on this state as in the classic Mesa driver. 113 * 114 * This is not yet handled correctly. 115 */ 116 117 find_output_registers(&compiler, fs); 118 119 if (compiler.Base.Debug) { 120 debug_printf("r300: Initial fragment program\n"); 121 tgsi_dump(fs->state.tokens, 0); 122 } 123 124 /* Translate TGSI to our internal representation */ 125 ttr.compiler = &compiler.Base; 126 ttr.info = &fs->info; 127 128 r300_tgsi_to_rc(&ttr, fs->state.tokens); 129 130 /* Invoke the compiler */ 131 r3xx_compile_fragment_program(&compiler); 132 if (compiler.Base.Error) { 133 /* Todo: Fallback to software rendering gracefully? */ 134 fprintf(stderr, "r300 FP: Compiler error: %s\n", compiler.Base.ErrorMsg); 135 136 if (compiler.is_r500) { 137 memcpy(compiler.code, &r5xx_passthrough_fragment_shader, sizeof(r5xx_passthrough_fragment_shader)); 138 } else { 139 memcpy(compiler.code, &r3xx_passthrough_fragment_shader, sizeof(r3xx_passthrough_fragment_shader)); 140 } 141 } 142 143 /* And, finally... */ 144 rc_destroy(&compiler.Base); 145 fs->translated = TRUE; 146} 147