r300_state.c revision 3f15acb7e8575faeacc50dcede6d68b1e583727d
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 26#include "util/u_debug.h" 27#include "pipe/internal/p_winsys_screen.h" 28 29#include "r300_context.h" 30#include "r300_reg.h" 31#include "r300_state_inlines.h" 32#include "r300_fs.h" 33 34/* r300_state: Functions used to intialize state context by translating 35 * Gallium state objects into semi-native r300 state objects. */ 36 37/* Create a new blend state based on the CSO blend state. 38 * 39 * This encompasses alpha blending, logic/raster ops, and blend dithering. */ 40static void* r300_create_blend_state(struct pipe_context* pipe, 41 const struct pipe_blend_state* state) 42{ 43 struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); 44 45 if (state->blend_enable) { 46 /* XXX for now, always do separate alpha... 47 * is it faster to do it with one reg? */ 48 blend->blend_control = R300_ALPHA_BLEND_ENABLE | 49 R300_SEPARATE_ALPHA_ENABLE | 50 R300_READ_ENABLE | 51 r300_translate_blend_function(state->rgb_func) | 52 (r300_translate_blend_factor(state->rgb_src_factor) << 53 R300_SRC_BLEND_SHIFT) | 54 (r300_translate_blend_factor(state->rgb_dst_factor) << 55 R300_DST_BLEND_SHIFT); 56 blend->alpha_blend_control = 57 r300_translate_blend_function(state->alpha_func) | 58 (r300_translate_blend_factor(state->alpha_src_factor) << 59 R300_SRC_BLEND_SHIFT) | 60 (r300_translate_blend_factor(state->alpha_dst_factor) << 61 R300_DST_BLEND_SHIFT); 62 } 63 64 /* PIPE_LOGICOP_* don't need to be translated, fortunately. */ 65 if (state->logicop_enable) { 66 blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE | 67 (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; 68 } 69 70 if (state->dither) { 71 blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT | 72 R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT; 73 } 74 75 return (void*)blend; 76} 77 78/* Bind blend state. */ 79static void r300_bind_blend_state(struct pipe_context* pipe, 80 void* state) 81{ 82 struct r300_context* r300 = r300_context(pipe); 83 84 r300->blend_state = (struct r300_blend_state*)state; 85 r300->dirty_state |= R300_NEW_BLEND; 86} 87 88/* Free blend state. */ 89static void r300_delete_blend_state(struct pipe_context* pipe, 90 void* state) 91{ 92 FREE(state); 93} 94 95/* Set blend color. 96 * Setup both R300 and R500 registers, figure out later which one to write. */ 97static void r300_set_blend_color(struct pipe_context* pipe, 98 const struct pipe_blend_color* color) 99{ 100 struct r300_context* r300 = r300_context(pipe); 101 ubyte ur, ug, ub, ua; 102 103 ur = float_to_ubyte(color->color[0]); 104 ug = float_to_ubyte(color->color[1]); 105 ub = float_to_ubyte(color->color[2]); 106 ua = float_to_ubyte(color->color[3]); 107 108 util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM, 109 &r300->blend_color_state->blend_color); 110 111 /* XXX this is wrong */ 112 r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16); 113 r300->blend_color_state->blend_color_green_blue = ub | (ug << 16); 114 115 r300->dirty_state |= R300_NEW_BLEND_COLOR; 116} 117 118static void r300_set_clip_state(struct pipe_context* pipe, 119 const struct pipe_clip_state* state) 120{ 121 struct r300_context* r300 = r300_context(pipe); 122 123 if (r300_screen(pipe->screen)->caps->has_tcl) { 124 r300->clip_state = *state; 125 r300->dirty_state |= R300_NEW_CLIP; 126 } else { 127 draw_flush(r300->draw); 128 draw_set_clip_state(r300->draw, state); 129 } 130} 131 132static void 133 r300_set_constant_buffer(struct pipe_context* pipe, 134 uint shader, uint index, 135 const struct pipe_constant_buffer* buffer) 136{ 137 struct r300_context* r300 = r300_context(pipe); 138 int i = r300->shader_constants[shader].user_count; 139 140 /* This entire chunk of code seems ever-so-slightly baked. 141 * It's as if I've got pipe_buffer* matryoshkas... */ 142 if (buffer && buffer->buffer && buffer->buffer->size) { 143 void* map = pipe->winsys->buffer_map(pipe->winsys, buffer->buffer, 144 PIPE_BUFFER_USAGE_CPU_READ); 145 memcpy(r300->shader_constants[shader].constants, 146 map, buffer->buffer->size); 147 pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer); 148 149 r300->shader_constants[shader].user_count = 150 buffer->buffer->size / (sizeof(float) * 4); 151 } else { 152 r300->shader_constants[shader].user_count = 0; 153 } 154 155 r300->dirty_state |= R300_NEW_CONSTANTS; 156 157 /* If the number of constants have changed, invalidate the shader. */ 158 if (r300->shader_constants[shader].user_count != i) { 159 if (shader == PIPE_SHADER_FRAGMENT && r300->fs && 160 r300->fs->uses_imms) { 161 r300->fs->translated = FALSE; 162 r300_translate_fragment_shader(r300, r300->fs); 163 } else if (shader == PIPE_SHADER_VERTEX && r300->vs && 164 r300->vs->uses_imms) { 165 r300->vs->translated = FALSE; 166 r300_translate_vertex_shader(r300, r300->vs); 167 } 168 } 169} 170 171/* Create a new depth, stencil, and alpha state based on the CSO dsa state. 172 * 173 * This contains the depth buffer, stencil buffer, alpha test, and such. 174 * On the Radeon, depth and stencil buffer setup are intertwined, which is 175 * the reason for some of the strange-looking assignments across registers. */ 176static void* 177 r300_create_dsa_state(struct pipe_context* pipe, 178 const struct pipe_depth_stencil_alpha_state* state) 179{ 180 struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); 181 182 /* Depth test setup. */ 183 if (state->depth.enabled) { 184 dsa->z_buffer_control |= R300_Z_ENABLE; 185 186 if (state->depth.writemask) { 187 dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; 188 } 189 190 dsa->z_stencil_control |= 191 (r300_translate_depth_stencil_function(state->depth.func) << 192 R300_Z_FUNC_SHIFT); 193 } 194 195 /* Stencil buffer setup. */ 196 if (state->stencil[0].enabled) { 197 dsa->z_buffer_control |= R300_STENCIL_ENABLE; 198 dsa->z_stencil_control |= 199 (r300_translate_depth_stencil_function(state->stencil[0].func) << 200 R300_S_FRONT_FUNC_SHIFT) | 201 (r300_translate_stencil_op(state->stencil[0].fail_op) << 202 R300_S_FRONT_SFAIL_OP_SHIFT) | 203 (r300_translate_stencil_op(state->stencil[0].zpass_op) << 204 R300_S_FRONT_ZPASS_OP_SHIFT) | 205 (r300_translate_stencil_op(state->stencil[0].zfail_op) << 206 R300_S_FRONT_ZFAIL_OP_SHIFT); 207 208 dsa->stencil_ref_mask = (state->stencil[0].ref_value) | 209 (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) | 210 (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT); 211 212 if (state->stencil[1].enabled) { 213 dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; 214 dsa->z_stencil_control |= 215 (r300_translate_depth_stencil_function(state->stencil[1].func) << 216 R300_S_BACK_FUNC_SHIFT) | 217 (r300_translate_stencil_op(state->stencil[1].fail_op) << 218 R300_S_BACK_SFAIL_OP_SHIFT) | 219 (r300_translate_stencil_op(state->stencil[1].zpass_op) << 220 R300_S_BACK_ZPASS_OP_SHIFT) | 221 (r300_translate_stencil_op(state->stencil[1].zfail_op) << 222 R300_S_BACK_ZFAIL_OP_SHIFT); 223 224 dsa->stencil_ref_bf = (state->stencil[1].ref_value) | 225 (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) | 226 (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT); 227 } 228 } 229 230 /* Alpha test setup. */ 231 if (state->alpha.enabled) { 232 dsa->alpha_function = 233 r300_translate_alpha_function(state->alpha.func) | 234 R300_FG_ALPHA_FUNC_ENABLE; 235 dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f, 236 0, 1023); 237 } else { 238 dsa->z_buffer_top = R300_ZTOP_ENABLE; 239 } 240 241 return (void*)dsa; 242} 243 244/* Bind DSA state. */ 245static void r300_bind_dsa_state(struct pipe_context* pipe, 246 void* state) 247{ 248 struct r300_context* r300 = r300_context(pipe); 249 250 r300->dsa_state = (struct r300_dsa_state*)state; 251 r300->dirty_state |= R300_NEW_DSA; 252} 253 254/* Free DSA state. */ 255static void r300_delete_dsa_state(struct pipe_context* pipe, 256 void* state) 257{ 258 FREE(state); 259} 260 261static void r300_set_edgeflags(struct pipe_context* pipe, 262 const unsigned* bitfield) 263{ 264 /* XXX you know it's bad when i915 has this blank too */ 265 /* XXX and even worse, I have no idea WTF the bitfield is */ 266} 267 268static void 269 r300_set_framebuffer_state(struct pipe_context* pipe, 270 const struct pipe_framebuffer_state* state) 271{ 272 struct r300_context* r300 = r300_context(pipe); 273 274 draw_flush(r300->draw); 275 276 r300->framebuffer_state = *state; 277 278 r300->dirty_state |= R300_NEW_FRAMEBUFFERS; 279} 280 281/* Create fragment shader state. */ 282static void* r300_create_fs_state(struct pipe_context* pipe, 283 const struct pipe_shader_state* shader) 284{ 285 struct r300_context* r300 = r300_context(pipe); 286 struct r300_fragment_shader* fs = NULL; 287 288 if (r300_screen(r300->context.screen)->caps->is_r500) { 289 fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader); 290 } else { 291 fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader); 292 } 293 294 /* Copy state directly into shader. */ 295 fs->state = *shader; 296 fs->state.tokens = tgsi_dup_tokens(shader->tokens); 297 298 tgsi_scan_shader(shader->tokens, &fs->info); 299 300 return (void*)fs; 301} 302 303/* Bind fragment shader state. */ 304static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) 305{ 306 struct r300_context* r300 = r300_context(pipe); 307 struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; 308 309 if (fs == NULL) { 310 r300->fs = NULL; 311 return; 312 } else if (!fs->translated) { 313 r300_translate_fragment_shader(r300, fs); 314 } 315 316 fs->translated = TRUE; 317 r300->fs = fs; 318 319 r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; 320} 321 322/* Delete fragment shader state. */ 323static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) 324{ 325 struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; 326 FREE(fs->state.tokens); 327 FREE(shader); 328} 329 330static void r300_set_polygon_stipple(struct pipe_context* pipe, 331 const struct pipe_poly_stipple* state) 332{ 333 /* XXX no idea how to set this up, but not terribly important */ 334} 335 336/* Create a new rasterizer state based on the CSO rasterizer state. 337 * 338 * This is a very large chunk of state, and covers most of the graphics 339 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks. 340 * 341 * In a not entirely unironic sidenote, this state has nearly nothing to do 342 * with the actual block on the Radeon called the rasterizer (RS). */ 343static void* r300_create_rs_state(struct pipe_context* pipe, 344 const struct pipe_rasterizer_state* state) 345{ 346 struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); 347 348 /* Copy rasterizer state for Draw. */ 349 rs->rs = *state; 350 351 rs->enable_vte = !state->bypass_vs_clip_and_viewport; 352 353 /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL. 354 * Else, enable HW TCL and force Draw's TCL off. */ 355 if (state->bypass_vs_clip_and_viewport || 356 !r300_screen(pipe->screen)->caps->has_tcl) { 357 rs->vap_control_status = R300_VAP_TCL_BYPASS; 358 } else { 359 rs->rs.bypass_vs_clip_and_viewport = TRUE; 360 rs->vap_control_status = 0; 361 } 362 363 rs->point_size = pack_float_16_6x(state->point_size) | 364 (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); 365 366 rs->point_minmax = 367 ((int)(state->point_size_min * 6.0) << 368 R300_GA_POINT_MINMAX_MIN_SHIFT) | 369 ((int)(state->point_size_max * 6.0) << 370 R300_GA_POINT_MINMAX_MAX_SHIFT); 371 372 rs->line_control = pack_float_16_6x(state->line_width) | 373 R300_GA_LINE_CNTL_END_TYPE_COMP; 374 375 /* Radeons don't think in "CW/CCW", they think in "front/back". */ 376 if (state->front_winding == PIPE_WINDING_CW) { 377 rs->cull_mode = R300_FRONT_FACE_CW; 378 379 if (state->offset_cw) { 380 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 381 } 382 if (state->offset_ccw) { 383 rs->polygon_offset_enable |= R300_BACK_ENABLE; 384 } 385 } else { 386 rs->cull_mode = R300_FRONT_FACE_CCW; 387 388 if (state->offset_ccw) { 389 rs->polygon_offset_enable |= R300_FRONT_ENABLE; 390 } 391 if (state->offset_cw) { 392 rs->polygon_offset_enable |= R300_BACK_ENABLE; 393 } 394 } 395 if (state->front_winding & state->cull_mode) { 396 rs->cull_mode |= R300_CULL_FRONT; 397 } 398 if (~(state->front_winding) & state->cull_mode) { 399 rs->cull_mode |= R300_CULL_BACK; 400 } 401 402 if (rs->polygon_offset_enable) { 403 rs->depth_offset_front = rs->depth_offset_back = 404 fui(state->offset_units); 405 rs->depth_scale_front = rs->depth_scale_back = 406 fui(state->offset_scale); 407 } 408 409 if (state->line_stipple_enable) { 410 rs->line_stipple_config = 411 R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE | 412 (fui((float)state->line_stipple_factor) & 413 R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK); 414 /* XXX this might need to be scaled up */ 415 rs->line_stipple_value = state->line_stipple_pattern; 416 } 417 418 if (state->flatshade) { 419 rs->color_control = R300_SHADE_MODEL_FLAT; 420 } else { 421 rs->color_control = R300_SHADE_MODEL_SMOOTH; 422 } 423 424 if (!state->flatshade_first) { 425 rs->color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST; 426 } 427 428 return (void*)rs; 429} 430 431/* Bind rasterizer state. */ 432static void r300_bind_rs_state(struct pipe_context* pipe, void* state) 433{ 434 struct r300_context* r300 = r300_context(pipe); 435 struct r300_rs_state* rs = (struct r300_rs_state*)state; 436 437 draw_flush(r300->draw); 438 draw_set_rasterizer_state(r300->draw, &rs->rs); 439 440 r300->rs_state = rs; 441 r300->dirty_state |= R300_NEW_RASTERIZER; 442} 443 444/* Free rasterizer state. */ 445static void r300_delete_rs_state(struct pipe_context* pipe, void* state) 446{ 447 FREE(state); 448} 449 450static void* 451 r300_create_sampler_state(struct pipe_context* pipe, 452 const struct pipe_sampler_state* state) 453{ 454 struct r300_context* r300 = r300_context(pipe); 455 struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); 456 int lod_bias; 457 458 sampler->filter0 |= 459 (r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | 460 (r300_translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) | 461 (r300_translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT); 462 463 sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter, 464 state->mag_img_filter, 465 state->min_mip_filter); 466 467 lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); 468 469 sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; 470 471 sampler->filter1 |= r300_anisotropy(state->max_anisotropy); 472 473 util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, 474 &sampler->border_color); 475 476 /* R500-specific fixups and optimizations */ 477 if (r300_screen(r300->context.screen)->caps->is_r500) { 478 sampler->filter1 |= R500_BORDER_FIX; 479 } 480 481 return (void*)sampler; 482} 483 484static void r300_bind_sampler_states(struct pipe_context* pipe, 485 unsigned count, 486 void** states) 487{ 488 struct r300_context* r300 = r300_context(pipe); 489 int i; 490 491 if (count > 8) { 492 return; 493 } 494 495 for (i = 0; i < count; i++) { 496 if (r300->sampler_states[i] != states[i]) { 497 r300->sampler_states[i] = (struct r300_sampler_state*)states[i]; 498 r300->dirty_state |= (R300_NEW_SAMPLER << i); 499 } 500 } 501 502 r300->sampler_count = count; 503} 504 505static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) 506{ 507 FREE(state); 508} 509 510static void r300_set_sampler_textures(struct pipe_context* pipe, 511 unsigned count, 512 struct pipe_texture** texture) 513{ 514 struct r300_context* r300 = r300_context(pipe); 515 int i; 516 517 /* XXX magic num */ 518 if (count > 8) { 519 return; 520 } 521 522 for (i = 0; i < count; i++) { 523 if (r300->textures[i] != (struct r300_texture*)texture[i]) { 524 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 525 texture[i]); 526 r300->dirty_state |= (R300_NEW_TEXTURE << i); 527 } 528 } 529 530 for (i = count; i < 8; i++) { 531 if (r300->textures[i]) { 532 pipe_texture_reference((struct pipe_texture**)&r300->textures[i], 533 NULL); 534 r300->dirty_state |= (R300_NEW_TEXTURE << i); 535 } 536 } 537 538 r300->texture_count = count; 539} 540 541static void r300_set_scissor_state(struct pipe_context* pipe, 542 const struct pipe_scissor_state* state) 543{ 544 struct r300_context* r300 = r300_context(pipe); 545 546 if (r300_screen(r300->context.screen)->caps->is_r500) { 547 r300->scissor_state->scissor_top_left = 548 (state->minx << R300_SCISSORS_X_SHIFT) | 549 (state->miny << R300_SCISSORS_Y_SHIFT); 550 r300->scissor_state->scissor_bottom_right = 551 (state->maxx << R300_SCISSORS_X_SHIFT) | 552 (state->maxy << R300_SCISSORS_Y_SHIFT); 553 } else { 554 /* Offset of 1440 in non-R500 chipsets. */ 555 r300->scissor_state->scissor_top_left = 556 ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) | 557 ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT); 558 r300->scissor_state->scissor_bottom_right = 559 ((state->maxx + 1440) << R300_SCISSORS_X_SHIFT) | 560 ((state->maxy + 1440) << R300_SCISSORS_Y_SHIFT); 561 } 562 563 r300->dirty_state |= R300_NEW_SCISSOR; 564} 565 566static void r300_set_viewport_state(struct pipe_context* pipe, 567 const struct pipe_viewport_state* state) 568{ 569 struct r300_context* r300 = r300_context(pipe); 570 571 /* Do the transform in HW. */ 572 r300->viewport_state->vte_control = R300_VTX_W0_FMT; 573 574 if (state->scale[0] != 1.0f) { 575 assert(state->scale[0] != 0.0f); 576 r300->viewport_state->xscale = state->scale[0]; 577 r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA; 578 } 579 if (state->scale[1] != 1.0f) { 580 assert(state->scale[1] != 0.0f); 581 r300->viewport_state->yscale = state->scale[1]; 582 r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA; 583 } 584 if (state->scale[2] != 1.0f) { 585 assert(state->scale[2] != 0.0f); 586 r300->viewport_state->zscale = state->scale[2]; 587 r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA; 588 } 589 if (state->translate[0] != 0.0f) { 590 r300->viewport_state->xoffset = state->translate[0]; 591 r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA; 592 } 593 if (state->translate[1] != 0.0f) { 594 r300->viewport_state->yoffset = state->translate[1]; 595 r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA; 596 } 597 if (state->translate[2] != 0.0f) { 598 r300->viewport_state->zoffset = state->translate[2]; 599 r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA; 600 } 601 602 r300->dirty_state |= R300_NEW_VIEWPORT; 603} 604 605static void r300_set_vertex_buffers(struct pipe_context* pipe, 606 unsigned count, 607 const struct pipe_vertex_buffer* buffers) 608{ 609 struct r300_context* r300 = r300_context(pipe); 610 611 memcpy(r300->vertex_buffers, buffers, 612 sizeof(struct pipe_vertex_buffer) * count); 613 614 r300->vertex_buffer_count = count; 615 616 draw_flush(r300->draw); 617 draw_set_vertex_buffers(r300->draw, count, buffers); 618} 619 620static void r300_set_vertex_elements(struct pipe_context* pipe, 621 unsigned count, 622 const struct pipe_vertex_element* elements) 623{ 624 struct r300_context* r300 = r300_context(pipe); 625 626 draw_flush(r300->draw); 627 draw_set_vertex_elements(r300->draw, count, elements); 628} 629 630static void* r300_create_vs_state(struct pipe_context* pipe, 631 const struct pipe_shader_state* shader) 632{ 633 struct r300_context* r300 = r300_context(pipe); 634 635 if (r300_screen(pipe->screen)->caps->has_tcl) { 636 struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader); 637 /* Copy state directly into shader. */ 638 vs->state = *shader; 639 vs->state.tokens = tgsi_dup_tokens(shader->tokens); 640 641 tgsi_scan_shader(shader->tokens, &vs->info); 642 643 /* Appease Draw. */ 644 vs->draw = draw_create_vertex_shader(r300->draw, shader); 645 646 return (void*)vs; 647 } else { 648 return draw_create_vertex_shader(r300->draw, shader); 649 } 650} 651 652static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) 653{ 654 struct r300_context* r300 = r300_context(pipe); 655 656 draw_flush(r300->draw); 657 658 if (r300_screen(pipe->screen)->caps->has_tcl) { 659 struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; 660 661 if (vs == NULL) { 662 r300->vs = NULL; 663 return; 664 } else if (!vs->translated) { 665 r300_translate_vertex_shader(r300, vs); 666 } 667 668 draw_bind_vertex_shader(r300->draw, vs->draw); 669 r300->vs = vs; 670 r300->dirty_state |= R300_NEW_VERTEX_SHADER; 671 } else { 672 draw_bind_vertex_shader(r300->draw, 673 (struct draw_vertex_shader*)shader); 674 } 675} 676 677static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) 678{ 679 struct r300_context* r300 = r300_context(pipe); 680 681 if (r300_screen(pipe->screen)->caps->has_tcl) { 682 struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; 683 684 draw_delete_vertex_shader(r300->draw, vs->draw); 685 FREE(vs->state.tokens); 686 FREE(shader); 687 } else { 688 draw_delete_vertex_shader(r300->draw, 689 (struct draw_vertex_shader*)shader); 690 } 691} 692 693void r300_init_state_functions(struct r300_context* r300) 694{ 695 r300->context.create_blend_state = r300_create_blend_state; 696 r300->context.bind_blend_state = r300_bind_blend_state; 697 r300->context.delete_blend_state = r300_delete_blend_state; 698 699 r300->context.set_blend_color = r300_set_blend_color; 700 701 r300->context.set_clip_state = r300_set_clip_state; 702 703 r300->context.set_constant_buffer = r300_set_constant_buffer; 704 705 r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; 706 r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; 707 r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; 708 709 r300->context.set_edgeflags = r300_set_edgeflags; 710 711 r300->context.set_framebuffer_state = r300_set_framebuffer_state; 712 713 r300->context.create_fs_state = r300_create_fs_state; 714 r300->context.bind_fs_state = r300_bind_fs_state; 715 r300->context.delete_fs_state = r300_delete_fs_state; 716 717 r300->context.set_polygon_stipple = r300_set_polygon_stipple; 718 719 r300->context.create_rasterizer_state = r300_create_rs_state; 720 r300->context.bind_rasterizer_state = r300_bind_rs_state; 721 r300->context.delete_rasterizer_state = r300_delete_rs_state; 722 723 r300->context.create_sampler_state = r300_create_sampler_state; 724 r300->context.bind_sampler_states = r300_bind_sampler_states; 725 r300->context.delete_sampler_state = r300_delete_sampler_state; 726 727 r300->context.set_sampler_textures = r300_set_sampler_textures; 728 729 r300->context.set_scissor_state = r300_set_scissor_state; 730 731 r300->context.set_viewport_state = r300_set_viewport_state; 732 733 r300->context.set_vertex_buffers = r300_set_vertex_buffers; 734 r300->context.set_vertex_elements = r300_set_vertex_elements; 735 736 r300->context.create_vs_state = r300_create_vs_state; 737 r300->context.bind_vs_state = r300_bind_vs_state; 738 r300->context.delete_vs_state = r300_delete_vs_state; 739} 740