r300_fs.c revision 80d89aa0d28ca987d958c1033eeb7e4a3c10368b
1/* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * Joakim Sindholt <opensource@zhasha.com> 4 * Copyright 2009 Marek Olšák <maraeo@gmail.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * on the rights to use, copy, modify, merge, publish, distribute, sub 10 * license, and/or sell copies of the Software, and to permit persons to whom 11 * the Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 23 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 24 25#include "util/u_math.h" 26#include "util/u_memory.h" 27 28#include "tgsi/tgsi_dump.h" 29#include "tgsi/tgsi_ureg.h" 30 31#include "r300_context.h" 32#include "r300_screen.h" 33#include "r300_fs.h" 34#include "r300_reg.h" 35#include "r300_tgsi_to_rc.h" 36 37#include "radeon_code.h" 38#include "radeon_compiler.h" 39 40/* Convert info about FS input semantics to r300_shader_semantics. */ 41void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, 42 struct r300_shader_semantics* fs_inputs) 43{ 44 int i; 45 unsigned index; 46 47 r300_shader_semantics_reset(fs_inputs); 48 49 for (i = 0; i < info->num_inputs; i++) { 50 index = info->input_semantic_index[i]; 51 52 switch (info->input_semantic_name[i]) { 53 case TGSI_SEMANTIC_COLOR: 54 assert(index < ATTR_COLOR_COUNT); 55 fs_inputs->color[index] = i; 56 break; 57 58 case TGSI_SEMANTIC_GENERIC: 59 assert(index < ATTR_GENERIC_COUNT); 60 fs_inputs->generic[index] = i; 61 break; 62 63 case TGSI_SEMANTIC_FOG: 64 assert(index == 0); 65 fs_inputs->fog = i; 66 break; 67 68 case TGSI_SEMANTIC_POSITION: 69 assert(index == 0); 70 fs_inputs->wpos = i; 71 break; 72 73 default: 74 fprintf(stderr, "r300: FP: Unknown input semantic: %i\n", 75 info->input_semantic_name[i]); 76 } 77 } 78} 79 80static void find_output_registers(struct r300_fragment_program_compiler * compiler, 81 struct r300_fragment_shader_code *shader) 82{ 83 unsigned i, colorbuf_count = 0; 84 85 /* Mark the outputs as not present initially */ 86 compiler->OutputColor[0] = shader->info.num_outputs; 87 compiler->OutputColor[1] = shader->info.num_outputs; 88 compiler->OutputColor[2] = shader->info.num_outputs; 89 compiler->OutputColor[3] = shader->info.num_outputs; 90 compiler->OutputDepth = shader->info.num_outputs; 91 92 /* Now see where they really are. */ 93 for(i = 0; i < shader->info.num_outputs; ++i) { 94 switch(shader->info.output_semantic_name[i]) { 95 case TGSI_SEMANTIC_COLOR: 96 compiler->OutputColor[colorbuf_count] = i; 97 colorbuf_count++; 98 break; 99 case TGSI_SEMANTIC_POSITION: 100 compiler->OutputDepth = i; 101 break; 102 } 103 } 104} 105 106static void allocate_hardware_inputs( 107 struct r300_fragment_program_compiler * c, 108 void (*allocate)(void * data, unsigned input, unsigned hwreg), 109 void * mydata) 110{ 111 struct r300_shader_semantics* inputs = 112 (struct r300_shader_semantics*)c->UserData; 113 int i, reg = 0; 114 115 /* Allocate input registers. */ 116 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 117 if (inputs->color[i] != ATTR_UNUSED) { 118 allocate(mydata, inputs->color[i], reg++); 119 } 120 } 121 for (i = 0; i < ATTR_GENERIC_COUNT; i++) { 122 if (inputs->generic[i] != ATTR_UNUSED) { 123 allocate(mydata, inputs->generic[i], reg++); 124 } 125 } 126 if (inputs->fog != ATTR_UNUSED) { 127 allocate(mydata, inputs->fog, reg++); 128 } 129 if (inputs->wpos != ATTR_UNUSED) { 130 allocate(mydata, inputs->wpos, reg++); 131 } 132} 133 134static void get_external_state( 135 struct r300_context* r300, 136 struct r300_fragment_program_external_state* state) 137{ 138 struct r300_textures_state *texstate = r300->textures_state.state; 139 unsigned i; 140 141 for (i = 0; i < texstate->sampler_state_count; i++) { 142 struct r300_sampler_state* s = texstate->sampler_states[i]; 143 144 if (!s) { 145 continue; 146 } 147 148 if (s->state.compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 149 /* XXX Gallium doesn't provide us with any information regarding 150 * this mode, so we are screwed. I'm setting 0 = LUMINANCE. */ 151 state->unit[i].depth_texture_mode = 0; 152 153 /* Fortunately, no need to translate this. */ 154 state->unit[i].texture_compare_func = s->state.compare_func; 155 } 156 157 state->unit[i].non_normalized_coords = !s->state.normalized_coords; 158 159 if (texstate->sampler_views[i]) { 160 struct r300_texture *t; 161 t = (struct r300_texture*)texstate->sampler_views[i]->base.texture; 162 163 /* XXX this should probably take into account STR, not just S. */ 164 if (t->uses_pitch) { 165 switch (s->state.wrap_s) { 166 case PIPE_TEX_WRAP_REPEAT: 167 state->unit[i].wrap_mode = RC_WRAP_REPEAT; 168 state->unit[i].fake_npot = TRUE; 169 break; 170 171 case PIPE_TEX_WRAP_MIRROR_REPEAT: 172 case PIPE_TEX_WRAP_MIRROR_CLAMP: 173 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 174 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 175 state->unit[i].wrap_mode = RC_WRAP_MIRROR; 176 state->unit[i].fake_npot = TRUE; 177 break; 178 179 default: 180 state->unit[i].wrap_mode = RC_WRAP_NONE; 181 break; 182 } 183 } 184 } 185 } 186} 187 188static void r300_translate_fragment_shader( 189 struct r300_context* r300, 190 struct r300_fragment_shader_code* shader, 191 const struct tgsi_token *tokens); 192 193static void r300_dummy_fragment_shader( 194 struct r300_context* r300, 195 struct r300_fragment_shader_code* shader) 196{ 197 struct pipe_shader_state state; 198 struct ureg_program *ureg; 199 struct ureg_dst out; 200 struct ureg_src imm; 201 202 /* Make a simple fragment shader which outputs (0, 0, 0, 1) */ 203 ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); 204 out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 205 imm = ureg_imm4f(ureg, 0, 0, 0, 1); 206 207 ureg_MOV(ureg, out, imm); 208 ureg_END(ureg); 209 210 state.tokens = ureg_finalize(ureg); 211 212 shader->dummy = TRUE; 213 r300_translate_fragment_shader(r300, shader, state.tokens); 214 215 ureg_destroy(ureg); 216} 217 218static void r300_translate_fragment_shader( 219 struct r300_context* r300, 220 struct r300_fragment_shader_code* shader, 221 const struct tgsi_token *tokens) 222{ 223 struct r300_fragment_program_compiler compiler; 224 struct tgsi_to_rc ttr; 225 int wpos; 226 unsigned i; 227 228 tgsi_scan_shader(tokens, &shader->info); 229 r300_shader_read_fs_inputs(&shader->info, &shader->inputs); 230 231 wpos = shader->inputs.wpos; 232 233 /* Setup the compiler. */ 234 memset(&compiler, 0, sizeof(compiler)); 235 rc_init(&compiler.Base); 236 compiler.Base.Debug = DBG_ON(r300, DBG_FP); 237 238 compiler.code = &shader->code; 239 compiler.state = shader->compare_state; 240 compiler.is_r500 = r300->screen->caps.is_r500; 241 compiler.max_temp_regs = compiler.is_r500 ? 128 : 32; 242 compiler.AllocateHwInputs = &allocate_hardware_inputs; 243 compiler.UserData = &shader->inputs; 244 245 find_output_registers(&compiler, shader); 246 247 if (compiler.Base.Debug) { 248 debug_printf("r300: Initial fragment program\n"); 249 tgsi_dump(tokens, 0); 250 } 251 252 /* Translate TGSI to our internal representation */ 253 ttr.compiler = &compiler.Base; 254 ttr.info = &shader->info; 255 ttr.use_half_swizzles = TRUE; 256 257 r300_tgsi_to_rc(&ttr, tokens); 258 259 /** 260 * Transform the program to support WPOS. 261 * 262 * Introduce a small fragment at the start of the program that will be 263 * the only code that directly reads the WPOS input. 264 * All other code pieces that reference that input will be rewritten 265 * to read from a newly allocated temporary. */ 266 if (wpos != ATTR_UNUSED) { 267 /* Moving the input to some other reg is not really necessary. */ 268 rc_transform_fragment_wpos(&compiler.Base, wpos, wpos, TRUE); 269 } 270 271 /* Invoke the compiler */ 272 r3xx_compile_fragment_program(&compiler); 273 274 if (compiler.Base.Error) { 275 fprintf(stderr, "r300 FP: Compiler Error:\n%sUsing a dummy shader" 276 " instead.\n", compiler.Base.ErrorMsg); 277 278 if (shader->dummy) { 279 fprintf(stderr, "r300 FP: Cannot compile the dummy shader! " 280 "Giving up...\n"); 281 abort(); 282 } 283 284 rc_destroy(&compiler.Base); 285 r300_dummy_fragment_shader(r300, shader); 286 return; 287 } 288 289 /* Initialize numbers of constants for each type. */ 290 shader->externals_count = ttr.immediate_offset; 291 shader->immediates_count = 0; 292 shader->rc_state_count = 0; 293 294 for (i = shader->externals_count; i < shader->code.constants.Count; i++) { 295 switch (shader->code.constants.Constants[i].Type) { 296 case RC_CONSTANT_IMMEDIATE: 297 ++shader->immediates_count; 298 break; 299 case RC_CONSTANT_STATE: 300 ++shader->rc_state_count; 301 break; 302 default: 303 assert(0); 304 } 305 } 306 307 /* Setup shader depth output. */ 308 if (shader->code.writes_depth) { 309 shader->fg_depth_src = R300_FG_DEPTH_SRC_SHADER; 310 shader->us_out_w = R300_W_FMT_W24 | R300_W_SRC_US; 311 } else { 312 shader->fg_depth_src = R300_FG_DEPTH_SRC_SCAN; 313 shader->us_out_w = R300_W_FMT_W0 | R300_W_SRC_US; 314 } 315 316 /* And, finally... */ 317 rc_destroy(&compiler.Base); 318} 319 320boolean r300_pick_fragment_shader(struct r300_context* r300) 321{ 322 struct r300_fragment_shader* fs = r300_fs(r300); 323 struct r300_fragment_program_external_state state = {{{ 0 }}}; 324 struct r300_fragment_shader_code* ptr; 325 326 get_external_state(r300, &state); 327 328 if (!fs->first) { 329 /* Build the fragment shader for the first time. */ 330 fs->first = fs->shader = CALLOC_STRUCT(r300_fragment_shader_code); 331 332 memcpy(&fs->shader->compare_state, &state, 333 sizeof(struct r300_fragment_program_external_state)); 334 r300_translate_fragment_shader(r300, fs->shader, fs->state.tokens); 335 return TRUE; 336 337 } else { 338 /* Check if the currently-bound shader has been compiled 339 * with the texture-compare state we need. */ 340 if (memcmp(&fs->shader->compare_state, &state, sizeof(state)) != 0) { 341 /* Search for the right shader. */ 342 ptr = fs->first; 343 while (ptr) { 344 if (memcmp(&ptr->compare_state, &state, sizeof(state)) == 0) { 345 if (fs->shader != ptr) { 346 fs->shader = ptr; 347 return TRUE; 348 } 349 /* The currently-bound one is OK. */ 350 return FALSE; 351 } 352 ptr = ptr->next; 353 } 354 355 /* Not found, gotta compile a new one. */ 356 ptr = CALLOC_STRUCT(r300_fragment_shader_code); 357 ptr->next = fs->first; 358 fs->first = fs->shader = ptr; 359 360 ptr->compare_state = state; 361 r300_translate_fragment_shader(r300, ptr, fs->state.tokens); 362 return TRUE; 363 } 364 } 365 366 return FALSE; 367} 368