r300_state.c revision a08a830fd3c22bdbad1ee840e4e56302152375f1
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 168static uint32_t translate_depth_stencil_function(int zs_func) { 169 switch (zs_func) { 170 case PIPE_FUNC_NEVER: 171 return R300_ZS_NEVER; 172 case PIPE_FUNC_LESS: 173 return R300_ZS_LESS; 174 case PIPE_FUNC_EQUAL: 175 return R300_ZS_EQUAL; 176 case PIPE_FUNC_LEQUAL: 177 return R300_ZS_LEQUAL; 178 case PIPE_FUNC_GREATER: 179 return R300_ZS_GREATER; 180 case PIPE_FUNC_NOTEQUAL: 181 return R300_ZS_NOTEQUAL; 182 case PIPE_FUNC_GEQUAL: 183 return R300_ZS_GEQUAL; 184 case PIPE_FUNC_ALWAYS: 185 return R300_ZS_ALWAYS; 186 default: 187 /* XXX shouldn't be reachable */ 188 break; 189 } 190 return 0; 191} 192 193static uint32_t translate_stencil_op(int s_op) { 194 switch (s_op) { 195 case PIPE_STENCIL_OP_KEEP: 196 return R300_ZS_KEEP; 197 case PIPE_STENCIL_OP_ZERO: 198 return R300_ZS_ZERO; 199 case PIPE_STENCIL_OP_REPLACE: 200 return R300_ZS_REPLACE; 201 case PIPE_STENCIL_OP_INCR: 202 return R300_ZS_INCR; 203 case PIPE_STENCIL_OP_DECR: 204 return R300_ZS_DECR; 205 case PIPE_STENCIL_OP_INCR_WRAP: 206 return R300_ZS_INCR_WRAP; 207 case PIPE_STENCIL_OP_DECR_WRAP: 208 return R300_ZS_DECR_WRAP; 209 case PIPE_STENCIL_OP_INVERT: 210 return R300_ZS_INVERT; 211 default: 212 /* XXX shouldn't be reachable */ 213 break; 214 } 215 return 0; 216} 217 218static uint32_t translate_alpha_function(int alpha_func) { 219 switch (alpha_func) { 220 case PIPE_FUNC_NEVER: 221 return R300_FG_ALPHA_FUNC_NEVER; 222 case PIPE_FUNC_LESS: 223 return R300_FG_ALPHA_FUNC_LESS; 224 case PIPE_FUNC_EQUAL: 225 return R300_FG_ALPHA_FUNC_EQUAL; 226 case PIPE_FUNC_LEQUAL: 227 return R300_FG_ALPHA_FUNC_LE; 228 case PIPE_FUNC_GREATER: 229 return R300_FG_ALPHA_FUNC_GREATER; 230 case PIPE_FUNC_NOTEQUAL: 231 return R300_FG_ALPHA_FUNC_NOTEQUAL; 232 case PIPE_FUNC_GEQUAL: 233 return R300_FG_ALPHA_FUNC_GE; 234 case PIPE_FUNC_ALWAYS: 235 return R300_FG_ALPHA_FUNC_ALWAYS; 236 default: 237 /* XXX shouldn't be reachable */ 238 break; 239 } 240 return 0; 241} 242 243/* Create a new depth, stencil, and alpha state based on the CSO dsa state. 244 * 245 * This contains the depth buffer, stencil buffer, alpha test, and such. 246 * On the Radeon, depth and stencil buffer setup are intertwined, which is 247 * the reason for some of the strange-looking assignments across registers. */ 248static void* r300_create_dsa_state(struct pipe_context* pipe, 249 struct pipe_depth_stencil_alpha_state* state) 250{ 251 struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); 252 253 /* Depth test setup. */ 254 if (state->depth.enabled) { 255 dsa->z_buffer_control |= R300_Z_ENABLE; 256 257 if (state->depth.writemask) { 258 dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; 259 } 260 261 dsa->z_stencil_control |= 262 (translate_depth_stencil_function(state->depth.func) << 263 R300_Z_FUNC_SHIFT); 264 } 265 266 /* Stencil buffer setup. */ 267 if (state->stencil[0].enabled) { 268 dsa->z_buffer_control |= R300_STENCIL_ENABLE; 269 dsa->z_stencil_control |= 270 (translate_depth_stencil_function(state->stencil[0].func) << 271 R300_S_FRONT_FUNC_SHIFT) | 272 (translate_stencil_op(state->stencil[0].fail_op) << 273 R300_S_FRONT_SFAIL_OP_SHIFT) | 274 (translate_stencil_op(state->stencil[0].zpass_op) << 275 R300_S_FRONT_ZPASS_OP_SHIFT) | 276 (translate_stencil_op(state->stencil[0].zfail_op) << 277 R300_S_FRONT_ZFAIL_OP_SHIFT); 278 279 dsa->stencil_ref_mask = (state->stencil[0].ref_value) | 280 (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) | 281 (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT); 282 283 if (state->stencil[1].enabled) { 284 dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; 285 dsa->z_stencil_control |= 286 (translate_depth_stencil_function(state->stencil[1].func) << 287 R300_S_BACK_FUNC_SHIFT) | 288 (translate_stencil_op(state->stencil[1].fail_op) << 289 R300_S_BACK_SFAIL_OP_SHIFT) | 290 (translate_stencil_op(state->stencil[1].zpass_op) << 291 R300_S_BACK_ZPASS_OP_SHIFT) | 292 (translate_stencil_op(state->stencil[1].zfail_op) << 293 R300_S_BACK_ZFAIL_OP_SHIFT); 294 295 dsa->stencil_ref_bf = (state->stencil[1].ref_value) | 296 (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) | 297 (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT); 298 } 299 } 300 301 /* Alpha test setup. */ 302 if (state->alpha.enabled) { 303 dsa->alpha_function = translate_alpha_function(state->alpha.func) | 304 R300_FG_ALPHA_FUNC_ENABLE; 305 dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023); 306 } else { 307 dsa->z_buffer_top = R300_ZTOP_ENABLE; 308 } 309 310 return (void*)dsa; 311} 312 313/* Bind DSA state. */ 314static void r300_bind_dsa_state(struct pipe_context* pipe, 315 void* state) 316{ 317 struct r300_context* r300 = r300_context(pipe); 318 319 r300->dsa_state = (struct r300_dsa_state*)state; 320 r300->dirty_state |= R300_NEW_DSA; 321} 322 323/* Free DSA state. */ 324static void r300_delete_dsa_state(struct pipe_context* pipe, 325 void* state) 326{ 327 FREE(state); 328} 329#if 0 330struct pipe_rasterizer_state 331{ 332 unsigned flatshade:1; 333 unsigned light_twoside:1; 334 unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ 335 unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ 336 unsigned scissor:1; 337 unsigned poly_smooth:1; 338 unsigned poly_stipple_enable:1; 339 unsigned point_smooth:1; 340 unsigned point_sprite:1; 341 unsigned point_size_per_vertex:1; /**< size computed in vertex shader */ 342 unsigned multisample:1; /* XXX maybe more ms state in future */ 343 unsigned line_smooth:1; 344 unsigned line_stipple_enable:1; 345 unsigned line_stipple_factor:8; /**< [1..256] actually */ 346 unsigned line_stipple_pattern:16; 347 unsigned line_last_pixel:1; 348 unsigned bypass_clipping:1; 349 unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is 350 still needed though, to indicate inputs/outputs */ 351 unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ 352 unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ 353 unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */ 354 355 float line_width; 356 float point_size; /**< used when no per-vertex size */ 357 float point_size_min; /* XXX - temporary, will go away */ 358 float point_size_max; /* XXX - temporary, will go away */ 359 ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */ 360}; 361#endif 362/* Create a new rasterizer state based on the CSO rasterizer state. 363 * 364 * This is a very large chunk of state, and covers most of the graphics 365 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks. 366 * 367 * In a not entirely unironic sidenote, this state has nearly nothing to do 368 * with the actual block on the Radeon called the rasterizer (RS). */ 369static void* r300_create_rs_state(struct pipe_context* pipe, 370 struct pipe_rasterizer_state* state) 371{ 372 struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); 373 374 /* Radeons don't think in "CW/CCW", they think in "front/back". */ 375 if (state->front_winding == PIPE_WINDING_CW) { 376 rs->cull_mode = R300_FRONT_FACE_CW; 377 378 if (state->offset_cw) { 379 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 380 } 381 if (state->offset_ccw) { 382 rs->polygon_offset_enable |= R300_BACK_ENABLE; 383 } 384 } else { 385 rs->cull_mode = R300_FRONT_FACE_CCW; 386 387 if (state->offset_ccw) { 388 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 389 } 390 if (state->offset_cw) { 391 rs->polygon_offset_enable |= R300_BACK_ENABLE; 392 } 393 } 394 if (state->front_winding & state->cull_mode) { 395 rs->cull_mode |= R300_CULL_FRONT; 396 } 397 if (~(state->front_winding) & state->cull_mode) { 398 rs->cull_mode |= R300_CULL_BACK; 399 } 400 401 if (rs->polygon_offset_enable) { 402 rs->depth_offset_front = rs->depth_offset_back = 403 pack_float_32(state->offset_units); 404 rs->depth_scale_front = rs->depth_scale_back = 405 pack_float_32(state->offset_scale); 406 } 407 408 return (void*)rs; 409} 410 411/* Bind rasterizer state. */ 412static void r300_bind_rs_state(struct pipe_context* pipe, void* state) 413{ 414 struct r300_context* r300 = r300_context(pipe); 415 416 r300->rs_state = (struct r300_rs_state*)state; 417 r300->dirty_state |= R300_NEW_RS; 418} 419 420/* Free rasterizer state. */ 421static void r300_delete_rs_state(struct pipe_context* pipe, void* state) 422{ 423 FREE(state); 424} 425 426static void r300_set_scissor_state(struct pipe_context* pipe, 427 struct pipe_scissor_state* state) 428{ 429 struct r300_context* r300 = r300_context(pipe); 430 draw_flush(r300->draw); 431 432 uint32_t left, top, right, bottom; 433 434 /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in 435 * both directions for all values, and can only be 13 bits wide. Why? 436 * We may never know. */ 437 left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff; 438 top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff; 439 right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff; 440 bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff; 441 442 r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) | 443 (top << R300_SCISSORS_Y_SHIFT); 444 r300->scissor_state->scissor_bottom_right = (right << R300_SCISSORS_X_SHIFT) | 445 (bottom << R300_SCISSORS_Y_SHIFT); 446 447 r300->dirty_state |= R300_NEW_SCISSOR; 448} 449 450static void* r300_create_vs_state(struct pipe_context* pipe, 451 struct pipe_shader_state* state) 452{ 453 struct r300_context* context = r300_context(pipe); 454 /* XXX handing this off to Draw for now */ 455 return draw_create_vertex_shader(context->draw, state); 456} 457 458static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { 459 struct r300_context* context = r300_context(pipe); 460 /* XXX handing this off to Draw for now */ 461 draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 462} 463 464static void r300_delete_vs_state(struct pipe_context* pipe, void* state) 465{ 466 struct r300_context* context = r300_context(pipe); 467 /* XXX handing this off to Draw for now */ 468 draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 469} 470 471void r300_init_state_functions(struct r300_context* r300) { 472 473 r300->context.create_blend_state = r300_create_blend_state; 474 r300->context.bind_blend_state = r300_bind_blend_state; 475 r300->context.delete_blend_state = r300_delete_blend_state; 476 477 r300->context.create_rasterizer_state = r300_create_rs_state; 478 r300->context.bind_rasterizer_state = r300_bind_rs_state; 479 r300->context.delete_rasterizer_state = r300_delete_rs_state; 480 481 r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; 482 r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; 483 r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; 484 485 r300->context.set_scissor_state = r300_set_scissor_state; 486 487 r300->context.create_vs_state = r300_create_vs_state; 488 r300->context.bind_vs_state = r300_bind_vs_state; 489 r300->context.delete_vs_state = r300_delete_vs_state; 490}