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