r300_state_derived.c revision 3332229b3ba7a183a9f120ae4bbf9865e96df110
1/* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * Copyright 2009 Marek Olšák <maraeo@gmail.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 "draw/draw_context.h" 25 26#include "util/u_math.h" 27#include "util/u_memory.h" 28#include "util/u_pack_color.h" 29 30#include "r300_context.h" 31#include "r300_fs.h" 32#include "r300_hyperz.h" 33#include "r300_screen.h" 34#include "r300_shader_semantics.h" 35#include "r300_state_inlines.h" 36#include "r300_texture.h" 37#include "r300_vs.h" 38 39/* r300_state_derived: Various bits of state which are dependent upon 40 * currently bound CSO data. */ 41 42enum r300_rs_swizzle { 43 SWIZ_XYZW = 0, 44 SWIZ_X001, 45 SWIZ_XY01, 46 SWIZ_0001, 47}; 48 49enum r300_rs_col_write_type { 50 WRITE_COLOR = 0, 51 WRITE_FACE 52}; 53 54static void r300_draw_emit_attrib(struct r300_context* r300, 55 enum attrib_emit emit, 56 enum interp_mode interp, 57 int index) 58{ 59 struct r300_vertex_shader* vs = r300->vs_state.state; 60 struct tgsi_shader_info* info = &vs->info; 61 int output; 62 63 output = draw_find_shader_output(r300->draw, 64 info->output_semantic_name[index], 65 info->output_semantic_index[index]); 66 draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output); 67} 68 69static void r300_draw_emit_all_attribs(struct r300_context* r300) 70{ 71 struct r300_vertex_shader* vs = r300->vs_state.state; 72 struct r300_shader_semantics* vs_outputs = &vs->outputs; 73 int i, gen_count; 74 75 /* Position. */ 76 if (vs_outputs->pos != ATTR_UNUSED) { 77 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, 78 vs_outputs->pos); 79 } else { 80 assert(0); 81 } 82 83 /* Point size. */ 84 if (vs_outputs->psize != ATTR_UNUSED) { 85 r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS, 86 vs_outputs->psize); 87 } 88 89 /* Colors. */ 90 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 91 if (vs_outputs->color[i] != ATTR_UNUSED) { 92 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR, 93 vs_outputs->color[i]); 94 } 95 } 96 97 /* Back-face colors. */ 98 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 99 if (vs_outputs->bcolor[i] != ATTR_UNUSED) { 100 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR, 101 vs_outputs->bcolor[i]); 102 } 103 } 104 105 /* Texture coordinates. */ 106 /* Only 8 generic vertex attributes can be used. If there are more, 107 * they won't be rasterized. */ 108 gen_count = 0; 109 for (i = 0; i < ATTR_GENERIC_COUNT && gen_count < 8; i++) { 110 if (vs_outputs->generic[i] != ATTR_UNUSED && 111 !(r300->sprite_coord_enable & (1 << i))) { 112 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, 113 vs_outputs->generic[i]); 114 gen_count++; 115 } 116 } 117 118 /* Fog coordinates. */ 119 if (gen_count < 8 && vs_outputs->fog != ATTR_UNUSED) { 120 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, 121 vs_outputs->fog); 122 gen_count++; 123 } 124 125 /* WPOS. */ 126 if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED && gen_count < 8) { 127 DBG(r300, DBG_SWTCL, "draw_emit_attrib: WPOS, index: %i\n", 128 vs_outputs->wpos); 129 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, 130 vs_outputs->wpos); 131 } 132} 133 134/* Update the PSC tables for SW TCL, using Draw. */ 135static void r300_swtcl_vertex_psc(struct r300_context *r300) 136{ 137 struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state; 138 struct vertex_info *vinfo = &r300->vertex_info; 139 uint16_t type, swizzle; 140 enum pipe_format format; 141 unsigned i, attrib_count; 142 int* vs_output_tab = r300->stream_loc_notcl; 143 144 memset(vstream, 0, sizeof(struct r300_vertex_stream_state)); 145 146 /* For each Draw attribute, route it to the fragment shader according 147 * to the vs_output_tab. */ 148 attrib_count = vinfo->num_attribs; 149 DBG(r300, DBG_SWTCL, "r300: attrib count: %d\n", attrib_count); 150 for (i = 0; i < attrib_count; i++) { 151 if (vs_output_tab[i] == -1) { 152 assert(0); 153 abort(); 154 } 155 156 format = draw_translate_vinfo_format(vinfo->attrib[i].emit); 157 158 DBG(r300, DBG_SWTCL, 159 "r300: swtcl_vertex_psc [%i] <- %s\n", 160 vs_output_tab[i], util_format_short_name(format)); 161 162 /* Obtain the type of data in this attribute. */ 163 type = r300_translate_vertex_data_type(format); 164 if (type == R300_INVALID_FORMAT) { 165 fprintf(stderr, "r300: Bad vertex format %s.\n", 166 util_format_short_name(format)); 167 assert(0); 168 abort(); 169 } 170 171 type |= vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT; 172 173 /* Obtain the swizzle for this attribute. Note that the default 174 * swizzle in the hardware is not XYZW! */ 175 swizzle = r300_translate_vertex_data_swizzle(format); 176 177 /* Add the attribute to the PSC table. */ 178 if (i & 1) { 179 vstream->vap_prog_stream_cntl[i >> 1] |= type << 16; 180 vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; 181 } else { 182 vstream->vap_prog_stream_cntl[i >> 1] |= type; 183 vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; 184 } 185 } 186 187 /* Set the last vector in the PSC. */ 188 if (i) { 189 i -= 1; 190 } 191 vstream->vap_prog_stream_cntl[i >> 1] |= 192 (R300_LAST_VEC << (i & 1 ? 16 : 0)); 193 194 vstream->count = (i >> 1) + 1; 195 r300_mark_atom_dirty(r300, &r300->vertex_stream_state); 196 r300->vertex_stream_state.size = (1 + vstream->count) * 2; 197} 198 199static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, 200 enum r300_rs_swizzle swiz) 201{ 202 rs->ip[id] |= R300_RS_COL_PTR(ptr); 203 if (swiz == SWIZ_0001) { 204 rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001); 205 } else { 206 rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA); 207 } 208 rs->inst[id] |= R300_RS_INST_COL_ID(id); 209} 210 211static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset, 212 enum r300_rs_col_write_type type) 213{ 214 assert(type == WRITE_COLOR); 215 rs->inst[id] |= R300_RS_INST_COL_CN_WRITE | 216 R300_RS_INST_COL_ADDR(fp_offset); 217} 218 219static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr, 220 enum r300_rs_swizzle swiz) 221{ 222 if (swiz == SWIZ_X001) { 223 rs->ip[id] |= R300_RS_TEX_PTR(ptr) | 224 R300_RS_SEL_S(R300_RS_SEL_C0) | 225 R300_RS_SEL_T(R300_RS_SEL_K0) | 226 R300_RS_SEL_R(R300_RS_SEL_K0) | 227 R300_RS_SEL_Q(R300_RS_SEL_K1); 228 } else if (swiz == SWIZ_XY01) { 229 rs->ip[id] |= R300_RS_TEX_PTR(ptr) | 230 R300_RS_SEL_S(R300_RS_SEL_C0) | 231 R300_RS_SEL_T(R300_RS_SEL_C1) | 232 R300_RS_SEL_R(R300_RS_SEL_K0) | 233 R300_RS_SEL_Q(R300_RS_SEL_K1); 234 } else { 235 rs->ip[id] |= R300_RS_TEX_PTR(ptr) | 236 R300_RS_SEL_S(R300_RS_SEL_C0) | 237 R300_RS_SEL_T(R300_RS_SEL_C1) | 238 R300_RS_SEL_R(R300_RS_SEL_C2) | 239 R300_RS_SEL_Q(R300_RS_SEL_C3); 240 } 241 rs->inst[id] |= R300_RS_INST_TEX_ID(id); 242} 243 244static void r300_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset) 245{ 246 rs->inst[id] |= R300_RS_INST_TEX_CN_WRITE | 247 R300_RS_INST_TEX_ADDR(fp_offset); 248} 249 250static void r500_rs_col(struct r300_rs_block* rs, int id, int ptr, 251 enum r300_rs_swizzle swiz) 252{ 253 rs->ip[id] |= R500_RS_COL_PTR(ptr); 254 if (swiz == SWIZ_0001) { 255 rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); 256 } else { 257 rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA); 258 } 259 rs->inst[id] |= R500_RS_INST_COL_ID(id); 260} 261 262static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset, 263 enum r300_rs_col_write_type type) 264{ 265 if (type == WRITE_FACE) 266 rs->inst[id] |= R500_RS_INST_COL_CN_WRITE_BACKFACE | 267 R500_RS_INST_COL_ADDR(fp_offset); 268 else 269 rs->inst[id] |= R500_RS_INST_COL_CN_WRITE | 270 R500_RS_INST_COL_ADDR(fp_offset); 271 272} 273 274static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr, 275 enum r300_rs_swizzle swiz) 276{ 277 if (swiz == SWIZ_X001) { 278 rs->ip[id] |= R500_RS_SEL_S(ptr) | 279 R500_RS_SEL_T(R500_RS_IP_PTR_K0) | 280 R500_RS_SEL_R(R500_RS_IP_PTR_K0) | 281 R500_RS_SEL_Q(R500_RS_IP_PTR_K1); 282 } else if (swiz == SWIZ_XY01) { 283 rs->ip[id] |= R500_RS_SEL_S(ptr) | 284 R500_RS_SEL_T(ptr + 1) | 285 R500_RS_SEL_R(R500_RS_IP_PTR_K0) | 286 R500_RS_SEL_Q(R500_RS_IP_PTR_K1); 287 } else { 288 rs->ip[id] |= R500_RS_SEL_S(ptr) | 289 R500_RS_SEL_T(ptr + 1) | 290 R500_RS_SEL_R(ptr + 2) | 291 R500_RS_SEL_Q(ptr + 3); 292 } 293 rs->inst[id] |= R500_RS_INST_TEX_ID(id); 294} 295 296static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset) 297{ 298 rs->inst[id] |= R500_RS_INST_TEX_CN_WRITE | 299 R500_RS_INST_TEX_ADDR(fp_offset); 300} 301 302/* Set up the RS block. 303 * 304 * This is the part of the chipset that is responsible for linking vertex 305 * and fragment shaders and stuffed texture coordinates. 306 * 307 * The rasterizer reads data from VAP, which produces vertex shader outputs, 308 * and GA, which produces stuffed texture coordinates. VAP outputs have 309 * precedence over GA. All outputs must be rasterized otherwise it locks up. 310 * If there are more outputs rasterized than is set in VAP/GA, it locks up 311 * too. The funky part is that this info has been pretty much obtained by trial 312 * and error. */ 313static void r300_update_rs_block(struct r300_context *r300) 314{ 315 struct r300_vertex_shader *vs = r300->vs_state.state; 316 struct r300_shader_semantics *vs_outputs = &vs->outputs; 317 struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs; 318 struct r300_rs_block rs = {0}; 319 int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0, tex_ptr = 0; 320 void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); 321 void (*rX00_rs_col_write)(struct r300_rs_block*, int, int, enum r300_rs_col_write_type); 322 void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); 323 void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int); 324 boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || 325 vs_outputs->bcolor[1] != ATTR_UNUSED; 326 int *stream_loc_notcl = r300->stream_loc_notcl; 327 uint32_t stuffing_enable = 0; 328 329 if (r300->screen->caps.is_r500) { 330 rX00_rs_col = r500_rs_col; 331 rX00_rs_col_write = r500_rs_col_write; 332 rX00_rs_tex = r500_rs_tex; 333 rX00_rs_tex_write = r500_rs_tex_write; 334 } else { 335 rX00_rs_col = r300_rs_col; 336 rX00_rs_col_write = r300_rs_col_write; 337 rX00_rs_tex = r300_rs_tex; 338 rX00_rs_tex_write = r300_rs_tex_write; 339 } 340 341 /* 0x5555 copied from classic, which means: 342 * Select user color 0 for COLOR0 up to COLOR7. 343 * What the hell does that mean? */ 344 rs.vap_vtx_state_cntl = 0x5555; 345 346 /* The position is always present in VAP. */ 347 rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS; 348 rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; 349 stream_loc_notcl[loc++] = 0; 350 351 /* Set up the point size in VAP. */ 352 if (vs_outputs->psize != ATTR_UNUSED) { 353 rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; 354 stream_loc_notcl[loc++] = 1; 355 } 356 357 /* Set up and rasterize colors. */ 358 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 359 if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || 360 vs_outputs->color[1] != ATTR_UNUSED) { 361 /* Set up the color in VAP. */ 362 rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; 363 rs.vap_out_vtx_fmt[0] |= 364 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; 365 stream_loc_notcl[loc++] = 2 + i; 366 367 /* Rasterize it. */ 368 rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW); 369 370 /* Write it to the FS input register if it's needed by the FS. */ 371 if (fs_inputs->color[i] != ATTR_UNUSED) { 372 rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR); 373 fp_offset++; 374 375 DBG(r300, DBG_RS, 376 "r300: Rasterized color %i written to FS.\n", i); 377 } else { 378 DBG(r300, DBG_RS, "r300: Rasterized color %i unused.\n", i); 379 } 380 col_count++; 381 } else { 382 /* Skip the FS input register, leave it uninitialized. */ 383 /* If we try to set it to (0,0,0,1), it will lock up. */ 384 if (fs_inputs->color[i] != ATTR_UNUSED) { 385 fp_offset++; 386 387 DBG(r300, DBG_RS, "r300: FS input color %i unassigned%s.\n", 388 i); 389 } 390 } 391 } 392 393 /* Set up back-face colors. The rasterizer will do the color selection 394 * automatically. */ 395 if (any_bcolor_used) { 396 if (r300->two_sided_color) { 397 /* Rasterize as back-face colors. */ 398 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 399 rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; 400 rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); 401 stream_loc_notcl[loc++] = 4 + i; 402 } 403 } else { 404 /* Rasterize two fake texcoords to prevent from the two-sided color 405 * selection. */ 406 /* XXX Consider recompiling the vertex shader to save 2 RS units. */ 407 for (i = 0; i < 2; i++) { 408 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 409 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 410 stream_loc_notcl[loc++] = 6 + tex_count; 411 412 /* Rasterize it. */ 413 rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW); 414 tex_count++; 415 tex_ptr += 4; 416 } 417 } 418 } 419 420 /* gl_FrontFacing. 421 * Note that we can use either the two-sided color selection based on 422 * the front and back vertex shader colors, or gl_FrontFacing, 423 * but not both! It locks up otherwise. 424 * 425 * In Direct3D 9, the two-sided color selection can be used 426 * with shaders 2.0 only, while gl_FrontFacing can be used 427 * with shaders 3.0 only. The hardware apparently hasn't been designed 428 * to support both at the same time. */ 429 if (r300->screen->caps.is_r500 && fs_inputs->face != ATTR_UNUSED && 430 !(any_bcolor_used && r300->two_sided_color)) { 431 rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW); 432 rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_FACE); 433 fp_offset++; 434 col_count++; 435 DBG(r300, DBG_RS, "r300: Rasterized FACE written to FS.\n"); 436 } else if (fs_inputs->face != ATTR_UNUSED) { 437 fprintf(stderr, "r300: ERROR: FS input FACE unassigned.\n"); 438 } 439 440 /* Rasterize texture coordinates. */ 441 for (i = 0; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) { 442 bool sprite_coord = false; 443 444 if (fs_inputs->generic[i] != ATTR_UNUSED) { 445 sprite_coord = !!(r300->sprite_coord_enable & (1 << i)); 446 } 447 448 if (vs_outputs->generic[i] != ATTR_UNUSED || sprite_coord) { 449 if (!sprite_coord) { 450 /* Set up the texture coordinates in VAP. */ 451 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 452 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 453 stream_loc_notcl[loc++] = 6 + tex_count; 454 } else 455 stuffing_enable |= 456 R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (tex_count*2)); 457 458 /* Rasterize it. */ 459 rX00_rs_tex(&rs, tex_count, tex_ptr, 460 sprite_coord ? SWIZ_XY01 : SWIZ_XYZW); 461 462 /* Write it to the FS input register if it's needed by the FS. */ 463 if (fs_inputs->generic[i] != ATTR_UNUSED) { 464 rX00_rs_tex_write(&rs, tex_count, fp_offset); 465 fp_offset++; 466 467 DBG(r300, DBG_RS, 468 "r300: Rasterized generic %i written to FS%s in texcoord %d.\n", 469 i, sprite_coord ? " (sprite coord)" : "", tex_count); 470 } else { 471 DBG(r300, DBG_RS, 472 "r300: Rasterized generic %i unused%s.\n", 473 i, sprite_coord ? " (sprite coord)" : ""); 474 } 475 tex_count++; 476 tex_ptr += sprite_coord ? 2 : 4; 477 } else { 478 /* Skip the FS input register, leave it uninitialized. */ 479 /* If we try to set it to (0,0,0,1), it will lock up. */ 480 if (fs_inputs->generic[i] != ATTR_UNUSED) { 481 fp_offset++; 482 483 DBG(r300, DBG_RS, "r300: FS input generic %i unassigned%s.\n", 484 i, sprite_coord ? " (sprite coord)" : ""); 485 } 486 } 487 } 488 489 for (; i < ATTR_GENERIC_COUNT; i++) { 490 if (fs_inputs->generic[i] != ATTR_UNUSED) { 491 fprintf(stderr, "r300: ERROR: FS input generic %i unassigned, " 492 "not enough hardware slots.\n", i); 493 } 494 } 495 496 /* Rasterize fog coordinates. */ 497 if (vs_outputs->fog != ATTR_UNUSED && tex_count < 8) { 498 /* Set up the fog coordinates in VAP. */ 499 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 500 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 501 stream_loc_notcl[loc++] = 6 + tex_count; 502 503 /* Rasterize it. */ 504 rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_X001); 505 506 /* Write it to the FS input register if it's needed by the FS. */ 507 if (fs_inputs->fog != ATTR_UNUSED) { 508 rX00_rs_tex_write(&rs, tex_count, fp_offset); 509 fp_offset++; 510 511 DBG(r300, DBG_RS, "r300: Rasterized fog written to FS.\n"); 512 } else { 513 DBG(r300, DBG_RS, "r300: Rasterized fog unused.\n"); 514 } 515 tex_count++; 516 tex_ptr += 4; 517 } else { 518 /* Skip the FS input register, leave it uninitialized. */ 519 /* If we try to set it to (0,0,0,1), it will lock up. */ 520 if (fs_inputs->fog != ATTR_UNUSED) { 521 fp_offset++; 522 523 if (tex_count < 8) { 524 DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n"); 525 } else { 526 fprintf(stderr, "r300: ERROR: FS input fog unassigned, " 527 "not enough hardware slots.\n"); 528 } 529 } 530 } 531 532 /* Rasterize WPOS. */ 533 /* Don't set it in VAP if the FS doesn't need it. */ 534 if (fs_inputs->wpos != ATTR_UNUSED && tex_count < 8) { 535 /* Set up the WPOS coordinates in VAP. */ 536 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 537 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 538 stream_loc_notcl[loc++] = 6 + tex_count; 539 540 /* Rasterize it. */ 541 rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW); 542 543 /* Write it to the FS input register. */ 544 rX00_rs_tex_write(&rs, tex_count, fp_offset); 545 546 DBG(r300, DBG_RS, "r300: Rasterized WPOS written to FS.\n"); 547 548 fp_offset++; 549 tex_count++; 550 tex_ptr += 4; 551 } else { 552 if (fs_inputs->wpos != ATTR_UNUSED && tex_count >= 8) { 553 fprintf(stderr, "r300: ERROR: FS input WPOS unassigned, " 554 "not enough hardware slots.\n"); 555 } 556 } 557 558 /* Invalidate the rest of the no-TCL (GA) stream locations. */ 559 for (; loc < 16;) { 560 stream_loc_notcl[loc++] = -1; 561 } 562 563 /* Rasterize at least one color, or bad things happen. */ 564 if (col_count == 0 && tex_count == 0) { 565 rX00_rs_col(&rs, 0, 0, SWIZ_0001); 566 col_count++; 567 568 DBG(r300, DBG_RS, "r300: Rasterized color 0 to prevent lockups.\n"); 569 } 570 571 DBG(r300, DBG_RS, "r300: --- Rasterizer status ---: colors: %i, " 572 "generics: %i.\n", col_count, tex_count); 573 574 rs.count = MIN2(tex_ptr, 32) | (col_count << R300_IC_COUNT_SHIFT) | 575 R300_HIRES_EN; 576 577 count = MAX3(col_count, tex_count, 1); 578 rs.inst_count = count - 1; 579 580 /* set the GB enable flags */ 581 if (r300->sprite_coord_enable) 582 stuffing_enable |= R300_GB_POINT_STUFF_ENABLE; 583 584 rs.gb_enable = stuffing_enable; 585 586 /* Now, after all that, see if we actually need to update the state. */ 587 if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) { 588 memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block)); 589 r300->rs_block_state.size = 13 + count*2; 590 } 591} 592 593static uint32_t r300_get_border_color(enum pipe_format format, 594 const float border[4], 595 boolean is_r500) 596{ 597 const struct util_format_description *desc; 598 float border_swizzled[4] = {0}; 599 unsigned i; 600 union util_color uc = {0}; 601 602 desc = util_format_description(format); 603 604 /* Do depth formats first. */ 605 if (util_format_is_depth_or_stencil(format)) { 606 switch (format) { 607 case PIPE_FORMAT_Z16_UNORM: 608 return util_pack_z(PIPE_FORMAT_Z16_UNORM, border[0]); 609 case PIPE_FORMAT_X8Z24_UNORM: 610 case PIPE_FORMAT_S8_USCALED_Z24_UNORM: 611 if (is_r500) { 612 return util_pack_z(PIPE_FORMAT_X8Z24_UNORM, border[0]); 613 } else { 614 return util_pack_z(PIPE_FORMAT_Z16_UNORM, border[0]) << 16; 615 } 616 default: 617 assert(0); 618 return 0; 619 } 620 } 621 622 /* Apply inverse swizzle of the format. */ 623 for (i = 0; i < 4; i++) { 624 switch (desc->swizzle[i]) { 625 case UTIL_FORMAT_SWIZZLE_X: 626 border_swizzled[2] = border[i]; 627 break; 628 case UTIL_FORMAT_SWIZZLE_Y: 629 border_swizzled[1] = border[i]; 630 break; 631 case UTIL_FORMAT_SWIZZLE_Z: 632 border_swizzled[0] = border[i]; 633 break; 634 case UTIL_FORMAT_SWIZZLE_W: 635 border_swizzled[3] = border[i]; 636 break; 637 } 638 } 639 640 /* Compressed formats. */ 641 if (util_format_is_compressed(format)) { 642 util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc); 643 return uc.ui; 644 } 645 646 switch (desc->channel[0].size) { 647 case 2: 648 util_pack_color(border_swizzled, PIPE_FORMAT_B2G3R3_UNORM, &uc); 649 break; 650 651 case 4: 652 util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc); 653 break; 654 655 case 5: 656 if (desc->channel[1].size == 5) { 657 util_pack_color(border_swizzled, PIPE_FORMAT_B5G5R5A1_UNORM, &uc); 658 } else if (desc->channel[1].size == 6) { 659 util_pack_color(border_swizzled, PIPE_FORMAT_B5G6R5_UNORM, &uc); 660 } else { 661 assert(0); 662 } 663 break; 664 665 default: 666 case 8: 667 util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); 668 break; 669 670 case 10: 671 util_pack_color(border_swizzled, PIPE_FORMAT_B10G10R10A2_UNORM, &uc); 672 break; 673 674 case 16: 675 if (desc->nr_channels <= 2) { 676 border_swizzled[0] = border_swizzled[2]; 677 util_pack_color(border_swizzled, PIPE_FORMAT_R16G16_UNORM, &uc); 678 } else { 679 util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); 680 } 681 break; 682 } 683 684 return uc.ui; 685} 686 687static void r300_merge_textures_and_samplers(struct r300_context* r300) 688{ 689 struct r300_textures_state *state = 690 (struct r300_textures_state*)r300->textures_state.state; 691 struct r300_texture_sampler_state *texstate; 692 struct r300_sampler_state *sampler; 693 struct r300_sampler_view *view; 694 struct r300_texture *tex; 695 unsigned min_level, max_level, i, j, size; 696 unsigned count = MIN2(state->sampler_view_count, 697 state->sampler_state_count); 698 699 /* The KIL opcode fix, see below. */ 700 if (!count && !r300->screen->caps.is_r500) 701 count = 1; 702 703 state->tx_enable = 0; 704 state->count = 0; 705 size = 2; 706 707 for (i = 0; i < count; i++) { 708 if (state->sampler_views[i] && state->sampler_states[i]) { 709 state->tx_enable |= 1 << i; 710 711 view = state->sampler_views[i]; 712 tex = r300_texture(view->base.texture); 713 sampler = state->sampler_states[i]; 714 715 texstate = &state->regs[i]; 716 texstate->format = view->format; 717 texstate->filter0 = sampler->filter0; 718 texstate->filter1 = sampler->filter1; 719 720 /* Set the border color. */ 721 texstate->border_color = 722 r300_get_border_color(view->base.format, 723 sampler->state.border_color, 724 r300->screen->caps.is_r500); 725 726 /* determine min/max levels */ 727 max_level = MIN3(sampler->max_lod + view->base.u.tex.first_level, 728 tex->desc.b.b.last_level, view->base.u.tex.last_level); 729 min_level = MIN2(sampler->min_lod + view->base.u.tex.first_level, 730 max_level); 731 732 if (tex->desc.is_npot && min_level > 0) { 733 /* Even though we do not implement mipmapping for NPOT 734 * textures, we should at least honor the minimum level 735 * which is allowed to be displayed. We do this by setting up 736 * an i-th mipmap level as the zero level. */ 737 r300_texture_setup_format_state(r300->screen, &tex->desc, 738 min_level, 739 &texstate->format); 740 texstate->format.tile_config |= 741 tex->desc.offset_in_bytes[min_level] & 0xffffffe0; 742 assert((tex->desc.offset_in_bytes[min_level] & 0x1f) == 0); 743 } 744 745 /* Assign a texture cache region. */ 746 texstate->format.format1 |= view->texcache_region; 747 748 /* Depth textures are kinda special. */ 749 if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) { 750 unsigned char depth_swizzle[4]; 751 752 if (!r300->screen->caps.is_r500 && 753 util_format_get_blocksizebits(tex->desc.b.b.format) == 32) { 754 /* X24x8 is sampled as Y16X16 on r3xx-r4xx. 755 * The depth here is at the Y component. */ 756 for (j = 0; j < 4; j++) 757 depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_Y; 758 } else { 759 for (j = 0; j < 4; j++) 760 depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_X; 761 } 762 763 /* If compare mode is disabled, sampler view swizzles 764 * are stored in the format. 765 * Otherwise, the swizzles must be applied after the compare 766 * mode in the fragment shader. */ 767 if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) { 768 texstate->format.format1 |= 769 r300_get_swizzle_combined(depth_swizzle, 770 view->swizzle, FALSE); 771 } else { 772 texstate->format.format1 |= 773 r300_get_swizzle_combined(depth_swizzle, 0, FALSE); 774 } 775 } 776 777 if (r300->screen->caps.dxtc_swizzle && 778 util_format_is_compressed(tex->desc.b.b.format)) { 779 texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE; 780 } 781 782 /* to emulate 1D textures through 2D ones correctly */ 783 if (tex->desc.b.b.target == PIPE_TEXTURE_1D) { 784 texstate->filter0 &= ~R300_TX_WRAP_T_MASK; 785 texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); 786 } 787 788 if (tex->desc.is_npot) { 789 /* NPOT textures don't support mip filter, unfortunately. 790 * This prevents incorrect rendering. */ 791 texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK; 792 793 /* Mask out the mirrored flag. */ 794 if (texstate->filter0 & R300_TX_WRAP_S(R300_TX_MIRRORED)) { 795 texstate->filter0 &= ~R300_TX_WRAP_S(R300_TX_MIRRORED); 796 } 797 if (texstate->filter0 & R300_TX_WRAP_T(R300_TX_MIRRORED)) { 798 texstate->filter0 &= ~R300_TX_WRAP_T(R300_TX_MIRRORED); 799 } 800 801 /* Change repeat to clamp-to-edge. 802 * (the repeat bit has a value of 0, no masking needed). */ 803 if ((texstate->filter0 & R300_TX_WRAP_S_MASK) == 804 R300_TX_WRAP_S(R300_TX_REPEAT)) { 805 texstate->filter0 |= R300_TX_WRAP_S(R300_TX_CLAMP_TO_EDGE); 806 } 807 if ((texstate->filter0 & R300_TX_WRAP_T_MASK) == 808 R300_TX_WRAP_T(R300_TX_REPEAT)) { 809 texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); 810 } 811 } else { 812 /* the MAX_MIP level is the largest (finest) one */ 813 texstate->format.format0 |= R300_TX_NUM_LEVELS(max_level); 814 texstate->filter0 |= R300_TX_MAX_MIP_LEVEL(min_level); 815 } 816 817 texstate->filter0 |= i << 28; 818 819 size += 16; 820 state->count = i+1; 821 } else { 822 /* For the KIL opcode to work on r3xx-r4xx, the texture unit 823 * assigned to this opcode (it's always the first one) must be 824 * enabled. Otherwise the opcode doesn't work. 825 * 826 * In order to not depend on the fragment shader, we just make 827 * the first unit enabled all the time. */ 828 if (i == 0 && !r300->screen->caps.is_r500) { 829 pipe_sampler_view_reference( 830 (struct pipe_sampler_view**)&state->sampler_views[i], 831 &r300->texkill_sampler->base); 832 833 state->tx_enable |= 1 << i; 834 835 texstate = &state->regs[i]; 836 837 /* Just set some valid state. */ 838 texstate->format = r300->texkill_sampler->format; 839 texstate->filter0 = 840 r300_translate_tex_filters(PIPE_TEX_FILTER_NEAREST, 841 PIPE_TEX_FILTER_NEAREST, 842 PIPE_TEX_FILTER_NEAREST, 843 FALSE); 844 texstate->filter1 = 0; 845 texstate->border_color = 0; 846 847 texstate->filter0 |= i << 28; 848 size += 16; 849 state->count = i+1; 850 } 851 } 852 } 853 854 r300->textures_state.size = size; 855 856 /* Pick a fragment shader based on either the texture compare state 857 * or the uses_pitch flag. */ 858 if (r300->fs.state && count) { 859 if (r300_pick_fragment_shader(r300)) { 860 r300_mark_fs_code_dirty(r300); 861 } 862 } 863} 864 865void r300_update_derived_state(struct r300_context* r300) 866{ 867 r300_flush_depth_textures(r300); 868 869 if (r300->textures_state.dirty) { 870 r300_merge_textures_and_samplers(r300); 871 } 872 873 if (r300->rs_block_state.dirty) { 874 r300_update_rs_block(r300); 875 876 if (r300->draw) { 877 memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); 878 r300_draw_emit_all_attribs(r300); 879 draw_compute_vertex_size(&r300->vertex_info); 880 r300_swtcl_vertex_psc(r300); 881 } 882 } 883 884 r300_update_hyperz_state(r300); 885} 886