r600_state_common.c revision 5c03d1fa0fbe130153a2e4c937f684c680ca20b2
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 int i; 400 401 /* Zero states. */ 402 for (i = 0; i < count; i++) { 403 if (!buffers[i].buffer) { 404 r600_context_pipe_state_set_fs_resource(rctx, NULL, i); 405 } 406 } 407 for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) { 408 r600_context_pipe_state_set_fs_resource(rctx, NULL, i); 409 } 410 411 u_vbuf_set_vertex_buffers(rctx->vbuf_mgr, count, buffers); 412} 413 414void *r600_create_vertex_elements(struct pipe_context *ctx, 415 unsigned count, 416 const struct pipe_vertex_element *elements) 417{ 418 struct r600_context *rctx = (struct r600_context *)ctx; 419 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 420 421 assert(count < 32); 422 if (!v) 423 return NULL; 424 425 v->count = count; 426 v->vmgr_elements = 427 u_vbuf_create_vertex_elements(rctx->vbuf_mgr, count, 428 elements, v->elements); 429 430 if (r600_vertex_elements_build_fetch_shader(rctx, v)) { 431 FREE(v); 432 return NULL; 433 } 434 435 return v; 436} 437 438void *r600_create_shader_state(struct pipe_context *ctx, 439 const struct pipe_shader_state *state) 440{ 441 struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); 442 int r; 443 444 shader->tokens = tgsi_dup_tokens(state->tokens); 445 shader->so = state->stream_output; 446 447 r = r600_pipe_shader_create(ctx, shader); 448 if (r) { 449 return NULL; 450 } 451 return shader; 452} 453 454void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 455{ 456 struct r600_context *rctx = (struct r600_context *)ctx; 457 458 if (!state) { 459 state = rctx->dummy_pixel_shader; 460 } 461 462 rctx->ps_shader = (struct r600_pipe_shader *)state; 463 464 r600_inval_shader_cache(rctx); 465 r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate); 466 467 rctx->cb_color_control &= C_028808_MULTIWRITE_ENABLE; 468 rctx->cb_color_control |= S_028808_MULTIWRITE_ENABLE(!!rctx->ps_shader->shader.fs_write_all); 469 470 if (rctx->ps_shader && rctx->vs_shader) { 471 r600_adjust_gprs(rctx); 472 } 473} 474 475void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 476{ 477 struct r600_context *rctx = (struct r600_context *)ctx; 478 479 rctx->vs_shader = (struct r600_pipe_shader *)state; 480 if (state) { 481 r600_inval_shader_cache(rctx); 482 r600_context_pipe_state_set(rctx, &rctx->vs_shader->rstate); 483 } 484 if (rctx->ps_shader && rctx->vs_shader) { 485 r600_adjust_gprs(rctx); 486 } 487} 488 489void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 490{ 491 struct r600_context *rctx = (struct r600_context *)ctx; 492 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 493 494 if (rctx->ps_shader == shader) { 495 rctx->ps_shader = NULL; 496 } 497 498 free(shader->tokens); 499 r600_pipe_shader_destroy(ctx, shader); 500 free(shader); 501} 502 503void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 504{ 505 struct r600_context *rctx = (struct r600_context *)ctx; 506 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 507 508 if (rctx->vs_shader == shader) { 509 rctx->vs_shader = NULL; 510 } 511 512 free(shader->tokens); 513 r600_pipe_shader_destroy(ctx, shader); 514 free(shader); 515} 516 517static void r600_update_alpha_ref(struct r600_context *rctx) 518{ 519 unsigned alpha_ref; 520 struct r600_pipe_state rstate; 521 522 alpha_ref = rctx->alpha_ref; 523 rstate.nregs = 0; 524 if (rctx->export_16bpc) 525 alpha_ref &= ~0x1FFF; 526 r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, NULL, 0); 527 528 r600_context_pipe_state_set(rctx, &rstate); 529 rctx->alpha_ref_dirty = false; 530} 531 532void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 533 struct pipe_resource *buffer) 534{ 535 struct r600_context *rctx = (struct r600_context *)ctx; 536 struct r600_resource *rbuffer = r600_resource(buffer); 537 struct r600_pipe_resource_state *rstate; 538 uint64_t va_offset; 539 uint32_t offset; 540 541 /* Note that the state tracker can unbind constant buffers by 542 * passing NULL here. 543 */ 544 if (buffer == NULL) { 545 return; 546 } 547 548 r600_inval_shader_cache(rctx); 549 550 r600_upload_const_buffer(rctx, &rbuffer, &offset); 551 va_offset = r600_resource_va(ctx->screen, (void*)rbuffer); 552 va_offset += offset; 553 va_offset >>= 8; 554 555 switch (shader) { 556 case PIPE_SHADER_VERTEX: 557 rctx->vs_const_buffer.nregs = 0; 558 r600_pipe_state_add_reg(&rctx->vs_const_buffer, 559 R_028180_ALU_CONST_BUFFER_SIZE_VS_0 + index * 4, 560 ALIGN_DIVUP(buffer->width0 >> 4, 16), 561 NULL, 0); 562 r600_pipe_state_add_reg(&rctx->vs_const_buffer, 563 R_028980_ALU_CONST_CACHE_VS_0 + index * 4, 564 va_offset, rbuffer, RADEON_USAGE_READ); 565 r600_context_pipe_state_set(rctx, &rctx->vs_const_buffer); 566 567 rstate = &rctx->vs_const_buffer_resource[index]; 568 if (!rstate->id) { 569 if (rctx->chip_class >= EVERGREEN) { 570 evergreen_pipe_init_buffer_resource(rctx, rstate); 571 } else { 572 r600_pipe_init_buffer_resource(rctx, rstate); 573 } 574 } 575 576 if (rctx->chip_class >= EVERGREEN) { 577 evergreen_pipe_mod_buffer_resource(ctx, rstate, rbuffer, offset, 16, RADEON_USAGE_READ); 578 } else { 579 r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, 16, RADEON_USAGE_READ); 580 } 581 r600_context_pipe_state_set_vs_resource(rctx, rstate, index); 582 break; 583 case PIPE_SHADER_FRAGMENT: 584 rctx->ps_const_buffer.nregs = 0; 585 r600_pipe_state_add_reg(&rctx->ps_const_buffer, 586 R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 587 ALIGN_DIVUP(buffer->width0 >> 4, 16), 588 NULL, 0); 589 r600_pipe_state_add_reg(&rctx->ps_const_buffer, 590 R_028940_ALU_CONST_CACHE_PS_0, 591 va_offset, rbuffer, RADEON_USAGE_READ); 592 r600_context_pipe_state_set(rctx, &rctx->ps_const_buffer); 593 594 rstate = &rctx->ps_const_buffer_resource[index]; 595 if (!rstate->id) { 596 if (rctx->chip_class >= EVERGREEN) { 597 evergreen_pipe_init_buffer_resource(rctx, rstate); 598 } else { 599 r600_pipe_init_buffer_resource(rctx, rstate); 600 } 601 } 602 if (rctx->chip_class >= EVERGREEN) { 603 evergreen_pipe_mod_buffer_resource(ctx, rstate, rbuffer, offset, 16, RADEON_USAGE_READ); 604 } else { 605 r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, 16, RADEON_USAGE_READ); 606 } 607 r600_context_pipe_state_set_ps_resource(rctx, rstate, index); 608 break; 609 default: 610 R600_ERR("unsupported %d\n", shader); 611 return; 612 } 613 614 if (buffer != &rbuffer->b.b.b) 615 pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL); 616} 617 618struct pipe_stream_output_target * 619r600_create_so_target(struct pipe_context *ctx, 620 struct pipe_resource *buffer, 621 unsigned buffer_offset, 622 unsigned buffer_size) 623{ 624 struct r600_context *rctx = (struct r600_context *)ctx; 625 struct r600_so_target *t; 626 void *ptr; 627 628 t = CALLOC_STRUCT(r600_so_target); 629 if (!t) { 630 return NULL; 631 } 632 633 t->b.reference.count = 1; 634 t->b.context = ctx; 635 pipe_resource_reference(&t->b.buffer, buffer); 636 t->b.buffer_offset = buffer_offset; 637 t->b.buffer_size = buffer_size; 638 639 t->filled_size = (struct r600_resource*) 640 pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, 4); 641 ptr = rctx->ws->buffer_map(t->filled_size->buf, rctx->cs, PIPE_TRANSFER_WRITE); 642 memset(ptr, 0, t->filled_size->buf->size); 643 rctx->ws->buffer_unmap(t->filled_size->buf); 644 645 return &t->b; 646} 647 648void r600_so_target_destroy(struct pipe_context *ctx, 649 struct pipe_stream_output_target *target) 650{ 651 struct r600_so_target *t = (struct r600_so_target*)target; 652 pipe_resource_reference(&t->b.buffer, NULL); 653 pipe_resource_reference((struct pipe_resource**)&t->filled_size, NULL); 654 FREE(t); 655} 656 657void r600_set_so_targets(struct pipe_context *ctx, 658 unsigned num_targets, 659 struct pipe_stream_output_target **targets, 660 unsigned append_bitmask) 661{ 662 struct r600_context *rctx = (struct r600_context *)ctx; 663 unsigned i; 664 665 /* Stop streamout. */ 666 if (rctx->num_so_targets) { 667 r600_context_streamout_end(rctx); 668 } 669 670 /* Set the new targets. */ 671 for (i = 0; i < num_targets; i++) { 672 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]); 673 } 674 for (; i < rctx->num_so_targets; i++) { 675 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL); 676 } 677 678 rctx->num_so_targets = num_targets; 679 rctx->streamout_start = num_targets != 0; 680 rctx->streamout_append_bitmask = append_bitmask; 681} 682 683static void r600_vertex_buffer_update(struct r600_context *rctx) 684{ 685 unsigned i, count; 686 687 r600_inval_vertex_cache(rctx); 688 689 count = rctx->vbuf_mgr->nr_real_vertex_buffers; 690 691 for (i = 0 ; i < count; i++) { 692 struct r600_pipe_resource_state *rstate = &rctx->fs_resource[i]; 693 struct pipe_vertex_buffer *vb = &rctx->vbuf_mgr->real_vertex_buffer[i]; 694 695 if (!vb->buffer) { 696 continue; 697 } 698 699 if (!rstate->id) { 700 if (rctx->chip_class >= EVERGREEN) { 701 evergreen_pipe_init_buffer_resource(rctx, rstate); 702 } else { 703 r600_pipe_init_buffer_resource(rctx, rstate); 704 } 705 } 706 707 if (rctx->chip_class >= EVERGREEN) { 708 evergreen_pipe_mod_buffer_resource(&rctx->context, rstate, (struct r600_resource*)vb->buffer, vb->buffer_offset, vb->stride, RADEON_USAGE_READ); 709 } else { 710 r600_pipe_mod_buffer_resource(rstate, (struct r600_resource*)vb->buffer, vb->buffer_offset, vb->stride, RADEON_USAGE_READ); 711 } 712 r600_context_pipe_state_set_fs_resource(rctx, rstate, i); 713 } 714} 715 716static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader) 717{ 718 struct r600_context *rctx = (struct r600_context *)ctx; 719 int r; 720 721 r600_pipe_shader_destroy(ctx, shader); 722 r = r600_pipe_shader_create(ctx, shader); 723 if (r) { 724 return r; 725 } 726 r600_context_pipe_state_set(rctx, &shader->rstate); 727 728 return 0; 729} 730 731static void r600_update_derived_state(struct r600_context *rctx) 732{ 733 struct pipe_context * ctx = (struct pipe_context*)rctx; 734 735 if (!rctx->blitter->running) { 736 if (rctx->have_depth_fb || rctx->have_depth_texture) 737 r600_flush_depth_textures(rctx); 738 } 739 740 if (rctx->chip_class < EVERGREEN) { 741 r600_update_sampler_states(rctx); 742 } 743 744 if ((rctx->ps_shader->shader.two_side != rctx->two_side) || 745 ((rctx->chip_class >= EVERGREEN) && rctx->ps_shader->shader.fs_write_all && 746 (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs))) { 747 r600_shader_rebuild(&rctx->context, rctx->ps_shader); 748 } 749 750 if (rctx->alpha_ref_dirty) { 751 r600_update_alpha_ref(rctx); 752 } 753 754 if (rctx->ps_shader && ((rctx->sprite_coord_enable && 755 (rctx->ps_shader->sprite_coord_enable != rctx->sprite_coord_enable)) || 756 (rctx->rasterizer && rctx->rasterizer->flatshade != rctx->ps_shader->flatshade))) { 757 758 if (rctx->chip_class >= EVERGREEN) 759 evergreen_pipe_shader_ps(ctx, rctx->ps_shader); 760 else 761 r600_pipe_shader_ps(ctx, rctx->ps_shader); 762 763 r600_context_pipe_state_set(rctx, &rctx->ps_shader->rstate); 764 } 765 766} 767 768static unsigned r600_conv_prim_to_gs_out(unsigned mode) 769{ 770 static const int prim_conv[] = { 771 V_028A6C_OUTPRIM_TYPE_POINTLIST, 772 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 773 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 774 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 775 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 776 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 777 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 778 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 779 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 780 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 781 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 782 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 783 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 784 V_028A6C_OUTPRIM_TYPE_TRISTRIP 785 }; 786 assert(mode < Elements(prim_conv)); 787 788 return prim_conv[mode]; 789} 790 791void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) 792{ 793 struct r600_context *rctx = (struct r600_context *)ctx; 794 struct pipe_draw_info info = *dinfo; 795 struct pipe_index_buffer ib = {}; 796 unsigned prim, mask, ls_mask = 0; 797 struct r600_block *dirty_block = NULL, *next_block = NULL; 798 struct r600_atom *state = NULL, *next_state = NULL; 799 struct radeon_winsys_cs *cs = rctx->cs; 800 uint64_t va; 801 802 if ((!info.count && (info.indexed || !info.count_from_stream_output)) || 803 (info.indexed && !rctx->vbuf_mgr->index_buffer.buffer) || 804 !r600_conv_pipe_prim(info.mode, &prim)) { 805 assert(0); 806 return; 807 } 808 809 if (!rctx->vs_shader) { 810 assert(0); 811 return; 812 } 813 814 r600_update_derived_state(rctx); 815 816 u_vbuf_draw_begin(rctx->vbuf_mgr, &info); 817 r600_vertex_buffer_update(rctx); 818 819 if (info.indexed) { 820 /* Initialize the index buffer struct. */ 821 pipe_resource_reference(&ib.buffer, rctx->vbuf_mgr->index_buffer.buffer); 822 ib.index_size = rctx->vbuf_mgr->index_buffer.index_size; 823 ib.offset = rctx->vbuf_mgr->index_buffer.offset + info.start * ib.index_size; 824 825 /* Translate or upload, if needed. */ 826 r600_translate_index_buffer(rctx, &ib, info.count); 827 828 if (u_vbuf_resource(ib.buffer)->user_ptr) { 829 r600_upload_index_buffer(rctx, &ib, info.count); 830 } 831 } else { 832 info.index_bias = info.start; 833 if (info.count_from_stream_output) { 834 r600_context_draw_opaque_count(rctx, (struct r600_so_target*)info.count_from_stream_output); 835 } 836 } 837 838 mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1; 839 840 if (rctx->vgt.id != R600_PIPE_STATE_VGT) { 841 rctx->vgt.id = R600_PIPE_STATE_VGT; 842 rctx->vgt.nregs = 0; 843 r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, NULL, 0); 844 r600_pipe_state_add_reg(&rctx->vgt, R_028A6C_VGT_GS_OUT_PRIM_TYPE, 0, NULL, 0); 845 r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, NULL, 0); 846 r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias, NULL, 0); 847 r600_pipe_state_add_reg(&rctx->vgt, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info.restart_index, NULL, 0); 848 r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info.primitive_restart, NULL, 0); 849 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance, NULL, 0); 850 r600_pipe_state_add_reg(&rctx->vgt, R_028A0C_PA_SC_LINE_STIPPLE, 0, NULL, 0); 851 if (rctx->chip_class <= R700) 852 r600_pipe_state_add_reg(&rctx->vgt, R_028808_CB_COLOR_CONTROL, rctx->cb_color_control, NULL, 0); 853 r600_pipe_state_add_reg(&rctx->vgt, R_02881C_PA_CL_VS_OUT_CNTL, 0, NULL, 0); 854 r600_pipe_state_add_reg(&rctx->vgt, R_028810_PA_CL_CLIP_CNTL, 0, NULL, 0); 855 } 856 857 rctx->vgt.nregs = 0; 858 r600_pipe_state_mod_reg(&rctx->vgt, prim); 859 r600_pipe_state_mod_reg(&rctx->vgt, r600_conv_prim_to_gs_out(info.mode)); 860 r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask); 861 r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias); 862 r600_pipe_state_mod_reg(&rctx->vgt, info.restart_index); 863 r600_pipe_state_mod_reg(&rctx->vgt, info.primitive_restart); 864 r600_pipe_state_mod_reg(&rctx->vgt, info.start_instance); 865 866 if (prim == V_008958_DI_PT_LINELIST) 867 ls_mask = 1; 868 else if (prim == V_008958_DI_PT_LINESTRIP) 869 ls_mask = 2; 870 r600_pipe_state_mod_reg(&rctx->vgt, S_028A0C_AUTO_RESET_CNTL(ls_mask) | rctx->pa_sc_line_stipple); 871 if (rctx->chip_class <= R700) 872 r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_color_control); 873 r600_pipe_state_mod_reg(&rctx->vgt, 874 rctx->vs_shader->pa_cl_vs_out_cntl | 875 (rctx->rasterizer->clip_plane_enable & rctx->vs_shader->shader.clip_dist_write)); 876 r600_pipe_state_mod_reg(&rctx->vgt, 877 rctx->pa_cl_clip_cntl | 878 (rctx->vs_shader->shader.clip_dist_write || 879 rctx->vs_shader->shader.vs_prohibit_ucps ? 880 0 : rctx->rasterizer->clip_plane_enable & 0x3F)); 881 882 r600_context_pipe_state_set(rctx, &rctx->vgt); 883 884 /* Emit states (the function expects that we emit at most 17 dwords here). */ 885 r600_need_cs_space(rctx, 0, TRUE); 886 887 LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) { 888 r600_emit_atom(rctx, state); 889 } 890 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) { 891 r600_context_block_emit_dirty(rctx, dirty_block); 892 } 893 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->resource_dirty,list) { 894 r600_context_block_resource_emit_dirty(rctx, dirty_block); 895 } 896 rctx->pm4_dirty_cdwords = 0; 897 898 /* Enable stream out if needed. */ 899 if (rctx->streamout_start) { 900 r600_context_streamout_begin(rctx); 901 rctx->streamout_start = FALSE; 902 } 903 904 /* draw packet */ 905 cs->buf[cs->cdw++] = PKT3(PKT3_INDEX_TYPE, 0, rctx->predicate_drawing); 906 cs->buf[cs->cdw++] = ib.index_size == 4 ? 907 (VGT_INDEX_32 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_32_BIT : 0)) : 908 (VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0)); 909 cs->buf[cs->cdw++] = PKT3(PKT3_NUM_INSTANCES, 0, rctx->predicate_drawing); 910 cs->buf[cs->cdw++] = info.instance_count; 911 if (info.indexed) { 912 va = r600_resource_va(ctx->screen, ib.buffer); 913 va += ib.offset; 914 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX, 3, rctx->predicate_drawing); 915 cs->buf[cs->cdw++] = va; 916 cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 917 cs->buf[cs->cdw++] = info.count; 918 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_DMA; 919 cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, rctx->predicate_drawing); 920 cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, (struct r600_resource*)ib.buffer, RADEON_USAGE_READ); 921 } else { 922 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, rctx->predicate_drawing); 923 cs->buf[cs->cdw++] = info.count; 924 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_AUTO_INDEX | 925 (info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0); 926 } 927 928 rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY | R600_CONTEXT_DRAW_PENDING; 929 930 if (rctx->framebuffer.zsbuf) 931 { 932 struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture; 933 ((struct r600_resource_texture *)tex)->dirty_db = TRUE; 934 } 935 936 pipe_resource_reference(&ib.buffer, NULL); 937 u_vbuf_draw_end(rctx->vbuf_mgr); 938} 939 940void _r600_pipe_state_add_reg(struct r600_context *ctx, 941 struct r600_pipe_state *state, 942 uint32_t offset, uint32_t value, 943 uint32_t range_id, uint32_t block_id, 944 struct r600_resource *bo, 945 enum radeon_bo_usage usage) 946{ 947 struct r600_range *range; 948 struct r600_block *block; 949 950 if (bo) assert(usage); 951 952 range = &ctx->range[range_id]; 953 block = range->blocks[block_id]; 954 state->regs[state->nregs].block = block; 955 state->regs[state->nregs].id = (offset - block->start_offset) >> 2; 956 957 state->regs[state->nregs].value = value; 958 state->regs[state->nregs].bo = bo; 959 state->regs[state->nregs].bo_usage = usage; 960 961 state->nregs++; 962 assert(state->nregs < R600_BLOCK_MAX_REG); 963} 964 965void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state, 966 uint32_t offset, uint32_t value, 967 struct r600_resource *bo, 968 enum radeon_bo_usage usage) 969{ 970 if (bo) assert(usage); 971 972 state->regs[state->nregs].id = offset; 973 state->regs[state->nregs].block = NULL; 974 state->regs[state->nregs].value = value; 975 state->regs[state->nregs].bo = bo; 976 state->regs[state->nregs].bo_usage = usage; 977 978 state->nregs++; 979 assert(state->nregs < R600_BLOCK_MAX_REG); 980} 981 982uint32_t r600_translate_stencil_op(int s_op) 983{ 984 switch (s_op) { 985 case PIPE_STENCIL_OP_KEEP: 986 return V_028800_STENCIL_KEEP; 987 case PIPE_STENCIL_OP_ZERO: 988 return V_028800_STENCIL_ZERO; 989 case PIPE_STENCIL_OP_REPLACE: 990 return V_028800_STENCIL_REPLACE; 991 case PIPE_STENCIL_OP_INCR: 992 return V_028800_STENCIL_INCR; 993 case PIPE_STENCIL_OP_DECR: 994 return V_028800_STENCIL_DECR; 995 case PIPE_STENCIL_OP_INCR_WRAP: 996 return V_028800_STENCIL_INCR_WRAP; 997 case PIPE_STENCIL_OP_DECR_WRAP: 998 return V_028800_STENCIL_DECR_WRAP; 999 case PIPE_STENCIL_OP_INVERT: 1000 return V_028800_STENCIL_INVERT; 1001 default: 1002 R600_ERR("Unknown stencil op %d", s_op); 1003 assert(0); 1004 break; 1005 } 1006 return 0; 1007} 1008 1009uint32_t r600_translate_fill(uint32_t func) 1010{ 1011 switch(func) { 1012 case PIPE_POLYGON_MODE_FILL: 1013 return 2; 1014 case PIPE_POLYGON_MODE_LINE: 1015 return 1; 1016 case PIPE_POLYGON_MODE_POINT: 1017 return 0; 1018 default: 1019 assert(0); 1020 return 0; 1021 } 1022} 1023 1024unsigned r600_tex_wrap(unsigned wrap) 1025{ 1026 switch (wrap) { 1027 default: 1028 case PIPE_TEX_WRAP_REPEAT: 1029 return V_03C000_SQ_TEX_WRAP; 1030 case PIPE_TEX_WRAP_CLAMP: 1031 return V_03C000_SQ_TEX_CLAMP_HALF_BORDER; 1032 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 1033 return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL; 1034 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 1035 return V_03C000_SQ_TEX_CLAMP_BORDER; 1036 case PIPE_TEX_WRAP_MIRROR_REPEAT: 1037 return V_03C000_SQ_TEX_MIRROR; 1038 case PIPE_TEX_WRAP_MIRROR_CLAMP: 1039 return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER; 1040 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 1041 return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; 1042 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 1043 return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER; 1044 } 1045} 1046 1047unsigned r600_tex_filter(unsigned filter) 1048{ 1049 switch (filter) { 1050 default: 1051 case PIPE_TEX_FILTER_NEAREST: 1052 return V_03C000_SQ_TEX_XY_FILTER_POINT; 1053 case PIPE_TEX_FILTER_LINEAR: 1054 return V_03C000_SQ_TEX_XY_FILTER_BILINEAR; 1055 } 1056} 1057 1058unsigned r600_tex_mipfilter(unsigned filter) 1059{ 1060 switch (filter) { 1061 case PIPE_TEX_MIPFILTER_NEAREST: 1062 return V_03C000_SQ_TEX_Z_FILTER_POINT; 1063 case PIPE_TEX_MIPFILTER_LINEAR: 1064 return V_03C000_SQ_TEX_Z_FILTER_LINEAR; 1065 default: 1066 case PIPE_TEX_MIPFILTER_NONE: 1067 return V_03C000_SQ_TEX_Z_FILTER_NONE; 1068 } 1069} 1070 1071unsigned r600_tex_compare(unsigned compare) 1072{ 1073 switch (compare) { 1074 default: 1075 case PIPE_FUNC_NEVER: 1076 return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER; 1077 case PIPE_FUNC_LESS: 1078 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS; 1079 case PIPE_FUNC_EQUAL: 1080 return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL; 1081 case PIPE_FUNC_LEQUAL: 1082 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; 1083 case PIPE_FUNC_GREATER: 1084 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER; 1085 case PIPE_FUNC_NOTEQUAL: 1086 return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; 1087 case PIPE_FUNC_GEQUAL: 1088 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; 1089 case PIPE_FUNC_ALWAYS: 1090 return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS; 1091 } 1092} 1093