r600_state_common.c revision 8fb7f1a8a4cbab5365491b4b41e50ff3f03306c8
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 "util/u_memory.h" 28#include "util/u_format.h" 29#include "pipebuffer/pb_buffer.h" 30#include "pipe/p_shader_tokens.h" 31#include "tgsi/tgsi_parse.h" 32#include "r600_formats.h" 33#include "r600_pipe.h" 34#include "r600d.h" 35 36static void r600_spi_update(struct r600_pipe_context *rctx); 37 38static int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) 39{ 40 static const int prim_conv[] = { 41 V_008958_DI_PT_POINTLIST, 42 V_008958_DI_PT_LINELIST, 43 V_008958_DI_PT_LINELOOP, 44 V_008958_DI_PT_LINESTRIP, 45 V_008958_DI_PT_TRILIST, 46 V_008958_DI_PT_TRISTRIP, 47 V_008958_DI_PT_TRIFAN, 48 V_008958_DI_PT_QUADLIST, 49 V_008958_DI_PT_QUADSTRIP, 50 V_008958_DI_PT_POLYGON, 51 -1, 52 -1, 53 -1, 54 -1 55 }; 56 57 *prim = prim_conv[pprim]; 58 if (*prim == -1) { 59 fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); 60 return -1; 61 } 62 return 0; 63} 64 65/* common state between evergreen and r600 */ 66void r600_bind_blend_state(struct pipe_context *ctx, void *state) 67{ 68 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 69 struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; 70 struct r600_pipe_state *rstate; 71 72 if (state == NULL) 73 return; 74 rstate = &blend->rstate; 75 rctx->states[rstate->id] = rstate; 76 rctx->cb_target_mask = blend->cb_target_mask; 77 r600_context_pipe_state_set(&rctx->ctx, rstate); 78} 79 80void r600_bind_dsa_state(struct pipe_context *ctx, void *state) 81{ 82 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 83 struct r600_pipe_dsa *dsa = state; 84 struct r600_pipe_state *rstate; 85 86 if (state == NULL) 87 return; 88 rstate = &dsa->rstate; 89 rctx->states[rstate->id] = rstate; 90 rctx->alpha_ref = dsa->alpha_ref; 91 rctx->alpha_ref_dirty = true; 92 r600_context_pipe_state_set(&rctx->ctx, rstate); 93} 94 95void r600_bind_rs_state(struct pipe_context *ctx, void *state) 96{ 97 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 98 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 99 100 if (state == NULL) 101 return; 102 103 rctx->clamp_vertex_color = rs->clamp_vertex_color; 104 rctx->clamp_fragment_color = rs->clamp_fragment_color; 105 rctx->flatshade = rs->flatshade; 106 rctx->sprite_coord_enable = rs->sprite_coord_enable; 107 rctx->rasterizer = rs; 108 109 rctx->states[rs->rstate.id] = &rs->rstate; 110 r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); 111 112 if (rctx->chip_class >= EVERGREEN) { 113 evergreen_polygon_offset_update(rctx); 114 } else { 115 r600_polygon_offset_update(rctx); 116 } 117 if (rctx->ps_shader && rctx->vs_shader) 118 rctx->spi_dirty = true; 119} 120 121void r600_delete_rs_state(struct pipe_context *ctx, void *state) 122{ 123 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 124 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 125 126 if (rctx->rasterizer == rs) { 127 rctx->rasterizer = NULL; 128 } 129 if (rctx->states[rs->rstate.id] == &rs->rstate) { 130 rctx->states[rs->rstate.id] = NULL; 131 } 132 free(rs); 133} 134 135void r600_sampler_view_destroy(struct pipe_context *ctx, 136 struct pipe_sampler_view *state) 137{ 138 struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; 139 140 pipe_resource_reference(&state->texture, NULL); 141 FREE(resource); 142} 143 144void r600_delete_state(struct pipe_context *ctx, void *state) 145{ 146 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 147 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 148 149 if (rctx->states[rstate->id] == rstate) { 150 rctx->states[rstate->id] = NULL; 151 } 152 for (int i = 0; i < rstate->nregs; i++) { 153 r600_bo_reference(&rstate->regs[i].bo, NULL); 154 } 155 free(rstate); 156} 157 158void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) 159{ 160 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 161 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 162 163 rctx->vertex_elements = v; 164 if (v) { 165 u_vbuf_mgr_bind_vertex_elements(rctx->vbuf_mgr, state, 166 v->vmgr_elements); 167 168 rctx->states[v->rstate.id] = &v->rstate; 169 r600_context_pipe_state_set(&rctx->ctx, &v->rstate); 170 } 171} 172 173void r600_delete_vertex_element(struct pipe_context *ctx, void *state) 174{ 175 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 176 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 177 178 if (rctx->states[v->rstate.id] == &v->rstate) { 179 rctx->states[v->rstate.id] = NULL; 180 } 181 if (rctx->vertex_elements == state) 182 rctx->vertex_elements = NULL; 183 184 r600_bo_reference(&v->fetch_shader, NULL); 185 u_vbuf_mgr_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements); 186 FREE(state); 187} 188 189 190void r600_set_index_buffer(struct pipe_context *ctx, 191 const struct pipe_index_buffer *ib) 192{ 193 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 194 195 if (ib) { 196 pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); 197 memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer)); 198 } else { 199 pipe_resource_reference(&rctx->index_buffer.buffer, NULL); 200 memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer)); 201 } 202 203 /* TODO make this more like a state */ 204} 205 206void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 207 const struct pipe_vertex_buffer *buffers) 208{ 209 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 210 int i; 211 212 /* Zero states. */ 213 for (i = 0; i < count; i++) { 214 if (!buffers[i].buffer) { 215 if (rctx->chip_class >= EVERGREEN) { 216 evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 217 } else { 218 r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 219 } 220 } 221 } 222 for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) { 223 if (rctx->chip_class >= EVERGREEN) { 224 evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 225 } else { 226 r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 227 } 228 } 229 230 u_vbuf_mgr_set_vertex_buffers(rctx->vbuf_mgr, count, buffers); 231} 232 233void *r600_create_vertex_elements(struct pipe_context *ctx, 234 unsigned count, 235 const struct pipe_vertex_element *elements) 236{ 237 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 238 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 239 240 assert(count < 32); 241 if (!v) 242 return NULL; 243 244 v->count = count; 245 v->vmgr_elements = 246 u_vbuf_mgr_create_vertex_elements(rctx->vbuf_mgr, count, 247 elements, v->elements); 248 249 if (r600_vertex_elements_build_fetch_shader(rctx, v)) { 250 FREE(v); 251 return NULL; 252 } 253 254 return v; 255} 256 257void *r600_create_shader_state(struct pipe_context *ctx, 258 const struct pipe_shader_state *state) 259{ 260 struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); 261 int r; 262 263 shader->tokens = tgsi_dup_tokens(state->tokens); 264 265 r = r600_pipe_shader_create(ctx, shader); 266 if (r) { 267 return NULL; 268 } 269 return shader; 270} 271 272void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 273{ 274 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 275 276 /* TODO delete old shader */ 277 rctx->ps_shader = (struct r600_pipe_shader *)state; 278 if (state) { 279 r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate); 280 } 281 if (rctx->ps_shader && rctx->vs_shader) { 282 rctx->spi_dirty = true; 283 r600_adjust_gprs(rctx); 284 } 285} 286 287void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 288{ 289 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 290 291 /* TODO delete old shader */ 292 rctx->vs_shader = (struct r600_pipe_shader *)state; 293 if (state) { 294 r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate); 295 } 296 if (rctx->ps_shader && rctx->vs_shader) { 297 rctx->spi_dirty = true; 298 r600_adjust_gprs(rctx); 299 } 300} 301 302void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 303{ 304 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 305 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 306 307 if (rctx->ps_shader == shader) { 308 rctx->ps_shader = NULL; 309 } 310 311 free(shader->tokens); 312 r600_pipe_shader_destroy(ctx, shader); 313 free(shader); 314} 315 316void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 317{ 318 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 319 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 320 321 if (rctx->vs_shader == shader) { 322 rctx->vs_shader = NULL; 323 } 324 325 free(shader->tokens); 326 r600_pipe_shader_destroy(ctx, shader); 327 free(shader); 328} 329 330static void r600_update_alpha_ref(struct r600_pipe_context *rctx) 331{ 332 unsigned alpha_ref; 333 struct r600_pipe_state rstate; 334 335 alpha_ref = rctx->alpha_ref; 336 rstate.nregs = 0; 337 if (rctx->export_16bpc) 338 alpha_ref &= ~0x1FFF; 339 r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL, 0); 340 341 r600_context_pipe_state_set(&rctx->ctx, &rstate); 342 rctx->alpha_ref_dirty = false; 343} 344 345/* FIXME optimize away spi update when it's not needed */ 346static void r600_spi_block_init(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate) 347{ 348 int i; 349 rstate->nregs = 0; 350 rstate->id = R600_PIPE_STATE_SPI; 351 for (i = 0; i < 32; i++) { 352 r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, 0, 0xFFFFFFFF, NULL, 0); 353 } 354} 355 356static void r600_spi_update(struct r600_pipe_context *rctx) 357{ 358 struct r600_pipe_shader *shader = rctx->ps_shader; 359 struct r600_pipe_state *rstate = &rctx->spi; 360 struct r600_shader *rshader = &shader->shader; 361 unsigned i, tmp, sid; 362 363 if (rctx->spi.id == 0) 364 r600_spi_block_init(rctx, &rctx->spi); 365 366 rstate->nregs = 0; 367 for (i = 0; i < rshader->ninput; i++) { 368 if (rshader->input[i].name == TGSI_SEMANTIC_POSITION || 369 rshader->input[i].name == TGSI_SEMANTIC_FACE) 370 if (rctx->chip_class >= EVERGREEN) 371 continue; 372 else 373 sid=0; 374 else 375 sid=r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i); 376 377 tmp = S_028644_SEMANTIC(sid); 378 379 if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || 380 rshader->input[i].name == TGSI_SEMANTIC_BCOLOR || 381 rshader->input[i].name == TGSI_SEMANTIC_POSITION) { 382 tmp |= S_028644_FLAT_SHADE(rctx->flatshade); 383 } 384 385 if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC && 386 rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) { 387 tmp |= S_028644_PT_SPRITE_TEX(1); 388 } 389 390 if (rctx->chip_class < EVERGREEN) { 391 if (rshader->input[i].centroid) 392 tmp |= S_028644_SEL_CENTROID(1); 393 394 if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR) 395 tmp |= S_028644_SEL_LINEAR(1); 396 } 397 398 r600_pipe_state_mod_reg(rstate, tmp); 399 } 400 401 rctx->spi_dirty = false; 402 r600_context_pipe_state_set(&rctx->ctx, rstate); 403} 404 405void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 406 struct pipe_resource *buffer) 407{ 408 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 409 struct r600_resource_buffer *rbuffer = r600_buffer(buffer); 410 struct r600_pipe_resource_state *rstate; 411 uint32_t offset; 412 413 /* Note that the state tracker can unbind constant buffers by 414 * passing NULL here. 415 */ 416 if (buffer == NULL) { 417 return; 418 } 419 420 r600_upload_const_buffer(rctx, &rbuffer, &offset); 421 422 switch (shader) { 423 case PIPE_SHADER_VERTEX: 424 rctx->vs_const_buffer.nregs = 0; 425 r600_pipe_state_add_reg(&rctx->vs_const_buffer, 426 R_028180_ALU_CONST_BUFFER_SIZE_VS_0, 427 ALIGN_DIVUP(buffer->width0 >> 4, 16), 428 0xFFFFFFFF, NULL, 0); 429 r600_pipe_state_add_reg(&rctx->vs_const_buffer, 430 R_028980_ALU_CONST_CACHE_VS_0, 431 offset >> 8, 0xFFFFFFFF, rbuffer->r.bo, RADEON_USAGE_READ); 432 r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_const_buffer); 433 434 rstate = &rctx->vs_const_buffer_resource[index]; 435 if (!rstate->id) { 436 if (rctx->chip_class >= EVERGREEN) { 437 evergreen_pipe_init_buffer_resource(rctx, rstate); 438 } else { 439 r600_pipe_init_buffer_resource(rctx, rstate); 440 } 441 } 442 443 if (rctx->chip_class >= EVERGREEN) { 444 evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ); 445 evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index); 446 } else { 447 r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ); 448 r600_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index); 449 } 450 break; 451 case PIPE_SHADER_FRAGMENT: 452 rctx->ps_const_buffer.nregs = 0; 453 r600_pipe_state_add_reg(&rctx->ps_const_buffer, 454 R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 455 ALIGN_DIVUP(buffer->width0 >> 4, 16), 456 0xFFFFFFFF, NULL, 0); 457 r600_pipe_state_add_reg(&rctx->ps_const_buffer, 458 R_028940_ALU_CONST_CACHE_PS_0, 459 offset >> 8, 0xFFFFFFFF, rbuffer->r.bo, RADEON_USAGE_READ); 460 r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_const_buffer); 461 462 rstate = &rctx->ps_const_buffer_resource[index]; 463 if (!rstate->id) { 464 if (rctx->chip_class >= EVERGREEN) { 465 evergreen_pipe_init_buffer_resource(rctx, rstate); 466 } else { 467 r600_pipe_init_buffer_resource(rctx, rstate); 468 } 469 } 470 if (rctx->chip_class >= EVERGREEN) { 471 evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ); 472 evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index); 473 } else { 474 r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16, RADEON_USAGE_READ); 475 r600_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index); 476 } 477 break; 478 default: 479 R600_ERR("unsupported %d\n", shader); 480 return; 481 } 482 483 if (buffer != &rbuffer->r.b.b.b) 484 pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL); 485} 486 487static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) 488{ 489 struct r600_pipe_resource_state *rstate; 490 struct r600_resource *rbuffer; 491 struct pipe_vertex_buffer *vertex_buffer; 492 unsigned i, count, offset; 493 494 if (rctx->vertex_elements->vbuffer_need_offset) { 495 /* one resource per vertex elements */ 496 count = rctx->vertex_elements->count; 497 } else { 498 /* bind vertex buffer once */ 499 count = rctx->vbuf_mgr->nr_real_vertex_buffers; 500 } 501 502 for (i = 0 ; i < count; i++) { 503 rstate = &rctx->fs_resource[i]; 504 505 if (rctx->vertex_elements->vbuffer_need_offset) { 506 /* one resource per vertex elements */ 507 unsigned vbuffer_index; 508 vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index; 509 vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[vbuffer_index]; 510 rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[vbuffer_index]; 511 offset = rctx->vertex_elements->vbuffer_offset[i]; 512 } else { 513 /* bind vertex buffer once */ 514 vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[i]; 515 rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[i]; 516 offset = 0; 517 } 518 if (vertex_buffer == NULL || rbuffer == NULL) 519 continue; 520 offset += vertex_buffer->buffer_offset; 521 522 if (!rstate->id) { 523 if (rctx->chip_class >= EVERGREEN) { 524 evergreen_pipe_init_buffer_resource(rctx, rstate); 525 } else { 526 r600_pipe_init_buffer_resource(rctx, rstate); 527 } 528 } 529 530 if (rctx->chip_class >= EVERGREEN) { 531 evergreen_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride, RADEON_USAGE_READ); 532 evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i); 533 } else { 534 r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride, RADEON_USAGE_READ); 535 r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i); 536 } 537 } 538} 539 540static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader) 541{ 542 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 543 int r; 544 545 r600_pipe_shader_destroy(ctx, shader); 546 r = r600_pipe_shader_create(ctx, shader); 547 if (r) { 548 return r; 549 } 550 r600_context_pipe_state_set(&rctx->ctx, &shader->rstate); 551 552 return 0; 553} 554 555void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) 556{ 557 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 558 struct r600_resource *rbuffer; 559 struct r600_draw rdraw; 560 struct r600_drawl draw; 561 unsigned prim, mask; 562 563 if (!rctx->blit) { 564 if (rctx->have_depth_fb || rctx->have_depth_texture) 565 r600_flush_depth_textures(rctx); 566 } 567 u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info); 568 r600_vertex_buffer_update(rctx); 569 570 draw.info = *info; 571 draw.ctx = ctx; 572 draw.index_buffer = NULL; 573 if (info->indexed && rctx->index_buffer.buffer) { 574 draw.info.start += rctx->index_buffer.offset / rctx->index_buffer.index_size; 575 pipe_resource_reference(&draw.index_buffer, rctx->index_buffer.buffer); 576 577 r600_translate_index_buffer(rctx, &draw.index_buffer, 578 &rctx->index_buffer.index_size, 579 &draw.info.start, 580 info->count); 581 582 draw.index_size = rctx->index_buffer.index_size; 583 draw.index_buffer_offset = draw.info.start * draw.index_size; 584 draw.info.start = 0; 585 586 if (u_vbuf_resource(draw.index_buffer)->user_ptr) { 587 r600_upload_index_buffer(rctx, &draw); 588 } 589 } else { 590 draw.index_size = 0; 591 draw.index_buffer_offset = 0; 592 draw.info.index_bias = info->start; 593 } 594 595 if (r600_conv_pipe_prim(draw.info.mode, &prim)) 596 return; 597 598 if (rctx->vs_shader->shader.clamp_color != rctx->clamp_vertex_color) 599 r600_shader_rebuild(ctx, rctx->vs_shader); 600 601 if ((rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color) || 602 ((rctx->chip_class >= EVERGREEN) && rctx->ps_shader->shader.fs_write_all && 603 (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs))) 604 r600_shader_rebuild(ctx, rctx->ps_shader); 605 606 if (rctx->spi_dirty) 607 r600_spi_update(rctx); 608 609 if (rctx->alpha_ref_dirty) 610 r600_update_alpha_ref(rctx); 611 612 mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1; 613 614 if (rctx->vgt.id != R600_PIPE_STATE_VGT) { 615 rctx->vgt.id = R600_PIPE_STATE_VGT; 616 rctx->vgt.nregs = 0; 617 r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, 0xFFFFFFFF, NULL, 0); 618 r600_pipe_state_add_reg(&rctx->vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL, 0); 619 r600_pipe_state_add_reg(&rctx->vgt, R_028400_VGT_MAX_VTX_INDX, draw.info.max_index, 0xFFFFFFFF, NULL, 0); 620 r600_pipe_state_add_reg(&rctx->vgt, R_028404_VGT_MIN_VTX_INDX, draw.info.min_index, 0xFFFFFFFF, NULL, 0); 621 r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, draw.info.index_bias, 0xFFFFFFFF, NULL, 0); 622 r600_pipe_state_add_reg(&rctx->vgt, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, draw.info.restart_index, 0xFFFFFFFF, NULL, 0); 623 r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, draw.info.primitive_restart, 0xFFFFFFFF, NULL, 0); 624 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL, 0); 625 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, draw.info.start_instance, 0xFFFFFFFF, NULL, 0); 626 r600_pipe_state_add_reg(&rctx->vgt, R_028814_PA_SU_SC_MODE_CNTL, 627 0, 628 S_028814_PROVOKING_VTX_LAST(1), NULL, 0); 629 630 } 631 632 rctx->vgt.nregs = 0; 633 r600_pipe_state_mod_reg(&rctx->vgt, prim); 634 r600_pipe_state_mod_reg(&rctx->vgt, rctx->cb_target_mask & mask); 635 r600_pipe_state_mod_reg(&rctx->vgt, draw.info.max_index); 636 r600_pipe_state_mod_reg(&rctx->vgt, draw.info.min_index); 637 r600_pipe_state_mod_reg(&rctx->vgt, draw.info.index_bias); 638 r600_pipe_state_mod_reg(&rctx->vgt, draw.info.restart_index); 639 r600_pipe_state_mod_reg(&rctx->vgt, draw.info.primitive_restart); 640 r600_pipe_state_mod_reg(&rctx->vgt, 0); 641 r600_pipe_state_mod_reg(&rctx->vgt, draw.info.start_instance); 642 if (draw.info.mode == PIPE_PRIM_QUADS || draw.info.mode == PIPE_PRIM_QUAD_STRIP || draw.info.mode == PIPE_PRIM_POLYGON) { 643 r600_pipe_state_mod_reg(&rctx->vgt, S_028814_PROVOKING_VTX_LAST(1)); 644 } 645 646 r600_context_pipe_state_set(&rctx->ctx, &rctx->vgt); 647 648 rdraw.vgt_num_indices = draw.info.count; 649 rdraw.vgt_num_instances = draw.info.instance_count; 650 rdraw.vgt_index_type = ((draw.index_size == 4) ? 1 : 0); 651 if (R600_BIG_ENDIAN) 652 rdraw.vgt_index_type |= (draw.index_size >> 1) << 2; 653 rdraw.vgt_draw_initiator = draw.index_size ? 0 : 2; 654 rdraw.indices = NULL; 655 if (draw.index_buffer) { 656 rbuffer = (struct r600_resource*)draw.index_buffer; 657 rdraw.indices = rbuffer->bo; 658 rdraw.indices_bo_offset = draw.index_buffer_offset; 659 } 660 661 if (rctx->chip_class >= EVERGREEN) { 662 evergreen_context_draw(&rctx->ctx, &rdraw); 663 } else { 664 r600_context_draw(&rctx->ctx, &rdraw); 665 } 666 667 if (rctx->framebuffer.zsbuf) 668 { 669 struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture; 670 ((struct r600_resource_texture *)tex)->dirty_db = TRUE; 671 } 672 673 pipe_resource_reference(&draw.index_buffer, NULL); 674 675 u_vbuf_mgr_draw_end(rctx->vbuf_mgr); 676} 677 678void _r600_pipe_state_add_reg(struct r600_context *ctx, 679 struct r600_pipe_state *state, 680 u32 offset, u32 value, u32 mask, 681 u32 range_id, u32 block_id, 682 struct r600_bo *bo, 683 enum radeon_bo_usage usage) 684{ 685 struct r600_range *range; 686 struct r600_block *block; 687 688 if (bo) assert(usage); 689 690 range = &ctx->range[range_id]; 691 block = range->blocks[block_id]; 692 state->regs[state->nregs].block = block; 693 state->regs[state->nregs].id = (offset - block->start_offset) >> 2; 694 695 state->regs[state->nregs].value = value; 696 state->regs[state->nregs].mask = mask; 697 state->regs[state->nregs].bo = bo; 698 state->regs[state->nregs].bo_usage = usage; 699 700 state->nregs++; 701 assert(state->nregs < R600_BLOCK_MAX_REG); 702} 703 704void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state, 705 u32 offset, u32 value, u32 mask, 706 struct r600_bo *bo, 707 enum radeon_bo_usage usage) 708{ 709 if (bo) assert(usage); 710 711 state->regs[state->nregs].id = offset; 712 state->regs[state->nregs].block = NULL; 713 state->regs[state->nregs].value = value; 714 state->regs[state->nregs].mask = mask; 715 state->regs[state->nregs].bo = bo; 716 state->regs[state->nregs].bo_usage = usage; 717 718 state->nregs++; 719 assert(state->nregs < R600_BLOCK_MAX_REG); 720} 721