r300_state.c revision 8c8bdcde6d9eb1cda7bf268cd75ca7676e220075
1/* 2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23#include "util/u_math.h" 24#include "util/u_pack_color.h" 25 26#include "r300_context.h" 27#include "r300_reg.h" 28 29/* r300_state: Functions used to intialize state context by translating 30 * Gallium state objects into semi-native r300 state objects. 31 * 32 * XXX break this file up into pieces if it gets too big! */ 33 34/* Pack a float into a dword. */ 35static uint32_t pack_float_32(float f) 36{ 37 union { 38 float f; 39 uint32_t u; 40 } u; 41 42 u.f = f; 43 return u.u; 44} 45 46static uint32_t translate_blend_function(int blend_func) { 47 switch (blend_func) { 48 case PIPE_BLEND_ADD: 49 return R300_COMB_FCN_ADD_CLAMP; 50 case PIPE_BLEND_SUBTRACT: 51 return R300_COMB_FCN_SUB_CLAMP; 52 case PIPE_BLEND_REVERSE_SUBTRACT: 53 return R300_COMB_FCN_RSUB_CLAMP; 54 case PIPE_BLEND_MIN: 55 return R300_COMB_FCN_MIN; 56 case PIPE_BLEND_MAX: 57 return R300_COMB_FCN_MAX; 58 default: 59 /* XXX should be unreachable, handle this */ 60 break; 61 } 62 return 0; 63} 64 65/* XXX we can also offer the D3D versions of some of these... */ 66static uint32_t translate_blend_factor(int blend_fact) { 67 switch (blend_fact) { 68 case PIPE_BLENDFACTOR_ONE: 69 return R300_BLEND_GL_ONE; 70 case PIPE_BLENDFACTOR_SRC_COLOR: 71 return R300_BLEND_GL_SRC_COLOR; 72 case PIPE_BLENDFACTOR_SRC_ALPHA: 73 return R300_BLEND_GL_SRC_ALPHA; 74 case PIPE_BLENDFACTOR_DST_ALPHA: 75 return R300_BLEND_GL_DST_ALPHA; 76 case PIPE_BLENDFACTOR_DST_COLOR: 77 return R300_BLEND_GL_DST_COLOR; 78 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 79 return R300_BLEND_GL_SRC_ALPHA_SATURATE; 80 case PIPE_BLENDFACTOR_CONST_COLOR: 81 return R300_BLEND_GL_CONST_COLOR; 82 case PIPE_BLENDFACTOR_CONST_ALPHA: 83 return R300_BLEND_GL_CONST_ALPHA; 84 /* XXX WTF are these? 85 case PIPE_BLENDFACTOR_SRC1_COLOR: 86 case PIPE_BLENDFACTOR_SRC1_ALPHA: */ 87 case PIPE_BLENDFACTOR_ZERO: 88 return R300_BLEND_GL_ZERO; 89 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 90 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR; 91 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 92 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA; 93 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 94 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA; 95 case PIPE_BLENDFACTOR_INV_DST_COLOR: 96 return R300_BLEND_GL_ONE_MINUS_DST_COLOR; 97 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 98 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR; 99 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 100 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA; 101 /* XXX see above 102 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 103 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */ 104 default: 105 /* XXX the mythical 0x16 blend factor! */ 106 break; 107 } 108 return 0; 109} 110 111/* Create a new blend state based on the CSO blend state. 112 * 113 * This encompasses alpha blending, logic/raster ops, and blend dithering. */ 114static void* r300_create_blend_state(struct pipe_context* pipe, 115 const struct pipe_blend_state* state) 116{ 117 struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); 118 119 if (state->blend_enable) { 120 /* XXX for now, always do separate alpha... 121 * is it faster to do it with one reg? */ 122 blend->blend_control = R300_ALPHA_BLEND_ENABLE | 123 R300_SEPARATE_ALPHA_ENABLE | 124 R300_READ_ENABLE | 125 translate_blend_function(state->rgb_func) | 126 (translate_blend_factor(state->rgb_src_factor) << 127 R300_SRC_BLEND_SHIFT) | 128 (translate_blend_factor(state->rgb_dst_factor) << 129 R300_DST_BLEND_SHIFT); 130 blend->alpha_blend_control = 131 translate_blend_function(state->alpha_func) | 132 (translate_blend_factor(state->alpha_src_factor) << 133 R300_SRC_BLEND_SHIFT) | 134 (translate_blend_factor(state->alpha_dst_factor) << 135 R300_DST_BLEND_SHIFT); 136 } 137 138 /* PIPE_LOGICOP_* don't need to be translated, fortunately. */ 139 /* XXX are logicops still allowed if blending's disabled? 140 * Does Gallium take care of it for us? */ 141 if (state->logicop_enable) { 142 blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE | 143 (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; 144 } 145 146 if (state->dither) { 147 blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT | 148 R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT; 149 } 150 151 return (void*)blend; 152} 153 154/* Bind blend state. */ 155static void r300_bind_blend_state(struct pipe_context* pipe, 156 void* state) 157{ 158 struct r300_context* r300 = r300_context(pipe); 159 160 r300->blend_state = (struct r300_blend_state*)state; 161 r300->dirty_state |= R300_NEW_BLEND; 162} 163 164/* Free blend state. */ 165static void r300_delete_blend_state(struct pipe_context* pipe, 166 void* state) 167{ 168 FREE(state); 169} 170 171/* Set blend color. 172 * Setup both R300 and R500 registers, figure out later which one to write. */ 173static void r300_set_blend_color(struct pipe_context* pipe, 174 const struct pipe_blend_color* color) 175{ 176 struct r300_context* r300 = r300_context(pipe); 177 uint32_t r, g, b, a; 178 ubyte ur, ug, ub, ua; 179 180 r = util_iround(color->color[0] * 1023.0f); 181 g = util_iround(color->color[1] * 1023.0f); 182 b = util_iround(color->color[2] * 1023.0f); 183 a = util_iround(color->color[3] * 1023.0f); 184 185 ur = float_to_ubyte(color->color[0]); 186 ug = float_to_ubyte(color->color[1]); 187 ub = float_to_ubyte(color->color[2]); 188 ua = float_to_ubyte(color->color[3]); 189 190 r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b; 191 192 r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16); 193 r300->blend_color_state->blend_color_green_blue = ub | (ug << 16); 194 195 r300->dirty_state |= R300_NEW_BLEND_COLOR; 196} 197 198static void r300_set_clip_state(struct pipe_context* pipe, 199 const struct pipe_clip_state* state) 200{ 201 struct r300_context* r300 = r300_context(pipe); 202 /* XXX Draw */ 203 draw_flush(r300->draw); 204 draw_set_clip_state(r300->draw, state); 205} 206 207static void 208 r300_set_constant_buffer(struct pipe_context* pipe, 209 uint shader, uint index, 210 const struct pipe_constant_buffer* buffer) 211{ 212 /* XXX */ 213} 214 215static uint32_t translate_depth_stencil_function(int zs_func) { 216 switch (zs_func) { 217 case PIPE_FUNC_NEVER: 218 return R300_ZS_NEVER; 219 case PIPE_FUNC_LESS: 220 return R300_ZS_LESS; 221 case PIPE_FUNC_EQUAL: 222 return R300_ZS_EQUAL; 223 case PIPE_FUNC_LEQUAL: 224 return R300_ZS_LEQUAL; 225 case PIPE_FUNC_GREATER: 226 return R300_ZS_GREATER; 227 case PIPE_FUNC_NOTEQUAL: 228 return R300_ZS_NOTEQUAL; 229 case PIPE_FUNC_GEQUAL: 230 return R300_ZS_GEQUAL; 231 case PIPE_FUNC_ALWAYS: 232 return R300_ZS_ALWAYS; 233 default: 234 /* XXX shouldn't be reachable */ 235 break; 236 } 237 return 0; 238} 239 240static uint32_t translate_stencil_op(int s_op) { 241 switch (s_op) { 242 case PIPE_STENCIL_OP_KEEP: 243 return R300_ZS_KEEP; 244 case PIPE_STENCIL_OP_ZERO: 245 return R300_ZS_ZERO; 246 case PIPE_STENCIL_OP_REPLACE: 247 return R300_ZS_REPLACE; 248 case PIPE_STENCIL_OP_INCR: 249 return R300_ZS_INCR; 250 case PIPE_STENCIL_OP_DECR: 251 return R300_ZS_DECR; 252 case PIPE_STENCIL_OP_INCR_WRAP: 253 return R300_ZS_INCR_WRAP; 254 case PIPE_STENCIL_OP_DECR_WRAP: 255 return R300_ZS_DECR_WRAP; 256 case PIPE_STENCIL_OP_INVERT: 257 return R300_ZS_INVERT; 258 default: 259 /* XXX shouldn't be reachable */ 260 break; 261 } 262 return 0; 263} 264 265static uint32_t translate_alpha_function(int alpha_func) { 266 switch (alpha_func) { 267 case PIPE_FUNC_NEVER: 268 return R300_FG_ALPHA_FUNC_NEVER; 269 case PIPE_FUNC_LESS: 270 return R300_FG_ALPHA_FUNC_LESS; 271 case PIPE_FUNC_EQUAL: 272 return R300_FG_ALPHA_FUNC_EQUAL; 273 case PIPE_FUNC_LEQUAL: 274 return R300_FG_ALPHA_FUNC_LE; 275 case PIPE_FUNC_GREATER: 276 return R300_FG_ALPHA_FUNC_GREATER; 277 case PIPE_FUNC_NOTEQUAL: 278 return R300_FG_ALPHA_FUNC_NOTEQUAL; 279 case PIPE_FUNC_GEQUAL: 280 return R300_FG_ALPHA_FUNC_GE; 281 case PIPE_FUNC_ALWAYS: 282 return R300_FG_ALPHA_FUNC_ALWAYS; 283 default: 284 /* XXX shouldn't be reachable */ 285 break; 286 } 287 return 0; 288} 289 290/* Create a new depth, stencil, and alpha state based on the CSO dsa state. 291 * 292 * This contains the depth buffer, stencil buffer, alpha test, and such. 293 * On the Radeon, depth and stencil buffer setup are intertwined, which is 294 * the reason for some of the strange-looking assignments across registers. */ 295static void* 296 r300_create_dsa_state(struct pipe_context* pipe, 297 const struct pipe_depth_stencil_alpha_state* state) 298{ 299 struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); 300 301 /* Depth test setup. */ 302 if (state->depth.enabled) { 303 dsa->z_buffer_control |= R300_Z_ENABLE; 304 305 if (state->depth.writemask) { 306 dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; 307 } 308 309 dsa->z_stencil_control |= 310 (translate_depth_stencil_function(state->depth.func) << 311 R300_Z_FUNC_SHIFT); 312 } 313 314 /* Stencil buffer setup. */ 315 if (state->stencil[0].enabled) { 316 dsa->z_buffer_control |= R300_STENCIL_ENABLE; 317 dsa->z_stencil_control |= 318 (translate_depth_stencil_function(state->stencil[0].func) << 319 R300_S_FRONT_FUNC_SHIFT) | 320 (translate_stencil_op(state->stencil[0].fail_op) << 321 R300_S_FRONT_SFAIL_OP_SHIFT) | 322 (translate_stencil_op(state->stencil[0].zpass_op) << 323 R300_S_FRONT_ZPASS_OP_SHIFT) | 324 (translate_stencil_op(state->stencil[0].zfail_op) << 325 R300_S_FRONT_ZFAIL_OP_SHIFT); 326 327 dsa->stencil_ref_mask = (state->stencil[0].ref_value) | 328 (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) | 329 (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT); 330 331 if (state->stencil[1].enabled) { 332 dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; 333 dsa->z_stencil_control |= 334 (translate_depth_stencil_function(state->stencil[1].func) << 335 R300_S_BACK_FUNC_SHIFT) | 336 (translate_stencil_op(state->stencil[1].fail_op) << 337 R300_S_BACK_SFAIL_OP_SHIFT) | 338 (translate_stencil_op(state->stencil[1].zpass_op) << 339 R300_S_BACK_ZPASS_OP_SHIFT) | 340 (translate_stencil_op(state->stencil[1].zfail_op) << 341 R300_S_BACK_ZFAIL_OP_SHIFT); 342 343 dsa->stencil_ref_bf = (state->stencil[1].ref_value) | 344 (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) | 345 (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT); 346 } 347 } 348 349 /* Alpha test setup. */ 350 if (state->alpha.enabled) { 351 dsa->alpha_function = translate_alpha_function(state->alpha.func) | 352 R300_FG_ALPHA_FUNC_ENABLE; 353 dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023); 354 } else { 355 dsa->z_buffer_top = R300_ZTOP_ENABLE; 356 } 357 358 return (void*)dsa; 359} 360 361/* Bind DSA state. */ 362static void r300_bind_dsa_state(struct pipe_context* pipe, 363 void* state) 364{ 365 struct r300_context* r300 = r300_context(pipe); 366 367 r300->dsa_state = (struct r300_dsa_state*)state; 368 r300->dirty_state |= R300_NEW_DSA; 369} 370 371/* Free DSA state. */ 372static void r300_delete_dsa_state(struct pipe_context* pipe, 373 void* state) 374{ 375 FREE(state); 376} 377 378static void r300_set_edgeflags(struct pipe_context* pipe, 379 const unsigned* bitfield) 380{ 381 /* XXX you know it's bad when i915 has this blank too */ 382} 383 384static void 385 r300_set_framebuffer_state(struct pipe_context* pipe, 386 const struct pipe_framebuffer_state* state) 387{ 388 struct r300_context* r300 = r300_context(pipe); 389 390 draw_flush(r300->draw); 391 392 r300->framebuffer_state = *state; 393 394 /* XXX do we need to mark dirty state? */ 395} 396 397/* Create fragment shader state. */ 398static void* r300_create_fs_state(struct pipe_context* pipe, 399 const struct pipe_shader_state* state) 400{ 401 struct r300_fs_state* fs = CALLOC_STRUCT(r300_fs_state); 402 403 return (void*)fs; 404} 405 406/* Bind fragment shader state. */ 407static void r300_bind_fs_state(struct pipe_context* pipe, void* state) 408{ 409 struct r300_context* r300 = r300_context(pipe); 410 411 r300->fs_state = (struct r300_fs_state*)state; 412 413 r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; 414} 415 416/* Delect fragment shader state. */ 417static void r300_delete_fs_state(struct pipe_context* pipe, void* state) 418{ 419 FREE(state); 420} 421 422static void r300_set_polygon_stipple(struct pipe_context* pipe, 423 const struct pipe_poly_stipple* state) 424{ 425 /* XXX */ 426} 427 428#if 0 429struct pipe_rasterizer_state 430{ 431 unsigned flatshade:1; 432 unsigned light_twoside:1; 433 unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ 434 unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ 435 unsigned scissor:1; 436 unsigned poly_smooth:1; 437 unsigned poly_stipple_enable:1; 438 unsigned point_smooth:1; 439 unsigned point_sprite:1; 440 unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ 441 unsigned multisample:1; /* XXX maybe more ms state in future */ 442 unsigned line_smooth:1; 443 unsigned line_last_pixel:1; 444 unsigned bypass_clipping:1; 445 unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is 446 still needed though, to indicate inputs/outputs */ 447 unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ 448 unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ 449 unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */ 450 451 float line_width; 452 float point_size; /**< used when no per-vertex size */ 453 float point_size_min; /* XXX - temporary, will go away */ 454 float point_size_max; /* XXX - temporary, will go away */ 455 ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ 456}; 457#endif 458/* Create a new rasterizer state based on the CSO rasterizer state. 459 * 460 * This is a very large chunk of state, and covers most of the graphics 461 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks. 462 * 463 * In a not entirely unironic sidenote, this state has nearly nothing to do 464 * with the actual block on the Radeon called the rasterizer (RS). */ 465static void* r300_create_rs_state(struct pipe_context* pipe, 466 const struct pipe_rasterizer_state* state) 467{ 468 struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); 469 470 /* Radeons don't think in "CW/CCW", they think in "front/back". */ 471 if (state->front_winding == PIPE_WINDING_CW) { 472 rs->cull_mode = R300_FRONT_FACE_CW; 473 474 if (state->offset_cw) { 475 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 476 } 477 if (state->offset_ccw) { 478 rs->polygon_offset_enable |= R300_BACK_ENABLE; 479 } 480 } else { 481 rs->cull_mode = R300_FRONT_FACE_CCW; 482 483 if (state->offset_ccw) { 484 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 485 } 486 if (state->offset_cw) { 487 rs->polygon_offset_enable |= R300_BACK_ENABLE; 488 } 489 } 490 if (state->front_winding & state->cull_mode) { 491 rs->cull_mode |= R300_CULL_FRONT; 492 } 493 if (~(state->front_winding) & state->cull_mode) { 494 rs->cull_mode |= R300_CULL_BACK; 495 } 496 497 if (rs->polygon_offset_enable) { 498 rs->depth_offset_front = rs->depth_offset_back = 499 pack_float_32(state->offset_units); 500 rs->depth_scale_front = rs->depth_scale_back = 501 pack_float_32(state->offset_scale); 502 } 503 504 if (state->line_stipple_enable) { 505 rs->line_stipple_config = 506 R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE | 507 (pack_float_32((float)state->line_stipple_factor) & 508 R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK); 509 /* XXX this might need to be scaled up */ 510 rs->line_stipple_value = state->line_stipple_pattern; 511 } 512 513 /* XXX this is part of HW TCL */ 514 /* XXX endian control */ 515 rs->vap_control_status = R300_VAP_TCL_BYPASS; 516 517 return (void*)rs; 518} 519 520/* Bind rasterizer state. */ 521static void r300_bind_rs_state(struct pipe_context* pipe, void* state) 522{ 523 struct r300_context* r300 = r300_context(pipe); 524 525 r300->rs_state = (struct r300_rs_state*)state; 526 r300->dirty_state |= R300_NEW_RASTERIZER; 527} 528 529/* Free rasterizer state. */ 530static void r300_delete_rs_state(struct pipe_context* pipe, void* state) 531{ 532 FREE(state); 533} 534 535static uint32_t translate_wrap(int wrap) { 536 switch (wrap) { 537 case PIPE_TEX_WRAP_REPEAT: 538 return R300_TX_REPEAT; 539 case PIPE_TEX_WRAP_CLAMP: 540 return R300_TX_CLAMP; 541 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 542 return R300_TX_CLAMP_TO_EDGE; 543 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 544 return R300_TX_CLAMP_TO_BORDER; 545 case PIPE_TEX_WRAP_MIRROR_REPEAT: 546 return R300_TX_REPEAT | R300_TX_MIRRORED; 547 case PIPE_TEX_WRAP_MIRROR_CLAMP: 548 return R300_TX_CLAMP | R300_TX_MIRRORED; 549 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 550 return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; 551 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 552 return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; 553 default: 554 /* XXX handle this? */ 555 return 0; 556 } 557} 558 559static uint32_t translate_tex_filters(int min, int mag, int mip) { 560 uint32_t retval = 0; 561 switch (min) { 562 case PIPE_TEX_FILTER_NEAREST: 563 retval |= R300_TX_MIN_FILTER_NEAREST; 564 case PIPE_TEX_FILTER_LINEAR: 565 retval |= R300_TX_MIN_FILTER_LINEAR; 566 case PIPE_TEX_FILTER_ANISO: 567 retval |= R300_TX_MIN_FILTER_ANISO; 568 default: 569 /* XXX WTF?! */ 570 break; 571 } 572 switch (mag) { 573 case PIPE_TEX_FILTER_NEAREST: 574 retval |= R300_TX_MAG_FILTER_NEAREST; 575 case PIPE_TEX_FILTER_LINEAR: 576 retval |= R300_TX_MAG_FILTER_LINEAR; 577 case PIPE_TEX_FILTER_ANISO: 578 retval |= R300_TX_MAG_FILTER_ANISO; 579 default: 580 /* XXX WTF?! */ 581 break; 582 } 583 switch (mip) { 584 case PIPE_TEX_MIPFILTER_NONE: 585 retval |= R300_TX_MIN_FILTER_MIP_NONE; 586 case PIPE_TEX_MIPFILTER_NEAREST: 587 retval |= R300_TX_MIN_FILTER_MIP_NEAREST; 588 case PIPE_TEX_MIPFILTER_LINEAR: 589 retval |= R300_TX_MIN_FILTER_MIP_LINEAR; 590 default: 591 /* XXX WTF?! */ 592 break; 593 } 594 595 return retval; 596} 597 598static uint32_t anisotropy(float max_aniso) { 599 if (max_aniso >= 16.0f) { 600 return R300_TX_MAX_ANISO_16_TO_1; 601 } else if (max_aniso >= 8.0f) { 602 return R300_TX_MAX_ANISO_8_TO_1; 603 } else if (max_aniso >= 4.0f) { 604 return R300_TX_MAX_ANISO_4_TO_1; 605 } else if (max_aniso >= 2.0f) { 606 return R300_TX_MAX_ANISO_2_TO_1; 607 } else { 608 return R300_TX_MAX_ANISO_1_TO_1; 609 } 610} 611 612static void* 613 r300_create_sampler_state(struct pipe_context* pipe, 614 const struct pipe_sampler_state* state) 615{ 616 struct r300_context* r300 = r300_context(pipe); 617 struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); 618 int lod_bias; 619 620 sampler->filter0 |= 621 (translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | 622 (translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) | 623 (translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT); 624 625 sampler->filter0 |= translate_tex_filters(state->min_img_filter, 626 state->mag_img_filter, 627 state->min_mip_filter); 628 629 lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); 630 631 sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; 632 633 sampler->filter1 |= anisotropy(state->max_anisotropy); 634 635 util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, 636 &sampler->border_color); 637 638 /* R500-specific fixups and optimizations */ 639 if (r300_screen(r300->context.screen)->caps->is_r500) { 640 sampler->filter1 |= R500_BORDER_FIX; 641 } 642 643 return (void*)sampler; 644} 645 646static void r300_bind_sampler_states(struct pipe_context* pipe, 647 unsigned count, 648 void** states) 649{ 650 struct r300_context* r300 = r300_context(pipe); 651 int i; 652 653 if (count > 8) { 654 return; 655 } 656 657 for (i = 0; i < count; i++) { 658 if (r300->sampler_states[i] != states[i]) { 659 r300->sampler_states[i] = (struct r300_sampler_state*)states[i]; 660 r300->dirty_state |= (R300_NEW_SAMPLER << i); 661 } 662 } 663 664 r300->sampler_count = count; 665} 666 667static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) 668{ 669 FREE(state); 670} 671 672static void r300_set_sampler_textures(struct pipe_context* pipe, 673 unsigned count, 674 struct pipe_texture** texture) 675{ 676 struct r300_context* r300 = r300_context(pipe); 677 int i; 678 679 /* XXX magic num */ 680 if (count > 8) { 681 return; 682 } 683 684 for (i = 0; i < count; i++) { 685 if (r300->textures[i] != (struct r300_texture*)texture[i]) { 686 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 687 texture[i]); 688 /* XXX NEW_TEXTURE instead? */ 689 r300->dirty_state |= (R300_NEW_SAMPLER << i); 690 } 691 } 692 693 for (i = count; i < 8; i++) { 694 /* XXX also state change? */ 695 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 696 NULL); 697 } 698 699 r300->texture_count = count; 700} 701 702static void r300_set_scissor_state(struct pipe_context* pipe, 703 const struct pipe_scissor_state* state) 704{ 705 struct r300_context* r300 = r300_context(pipe); 706 draw_flush(r300->draw); 707 708 uint32_t left, top, right, bottom; 709 710 /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in 711 * both directions for all values, and can only be 13 bits wide. Why? 712 * We may never know. */ 713 left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff; 714 top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff; 715 right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff; 716 bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff; 717 718 r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) | 719 (top << R300_SCISSORS_Y_SHIFT); 720 r300->scissor_state->scissor_bottom_right = 721 (right << R300_SCISSORS_X_SHIFT) | (bottom << R300_SCISSORS_Y_SHIFT); 722 723 r300->dirty_state |= R300_NEW_SCISSOR; 724} 725 726static void r300_set_viewport_state(struct pipe_context* pipe, 727 const struct pipe_viewport_state* state) 728{ 729 struct r300_context* r300 = r300_context(pipe); 730 /* XXX handing this off to Draw for now */ 731 draw_set_viewport_state(r300->draw, state); 732} 733 734static void r300_set_vertex_buffers(struct pipe_context* pipe, 735 unsigned count, 736 const struct pipe_vertex_buffer* buffers) 737{ 738 struct r300_context* r300 = r300_context(pipe); 739 /* XXX Draw */ 740 draw_flush(r300->draw); 741 draw_set_vertex_buffers(r300->draw, count, buffers); 742} 743 744static void r300_set_vertex_elements(struct pipe_context* pipe, 745 unsigned count, 746 const struct pipe_vertex_element* elements) 747{ 748 struct r300_context* r300 = r300_context(pipe); 749 /* XXX Draw */ 750 draw_flush(r300->draw); 751 draw_set_vertex_elements(r300->draw, count, elements); 752} 753 754static void* r300_create_vs_state(struct pipe_context* pipe, 755 const struct pipe_shader_state* state) 756{ 757 struct r300_context* context = r300_context(pipe); 758 /* XXX handing this off to Draw for now */ 759 return draw_create_vertex_shader(context->draw, state); 760} 761 762static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { 763 struct r300_context* context = r300_context(pipe); 764 /* XXX handing this off to Draw for now */ 765 draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 766} 767 768static void r300_delete_vs_state(struct pipe_context* pipe, void* state) 769{ 770 struct r300_context* context = r300_context(pipe); 771 /* XXX handing this off to Draw for now */ 772 draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 773} 774 775void r300_init_state_functions(struct r300_context* r300) 776{ 777 r300->context.create_blend_state = r300_create_blend_state; 778 r300->context.bind_blend_state = r300_bind_blend_state; 779 r300->context.delete_blend_state = r300_delete_blend_state; 780 781 r300->context.set_blend_color = r300_set_blend_color; 782 783 r300->context.set_clip_state = r300_set_clip_state; 784 785 r300->context.set_constant_buffer = r300_set_constant_buffer; 786 787 r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; 788 r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; 789 r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; 790 791 r300->context.set_edgeflags = r300_set_edgeflags; 792 793 r300->context.set_framebuffer_state = r300_set_framebuffer_state; 794 795 r300->context.create_fs_state = r300_create_fs_state; 796 r300->context.bind_fs_state = r300_bind_fs_state; 797 r300->context.delete_fs_state = r300_delete_fs_state; 798 799 r300->context.set_polygon_stipple = r300_set_polygon_stipple; 800 801 r300->context.create_rasterizer_state = r300_create_rs_state; 802 r300->context.bind_rasterizer_state = r300_bind_rs_state; 803 r300->context.delete_rasterizer_state = r300_delete_rs_state; 804 805 r300->context.create_sampler_state = r300_create_sampler_state; 806 r300->context.bind_sampler_states = r300_bind_sampler_states; 807 r300->context.delete_sampler_state = r300_delete_sampler_state; 808 809 r300->context.set_sampler_textures = r300_set_sampler_textures; 810 811 r300->context.set_scissor_state = r300_set_scissor_state; 812 813 r300->context.set_viewport_state = r300_set_viewport_state; 814 815 r300->context.set_vertex_buffers = r300_set_vertex_buffers; 816 r300->context.set_vertex_elements = r300_set_vertex_elements; 817 818 r300->context.create_vs_state = r300_create_vs_state; 819 r300->context.bind_vs_state = r300_bind_vs_state; 820 r300->context.delete_vs_state = r300_delete_vs_state; 821} 822