r300_state.c revision 3aabfa46083daf60859bb26b65568de4cf40915f
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 debug_printf("r300: Unknown blend function %d\n", blend_func); 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 debug_printf("r300: Unknown blend factor %d\n", blend_fact); 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 debug_printf("r300: Unknown depth/stencil function %d\n", 235 zs_func); 236 break; 237 } 238 return 0; 239} 240 241static uint32_t translate_stencil_op(int s_op) { 242 switch (s_op) { 243 case PIPE_STENCIL_OP_KEEP: 244 return R300_ZS_KEEP; 245 case PIPE_STENCIL_OP_ZERO: 246 return R300_ZS_ZERO; 247 case PIPE_STENCIL_OP_REPLACE: 248 return R300_ZS_REPLACE; 249 case PIPE_STENCIL_OP_INCR: 250 return R300_ZS_INCR; 251 case PIPE_STENCIL_OP_DECR: 252 return R300_ZS_DECR; 253 case PIPE_STENCIL_OP_INCR_WRAP: 254 return R300_ZS_INCR_WRAP; 255 case PIPE_STENCIL_OP_DECR_WRAP: 256 return R300_ZS_DECR_WRAP; 257 case PIPE_STENCIL_OP_INVERT: 258 return R300_ZS_INVERT; 259 default: 260 debug_printf("r300: Unknown stencil op %d", s_op); 261 break; 262 } 263 return 0; 264} 265 266static uint32_t translate_alpha_function(int alpha_func) { 267 switch (alpha_func) { 268 case PIPE_FUNC_NEVER: 269 return R300_FG_ALPHA_FUNC_NEVER; 270 case PIPE_FUNC_LESS: 271 return R300_FG_ALPHA_FUNC_LESS; 272 case PIPE_FUNC_EQUAL: 273 return R300_FG_ALPHA_FUNC_EQUAL; 274 case PIPE_FUNC_LEQUAL: 275 return R300_FG_ALPHA_FUNC_LE; 276 case PIPE_FUNC_GREATER: 277 return R300_FG_ALPHA_FUNC_GREATER; 278 case PIPE_FUNC_NOTEQUAL: 279 return R300_FG_ALPHA_FUNC_NOTEQUAL; 280 case PIPE_FUNC_GEQUAL: 281 return R300_FG_ALPHA_FUNC_GE; 282 case PIPE_FUNC_ALWAYS: 283 return R300_FG_ALPHA_FUNC_ALWAYS; 284 default: 285 debug_printf("r300: Unknown alpha function %d", alpha_func); 286 break; 287 } 288 return 0; 289} 290 291/* Create a new depth, stencil, and alpha state based on the CSO dsa state. 292 * 293 * This contains the depth buffer, stencil buffer, alpha test, and such. 294 * On the Radeon, depth and stencil buffer setup are intertwined, which is 295 * the reason for some of the strange-looking assignments across registers. */ 296static void* 297 r300_create_dsa_state(struct pipe_context* pipe, 298 const struct pipe_depth_stencil_alpha_state* state) 299{ 300 struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); 301 302 /* Depth test setup. */ 303 if (state->depth.enabled) { 304 dsa->z_buffer_control |= R300_Z_ENABLE; 305 306 if (state->depth.writemask) { 307 dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; 308 } 309 310 dsa->z_stencil_control |= 311 (translate_depth_stencil_function(state->depth.func) << 312 R300_Z_FUNC_SHIFT); 313 } 314 315 /* Stencil buffer setup. */ 316 if (state->stencil[0].enabled) { 317 dsa->z_buffer_control |= R300_STENCIL_ENABLE; 318 dsa->z_stencil_control |= 319 (translate_depth_stencil_function(state->stencil[0].func) << 320 R300_S_FRONT_FUNC_SHIFT) | 321 (translate_stencil_op(state->stencil[0].fail_op) << 322 R300_S_FRONT_SFAIL_OP_SHIFT) | 323 (translate_stencil_op(state->stencil[0].zpass_op) << 324 R300_S_FRONT_ZPASS_OP_SHIFT) | 325 (translate_stencil_op(state->stencil[0].zfail_op) << 326 R300_S_FRONT_ZFAIL_OP_SHIFT); 327 328 dsa->stencil_ref_mask = (state->stencil[0].ref_value) | 329 (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) | 330 (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT); 331 332 if (state->stencil[1].enabled) { 333 dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; 334 dsa->z_stencil_control |= 335 (translate_depth_stencil_function(state->stencil[1].func) << 336 R300_S_BACK_FUNC_SHIFT) | 337 (translate_stencil_op(state->stencil[1].fail_op) << 338 R300_S_BACK_SFAIL_OP_SHIFT) | 339 (translate_stencil_op(state->stencil[1].zpass_op) << 340 R300_S_BACK_ZPASS_OP_SHIFT) | 341 (translate_stencil_op(state->stencil[1].zfail_op) << 342 R300_S_BACK_ZFAIL_OP_SHIFT); 343 344 dsa->stencil_ref_bf = (state->stencil[1].ref_value) | 345 (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) | 346 (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT); 347 } 348 } 349 350 /* Alpha test setup. */ 351 if (state->alpha.enabled) { 352 dsa->alpha_function = translate_alpha_function(state->alpha.func) | 353 R300_FG_ALPHA_FUNC_ENABLE; 354 dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f, 355 0, 1023); 356 } else { 357 dsa->z_buffer_top = R300_ZTOP_ENABLE; 358 } 359 360 return (void*)dsa; 361} 362 363/* Bind DSA state. */ 364static void r300_bind_dsa_state(struct pipe_context* pipe, 365 void* state) 366{ 367 struct r300_context* r300 = r300_context(pipe); 368 369 r300->dsa_state = (struct r300_dsa_state*)state; 370 r300->dirty_state |= R300_NEW_DSA; 371} 372 373/* Free DSA state. */ 374static void r300_delete_dsa_state(struct pipe_context* pipe, 375 void* state) 376{ 377 FREE(state); 378} 379 380static void r300_set_edgeflags(struct pipe_context* pipe, 381 const unsigned* bitfield) 382{ 383 /* XXX you know it's bad when i915 has this blank too */ 384} 385 386static void 387 r300_set_framebuffer_state(struct pipe_context* pipe, 388 const struct pipe_framebuffer_state* state) 389{ 390 struct r300_context* r300 = r300_context(pipe); 391 392 draw_flush(r300->draw); 393 394 r300->framebuffer_state = *state; 395 396 /* XXX do we need to mark dirty state? */ 397} 398 399/* Create fragment shader state. */ 400static void* r300_create_fs_state(struct pipe_context* pipe, 401 const struct pipe_shader_state* state) 402{ 403 struct r300_fs_state* fs = CALLOC_STRUCT(r300_fs_state); 404 405 return (void*)fs; 406} 407 408/* Bind fragment shader state. */ 409static void r300_bind_fs_state(struct pipe_context* pipe, void* state) 410{ 411 struct r300_context* r300 = r300_context(pipe); 412 413 r300->fs_state = (struct r300_fs_state*)state; 414 415 r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; 416} 417 418/* Delect fragment shader state. */ 419static void r300_delete_fs_state(struct pipe_context* pipe, void* state) 420{ 421 FREE(state); 422} 423 424static void r300_set_polygon_stipple(struct pipe_context* pipe, 425 const struct pipe_poly_stipple* state) 426{ 427 /* XXX */ 428} 429 430#if 0 431struct pipe_rasterizer_state 432{ 433 unsigned flatshade:1; 434 unsigned light_twoside:1; 435 unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ 436 unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ 437 unsigned scissor:1; 438 unsigned poly_smooth:1; 439 unsigned poly_stipple_enable:1; 440 unsigned point_smooth:1; 441 unsigned point_sprite:1; 442 unsigned multisample:1; /* XXX maybe more ms state in future */ 443 unsigned line_smooth:1; 444 unsigned line_last_pixel:1; 445 unsigned bypass_clipping:1; 446 unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is 447 still needed though, to indicate inputs/outputs */ 448 unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ 449 unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ 450 unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */ 451 ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ 452}; 453#endif 454 455static INLINE int pack_float_16_6x(float f) { 456 return ((int)(f * 6.0) & 0xffff); 457} 458 459/* Create a new rasterizer state based on the CSO rasterizer state. 460 * 461 * This is a very large chunk of state, and covers most of the graphics 462 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks. 463 * 464 * In a not entirely unironic sidenote, this state has nearly nothing to do 465 * with the actual block on the Radeon called the rasterizer (RS). */ 466static void* r300_create_rs_state(struct pipe_context* pipe, 467 const struct pipe_rasterizer_state* state) 468{ 469 struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); 470 471 /* XXX this is part of HW TCL */ 472 /* XXX endian control */ 473 rs->vap_control_status = R300_VAP_TCL_BYPASS; 474 475 rs->point_size = pack_float_16_6x(state->point_size) | 476 (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); 477 478 rs->line_control = pack_float_16_6x(state->line_width) | 479 R300_GA_LINE_CNTL_END_TYPE_COMP; 480 481 /* Radeons don't think in "CW/CCW", they think in "front/back". */ 482 if (state->front_winding == PIPE_WINDING_CW) { 483 rs->cull_mode = R300_FRONT_FACE_CW; 484 485 if (state->offset_cw) { 486 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 487 } 488 if (state->offset_ccw) { 489 rs->polygon_offset_enable |= R300_BACK_ENABLE; 490 } 491 } else { 492 rs->cull_mode = R300_FRONT_FACE_CCW; 493 494 if (state->offset_ccw) { 495 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 496 } 497 if (state->offset_cw) { 498 rs->polygon_offset_enable |= R300_BACK_ENABLE; 499 } 500 } 501 if (state->front_winding & state->cull_mode) { 502 rs->cull_mode |= R300_CULL_FRONT; 503 } 504 if (~(state->front_winding) & state->cull_mode) { 505 rs->cull_mode |= R300_CULL_BACK; 506 } 507 508 if (rs->polygon_offset_enable) { 509 rs->depth_offset_front = rs->depth_offset_back = 510 pack_float_32(state->offset_units); 511 rs->depth_scale_front = rs->depth_scale_back = 512 pack_float_32(state->offset_scale); 513 } 514 515 if (state->line_stipple_enable) { 516 rs->line_stipple_config = 517 R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE | 518 (pack_float_32((float)state->line_stipple_factor) & 519 R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK); 520 /* XXX this might need to be scaled up */ 521 rs->line_stipple_value = state->line_stipple_pattern; 522 } 523 524 return (void*)rs; 525} 526 527/* Bind rasterizer state. */ 528static void r300_bind_rs_state(struct pipe_context* pipe, void* state) 529{ 530 struct r300_context* r300 = r300_context(pipe); 531 532 r300->rs_state = (struct r300_rs_state*)state; 533 r300->dirty_state |= R300_NEW_RASTERIZER; 534} 535 536/* Free rasterizer state. */ 537static void r300_delete_rs_state(struct pipe_context* pipe, void* state) 538{ 539 FREE(state); 540} 541 542static uint32_t translate_wrap(int wrap) { 543 switch (wrap) { 544 case PIPE_TEX_WRAP_REPEAT: 545 return R300_TX_REPEAT; 546 case PIPE_TEX_WRAP_CLAMP: 547 return R300_TX_CLAMP; 548 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 549 return R300_TX_CLAMP_TO_EDGE; 550 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 551 return R300_TX_CLAMP_TO_BORDER; 552 case PIPE_TEX_WRAP_MIRROR_REPEAT: 553 return R300_TX_REPEAT | R300_TX_MIRRORED; 554 case PIPE_TEX_WRAP_MIRROR_CLAMP: 555 return R300_TX_CLAMP | R300_TX_MIRRORED; 556 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 557 return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; 558 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 559 return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; 560 default: 561 debug_printf("r300: Unknown texture wrap %d", wrap); 562 return 0; 563 } 564} 565 566static uint32_t translate_tex_filters(int min, int mag, int mip) { 567 uint32_t retval = 0; 568 switch (min) { 569 case PIPE_TEX_FILTER_NEAREST: 570 retval |= R300_TX_MIN_FILTER_NEAREST; 571 case PIPE_TEX_FILTER_LINEAR: 572 retval |= R300_TX_MIN_FILTER_LINEAR; 573 case PIPE_TEX_FILTER_ANISO: 574 retval |= R300_TX_MIN_FILTER_ANISO; 575 default: 576 debug_printf("r300: Unknown texture filter %d", min); 577 break; 578 } 579 switch (mag) { 580 case PIPE_TEX_FILTER_NEAREST: 581 retval |= R300_TX_MAG_FILTER_NEAREST; 582 case PIPE_TEX_FILTER_LINEAR: 583 retval |= R300_TX_MAG_FILTER_LINEAR; 584 case PIPE_TEX_FILTER_ANISO: 585 retval |= R300_TX_MAG_FILTER_ANISO; 586 default: 587 debug_printf("r300: Unknown texture filter %d", mag); 588 break; 589 } 590 switch (mip) { 591 case PIPE_TEX_MIPFILTER_NONE: 592 retval |= R300_TX_MIN_FILTER_MIP_NONE; 593 case PIPE_TEX_MIPFILTER_NEAREST: 594 retval |= R300_TX_MIN_FILTER_MIP_NEAREST; 595 case PIPE_TEX_MIPFILTER_LINEAR: 596 retval |= R300_TX_MIN_FILTER_MIP_LINEAR; 597 default: 598 debug_printf("r300: Unknown texture filter %d", mip); 599 break; 600 } 601 602 return retval; 603} 604 605static uint32_t anisotropy(float max_aniso) { 606 if (max_aniso >= 16.0f) { 607 return R300_TX_MAX_ANISO_16_TO_1; 608 } else if (max_aniso >= 8.0f) { 609 return R300_TX_MAX_ANISO_8_TO_1; 610 } else if (max_aniso >= 4.0f) { 611 return R300_TX_MAX_ANISO_4_TO_1; 612 } else if (max_aniso >= 2.0f) { 613 return R300_TX_MAX_ANISO_2_TO_1; 614 } else { 615 return R300_TX_MAX_ANISO_1_TO_1; 616 } 617} 618 619static void* 620 r300_create_sampler_state(struct pipe_context* pipe, 621 const struct pipe_sampler_state* state) 622{ 623 struct r300_context* r300 = r300_context(pipe); 624 struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); 625 int lod_bias; 626 627 sampler->filter0 |= 628 (translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | 629 (translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) | 630 (translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT); 631 632 sampler->filter0 |= translate_tex_filters(state->min_img_filter, 633 state->mag_img_filter, 634 state->min_mip_filter); 635 636 lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); 637 638 sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; 639 640 sampler->filter1 |= anisotropy(state->max_anisotropy); 641 642 util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, 643 &sampler->border_color); 644 645 /* R500-specific fixups and optimizations */ 646 if (r300_screen(r300->context.screen)->caps->is_r500) { 647 sampler->filter1 |= R500_BORDER_FIX; 648 } 649 650 return (void*)sampler; 651} 652 653static void r300_bind_sampler_states(struct pipe_context* pipe, 654 unsigned count, 655 void** states) 656{ 657 struct r300_context* r300 = r300_context(pipe); 658 int i; 659 660 if (count > 8) { 661 return; 662 } 663 664 for (i = 0; i < count; i++) { 665 if (r300->sampler_states[i] != states[i]) { 666 r300->sampler_states[i] = (struct r300_sampler_state*)states[i]; 667 r300->dirty_state |= (R300_NEW_SAMPLER << i); 668 } 669 } 670 671 r300->sampler_count = count; 672} 673 674static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) 675{ 676 FREE(state); 677} 678 679static void r300_set_sampler_textures(struct pipe_context* pipe, 680 unsigned count, 681 struct pipe_texture** texture) 682{ 683 struct r300_context* r300 = r300_context(pipe); 684 int i; 685 686 /* XXX magic num */ 687 if (count > 8) { 688 return; 689 } 690 691 for (i = 0; i < count; i++) { 692 if (r300->textures[i] != (struct r300_texture*)texture[i]) { 693 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 694 texture[i]); 695 /* XXX NEW_TEXTURE instead? */ 696 r300->dirty_state |= (R300_NEW_SAMPLER << i); 697 } 698 } 699 700 for (i = count; i < 8; i++) { 701 /* XXX also state change? */ 702 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 703 NULL); 704 } 705 706 r300->texture_count = count; 707} 708 709static void r300_set_scissor_state(struct pipe_context* pipe, 710 const struct pipe_scissor_state* state) 711{ 712 struct r300_context* r300 = r300_context(pipe); 713 draw_flush(r300->draw); 714 715 uint32_t left, top, right, bottom; 716 717 /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in 718 * both directions for all values, and can only be 13 bits wide. Why? 719 * We may never know. */ 720 left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff; 721 top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff; 722 right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff; 723 bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff; 724 725 r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) | 726 (top << R300_SCISSORS_Y_SHIFT); 727 r300->scissor_state->scissor_bottom_right = 728 (right << R300_SCISSORS_X_SHIFT) | (bottom << R300_SCISSORS_Y_SHIFT); 729 730 r300->dirty_state |= R300_NEW_SCISSOR; 731} 732 733static void r300_set_viewport_state(struct pipe_context* pipe, 734 const struct pipe_viewport_state* state) 735{ 736 struct r300_context* r300 = r300_context(pipe); 737 /* XXX handing this off to Draw for now */ 738 draw_set_viewport_state(r300->draw, state); 739} 740 741static void r300_set_vertex_buffers(struct pipe_context* pipe, 742 unsigned count, 743 const struct pipe_vertex_buffer* buffers) 744{ 745 struct r300_context* r300 = r300_context(pipe); 746 /* XXX Draw */ 747 draw_flush(r300->draw); 748 draw_set_vertex_buffers(r300->draw, count, buffers); 749} 750 751static void r300_set_vertex_elements(struct pipe_context* pipe, 752 unsigned count, 753 const struct pipe_vertex_element* elements) 754{ 755 struct r300_context* r300 = r300_context(pipe); 756 /* XXX Draw */ 757 draw_flush(r300->draw); 758 draw_set_vertex_elements(r300->draw, count, elements); 759} 760 761static void* r300_create_vs_state(struct pipe_context* pipe, 762 const struct pipe_shader_state* state) 763{ 764 struct r300_context* context = r300_context(pipe); 765 /* XXX handing this off to Draw for now */ 766 return draw_create_vertex_shader(context->draw, state); 767} 768 769static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { 770 struct r300_context* context = r300_context(pipe); 771 /* XXX handing this off to Draw for now */ 772 draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 773} 774 775static void r300_delete_vs_state(struct pipe_context* pipe, void* state) 776{ 777 struct r300_context* context = r300_context(pipe); 778 /* XXX handing this off to Draw for now */ 779 draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 780} 781 782void r300_init_state_functions(struct r300_context* r300) 783{ 784 r300->context.create_blend_state = r300_create_blend_state; 785 r300->context.bind_blend_state = r300_bind_blend_state; 786 r300->context.delete_blend_state = r300_delete_blend_state; 787 788 r300->context.set_blend_color = r300_set_blend_color; 789 790 r300->context.set_clip_state = r300_set_clip_state; 791 792 r300->context.set_constant_buffer = r300_set_constant_buffer; 793 794 r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; 795 r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; 796 r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; 797 798 r300->context.set_edgeflags = r300_set_edgeflags; 799 800 r300->context.set_framebuffer_state = r300_set_framebuffer_state; 801 802 r300->context.create_fs_state = r300_create_fs_state; 803 r300->context.bind_fs_state = r300_bind_fs_state; 804 r300->context.delete_fs_state = r300_delete_fs_state; 805 806 r300->context.set_polygon_stipple = r300_set_polygon_stipple; 807 808 r300->context.create_rasterizer_state = r300_create_rs_state; 809 r300->context.bind_rasterizer_state = r300_bind_rs_state; 810 r300->context.delete_rasterizer_state = r300_delete_rs_state; 811 812 r300->context.create_sampler_state = r300_create_sampler_state; 813 r300->context.bind_sampler_states = r300_bind_sampler_states; 814 r300->context.delete_sampler_state = r300_delete_sampler_state; 815 816 r300->context.set_sampler_textures = r300_set_sampler_textures; 817 818 r300->context.set_scissor_state = r300_set_scissor_state; 819 820 r300->context.set_viewport_state = r300_set_viewport_state; 821 822 r300->context.set_vertex_buffers = r300_set_vertex_buffers; 823 r300->context.set_vertex_elements = r300_set_vertex_elements; 824 825 r300->context.create_vs_state = r300_create_vs_state; 826 r300->context.bind_vs_state = r300_bind_vs_state; 827 r300->context.delete_vs_state = r300_delete_vs_state; 828} 829