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