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