r300_state_derived.c revision cf5dff1f2337303f49780dc646a44c6dbbe48e5a
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 29#include "r300_context.h" 30#include "r300_fs.h" 31#include "r300_hyperz.h" 32#include "r300_screen.h" 33#include "r300_shader_semantics.h" 34#include "r300_state.h" 35#include "r300_state_derived.h" 36#include "r300_state_inlines.h" 37#include "r300_texture.h" 38#include "r300_vs.h" 39 40/* r300_state_derived: Various bits of state which are dependent upon 41 * currently bound CSO data. */ 42 43enum r300_rs_swizzle { 44 SWIZ_XYZW = 0, 45 SWIZ_X001, 46 SWIZ_XY01, 47 SWIZ_0001, 48}; 49 50static void r300_draw_emit_attrib(struct r300_context* r300, 51 enum attrib_emit emit, 52 enum interp_mode interp, 53 int index) 54{ 55 struct r300_vertex_shader* vs = r300->vs_state.state; 56 struct tgsi_shader_info* info = &vs->info; 57 int output; 58 59 output = draw_find_shader_output(r300->draw, 60 info->output_semantic_name[index], 61 info->output_semantic_index[index]); 62 draw_emit_vertex_attr(&r300->vertex_info, emit, interp, output); 63} 64 65static void r300_draw_emit_all_attribs(struct r300_context* r300) 66{ 67 struct r300_vertex_shader* vs = r300->vs_state.state; 68 struct r300_shader_semantics* vs_outputs = &vs->outputs; 69 int i, gen_count; 70 71 /* Position. */ 72 if (vs_outputs->pos != ATTR_UNUSED) { 73 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, 74 vs_outputs->pos); 75 } else { 76 assert(0); 77 } 78 79 /* Point size. */ 80 if (vs_outputs->psize != ATTR_UNUSED) { 81 r300_draw_emit_attrib(r300, EMIT_1F_PSIZE, INTERP_POS, 82 vs_outputs->psize); 83 } 84 85 /* Colors. */ 86 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 87 if (vs_outputs->color[i] != ATTR_UNUSED) { 88 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR, 89 vs_outputs->color[i]); 90 } 91 } 92 93 /* XXX Back-face colors. */ 94 95 /* Texture coordinates. */ 96 /* Only 8 generic vertex attributes can be used. If there are more, 97 * they won't be rasterized. */ 98 gen_count = 0; 99 for (i = 0; i < ATTR_GENERIC_COUNT && gen_count < 8; i++) { 100 if (vs_outputs->generic[i] != ATTR_UNUSED) { 101 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, 102 vs_outputs->generic[i]); 103 gen_count++; 104 } 105 } 106 107 /* Fog coordinates. */ 108 if (gen_count < 8 && vs_outputs->fog != ATTR_UNUSED) { 109 r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE, 110 vs_outputs->fog); 111 gen_count++; 112 } 113} 114 115/* Update the PSC tables for SW TCL, using Draw. */ 116static void r300_swtcl_vertex_psc(struct r300_context *r300) 117{ 118 struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state; 119 struct vertex_info *vinfo = &r300->vertex_info; 120 uint16_t type, swizzle; 121 enum pipe_format format; 122 unsigned i, attrib_count; 123 int* vs_output_tab = r300->stream_loc_notcl; 124 125 memset(vstream, 0, sizeof(struct r300_vertex_stream_state)); 126 127 /* For each Draw attribute, route it to the fragment shader according 128 * to the vs_output_tab. */ 129 attrib_count = vinfo->num_attribs; 130 DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count); 131 for (i = 0; i < attrib_count; i++) { 132 DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d," 133 " vs_output_tab %d\n", vinfo->attrib[i].src_index, 134 vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, 135 vs_output_tab[i]); 136 137 /* Make sure we have a proper destination for our attribute. */ 138 assert(vs_output_tab[i] != -1); 139 140 format = draw_translate_vinfo_format(vinfo->attrib[i].emit); 141 142 /* Obtain the type of data in this attribute. */ 143 type = r300_translate_vertex_data_type(format) | 144 vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT; 145 146 /* Obtain the swizzle for this attribute. Note that the default 147 * swizzle in the hardware is not XYZW! */ 148 swizzle = r300_translate_vertex_data_swizzle(format); 149 150 /* Add the attribute to the PSC table. */ 151 if (i & 1) { 152 vstream->vap_prog_stream_cntl[i >> 1] |= type << 16; 153 vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16; 154 } else { 155 vstream->vap_prog_stream_cntl[i >> 1] |= type; 156 vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle; 157 } 158 } 159 160 /* Set the last vector in the PSC. */ 161 if (i) { 162 i -= 1; 163 } 164 vstream->vap_prog_stream_cntl[i >> 1] |= 165 (R300_LAST_VEC << (i & 1 ? 16 : 0)); 166 167 vstream->count = (i >> 1) + 1; 168 r300->vertex_stream_state.dirty = TRUE; 169 r300->vertex_stream_state.size = (1 + vstream->count) * 2; 170} 171 172static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, 173 enum r300_rs_swizzle swiz) 174{ 175 rs->ip[id] |= R300_RS_COL_PTR(ptr); 176 if (swiz == SWIZ_0001) { 177 rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001); 178 } else { 179 rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA); 180 } 181 rs->inst[id] |= R300_RS_INST_COL_ID(id); 182} 183 184static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) 185{ 186 rs->inst[id] |= R300_RS_INST_COL_CN_WRITE | 187 R300_RS_INST_COL_ADDR(fp_offset); 188} 189 190static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr, 191 enum r300_rs_swizzle swiz) 192{ 193 if (swiz == SWIZ_X001) { 194 rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | 195 R300_RS_SEL_S(R300_RS_SEL_C0) | 196 R300_RS_SEL_T(R300_RS_SEL_K0) | 197 R300_RS_SEL_R(R300_RS_SEL_K0) | 198 R300_RS_SEL_Q(R300_RS_SEL_K1); 199 } else if (swiz == SWIZ_XY01) { 200 rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | 201 R300_RS_SEL_S(R300_RS_SEL_C0) | 202 R300_RS_SEL_T(R300_RS_SEL_C1) | 203 R300_RS_SEL_R(R300_RS_SEL_K0) | 204 R300_RS_SEL_Q(R300_RS_SEL_K1); 205 } else { 206 rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | 207 R300_RS_SEL_S(R300_RS_SEL_C0) | 208 R300_RS_SEL_T(R300_RS_SEL_C1) | 209 R300_RS_SEL_R(R300_RS_SEL_C2) | 210 R300_RS_SEL_Q(R300_RS_SEL_C3); 211 } 212 rs->inst[id] |= R300_RS_INST_TEX_ID(id); 213} 214 215static void r300_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset) 216{ 217 rs->inst[id] |= R300_RS_INST_TEX_CN_WRITE | 218 R300_RS_INST_TEX_ADDR(fp_offset); 219} 220 221static void r500_rs_col(struct r300_rs_block* rs, int id, int ptr, 222 enum r300_rs_swizzle swiz) 223{ 224 rs->ip[id] |= R500_RS_COL_PTR(ptr); 225 if (swiz == SWIZ_0001) { 226 rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001); 227 } else { 228 rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA); 229 } 230 rs->inst[id] |= R500_RS_INST_COL_ID(id); 231} 232 233static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) 234{ 235 rs->inst[id] |= R500_RS_INST_COL_CN_WRITE | 236 R500_RS_INST_COL_ADDR(fp_offset); 237} 238 239static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr, 240 enum r300_rs_swizzle swiz) 241{ 242 int rs_tex_comp = ptr*4; 243 244 if (swiz == SWIZ_X001) { 245 rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | 246 R500_RS_SEL_T(R500_RS_IP_PTR_K0) | 247 R500_RS_SEL_R(R500_RS_IP_PTR_K0) | 248 R500_RS_SEL_Q(R500_RS_IP_PTR_K1); 249 } else if (swiz == SWIZ_XY01) { 250 rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | 251 R500_RS_SEL_T(rs_tex_comp + 1) | 252 R500_RS_SEL_R(R500_RS_IP_PTR_K0) | 253 R500_RS_SEL_Q(R500_RS_IP_PTR_K1); 254 } else { 255 rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | 256 R500_RS_SEL_T(rs_tex_comp + 1) | 257 R500_RS_SEL_R(rs_tex_comp + 2) | 258 R500_RS_SEL_Q(rs_tex_comp + 3); 259 } 260 rs->inst[id] |= R500_RS_INST_TEX_ID(id); 261} 262 263static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset) 264{ 265 rs->inst[id] |= R500_RS_INST_TEX_CN_WRITE | 266 R500_RS_INST_TEX_ADDR(fp_offset); 267} 268 269/* Set up the RS block. 270 * 271 * This is the part of the chipset that is responsible for linking vertex 272 * and fragment shaders and stuffed texture coordinates. 273 * 274 * The rasterizer reads data from VAP, which produces vertex shader outputs, 275 * and GA, which produces stuffed texture coordinates. VAP outputs have 276 * precedence over GA. All outputs must be rasterized otherwise it locks up. 277 * If there are more outputs rasterized than is set in VAP/GA, it locks up 278 * too. The funky part is that this info has been pretty much obtained by trial 279 * and error. */ 280static void r300_update_rs_block(struct r300_context *r300) 281{ 282 struct r300_vertex_shader *vs = r300->vs_state.state; 283 struct r300_shader_semantics *vs_outputs = &vs->outputs; 284 struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs; 285 struct r300_rs_block rs = {0}; 286 int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0; 287 void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); 288 void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); 289 void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); 290 void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int); 291 boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || 292 vs_outputs->bcolor[1] != ATTR_UNUSED; 293 int *stream_loc_notcl = r300->stream_loc_notcl; 294 295 if (r300->screen->caps.is_r500) { 296 rX00_rs_col = r500_rs_col; 297 rX00_rs_col_write = r500_rs_col_write; 298 rX00_rs_tex = r500_rs_tex; 299 rX00_rs_tex_write = r500_rs_tex_write; 300 } else { 301 rX00_rs_col = r300_rs_col; 302 rX00_rs_col_write = r300_rs_col_write; 303 rX00_rs_tex = r300_rs_tex; 304 rX00_rs_tex_write = r300_rs_tex_write; 305 } 306 307 /* The position is always present in VAP. */ 308 rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS; 309 rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; 310 stream_loc_notcl[loc++] = 0; 311 312 /* Set up the point size in VAP. */ 313 if (vs_outputs->psize != ATTR_UNUSED) { 314 rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT; 315 stream_loc_notcl[loc++] = 1; 316 } 317 318 /* Set up and rasterize colors. */ 319 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 320 if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used || 321 vs_outputs->color[1] != ATTR_UNUSED) { 322 /* Set up the color in VAP. */ 323 rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; 324 rs.vap_out_vtx_fmt[0] |= 325 R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i; 326 stream_loc_notcl[loc++] = 2 + i; 327 328 /* Rasterize it. */ 329 rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW); 330 331 /* Write it to the FS input register if it's needed by the FS. */ 332 if (fs_inputs->color[i] != ATTR_UNUSED) { 333 rX00_rs_col_write(&rs, col_count, fp_offset); 334 fp_offset++; 335 336 DBG(r300, DBG_RS, 337 "r300: Rasterized color %i written to FS.\n", i); 338 } else { 339 DBG(r300, DBG_RS, "r300: Rasterized color %i unused.\n", i); 340 } 341 col_count++; 342 } else { 343 /* Skip the FS input register, leave it uninitialized. */ 344 /* If we try to set it to (0,0,0,1), it will lock up. */ 345 if (fs_inputs->color[i] != ATTR_UNUSED) { 346 fp_offset++; 347 348 DBG(r300, DBG_RS, "r300: FS input color %i unassigned%s.\n", 349 i); 350 } 351 } 352 } 353 354 /* Set up back-face colors. The rasterizer will do the color selection 355 * automatically. */ 356 if (any_bcolor_used) { 357 if (r300->two_sided_color) { 358 /* Rasterize as back-face colors. */ 359 for (i = 0; i < ATTR_COLOR_COUNT; i++) { 360 rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR; 361 rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i); 362 stream_loc_notcl[loc++] = 4 + i; 363 } 364 } else { 365 /* Rasterize two fake texcoords to prevent from the two-sided color 366 * selection. */ 367 /* XXX Consider recompiling the vertex shader to save 2 RS units. */ 368 for (i = 0; i < 2; i++) { 369 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 370 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 371 stream_loc_notcl[loc++] = 6 + tex_count; 372 373 /* Rasterize it. */ 374 rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); 375 tex_count++; 376 } 377 } 378 } 379 380 /* Rasterize texture coordinates. */ 381 for (i = 0; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) { 382 bool sprite_coord = !!(r300->sprite_coord_enable & (1 << i)); 383 384 if (vs_outputs->generic[i] != ATTR_UNUSED || sprite_coord) { 385 if (!sprite_coord) { 386 /* Set up the texture coordinates in VAP. */ 387 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 388 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 389 stream_loc_notcl[loc++] = 6 + tex_count; 390 } 391 392 /* Rasterize it. */ 393 rX00_rs_tex(&rs, tex_count, tex_count, 394 sprite_coord ? SWIZ_XY01 : SWIZ_XYZW); 395 396 /* Write it to the FS input register if it's needed by the FS. */ 397 if (fs_inputs->generic[i] != ATTR_UNUSED) { 398 rX00_rs_tex_write(&rs, tex_count, fp_offset); 399 fp_offset++; 400 401 DBG(r300, DBG_RS, 402 "r300: Rasterized generic %i written to FS%s.\n", 403 i, sprite_coord ? " (sprite coord)" : ""); 404 } else { 405 DBG(r300, DBG_RS, 406 "r300: Rasterized generic %i unused%s.\n", 407 i, sprite_coord ? " (sprite coord)" : ""); 408 } 409 tex_count++; 410 } else { 411 /* Skip the FS input register, leave it uninitialized. */ 412 /* If we try to set it to (0,0,0,1), it will lock up. */ 413 if (fs_inputs->generic[i] != ATTR_UNUSED) { 414 fp_offset++; 415 416 DBG(r300, DBG_RS, "r300: FS input generic %i unassigned%s.\n", 417 i, sprite_coord ? " (sprite coord)" : ""); 418 } 419 } 420 } 421 422 /* Rasterize fog coordinates. */ 423 if (vs_outputs->fog != ATTR_UNUSED && tex_count < 8) { 424 /* Set up the fog coordinates in VAP. */ 425 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 426 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 427 stream_loc_notcl[loc++] = 6 + tex_count; 428 429 /* Rasterize it. */ 430 rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_X001); 431 432 /* Write it to the FS input register if it's needed by the FS. */ 433 if (fs_inputs->fog != ATTR_UNUSED) { 434 rX00_rs_tex_write(&rs, tex_count, fp_offset); 435 fp_offset++; 436 437 DBG(r300, DBG_RS, "r300: Rasterized fog written to FS.\n"); 438 } else { 439 DBG(r300, DBG_RS, "r300: Rasterized fog unused.\n"); 440 } 441 tex_count++; 442 } else { 443 /* Skip the FS input register, leave it uninitialized. */ 444 /* If we try to set it to (0,0,0,1), it will lock up. */ 445 if (fs_inputs->fog != ATTR_UNUSED) { 446 fp_offset++; 447 448 DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n"); 449 } 450 } 451 452 /* Rasterize WPOS. */ 453 /* Don't set it in VAP if the FS doesn't need it. */ 454 if (fs_inputs->wpos != ATTR_UNUSED && tex_count < 8) { 455 /* Set up the WPOS coordinates in VAP. */ 456 rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count); 457 rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count)); 458 stream_loc_notcl[loc++] = 6 + tex_count; 459 460 /* Rasterize it. */ 461 rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); 462 463 /* Write it to the FS input register. */ 464 rX00_rs_tex_write(&rs, tex_count, fp_offset); 465 466 DBG(r300, DBG_RS, "r300: Rasterized WPOS written to FS.\n"); 467 468 fp_offset++; 469 tex_count++; 470 } 471 472 /* Invalidate the rest of the no-TCL (GA) stream locations. */ 473 for (; loc < 16;) { 474 stream_loc_notcl[loc++] = -1; 475 } 476 477 /* Rasterize at least one color, or bad things happen. */ 478 if (col_count == 0 && tex_count == 0) { 479 rX00_rs_col(&rs, 0, 0, SWIZ_0001); 480 col_count++; 481 482 DBG(r300, DBG_RS, "r300: Rasterized color 0 to prevent lockups.\n"); 483 } 484 485 DBG(r300, DBG_RS, "r300: --- Rasterizer status ---: colors: %i, " 486 "generics: %i.\n", col_count, tex_count); 487 488 rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | 489 R300_HIRES_EN; 490 491 count = MAX3(col_count, tex_count, 1); 492 rs.inst_count = count - 1; 493 494 /* Now, after all that, see if we actually need to update the state. */ 495 if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) { 496 memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block)); 497 r300->rs_block_state.size = 11 + count*2; 498 } 499} 500 501static void r300_merge_textures_and_samplers(struct r300_context* r300) 502{ 503 struct r300_textures_state *state = 504 (struct r300_textures_state*)r300->textures_state.state; 505 struct r300_texture_sampler_state *texstate; 506 struct r300_sampler_state *sampler; 507 struct r300_sampler_view *view; 508 struct r300_texture *tex; 509 unsigned min_level, max_level, i, size; 510 unsigned count = MIN2(state->sampler_view_count, 511 state->sampler_state_count); 512 unsigned char depth_swizzle[4] = { 513 UTIL_FORMAT_SWIZZLE_X, 514 UTIL_FORMAT_SWIZZLE_X, 515 UTIL_FORMAT_SWIZZLE_X, 516 UTIL_FORMAT_SWIZZLE_X 517 }; 518 519 state->tx_enable = 0; 520 state->count = 0; 521 size = 2; 522 523 for (i = 0; i < count; i++) { 524 if (state->sampler_views[i] && state->sampler_states[i]) { 525 state->tx_enable |= 1 << i; 526 527 view = state->sampler_views[i]; 528 tex = r300_texture(view->base.texture); 529 sampler = state->sampler_states[i]; 530 531 texstate = &state->regs[i]; 532 texstate->format = view->format; 533 texstate->filter0 = sampler->filter0; 534 texstate->filter1 = sampler->filter1; 535 texstate->border_color = sampler->border_color; 536 537 /* If compare mode is disabled, the sampler view swizzles 538 * are stored in the format. 539 * Otherwise, swizzles must be applied after the compare mode 540 * in the fragment shader. */ 541 if (util_format_is_depth_or_stencil(tex->b.b.format)) { 542 if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) { 543 texstate->format.format1 |= 544 r300_get_swizzle_combined(depth_swizzle, view->swizzle); 545 } else { 546 texstate->format.format1 |= 547 r300_get_swizzle_combined(depth_swizzle, 0); 548 } 549 } 550 551 /* to emulate 1D textures through 2D ones correctly */ 552 if (tex->b.b.target == PIPE_TEXTURE_1D) { 553 texstate->filter0 &= ~R300_TX_WRAP_T_MASK; 554 texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); 555 } 556 557 if (tex->uses_pitch) { 558 /* NPOT textures don't support mip filter, unfortunately. 559 * This prevents incorrect rendering. */ 560 texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK; 561 562 /* Mask out the mirrored flag. */ 563 if (texstate->filter0 & R300_TX_WRAP_S(R300_TX_MIRRORED)) { 564 texstate->filter0 &= ~R300_TX_WRAP_S(R300_TX_MIRRORED); 565 } 566 if (texstate->filter0 & R300_TX_WRAP_T(R300_TX_MIRRORED)) { 567 texstate->filter0 &= ~R300_TX_WRAP_T(R300_TX_MIRRORED); 568 } 569 570 /* Change repeat to clamp-to-edge. 571 * (the repeat bit has a value of 0, no masking needed). */ 572 if ((texstate->filter0 & R300_TX_WRAP_S_MASK) == 573 R300_TX_WRAP_S(R300_TX_REPEAT)) { 574 texstate->filter0 |= R300_TX_WRAP_S(R300_TX_CLAMP_TO_EDGE); 575 } 576 if ((texstate->filter0 & R300_TX_WRAP_T_MASK) == 577 R300_TX_WRAP_T(R300_TX_REPEAT)) { 578 texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); 579 } 580 } else { 581 /* determine min/max levels */ 582 /* the MAX_MIP level is the largest (finest) one */ 583 max_level = MIN3(sampler->max_lod + view->base.first_level, 584 tex->b.b.last_level, view->base.last_level); 585 min_level = MIN2(sampler->min_lod + view->base.first_level, 586 max_level); 587 texstate->format.format0 |= R300_TX_NUM_LEVELS(max_level); 588 texstate->filter0 |= R300_TX_MAX_MIP_LEVEL(min_level); 589 } 590 591 texstate->filter0 |= i << 28; 592 593 size += 16; 594 state->count = i+1; 595 } 596 } 597 598 r300->textures_state.size = size; 599 600 /* Pick a fragment shader based on either the texture compare state 601 * or the uses_pitch flag. */ 602 if (r300->fs.state && count) { 603 if (r300_pick_fragment_shader(r300)) { 604 r300_mark_fs_code_dirty(r300); 605 } 606 } 607} 608 609void r300_update_derived_state(struct r300_context* r300) 610{ 611 if (r300->textures_state.dirty) { 612 r300_merge_textures_and_samplers(r300); 613 } 614 615 if (r300->rs_block_state.dirty) { 616 r300_update_rs_block(r300); 617 } 618 619 if (r300->draw) { 620 memset(&r300->vertex_info, 0, sizeof(struct vertex_info)); 621 r300_draw_emit_all_attribs(r300); 622 draw_compute_vertex_size(&r300->vertex_info); 623 r300_swtcl_vertex_psc(r300); 624 } 625 626 r300_update_hyperz_state(r300); 627} 628