r300_state.c revision 6885560de54db26683eb813756e09fa3822c3492
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 25#include "r300_context.h" 26#include "r300_reg.h" 27 28/* r300_state: Functions used to intialize state context by translating 29 * Gallium state objects into semi-native r300 state objects. 30 * 31 * XXX break this file up into pieces if it gets too big! */ 32 33/* Pack a float into a dword. */ 34static uint32_t pack_float_32(float f) 35{ 36 union { 37 float f; 38 uint32_t u; 39 } u; 40 41 u.f = f; 42 return u.u; 43} 44 45static uint32_t translate_blend_function(int blend_func) { 46 switch (blend_func) { 47 case PIPE_BLEND_ADD: 48 return R300_COMB_FCN_ADD_CLAMP; 49 case PIPE_BLEND_SUBTRACT: 50 return R300_COMB_FCN_SUB_CLAMP; 51 case PIPE_BLEND_REVERSE_SUBTRACT: 52 return R300_COMB_FCN_RSUB_CLAMP; 53 case PIPE_BLEND_MIN: 54 return R300_COMB_FCN_MIN; 55 case PIPE_BLEND_MAX: 56 return R300_COMB_FCN_MAX; 57 default: 58 /* XXX should be unreachable, handle this */ 59 break; 60 } 61 return 0; 62} 63 64/* XXX we can also offer the D3D versions of some of these... */ 65static uint32_t translate_blend_factor(int blend_fact) { 66 switch (blend_fact) { 67 case PIPE_BLENDFACTOR_ONE: 68 return R300_BLEND_GL_ONE; 69 case PIPE_BLENDFACTOR_SRC_COLOR: 70 return R300_BLEND_GL_SRC_COLOR; 71 case PIPE_BLENDFACTOR_SRC_ALPHA: 72 return R300_BLEND_GL_SRC_ALPHA; 73 case PIPE_BLENDFACTOR_DST_ALPHA: 74 return R300_BLEND_GL_DST_ALPHA; 75 case PIPE_BLENDFACTOR_DST_COLOR: 76 return R300_BLEND_GL_DST_COLOR; 77 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 78 return R300_BLEND_GL_SRC_ALPHA_SATURATE; 79 case PIPE_BLENDFACTOR_CONST_COLOR: 80 return R300_BLEND_GL_CONST_COLOR; 81 case PIPE_BLENDFACTOR_CONST_ALPHA: 82 return R300_BLEND_GL_CONST_ALPHA; 83 /* XXX WTF are these? 84 case PIPE_BLENDFACTOR_SRC1_COLOR: 85 case PIPE_BLENDFACTOR_SRC1_ALPHA: */ 86 case PIPE_BLENDFACTOR_ZERO: 87 return R300_BLEND_GL_ZERO; 88 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 89 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR; 90 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 91 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA; 92 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 93 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA; 94 case PIPE_BLENDFACTOR_INV_DST_COLOR: 95 return R300_BLEND_GL_ONE_MINUS_DST_COLOR; 96 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 97 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR; 98 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 99 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA; 100 /* XXX see above 101 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 102 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */ 103 default: 104 /* XXX the mythical 0x16 blend factor! */ 105 break; 106 } 107 return 0; 108} 109 110/* Create a new blend state based on the CSO blend state. 111 * 112 * This encompasses alpha blending, logic/raster ops, and blend dithering. */ 113static void* r300_create_blend_state(struct pipe_context* pipe, 114 const struct pipe_blend_state* state) 115{ 116 struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); 117 118 if (state->blend_enable) { 119 /* XXX for now, always do separate alpha... 120 * is it faster to do it with one reg? */ 121 blend->blend_control = R300_ALPHA_BLEND_ENABLE | 122 R300_SEPARATE_ALPHA_ENABLE | 123 R300_READ_ENABLE | 124 translate_blend_function(state->rgb_func) | 125 (translate_blend_factor(state->rgb_src_factor) << 126 R300_SRC_BLEND_SHIFT) | 127 (translate_blend_factor(state->rgb_dst_factor) << 128 R300_DST_BLEND_SHIFT); 129 blend->alpha_blend_control = 130 translate_blend_function(state->alpha_func) | 131 (translate_blend_factor(state->alpha_src_factor) << 132 R300_SRC_BLEND_SHIFT) | 133 (translate_blend_factor(state->alpha_dst_factor) << 134 R300_DST_BLEND_SHIFT); 135 } 136 137 /* PIPE_LOGICOP_* don't need to be translated, fortunately. */ 138 /* XXX are logicops still allowed if blending's disabled? 139 * Does Gallium take care of it for us? */ 140 if (state->logicop_enable) { 141 blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE | 142 (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; 143 } 144 145 if (state->dither) { 146 blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT | 147 R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT; 148 } 149 150 return (void*)blend; 151} 152 153/* Bind blend state. */ 154static void r300_bind_blend_state(struct pipe_context* pipe, 155 void* state) 156{ 157 struct r300_context* r300 = r300_context(pipe); 158 159 r300->blend_state = (struct r300_blend_state*)state; 160 r300->dirty_state |= R300_NEW_BLEND; 161} 162 163/* Free blend state. */ 164static void r300_delete_blend_state(struct pipe_context* pipe, 165 void* state) 166{ 167 FREE(state); 168} 169 170/* Set blend color. 171 * Setup both R300 and R500 registers, figure out later which one to write. */ 172static void r300_set_blend_color(struct pipe_context* pipe, 173 const struct pipe_blend_color* color) 174{ 175 struct r300_context* r300 = r300_context(pipe); 176 uint32_t r, g, b, a; 177 ubyte ur, ug, ub, ua; 178 179 r = util_iround(color->color[0] * 1023.0f); 180 g = util_iround(color->color[1] * 1023.0f); 181 b = util_iround(color->color[2] * 1023.0f); 182 a = util_iround(color->color[3] * 1023.0f); 183 184 ur = float_to_ubyte(color->color[0]); 185 ug = float_to_ubyte(color->color[1]); 186 ub = float_to_ubyte(color->color[2]); 187 ua = float_to_ubyte(color->color[3]); 188 189 r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b; 190 191 r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16); 192 r300->blend_color_state->blend_color_green_blue = ub | (ug << 16); 193 194 r300->dirty_state |= R300_NEW_BLEND_COLOR; 195} 196 197static uint32_t translate_depth_stencil_function(int zs_func) { 198 switch (zs_func) { 199 case PIPE_FUNC_NEVER: 200 return R300_ZS_NEVER; 201 case PIPE_FUNC_LESS: 202 return R300_ZS_LESS; 203 case PIPE_FUNC_EQUAL: 204 return R300_ZS_EQUAL; 205 case PIPE_FUNC_LEQUAL: 206 return R300_ZS_LEQUAL; 207 case PIPE_FUNC_GREATER: 208 return R300_ZS_GREATER; 209 case PIPE_FUNC_NOTEQUAL: 210 return R300_ZS_NOTEQUAL; 211 case PIPE_FUNC_GEQUAL: 212 return R300_ZS_GEQUAL; 213 case PIPE_FUNC_ALWAYS: 214 return R300_ZS_ALWAYS; 215 default: 216 /* XXX shouldn't be reachable */ 217 break; 218 } 219 return 0; 220} 221 222static uint32_t translate_stencil_op(int s_op) { 223 switch (s_op) { 224 case PIPE_STENCIL_OP_KEEP: 225 return R300_ZS_KEEP; 226 case PIPE_STENCIL_OP_ZERO: 227 return R300_ZS_ZERO; 228 case PIPE_STENCIL_OP_REPLACE: 229 return R300_ZS_REPLACE; 230 case PIPE_STENCIL_OP_INCR: 231 return R300_ZS_INCR; 232 case PIPE_STENCIL_OP_DECR: 233 return R300_ZS_DECR; 234 case PIPE_STENCIL_OP_INCR_WRAP: 235 return R300_ZS_INCR_WRAP; 236 case PIPE_STENCIL_OP_DECR_WRAP: 237 return R300_ZS_DECR_WRAP; 238 case PIPE_STENCIL_OP_INVERT: 239 return R300_ZS_INVERT; 240 default: 241 /* XXX shouldn't be reachable */ 242 break; 243 } 244 return 0; 245} 246 247static uint32_t translate_alpha_function(int alpha_func) { 248 switch (alpha_func) { 249 case PIPE_FUNC_NEVER: 250 return R300_FG_ALPHA_FUNC_NEVER; 251 case PIPE_FUNC_LESS: 252 return R300_FG_ALPHA_FUNC_LESS; 253 case PIPE_FUNC_EQUAL: 254 return R300_FG_ALPHA_FUNC_EQUAL; 255 case PIPE_FUNC_LEQUAL: 256 return R300_FG_ALPHA_FUNC_LE; 257 case PIPE_FUNC_GREATER: 258 return R300_FG_ALPHA_FUNC_GREATER; 259 case PIPE_FUNC_NOTEQUAL: 260 return R300_FG_ALPHA_FUNC_NOTEQUAL; 261 case PIPE_FUNC_GEQUAL: 262 return R300_FG_ALPHA_FUNC_GE; 263 case PIPE_FUNC_ALWAYS: 264 return R300_FG_ALPHA_FUNC_ALWAYS; 265 default: 266 /* XXX shouldn't be reachable */ 267 break; 268 } 269 return 0; 270} 271 272/* Create a new depth, stencil, and alpha state based on the CSO dsa state. 273 * 274 * This contains the depth buffer, stencil buffer, alpha test, and such. 275 * On the Radeon, depth and stencil buffer setup are intertwined, which is 276 * the reason for some of the strange-looking assignments across registers. */ 277static void* 278 r300_create_dsa_state(struct pipe_context* pipe, 279 const struct pipe_depth_stencil_alpha_state* state) 280{ 281 struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); 282 283 /* Depth test setup. */ 284 if (state->depth.enabled) { 285 dsa->z_buffer_control |= R300_Z_ENABLE; 286 287 if (state->depth.writemask) { 288 dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; 289 } 290 291 dsa->z_stencil_control |= 292 (translate_depth_stencil_function(state->depth.func) << 293 R300_Z_FUNC_SHIFT); 294 } 295 296 /* Stencil buffer setup. */ 297 if (state->stencil[0].enabled) { 298 dsa->z_buffer_control |= R300_STENCIL_ENABLE; 299 dsa->z_stencil_control |= 300 (translate_depth_stencil_function(state->stencil[0].func) << 301 R300_S_FRONT_FUNC_SHIFT) | 302 (translate_stencil_op(state->stencil[0].fail_op) << 303 R300_S_FRONT_SFAIL_OP_SHIFT) | 304 (translate_stencil_op(state->stencil[0].zpass_op) << 305 R300_S_FRONT_ZPASS_OP_SHIFT) | 306 (translate_stencil_op(state->stencil[0].zfail_op) << 307 R300_S_FRONT_ZFAIL_OP_SHIFT); 308 309 dsa->stencil_ref_mask = (state->stencil[0].ref_value) | 310 (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) | 311 (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT); 312 313 if (state->stencil[1].enabled) { 314 dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; 315 dsa->z_stencil_control |= 316 (translate_depth_stencil_function(state->stencil[1].func) << 317 R300_S_BACK_FUNC_SHIFT) | 318 (translate_stencil_op(state->stencil[1].fail_op) << 319 R300_S_BACK_SFAIL_OP_SHIFT) | 320 (translate_stencil_op(state->stencil[1].zpass_op) << 321 R300_S_BACK_ZPASS_OP_SHIFT) | 322 (translate_stencil_op(state->stencil[1].zfail_op) << 323 R300_S_BACK_ZFAIL_OP_SHIFT); 324 325 dsa->stencil_ref_bf = (state->stencil[1].ref_value) | 326 (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) | 327 (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT); 328 } 329 } 330 331 /* Alpha test setup. */ 332 if (state->alpha.enabled) { 333 dsa->alpha_function = translate_alpha_function(state->alpha.func) | 334 R300_FG_ALPHA_FUNC_ENABLE; 335 dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023); 336 } else { 337 dsa->z_buffer_top = R300_ZTOP_ENABLE; 338 } 339 340 return (void*)dsa; 341} 342 343/* Bind DSA state. */ 344static void r300_bind_dsa_state(struct pipe_context* pipe, 345 void* state) 346{ 347 struct r300_context* r300 = r300_context(pipe); 348 349 r300->dsa_state = (struct r300_dsa_state*)state; 350 r300->dirty_state |= R300_NEW_DSA; 351} 352 353/* Free DSA state. */ 354static void r300_delete_dsa_state(struct pipe_context* pipe, 355 void* state) 356{ 357 FREE(state); 358} 359#if 0 360struct pipe_rasterizer_state 361{ 362 unsigned flatshade:1; 363 unsigned light_twoside:1; 364 unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ 365 unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ 366 unsigned scissor:1; 367 unsigned poly_smooth:1; 368 unsigned poly_stipple_enable:1; 369 unsigned point_smooth:1; 370 unsigned point_sprite:1; 371 unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ 372 unsigned multisample:1; /* XXX maybe more ms state in future */ 373 unsigned line_smooth:1; 374 unsigned line_stipple_enable:1; 375 unsigned line_stipple_factor:8; /**< [1..256] actually */ 376 unsigned line_stipple_pattern:16; 377 unsigned line_last_pixel:1; 378 unsigned bypass_clipping:1; 379 unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is 380 still needed though, to indicate inputs/outputs */ 381 unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ 382 unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ 383 unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */ 384 385 float line_width; 386 float point_size; /**< used when no per-vertex size */ 387 float point_size_min; /* XXX - temporary, will go away */ 388 float point_size_max; /* XXX - temporary, will go away */ 389 ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ 390}; 391#endif 392/* Create a new rasterizer state based on the CSO rasterizer state. 393 * 394 * This is a very large chunk of state, and covers most of the graphics 395 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks. 396 * 397 * In a not entirely unironic sidenote, this state has nearly nothing to do 398 * with the actual block on the Radeon called the rasterizer (RS). */ 399static void* r300_create_rs_state(struct pipe_context* pipe, 400 const struct pipe_rasterizer_state* state) 401{ 402 struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); 403 404 /* Radeons don't think in "CW/CCW", they think in "front/back". */ 405 if (state->front_winding == PIPE_WINDING_CW) { 406 rs->cull_mode = R300_FRONT_FACE_CW; 407 408 if (state->offset_cw) { 409 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 410 } 411 if (state->offset_ccw) { 412 rs->polygon_offset_enable |= R300_BACK_ENABLE; 413 } 414 } else { 415 rs->cull_mode = R300_FRONT_FACE_CCW; 416 417 if (state->offset_ccw) { 418 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 419 } 420 if (state->offset_cw) { 421 rs->polygon_offset_enable |= R300_BACK_ENABLE; 422 } 423 } 424 if (state->front_winding & state->cull_mode) { 425 rs->cull_mode |= R300_CULL_FRONT; 426 } 427 if (~(state->front_winding) & state->cull_mode) { 428 rs->cull_mode |= R300_CULL_BACK; 429 } 430 431 if (rs->polygon_offset_enable) { 432 rs->depth_offset_front = rs->depth_offset_back = 433 pack_float_32(state->offset_units); 434 rs->depth_scale_front = rs->depth_scale_back = 435 pack_float_32(state->offset_scale); 436 } 437 438 /* XXX this is part of HW TCL */ 439 /* XXX endian control */ 440 rs->vap_control_status = R300_VAP_TCL_BYPASS; 441 442 return (void*)rs; 443} 444 445/* Bind rasterizer state. */ 446static void r300_bind_rs_state(struct pipe_context* pipe, void* state) 447{ 448 struct r300_context* r300 = r300_context(pipe); 449 450 r300->rs_state = (struct r300_rs_state*)state; 451 r300->dirty_state |= R300_NEW_RS; 452} 453 454/* Free rasterizer state. */ 455static void r300_delete_rs_state(struct pipe_context* pipe, void* state) 456{ 457 FREE(state); 458} 459 460static void r300_set_scissor_state(struct pipe_context* pipe, 461 const struct pipe_scissor_state* state) 462{ 463 struct r300_context* r300 = r300_context(pipe); 464 draw_flush(r300->draw); 465 466 uint32_t left, top, right, bottom; 467 468 /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in 469 * both directions for all values, and can only be 13 bits wide. Why? 470 * We may never know. */ 471 left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff; 472 top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff; 473 right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff; 474 bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff; 475 476 r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) | 477 (top << R300_SCISSORS_Y_SHIFT); 478 r300->scissor_state->scissor_bottom_right = (right << R300_SCISSORS_X_SHIFT) | 479 (bottom << R300_SCISSORS_Y_SHIFT); 480 481 r300->dirty_state |= R300_NEW_SCISSOR; 482} 483 484static void* r300_create_vs_state(struct pipe_context* pipe, 485 const struct pipe_shader_state* state) 486{ 487 struct r300_context* context = r300_context(pipe); 488 /* XXX handing this off to Draw for now */ 489 return draw_create_vertex_shader(context->draw, state); 490} 491 492static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { 493 struct r300_context* context = r300_context(pipe); 494 /* XXX handing this off to Draw for now */ 495 draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 496} 497 498static void r300_delete_vs_state(struct pipe_context* pipe, void* state) 499{ 500 struct r300_context* context = r300_context(pipe); 501 /* XXX handing this off to Draw for now */ 502 draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 503} 504 505void r300_init_state_functions(struct r300_context* r300) { 506 507 r300->context.create_blend_state = r300_create_blend_state; 508 r300->context.bind_blend_state = r300_bind_blend_state; 509 r300->context.delete_blend_state = r300_delete_blend_state; 510 511 r300->context.set_blend_color = r300_set_blend_color; 512 513 r300->context.create_rasterizer_state = r300_create_rs_state; 514 r300->context.bind_rasterizer_state = r300_bind_rs_state; 515 r300->context.delete_rasterizer_state = r300_delete_rs_state; 516 517 r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; 518 r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; 519 r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; 520 521 r300->context.set_scissor_state = r300_set_scissor_state; 522 523 r300->context.create_vs_state = r300_create_vs_state; 524 r300->context.bind_vs_state = r300_bind_vs_state; 525 r300->context.delete_vs_state = r300_delete_vs_state; 526}