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