r300_state.c revision 21a5a133fff3ab1a068a11a32144dcb63f1d5020
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 26static uint32_t translate_blend_function(int blend_func) { 27 switch (blend_func) { 28 case PIPE_BLEND_ADD: 29 return R300_COMB_FCN_ADD_CLAMP; 30 case PIPE_BLEND_SUBTRACT: 31 return R300_COMB_FCN_SUB_CLAMP; 32 case PIPE_BLEND_REVERSE_SUBTRACT: 33 return R300_COMB_FCN_RSUB_CLAMP; 34 case PIPE_BLEND_MIN: 35 return R300_COMB_FCN_MIN; 36 case PIPE_BLEND_MAX: 37 return R300_COMB_FCN_MAX; 38 default: 39 /* XXX should be unreachable, handle this */ 40 break; 41 } 42 return 0; 43} 44 45/* XXX we can also offer the D3D versions of some of these... */ 46static uint32_t translate_blend_factor(int blend_fact) { 47 switch (blend_fact) { 48 case PIPE_BLENDFACTOR_ONE: 49 return R300_BLEND_GL_ONE; 50 case PIPE_BLENDFACTOR_SRC_COLOR: 51 return R300_BLEND_GL_SRC_COLOR; 52 case PIPE_BLENDFACTOR_SRC_ALPHA: 53 return R300_BLEND_GL_SRC_ALPHA; 54 case PIPE_BLENDFACTOR_DST_ALPHA: 55 return R300_BLEND_GL_DST_ALPHA; 56 case PIPE_BLENDFACTOR_DST_COLOR: 57 return R300_BLEND_GL_DST_COLOR; 58 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: 59 return R300_BLEND_GL_SRC_ALPHA_SATURATE; 60 case PIPE_BLENDFACTOR_CONST_COLOR: 61 return R300_BLEND_GL_CONST_COLOR; 62 case PIPE_BLENDFACTOR_CONST_ALPHA: 63 return R300_BLEND_GL_CONST_ALPHA; 64 /* XXX WTF are these? 65 case PIPE_BLENDFACTOR_SRC1_COLOR: 66 case PIPE_BLENDFACTOR_SRC1_ALPHA: */ 67 case PIPE_BLENDFACTOR_ZERO: 68 return R300_BLEND_GL_ZERO; 69 case PIPE_BLENDFACTOR_INV_SRC_COLOR: 70 return R300_BLEND_GL_ONE_MINUS_SRC_COLOR; 71 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: 72 return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA; 73 case PIPE_BLENDFACTOR_INV_DST_ALPHA: 74 return R300_BLEND_GL_ONE_MINUS_DST_ALPHA; 75 case PIPE_BLENDFACTOR_INV_DST_COLOR: 76 return R300_BLEND_GL_ONE_MINUS_DST_COLOR; 77 case PIPE_BLENDFACTOR_INV_CONST_COLOR: 78 return R300_BLEND_GL_ONE_MINUS_CONST_COLOR; 79 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 80 return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA; 81 /* XXX see above 82 case PIPE_BLENDFACTOR_INV_SRC1_COLOR: 83 case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */ 84 default: 85 /* XXX the mythical 0x16 blend factor! */ 86 break; 87 } 88 return 0; 89} 90 91/* Create a new blend state based on the CSO blend state. 92 * 93 * This encompasses alpha blending, logic/raster ops, and blend dithering. */ 94static void* r300_create_blend_state(struct pipe_context* pipe, 95 const struct pipe_blend_state* state) 96{ 97 struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); 98 99 if (state->blend_enable) { 100 /* XXX for now, always do separate alpha... 101 * is it faster to do it with one reg? */ 102 blend->blend_control = R300_ALPHA_BLEND_ENABLE | 103 R300_SEPARATE_ALPHA_ENABLE | 104 R300_READ_ENABLE | 105 translate_blend_function(state->rgb_func) | 106 (translate_blend_factor(state->rgb_src_factor) << 107 R300_SRC_BLEND_SHIFT) | 108 (translate_blend_factor(state->rgb_dst_factor) << 109 R300_DST_BLEND_SHIFT); 110 blend->alpha_blend_control = 111 translate_blend_function(state->alpha_func) | 112 (translate_blend_factor(state->alpha_src_factor) << 113 R300_SRC_BLEND_SHIFT) | 114 (translate_blend_factor(state->alpha_dst_factor) << 115 R300_DST_BLEND_SHIFT); 116 } 117 118 /* PIPE_LOGICOP_* don't need to be translated, fortunately. */ 119 /* XXX are logicops still allowed if blending's disabled? 120 * Does Gallium take care of it for us? */ 121 if (state->logicop_enable) { 122 blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE | 123 (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; 124 } 125 126 if (state->dither) { 127 blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT | 128 R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT; 129 } 130 131 return (void*)blend; 132} 133 134/* Bind blend state. */ 135static void r300_bind_blend_state(struct pipe_context* pipe, 136 void* state) 137{ 138 struct r300_context* r300 = r300_context(pipe); 139 140 r300->blend_state = (struct r300_blend_state*)state; 141 r300->dirty_state |= R300_NEW_BLEND; 142} 143 144/* Free blend state. */ 145static void r300_delete_blend_state(struct pipe_context* pipe, 146 void* state) 147{ 148 FREE(state); 149} 150 151static uint32_t translate_depth_stencil_function(int zs_func) { 152 switch (zs_func) { 153 case PIPE_FUNC_NEVER: 154 return R300_ZS_NEVER; 155 case PIPE_FUNC_LESS: 156 return R300_ZS_LESS; 157 case PIPE_FUNC_EQUAL: 158 return R300_ZS_EQUAL; 159 case PIPE_FUNC_LEQUAL: 160 return R300_ZS_LEQUAL; 161 case PIPE_FUNC_GREATER: 162 return R300_ZS_GREATER; 163 case PIPE_FUNC_NOTEQUAL: 164 return R300_ZS_NOTEQUAL; 165 case PIPE_FUNC_GEQUAL: 166 return R300_ZS_GEQUAL; 167 case PIPE_FUNC_ALWAYS: 168 return R300_ZS_ALWAYS; 169 default: 170 /* XXX shouldn't be reachable */ 171 break; 172 } 173 return 0; 174} 175 176static uint32_t translate_stencil_op(int s_op) { 177 switch (s_op) { 178 case PIPE_STENCIL_OP_KEEP: 179 return R300_ZS_KEEP; 180 case PIPE_STENCIL_OP_ZERO: 181 return R300_ZS_ZERO; 182 case PIPE_STENCIL_OP_REPLACE: 183 return R300_ZS_REPLACE; 184 case PIPE_STENCIL_OP_INCR: 185 return R300_ZS_INCR; 186 case PIPE_STENCIL_OP_DECR: 187 return R300_ZS_DECR; 188 case PIPE_STENCIL_OP_INCR_WRAP: 189 return R300_ZS_INCR_WRAP; 190 case PIPE_STENCIL_OP_DECR_WRAP: 191 return R300_ZS_DECR_WRAP; 192 case PIPE_STENCIL_OP_INVERT: 193 return R300_ZS_INVERT; 194 default: 195 /* XXX shouldn't be reachable */ 196 break; 197 } 198 return 0; 199} 200 201static uint32_t translate_alpha_function(int alpha_func) { 202 switch (alpha_func) { 203 case PIPE_FUNC_NEVER: 204 return R300_FG_ALPHA_FUNC_NEVER; 205 case PIPE_FUNC_LESS: 206 return R300_FG_ALPHA_FUNC_LESS; 207 case PIPE_FUNC_EQUAL: 208 return R300_FG_ALPHA_FUNC_EQUAL; 209 case PIPE_FUNC_LEQUAL: 210 return R300_FG_ALPHA_FUNC_LE; 211 case PIPE_FUNC_GREATER: 212 return R300_FG_ALPHA_FUNC_GREATER; 213 case PIPE_FUNC_NOTEQUAL: 214 return R300_FG_ALPHA_FUNC_NOTEQUAL; 215 case PIPE_FUNC_GEQUAL: 216 return R300_FG_ALPHA_FUNC_GE; 217 case PIPE_FUNC_ALWAYS: 218 return R300_FG_ALPHA_FUNC_ALWAYS; 219 default: 220 /* XXX shouldn't be reachable */ 221 break; 222 } 223 return 0; 224} 225 226/* Create a new depth, stencil, and alpha state based on the CSO dsa state. 227 * 228 * This contains the depth buffer, stencil buffer, alpha test, and such. 229 * On the Radeon, depth and stencil buffer setup are intertwined, which is 230 * the reason for some of the strange-looking assignments across registers. */ 231static void* r300_create_dsa_state(struct pipe_context* pipe, 232 struct pipe_depth_stencil_alpha_state* state) 233{ 234 struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); 235 236 /* Depth test setup. */ 237 if (state->depth.enabled) { 238 dsa->z_buffer_control |= R300_Z_ENABLE; 239 240 if (state->depth.writemask) { 241 dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; 242 } 243 244 dsa->z_stencil_control |= 245 (translate_depth_stencil_function(state->depth.func) << 246 R300_Z_FUNC_SHIFT); 247 } 248 249 /* Stencil buffer setup. */ 250 if (state->stencil[0].enabled) { 251 dsa->z_buffer_control |= R300_STENCIL_ENABLE; 252 dsa->z_stencil_control |= 253 (translate_depth_stencil_function(state->stencil[0].func) << 254 R300_S_FRONT_FUNC_SHIFT) | 255 (translate_stencil_op(state->stencil[0].fail_op) << 256 R300_S_FRONT_SFAIL_OP_SHIFT) | 257 (translate_stencil_op(state->stencil[0].zpass_op) << 258 R300_S_FRONT_ZPASS_OP_SHIFT) | 259 (translate_stencil_op(state->stencil[0].zfail_op) << 260 R300_S_FRONT_ZFAIL_OP_SHIFT); 261 262 dsa->stencil_ref_mask = (state->stencil[0].ref_value) | 263 (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) | 264 (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT); 265 266 if (state->stencil[1].enabled) { 267 dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; 268 dsa->z_stencil_control |= 269 (translate_depth_stencil_function(state->stencil[1].func) << 270 R300_S_BACK_FUNC_SHIFT) | 271 (translate_stencil_op(state->stencil[1].fail_op) << 272 R300_S_BACK_SFAIL_OP_SHIFT) | 273 (translate_stencil_op(state->stencil[1].zpass_op) << 274 R300_S_BACK_ZPASS_OP_SHIFT) | 275 (translate_stencil_op(state->stencil[1].zfail_op) << 276 R300_S_BACK_ZFAIL_OP_SHIFT); 277 278 dsa->stencil_ref_bf = (state->stencil[1].ref_value) | 279 (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) | 280 (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT); 281 } 282 } 283 284 /* Alpha test setup. */ 285 if (state->alpha.enabled) { 286 dsa->alpha_function = translate_alpha_function(state->alpha.func) | 287 R300_FG_ALPHA_FUNC_ENABLE; 288 dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023); 289 } else { 290 dsa->z_buffer_top = R300_ZTOP_ENABLE; 291 } 292 293 return (void*)dsa; 294} 295 296/* Bind DSA state. */ 297static void r300_bind_dsa_state(struct pipe_context* pipe, 298 void* state) 299{ 300 struct r300_context* r300 = r300_context(pipe); 301 302 r300->dsa_state = (struct r300_dsa_state*)state; 303 r300->dirty_state |= R300_NEW_DSA; 304} 305 306/* Free DSA state. */ 307static void r300_delete_dsa_state(struct pipe_context* pipe, 308 void* state) 309{ 310 FREE(state); 311} 312 313static void r300_set_scissor_state(struct pipe_context* pipe, 314 struct pipe_scissor_state* state) 315{ 316 struct r300_context* r300 = r300_context(pipe); 317 draw_flush(r300->draw); 318 319 /* XXX figure out how this memory doesn't get lost in space 320 memcpy(r300->scissor, scissor, sizeof(struct pipe_scissor_state)); */ 321 r300->dirty_state |= R300_NEW_SCISSOR; 322} 323 324static void* r300_create_vs_state(struct pipe_context* pipe, 325 struct pipe_shader_state* state) 326{ 327 struct r300_context* context = r300_context(pipe); 328 /* XXX handing this off to Draw for now */ 329 return draw_create_vertex_shader(context->draw, state); 330} 331 332static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { 333 struct r300_context* context = r300_context(pipe); 334 /* XXX handing this off to Draw for now */ 335 draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 336} 337 338static void r300_delete_vs_state(struct pipe_context* pipe, void* state) 339{ 340 struct r300_context* context = r300_context(pipe); 341 /* XXX handing this off to Draw for now */ 342 draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); 343} 344 345void r300_init_state_functions(struct r300_context* r300) { 346 347 r300->context.create_blend_state = r300_create_blend_state; 348 r300->context.bind_blend_state = r300_bind_blend_state; 349 r300->context.delete_blend_state = r300_delete_blend_state; 350 351 r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; 352 r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; 353 r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; 354 355 r300->context.set_scissor_state = r300_set_scissor_state; 356 357 r300->context.create_vs_state = r300_create_vs_state; 358 r300->context.bind_vs_state = r300_bind_vs_state; 359 r300->context.delete_vs_state = r300_delete_vs_state; 360}