r600_state_common.c revision 68bbfc1afe210d82acfb14a78b0fd8c436a8f78c
1/* 2 * Copyright 2010 Red Hat Inc. 3 * 2010 Jerome Glisse 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Dave Airlie <airlied@redhat.com> 25 * Jerome Glisse <jglisse@redhat.com> 26 */ 27#include "r600_formats.h" 28#include "r600d.h" 29 30#include "util/u_blitter.h" 31#include "tgsi/tgsi_parse.h" 32 33static void r600_emit_command_buffer(struct r600_context *rctx, struct r600_atom *atom) 34{ 35 struct radeon_winsys_cs *cs = rctx->cs; 36 struct r600_command_buffer *cb = (struct r600_command_buffer*)atom; 37 38 assert(cs->cdw + cb->atom.num_dw <= RADEON_MAX_CMDBUF_DWORDS); 39 memcpy(cs->buf + cs->cdw, cb->buf, 4 * cb->atom.num_dw); 40 cs->cdw += cb->atom.num_dw; 41} 42 43void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags) 44{ 45 cb->atom.emit = r600_emit_command_buffer; 46 cb->atom.num_dw = 0; 47 cb->atom.flags = flags; 48 cb->buf = CALLOC(1, 4 * num_dw); 49 cb->max_num_dw = num_dw; 50} 51 52void r600_release_command_buffer(struct r600_command_buffer *cb) 53{ 54 FREE(cb->buf); 55} 56 57static void r600_emit_surface_sync(struct r600_context *rctx, struct r600_atom *atom) 58{ 59 struct radeon_winsys_cs *cs = rctx->cs; 60 struct r600_surface_sync_cmd *a = (struct r600_surface_sync_cmd*)atom; 61 62 cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0); 63 cs->buf[cs->cdw++] = a->flush_flags; /* CP_COHER_CNTL */ 64 cs->buf[cs->cdw++] = 0xffffffff; /* CP_COHER_SIZE */ 65 cs->buf[cs->cdw++] = 0; /* CP_COHER_BASE */ 66 cs->buf[cs->cdw++] = 0x0000000A; /* POLL_INTERVAL */ 67 68 a->flush_flags = 0; 69} 70 71static void r600_emit_r6xx_flush_and_inv(struct r600_context *rctx, struct r600_atom *atom) 72{ 73 struct radeon_winsys_cs *cs = rctx->cs; 74 cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); 75 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); 76} 77 78void r600_init_atom(struct r600_atom *atom, 79 void (*emit)(struct r600_context *ctx, struct r600_atom *state), 80 unsigned num_dw, enum r600_atom_flags flags) 81{ 82 atom->emit = emit; 83 atom->num_dw = num_dw; 84 atom->flags = flags; 85} 86 87void r600_init_common_atoms(struct r600_context *rctx) 88{ 89 r600_init_atom(&rctx->surface_sync_cmd.atom, r600_emit_surface_sync, 5, EMIT_EARLY); 90 r600_init_atom(&rctx->r6xx_flush_and_inv_cmd, r600_emit_r6xx_flush_and_inv, 2, EMIT_EARLY); 91} 92 93unsigned r600_get_cb_flush_flags(struct r600_context *rctx) 94{ 95 unsigned flags = 0; 96 97 if (rctx->framebuffer.nr_cbufs) { 98 flags |= S_0085F0_CB_ACTION_ENA(1) | 99 (((1 << rctx->framebuffer.nr_cbufs) - 1) << S_0085F0_CB0_DEST_BASE_ENA_SHIFT); 100 } 101 102 /* Workaround for broken flushing on some R6xx chipsets. */ 103 if (rctx->family == CHIP_RV670 || 104 rctx->family == CHIP_RS780 || 105 rctx->family == CHIP_RS880) { 106 flags |= S_0085F0_CB1_DEST_BASE_ENA(1) | 107 S_0085F0_DEST_BASE_0_ENA(1); 108 } 109 return flags; 110} 111 112void r600_texture_barrier(struct pipe_context *ctx) 113{ 114 struct r600_context *rctx = (struct r600_context *)ctx; 115 116 rctx->surface_sync_cmd.flush_flags |= S_0085F0_TC_ACTION_ENA(1) | r600_get_cb_flush_flags(rctx); 117 r600_atom_dirty(rctx, &rctx->surface_sync_cmd.atom); 118} 119 120static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim) 121{ 122 static const int prim_conv[] = { 123 V_008958_DI_PT_POINTLIST, 124 V_008958_DI_PT_LINELIST, 125 V_008958_DI_PT_LINELOOP, 126 V_008958_DI_PT_LINESTRIP, 127 V_008958_DI_PT_TRILIST, 128 V_008958_DI_PT_TRISTRIP, 129 V_008958_DI_PT_TRIFAN, 130 V_008958_DI_PT_QUADLIST, 131 V_008958_DI_PT_QUADSTRIP, 132 V_008958_DI_PT_POLYGON, 133 -1, 134 -1, 135 -1, 136 -1 137 }; 138 139 *prim = prim_conv[pprim]; 140 if (*prim == -1) { 141 fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); 142 return false; 143 } 144 return true; 145} 146 147/* common state between evergreen and r600 */ 148void r600_bind_blend_state(struct pipe_context *ctx, void *state) 149{ 150 struct r600_context *rctx = (struct r600_context *)ctx; 151 struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; 152 struct r600_pipe_state *rstate; 153 154 if (state == NULL) 155 return; 156 rstate = &blend->rstate; 157 rctx->states[rstate->id] = rstate; 158 rctx->cb_target_mask = blend->cb_target_mask; 159 160 /* Replace every bit except MULTIWRITE_ENABLE. */ 161 rctx->cb_color_control &= ~C_028808_MULTIWRITE_ENABLE; 162 rctx->cb_color_control |= blend->cb_color_control & C_028808_MULTIWRITE_ENABLE; 163 164 r600_context_pipe_state_set(rctx, rstate); 165} 166 167void r600_set_blend_color(struct pipe_context *ctx, 168 const struct pipe_blend_color *state) 169{ 170 struct r600_context *rctx = (struct r600_context *)ctx; 171 struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); 172 173 if (rstate == NULL) 174 return; 175 176 rstate->id = R600_PIPE_STATE_BLEND_COLOR; 177 r600_pipe_state_add_reg(rstate, R_028414_CB_BLEND_RED, fui(state->color[0]), NULL, 0); 178 r600_pipe_state_add_reg(rstate, R_028418_CB_BLEND_GREEN, fui(state->color[1]), NULL, 0); 179 r600_pipe_state_add_reg(rstate, R_02841C_CB_BLEND_BLUE, fui(state->color[2]), NULL, 0); 180 r600_pipe_state_add_reg(rstate, R_028420_CB_BLEND_ALPHA, fui(state->color[3]), NULL, 0); 181 182 free(rctx->states[R600_PIPE_STATE_BLEND_COLOR]); 183 rctx->states[R600_PIPE_STATE_BLEND_COLOR] = rstate; 184 r600_context_pipe_state_set(rctx, rstate); 185} 186 187static void r600_set_stencil_ref(struct pipe_context *ctx, 188 const struct r600_stencil_ref *state) 189{ 190 struct r600_context *rctx = (struct r600_context *)ctx; 191 struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); 192 193 if (rstate == NULL) 194 return; 195 196 rstate->id = R600_PIPE_STATE_STENCIL_REF; 197 r600_pipe_state_add_reg(rstate, 198 R_028430_DB_STENCILREFMASK, 199 S_028430_STENCILREF(state->ref_value[0]) | 200 S_028430_STENCILMASK(state->valuemask[0]) | 201 S_028430_STENCILWRITEMASK(state->writemask[0]), 202 NULL, 0); 203 r600_pipe_state_add_reg(rstate, 204 R_028434_DB_STENCILREFMASK_BF, 205 S_028434_STENCILREF_BF(state->ref_value[1]) | 206 S_028434_STENCILMASK_BF(state->valuemask[1]) | 207 S_028434_STENCILWRITEMASK_BF(state->writemask[1]), 208 NULL, 0); 209 210 free(rctx->states[R600_PIPE_STATE_STENCIL_REF]); 211 rctx->states[R600_PIPE_STATE_STENCIL_REF] = rstate; 212 r600_context_pipe_state_set(rctx, rstate); 213} 214 215void r600_set_pipe_stencil_ref(struct pipe_context *ctx, 216 const struct pipe_stencil_ref *state) 217{ 218 struct r600_context *rctx = (struct r600_context *)ctx; 219 struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)rctx->states[R600_PIPE_STATE_DSA]; 220 struct r600_stencil_ref ref; 221 222 rctx->stencil_ref = *state; 223 224 if (!dsa) 225 return; 226 227 ref.ref_value[0] = state->ref_value[0]; 228 ref.ref_value[1] = state->ref_value[1]; 229 ref.valuemask[0] = dsa->valuemask[0]; 230 ref.valuemask[1] = dsa->valuemask[1]; 231 ref.writemask[0] = dsa->writemask[0]; 232 ref.writemask[1] = dsa->writemask[1]; 233 234 r600_set_stencil_ref(ctx, &ref); 235} 236 237void r600_bind_dsa_state(struct pipe_context *ctx, void *state) 238{ 239 struct r600_context *rctx = (struct r600_context *)ctx; 240 struct r600_pipe_dsa *dsa = state; 241 struct r600_pipe_state *rstate; 242 struct r600_stencil_ref ref; 243 244 if (state == NULL) 245 return; 246 rstate = &dsa->rstate; 247 rctx->states[rstate->id] = rstate; 248 rctx->alpha_ref = dsa->alpha_ref; 249 rctx->alpha_ref_dirty = true; 250 r600_context_pipe_state_set(rctx, rstate); 251 252 ref.ref_value[0] = rctx->stencil_ref.ref_value[0]; 253 ref.ref_value[1] = rctx->stencil_ref.ref_value[1]; 254 ref.valuemask[0] = dsa->valuemask[0]; 255 ref.valuemask[1] = dsa->valuemask[1]; 256 ref.writemask[0] = dsa->writemask[0]; 257 ref.writemask[1] = dsa->writemask[1]; 258 259 r600_set_stencil_ref(ctx, &ref); 260 261 if (rctx->db_misc_state.flush_depthstencil_enabled != dsa->is_flush) { 262 rctx->db_misc_state.flush_depthstencil_enabled = dsa->is_flush; 263 r600_atom_dirty(rctx, &rctx->db_misc_state.atom); 264 } 265} 266 267void r600_set_max_scissor(struct r600_context *rctx) 268{ 269 /* Set a scissor state such that it doesn't do anything. */ 270 struct pipe_scissor_state scissor; 271 scissor.minx = 0; 272 scissor.miny = 0; 273 scissor.maxx = 8192; 274 scissor.maxy = 8192; 275 276 r600_set_scissor_state(rctx, &scissor); 277} 278 279void r600_bind_rs_state(struct pipe_context *ctx, void *state) 280{ 281 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 282 struct r600_context *rctx = (struct r600_context *)ctx; 283 284 if (state == NULL) 285 return; 286 287 rctx->sprite_coord_enable = rs->sprite_coord_enable; 288 rctx->two_side = rs->two_side; 289 rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple; 290 rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl; 291 292 rctx->rasterizer = rs; 293 294 rctx->states[rs->rstate.id] = &rs->rstate; 295 r600_context_pipe_state_set(rctx, &rs->rstate); 296 297 if (rctx->chip_class >= EVERGREEN) { 298 evergreen_polygon_offset_update(rctx); 299 } else { 300 r600_polygon_offset_update(rctx); 301 } 302 303 /* Workaround for a missing scissor enable on r600. */ 304 if (rctx->chip_class == R600) { 305 if (rs->scissor_enable != rctx->scissor_enable) { 306 rctx->scissor_enable = rs->scissor_enable; 307 308 if (rs->scissor_enable) { 309 r600_set_scissor_state(rctx, &rctx->scissor_state); 310 } else { 311 r600_set_max_scissor(rctx); 312 } 313 } 314 } 315} 316 317void r600_delete_rs_state(struct pipe_context *ctx, void *state) 318{ 319 struct r600_context *rctx = (struct r600_context *)ctx; 320 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 321 322 if (rctx->rasterizer == rs) { 323 rctx->rasterizer = NULL; 324 } 325 if (rctx->states[rs->rstate.id] == &rs->rstate) { 326 rctx->states[rs->rstate.id] = NULL; 327 } 328 free(rs); 329} 330 331void r600_sampler_view_destroy(struct pipe_context *ctx, 332 struct pipe_sampler_view *state) 333{ 334 struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; 335 336 pipe_resource_reference(&state->texture, NULL); 337 FREE(resource); 338} 339 340void r600_delete_state(struct pipe_context *ctx, void *state) 341{ 342 struct r600_context *rctx = (struct r600_context *)ctx; 343 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 344 345 if (rctx->states[rstate->id] == rstate) { 346 rctx->states[rstate->id] = NULL; 347 } 348 for (int i = 0; i < rstate->nregs; i++) { 349 pipe_resource_reference((struct pipe_resource**)&rstate->regs[i].bo, NULL); 350 } 351 free(rstate); 352} 353 354void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) 355{ 356 struct r600_context *rctx = (struct r600_context *)ctx; 357 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 358 359 rctx->vertex_elements = v; 360 if (v) { 361 r600_inval_shader_cache(rctx); 362 u_vbuf_bind_vertex_elements(rctx->vbuf_mgr, state, 363 v->vmgr_elements); 364 365 rctx->states[v->rstate.id] = &v->rstate; 366 r600_context_pipe_state_set(rctx, &v->rstate); 367 } 368} 369 370void r600_delete_vertex_element(struct pipe_context *ctx, void *state) 371{ 372 struct r600_context *rctx = (struct r600_context *)ctx; 373 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 374 375 if (rctx->states[v->rstate.id] == &v->rstate) { 376 rctx->states[v->rstate.id] = NULL; 377 } 378 if (rctx->vertex_elements == state) 379 rctx->vertex_elements = NULL; 380 381 pipe_resource_reference((struct pipe_resource**)&v->fetch_shader, NULL); 382 u_vbuf_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements); 383 FREE(state); 384} 385 386 387void r600_set_index_buffer(struct pipe_context *ctx, 388 const struct pipe_index_buffer *ib) 389{ 390 struct r600_context *rctx = (struct r600_context *)ctx; 391 392 u_vbuf_set_index_buffer(rctx->vbuf_mgr, ib); 393} 394 395void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 396 const struct pipe_vertex_buffer *buffers) 397{ 398 struct r600_context *rctx = (struct r600_context *)ctx; 399 400 u_vbuf_set_vertex_buffers(rctx->vbuf_mgr, count, buffers); 401 rctx->vertex_buffers_dirty = true; 402} 403 404void *r600_create_vertex_elements(struct pipe_context *ctx, 405 unsigned count, 406 const struct pipe_vertex_element *elements) 407{ 408 struct r600_context *rctx = (struct r600_context *)ctx; 409 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 410 411 assert(count < 32); 412 if (!v) 413 return NULL; 414 415 v->count = count; 416 v->vmgr_elements = 417 u_vbuf_create_vertex_elements(rctx->vbuf_mgr, count, 418 elements, v->elements); 419 420 if (r600_vertex_elements_build_fetch_shader(rctx, v)) { 421 FREE(v); 422 return NULL; 423 } 424 425 return v; 426} 427 428void *r600_create_shader_state(struct pipe_context *ctx, 429 const struct pipe_shader_state *state) 430{ 431 struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); 432 int r; 433 434 shader->tokens = tgsi_dup_tokens(state->tokens); 435 shader->so = state->stream_output; 436 437 r = r600_pipe_shader_create(ctx, shader); 438 if (r) { 439 return NULL; 440 } 441 return shader; 442} 443 444void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 445{ 446 struct r600_context *rctx = (struct r600_context *)ctx; 447 448 if (!state) { 449 state = rctx->dummy_pixel_shader; 450 } 451 452 rctx->ps_shader = (struct r600_pipe_shader *)state; 453 454 r600_inval_shader_cache(rctx); 455 r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate); 456 457 rctx->cb_color_control &= C_028808_MULTIWRITE_ENABLE; 458 rctx->cb_color_control |= S_028808_MULTIWRITE_ENABLE(!!rctx->ps_shader->shader.fs_write_all); 459 460 if (rctx->ps_shader && rctx->vs_shader) { 461 r600_adjust_gprs(rctx); 462 } 463} 464 465void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 466{ 467 struct r600_context *rctx = (struct r600_context *)ctx; 468 469 rctx->vs_shader = (struct r600_pipe_shader *)state; 470 if (state) { 471 r600_inval_shader_cache(rctx); 472 r600_context_pipe_state_set(rctx, &rctx->vs_shader->rstate); 473 } 474 if (rctx->ps_shader && rctx->vs_shader) { 475 r600_adjust_gprs(rctx); 476 } 477} 478 479void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 480{ 481 struct r600_context *rctx = (struct r600_context *)ctx; 482 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 483 484 if (rctx->ps_shader == shader) { 485 rctx->ps_shader = NULL; 486 } 487 488 free(shader->tokens); 489 r600_pipe_shader_destroy(ctx, shader); 490 free(shader); 491} 492 493void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 494{ 495 struct r600_context *rctx = (struct r600_context *)ctx; 496 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 497 498 if (rctx->vs_shader == shader) { 499 rctx->vs_shader = NULL; 500 } 501 502 free(shader->tokens); 503 r600_pipe_shader_destroy(ctx, shader); 504 free(shader); 505} 506 507static void r600_update_alpha_ref(struct r600_context *rctx) 508{ 509 unsigned alpha_ref; 510 struct r600_pipe_state rstate; 511 512 alpha_ref = rctx->alpha_ref; 513 rstate.nregs = 0; 514 if (rctx->export_16bpc) 515 alpha_ref &= ~0x1FFF; 516 r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, NULL, 0); 517 518 r600_context_pipe_state_set(rctx, &rstate); 519 rctx->alpha_ref_dirty = false; 520} 521 522void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state) 523{ 524 state->atom.num_dw = rctx->chip_class >= EVERGREEN ? util_bitcount(state->dirty_mask)*20 525 : util_bitcount(state->dirty_mask)*19; 526 r600_atom_dirty(rctx, &state->atom); 527} 528 529void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 530 struct pipe_resource *buffer) 531{ 532 struct r600_context *rctx = (struct r600_context *)ctx; 533 struct r600_resource *rbuffer = r600_resource(buffer); 534 struct r600_constbuf_state *state; 535 struct r600_constant_buffer *cb; 536 uint32_t offset; 537 538 switch (shader) { 539 case PIPE_SHADER_VERTEX: 540 state = &rctx->vs_constbuf_state; 541 break; 542 case PIPE_SHADER_FRAGMENT: 543 state = &rctx->ps_constbuf_state; 544 break; 545 default: 546 return; 547 } 548 549 /* Note that the state tracker can unbind constant buffers by 550 * passing NULL here. 551 */ 552 if (buffer == NULL) { 553 state->enabled_mask &= ~(1 << index); 554 state->dirty_mask &= ~(1 << index); 555 pipe_resource_reference(&state->cb[index].buffer, NULL); 556 return; 557 } 558 559 r600_inval_shader_cache(rctx); 560 r600_upload_const_buffer(rctx, &rbuffer, &offset); 561 562 cb = &state->cb[index]; 563 pipe_resource_reference(&cb->buffer, &rbuffer->b.b.b); 564 cb->buffer_offset = offset; 565 cb->buffer_size = buffer->width0; 566 567 state->enabled_mask |= 1 << index; 568 state->dirty_mask |= 1 << index; 569 r600_constant_buffers_dirty(rctx, state); 570 571 if (buffer != &rbuffer->b.b.b) 572 pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL); 573} 574 575struct pipe_stream_output_target * 576r600_create_so_target(struct pipe_context *ctx, 577 struct pipe_resource *buffer, 578 unsigned buffer_offset, 579 unsigned buffer_size) 580{ 581 struct r600_context *rctx = (struct r600_context *)ctx; 582 struct r600_so_target *t; 583 void *ptr; 584 585 t = CALLOC_STRUCT(r600_so_target); 586 if (!t) { 587 return NULL; 588 } 589 590 t->b.reference.count = 1; 591 t->b.context = ctx; 592 pipe_resource_reference(&t->b.buffer, buffer); 593 t->b.buffer_offset = buffer_offset; 594 t->b.buffer_size = buffer_size; 595 596 t->filled_size = (struct r600_resource*) 597 pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, 4); 598 ptr = rctx->ws->buffer_map(t->filled_size->buf, rctx->cs, PIPE_TRANSFER_WRITE); 599 memset(ptr, 0, t->filled_size->buf->size); 600 rctx->ws->buffer_unmap(t->filled_size->buf); 601 602 return &t->b; 603} 604 605void r600_so_target_destroy(struct pipe_context *ctx, 606 struct pipe_stream_output_target *target) 607{ 608 struct r600_so_target *t = (struct r600_so_target*)target; 609 pipe_resource_reference(&t->b.buffer, NULL); 610 pipe_resource_reference((struct pipe_resource**)&t->filled_size, NULL); 611 FREE(t); 612} 613 614void r600_set_so_targets(struct pipe_context *ctx, 615 unsigned num_targets, 616 struct pipe_stream_output_target **targets, 617 unsigned append_bitmask) 618{ 619 struct r600_context *rctx = (struct r600_context *)ctx; 620 unsigned i; 621 622 /* Stop streamout. */ 623 if (rctx->num_so_targets) { 624 r600_context_streamout_end(rctx); 625 } 626 627 /* Set the new targets. */ 628 for (i = 0; i < num_targets; i++) { 629 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]); 630 } 631 for (; i < rctx->num_so_targets; i++) { 632 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL); 633 } 634 635 rctx->num_so_targets = num_targets; 636 rctx->streamout_start = num_targets != 0; 637 rctx->streamout_append_bitmask = append_bitmask; 638} 639 640static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader) 641{ 642 struct r600_context *rctx = (struct r600_context *)ctx; 643 int r; 644 645 r600_pipe_shader_destroy(ctx, shader); 646 r = r600_pipe_shader_create(ctx, shader); 647 if (r) { 648 return r; 649 } 650 r600_context_pipe_state_set(rctx, &shader->rstate); 651 652 return 0; 653} 654 655static void r600_update_derived_state(struct r600_context *rctx) 656{ 657 struct pipe_context * ctx = (struct pipe_context*)rctx; 658 659 if (!rctx->blitter->running) { 660 if (rctx->have_depth_fb || rctx->have_depth_texture) 661 r600_flush_depth_textures(rctx); 662 } 663 664 if (rctx->chip_class < EVERGREEN) { 665 r600_update_sampler_states(rctx); 666 } 667 668 if ((rctx->ps_shader->shader.two_side != rctx->two_side) || 669 ((rctx->chip_class >= EVERGREEN) && rctx->ps_shader->shader.fs_write_all && 670 (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs))) { 671 r600_shader_rebuild(&rctx->context, rctx->ps_shader); 672 } 673 674 if (rctx->alpha_ref_dirty) { 675 r600_update_alpha_ref(rctx); 676 } 677 678 if (rctx->ps_shader && ((rctx->sprite_coord_enable && 679 (rctx->ps_shader->sprite_coord_enable != rctx->sprite_coord_enable)) || 680 (rctx->rasterizer && rctx->rasterizer->flatshade != rctx->ps_shader->flatshade))) { 681 682 if (rctx->chip_class >= EVERGREEN) 683 evergreen_pipe_shader_ps(ctx, rctx->ps_shader); 684 else 685 r600_pipe_shader_ps(ctx, rctx->ps_shader); 686 687 r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate); 688 } 689 690} 691 692static unsigned r600_conv_prim_to_gs_out(unsigned mode) 693{ 694 static const int prim_conv[] = { 695 V_028A6C_OUTPRIM_TYPE_POINTLIST, 696 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 697 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 698 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 699 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 700 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 701 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 702 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 703 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 704 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 705 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 706 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 707 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 708 V_028A6C_OUTPRIM_TYPE_TRISTRIP 709 }; 710 assert(mode < Elements(prim_conv)); 711 712 return prim_conv[mode]; 713} 714 715void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) 716{ 717 struct r600_context *rctx = (struct r600_context *)ctx; 718 struct pipe_draw_info info = *dinfo; 719 struct pipe_index_buffer ib = {}; 720 unsigned prim, mask, ls_mask = 0; 721 struct r600_block *dirty_block = NULL, *next_block = NULL; 722 struct r600_atom *state = NULL, *next_state = NULL; 723 struct radeon_winsys_cs *cs = rctx->cs; 724 uint64_t va; 725 726 if ((!info.count && (info.indexed || !info.count_from_stream_output)) || 727 (info.indexed && !rctx->vbuf_mgr->index_buffer.buffer) || 728 !r600_conv_pipe_prim(info.mode, &prim)) { 729 assert(0); 730 return; 731 } 732 733 if (!rctx->vs_shader) { 734 assert(0); 735 return; 736 } 737 738 r600_update_derived_state(rctx); 739 740 /* Update vertex buffers. */ 741 if ((u_vbuf_draw_begin(rctx->vbuf_mgr, &info) & U_VBUF_BUFFERS_UPDATED) || 742 rctx->vertex_buffers_dirty) { 743 r600_inval_vertex_cache(rctx); 744 rctx->vertex_buffer_state.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 10) * 745 rctx->vbuf_mgr->nr_real_vertex_buffers; 746 r600_atom_dirty(rctx, &rctx->vertex_buffer_state); 747 rctx->vertex_buffers_dirty = FALSE; 748 } 749 750 if (info.indexed) { 751 /* Initialize the index buffer struct. */ 752 pipe_resource_reference(&ib.buffer, rctx->vbuf_mgr->index_buffer.buffer); 753 ib.index_size = rctx->vbuf_mgr->index_buffer.index_size; 754 ib.offset = rctx->vbuf_mgr->index_buffer.offset + info.start * ib.index_size; 755 756 /* Translate or upload, if needed. */ 757 r600_translate_index_buffer(rctx, &ib, info.count); 758 759 if (u_vbuf_resource(ib.buffer)->user_ptr) { 760 r600_upload_index_buffer(rctx, &ib, info.count); 761 } 762 } else { 763 info.index_bias = info.start; 764 if (info.count_from_stream_output) { 765 r600_context_draw_opaque_count(rctx, (struct r600_so_target*)info.count_from_stream_output); 766 } 767 } 768 769 mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1; 770 771 if (rctx->vgt.id != R600_PIPE_STATE_VGT) { 772 rctx->vgt.id = R600_PIPE_STATE_VGT; 773 rctx->vgt.nregs = 0; 774 r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, NULL, 0); 775 r600_pipe_state_add_reg(&rctx->vgt, R_028A6C_VGT_GS_OUT_PRIM_TYPE, 0, NULL, 0); 776 r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, NULL, 0); 777 r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias, NULL, 0); 778 r600_pipe_state_add_reg(&rctx->vgt, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info.restart_index, NULL, 0); 779 r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info.primitive_restart, NULL, 0); 780 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance, NULL, 0); 781 r600_pipe_state_add_reg(&rctx->vgt, R_028A0C_PA_SC_LINE_STIPPLE, 0, NULL, 0); 782 if (rctx->chip_class <= R700) 783 r600_pipe_state_add_reg(&rctx->vgt, R_028808_CB_COLOR_CONTROL, rctx->cb_color_control, NULL, 0); 784 r600_pipe_state_add_reg(&rctx->vgt, R_02881C_PA_CL_VS_OUT_CNTL, 0, NULL, 0); 785 r600_pipe_state_add_reg(&rctx->vgt, R_028810_PA_CL_CLIP_CNTL, 0, NULL, 0); 786 } 787 788 rctx->vgt.nregs = 0; 789 r600_pipe_state_mod_reg(&rctx->vgt, prim); 790 r600_pipe_state_mod_reg(&rctx->vgt, r600_conv_prim_to_gs_out(info.mode)); 791 r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask); 792 r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias); 793 r600_pipe_state_mod_reg(&rctx->vgt, info.restart_index); 794 r600_pipe_state_mod_reg(&rctx->vgt, info.primitive_restart); 795 r600_pipe_state_mod_reg(&rctx->vgt, info.start_instance); 796 797 if (prim == V_008958_DI_PT_LINELIST) 798 ls_mask = 1; 799 else if (prim == V_008958_DI_PT_LINESTRIP) 800 ls_mask = 2; 801 r600_pipe_state_mod_reg(&rctx->vgt, S_028A0C_AUTO_RESET_CNTL(ls_mask) | rctx->pa_sc_line_stipple); 802 if (rctx->chip_class <= R700) 803 r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_color_control); 804 r600_pipe_state_mod_reg(&rctx->vgt, 805 rctx->vs_shader->pa_cl_vs_out_cntl | 806 (rctx->rasterizer->clip_plane_enable & rctx->vs_shader->shader.clip_dist_write)); 807 r600_pipe_state_mod_reg(&rctx->vgt, 808 rctx->pa_cl_clip_cntl | 809 (rctx->vs_shader->shader.clip_dist_write || 810 rctx->vs_shader->shader.vs_prohibit_ucps ? 811 0 : rctx->rasterizer->clip_plane_enable & 0x3F)); 812 813 r600_context_pipe_state_set(rctx, &rctx->vgt); 814 815 /* Emit states (the function expects that we emit at most 17 dwords here). */ 816 r600_need_cs_space(rctx, 0, TRUE); 817 818 LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) { 819 r600_emit_atom(rctx, state); 820 } 821 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) { 822 r600_context_block_emit_dirty(rctx, dirty_block); 823 } 824 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->resource_dirty,list) { 825 r600_context_block_resource_emit_dirty(rctx, dirty_block); 826 } 827 rctx->pm4_dirty_cdwords = 0; 828 829 /* Enable stream out if needed. */ 830 if (rctx->streamout_start) { 831 r600_context_streamout_begin(rctx); 832 rctx->streamout_start = FALSE; 833 } 834 835 /* draw packet */ 836 cs->buf[cs->cdw++] = PKT3(PKT3_INDEX_TYPE, 0, rctx->predicate_drawing); 837 cs->buf[cs->cdw++] = ib.index_size == 4 ? 838 (VGT_INDEX_32 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_32_BIT : 0)) : 839 (VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0)); 840 cs->buf[cs->cdw++] = PKT3(PKT3_NUM_INSTANCES, 0, rctx->predicate_drawing); 841 cs->buf[cs->cdw++] = info.instance_count; 842 if (info.indexed) { 843 va = r600_resource_va(ctx->screen, ib.buffer); 844 va += ib.offset; 845 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX, 3, rctx->predicate_drawing); 846 cs->buf[cs->cdw++] = va; 847 cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 848 cs->buf[cs->cdw++] = info.count; 849 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_DMA; 850 cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, rctx->predicate_drawing); 851 cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, (struct r600_resource*)ib.buffer, RADEON_USAGE_READ); 852 } else { 853 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, rctx->predicate_drawing); 854 cs->buf[cs->cdw++] = info.count; 855 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_AUTO_INDEX | 856 (info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0); 857 } 858 859 rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY | R600_CONTEXT_DRAW_PENDING; 860 861 if (rctx->framebuffer.zsbuf) 862 { 863 struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture; 864 ((struct r600_resource_texture *)tex)->dirty_db = TRUE; 865 } 866 867 pipe_resource_reference(&ib.buffer, NULL); 868 u_vbuf_draw_end(rctx->vbuf_mgr); 869} 870 871void _r600_pipe_state_add_reg(struct r600_context *ctx, 872 struct r600_pipe_state *state, 873 uint32_t offset, uint32_t value, 874 uint32_t range_id, uint32_t block_id, 875 struct r600_resource *bo, 876 enum radeon_bo_usage usage) 877{ 878 struct r600_range *range; 879 struct r600_block *block; 880 881 if (bo) assert(usage); 882 883 range = &ctx->range[range_id]; 884 block = range->blocks[block_id]; 885 state->regs[state->nregs].block = block; 886 state->regs[state->nregs].id = (offset - block->start_offset) >> 2; 887 888 state->regs[state->nregs].value = value; 889 state->regs[state->nregs].bo = bo; 890 state->regs[state->nregs].bo_usage = usage; 891 892 state->nregs++; 893 assert(state->nregs < R600_BLOCK_MAX_REG); 894} 895 896void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state, 897 uint32_t offset, uint32_t value, 898 struct r600_resource *bo, 899 enum radeon_bo_usage usage) 900{ 901 if (bo) assert(usage); 902 903 state->regs[state->nregs].id = offset; 904 state->regs[state->nregs].block = NULL; 905 state->regs[state->nregs].value = value; 906 state->regs[state->nregs].bo = bo; 907 state->regs[state->nregs].bo_usage = usage; 908 909 state->nregs++; 910 assert(state->nregs < R600_BLOCK_MAX_REG); 911} 912 913uint32_t r600_translate_stencil_op(int s_op) 914{ 915 switch (s_op) { 916 case PIPE_STENCIL_OP_KEEP: 917 return V_028800_STENCIL_KEEP; 918 case PIPE_STENCIL_OP_ZERO: 919 return V_028800_STENCIL_ZERO; 920 case PIPE_STENCIL_OP_REPLACE: 921 return V_028800_STENCIL_REPLACE; 922 case PIPE_STENCIL_OP_INCR: 923 return V_028800_STENCIL_INCR; 924 case PIPE_STENCIL_OP_DECR: 925 return V_028800_STENCIL_DECR; 926 case PIPE_STENCIL_OP_INCR_WRAP: 927 return V_028800_STENCIL_INCR_WRAP; 928 case PIPE_STENCIL_OP_DECR_WRAP: 929 return V_028800_STENCIL_DECR_WRAP; 930 case PIPE_STENCIL_OP_INVERT: 931 return V_028800_STENCIL_INVERT; 932 default: 933 R600_ERR("Unknown stencil op %d", s_op); 934 assert(0); 935 break; 936 } 937 return 0; 938} 939 940uint32_t r600_translate_fill(uint32_t func) 941{ 942 switch(func) { 943 case PIPE_POLYGON_MODE_FILL: 944 return 2; 945 case PIPE_POLYGON_MODE_LINE: 946 return 1; 947 case PIPE_POLYGON_MODE_POINT: 948 return 0; 949 default: 950 assert(0); 951 return 0; 952 } 953} 954 955unsigned r600_tex_wrap(unsigned wrap) 956{ 957 switch (wrap) { 958 default: 959 case PIPE_TEX_WRAP_REPEAT: 960 return V_03C000_SQ_TEX_WRAP; 961 case PIPE_TEX_WRAP_CLAMP: 962 return V_03C000_SQ_TEX_CLAMP_HALF_BORDER; 963 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 964 return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL; 965 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 966 return V_03C000_SQ_TEX_CLAMP_BORDER; 967 case PIPE_TEX_WRAP_MIRROR_REPEAT: 968 return V_03C000_SQ_TEX_MIRROR; 969 case PIPE_TEX_WRAP_MIRROR_CLAMP: 970 return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER; 971 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 972 return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; 973 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 974 return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER; 975 } 976} 977 978unsigned r600_tex_filter(unsigned filter) 979{ 980 switch (filter) { 981 default: 982 case PIPE_TEX_FILTER_NEAREST: 983 return V_03C000_SQ_TEX_XY_FILTER_POINT; 984 case PIPE_TEX_FILTER_LINEAR: 985 return V_03C000_SQ_TEX_XY_FILTER_BILINEAR; 986 } 987} 988 989unsigned r600_tex_mipfilter(unsigned filter) 990{ 991 switch (filter) { 992 case PIPE_TEX_MIPFILTER_NEAREST: 993 return V_03C000_SQ_TEX_Z_FILTER_POINT; 994 case PIPE_TEX_MIPFILTER_LINEAR: 995 return V_03C000_SQ_TEX_Z_FILTER_LINEAR; 996 default: 997 case PIPE_TEX_MIPFILTER_NONE: 998 return V_03C000_SQ_TEX_Z_FILTER_NONE; 999 } 1000} 1001 1002unsigned r600_tex_compare(unsigned compare) 1003{ 1004 switch (compare) { 1005 default: 1006 case PIPE_FUNC_NEVER: 1007 return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER; 1008 case PIPE_FUNC_LESS: 1009 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS; 1010 case PIPE_FUNC_EQUAL: 1011 return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL; 1012 case PIPE_FUNC_LEQUAL: 1013 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; 1014 case PIPE_FUNC_GREATER: 1015 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER; 1016 case PIPE_FUNC_NOTEQUAL: 1017 return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; 1018 case PIPE_FUNC_GEQUAL: 1019 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; 1020 case PIPE_FUNC_ALWAYS: 1021 return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS; 1022 } 1023} 1024