r600_state_common.c revision d7577ae3a6d6e174ab36d244f6bd4dedd63c3d1d
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 "r600_formats.h" 32#include "r600_pipe.h" 33#include "r600d.h" 34 35static int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) 36{ 37 switch (pprim) { 38 case PIPE_PRIM_POINTS: 39 *prim = V_008958_DI_PT_POINTLIST; 40 return 0; 41 case PIPE_PRIM_LINES: 42 *prim = V_008958_DI_PT_LINELIST; 43 return 0; 44 case PIPE_PRIM_LINE_STRIP: 45 *prim = V_008958_DI_PT_LINESTRIP; 46 return 0; 47 case PIPE_PRIM_LINE_LOOP: 48 *prim = V_008958_DI_PT_LINELOOP; 49 return 0; 50 case PIPE_PRIM_TRIANGLES: 51 *prim = V_008958_DI_PT_TRILIST; 52 return 0; 53 case PIPE_PRIM_TRIANGLE_STRIP: 54 *prim = V_008958_DI_PT_TRISTRIP; 55 return 0; 56 case PIPE_PRIM_TRIANGLE_FAN: 57 *prim = V_008958_DI_PT_TRIFAN; 58 return 0; 59 case PIPE_PRIM_POLYGON: 60 *prim = V_008958_DI_PT_POLYGON; 61 return 0; 62 case PIPE_PRIM_QUADS: 63 *prim = V_008958_DI_PT_QUADLIST; 64 return 0; 65 case PIPE_PRIM_QUAD_STRIP: 66 *prim = V_008958_DI_PT_QUADSTRIP; 67 return 0; 68 default: 69 fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); 70 return -1; 71 } 72} 73 74/* common state between evergreen and r600 */ 75void r600_bind_blend_state(struct pipe_context *ctx, void *state) 76{ 77 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 78 struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; 79 struct r600_pipe_state *rstate; 80 81 if (state == NULL) 82 return; 83 rstate = &blend->rstate; 84 rctx->states[rstate->id] = rstate; 85 rctx->cb_target_mask = blend->cb_target_mask; 86 r600_context_pipe_state_set(&rctx->ctx, rstate); 87} 88 89void r600_bind_rs_state(struct pipe_context *ctx, void *state) 90{ 91 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 92 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 93 94 if (state == NULL) 95 return; 96 97 rctx->flatshade = rs->flatshade; 98 rctx->sprite_coord_enable = rs->sprite_coord_enable; 99 rctx->rasterizer = rs; 100 101 rctx->states[rs->rstate.id] = &rs->rstate; 102 r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); 103 104 if (rctx->family >= CHIP_CEDAR) { 105 evergreen_polygon_offset_update(rctx); 106 } else { 107 r600_polygon_offset_update(rctx); 108 } 109} 110 111void r600_delete_rs_state(struct pipe_context *ctx, void *state) 112{ 113 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 114 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 115 116 if (rctx->rasterizer == rs) { 117 rctx->rasterizer = NULL; 118 } 119 if (rctx->states[rs->rstate.id] == &rs->rstate) { 120 rctx->states[rs->rstate.id] = NULL; 121 } 122 free(rs); 123} 124 125void r600_sampler_view_destroy(struct pipe_context *ctx, 126 struct pipe_sampler_view *state) 127{ 128 struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; 129 130 pipe_resource_reference(&state->texture, NULL); 131 FREE(resource); 132} 133 134void r600_bind_state(struct pipe_context *ctx, void *state) 135{ 136 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 137 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 138 139 if (state == NULL) 140 return; 141 rctx->states[rstate->id] = rstate; 142 r600_context_pipe_state_set(&rctx->ctx, rstate); 143} 144 145void r600_delete_state(struct pipe_context *ctx, void *state) 146{ 147 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 148 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 149 150 if (rctx->states[rstate->id] == rstate) { 151 rctx->states[rstate->id] = NULL; 152 } 153 for (int i = 0; i < rstate->nregs; i++) { 154 r600_bo_reference(rctx->radeon, &rstate->regs[i].bo, NULL); 155 } 156 free(rstate); 157} 158 159void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) 160{ 161 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 162 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 163 164 rctx->vertex_elements = v; 165 if (v) { 166 u_vbuf_mgr_bind_vertex_elements(rctx->vbuf_mgr, state, 167 v->vmgr_elements); 168 169 rctx->states[v->rstate.id] = &v->rstate; 170 r600_context_pipe_state_set(&rctx->ctx, &v->rstate); 171 } 172} 173 174void r600_delete_vertex_element(struct pipe_context *ctx, void *state) 175{ 176 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 177 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 178 179 if (rctx->states[v->rstate.id] == &v->rstate) { 180 rctx->states[v->rstate.id] = NULL; 181 } 182 if (rctx->vertex_elements == state) 183 rctx->vertex_elements = NULL; 184 185 r600_bo_reference(rctx->radeon, &v->fetch_shader, NULL); 186 u_vbuf_mgr_destroy_vertex_elements(rctx->vbuf_mgr, v->vmgr_elements); 187 FREE(state); 188} 189 190 191void r600_set_index_buffer(struct pipe_context *ctx, 192 const struct pipe_index_buffer *ib) 193{ 194 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 195 196 if (ib) { 197 pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); 198 memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer)); 199 } else { 200 pipe_resource_reference(&rctx->index_buffer.buffer, NULL); 201 memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer)); 202 } 203 204 /* TODO make this more like a state */ 205} 206 207void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 208 const struct pipe_vertex_buffer *buffers) 209{ 210 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 211 int i; 212 213 /* Zero states. */ 214 for (i = 0; i < count; i++) { 215 if (!buffers[i].buffer) { 216 if (rctx->family >= CHIP_CEDAR) { 217 evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 218 } else { 219 r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 220 } 221 } 222 } 223 for (; i < rctx->vbuf_mgr->nr_real_vertex_buffers; i++) { 224 if (rctx->family >= CHIP_CEDAR) { 225 evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 226 } else { 227 r600_context_pipe_state_set_fs_resource(&rctx->ctx, NULL, i); 228 } 229 } 230 231 u_vbuf_mgr_set_vertex_buffers(rctx->vbuf_mgr, count, buffers); 232} 233 234void *r600_create_vertex_elements(struct pipe_context *ctx, 235 unsigned count, 236 const struct pipe_vertex_element *elements) 237{ 238 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 239 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 240 241 assert(count < 32); 242 if (!v) 243 return NULL; 244 245 v->count = count; 246 v->vmgr_elements = 247 u_vbuf_mgr_create_vertex_elements(rctx->vbuf_mgr, count, 248 elements, v->elements); 249 250 if (r600_vertex_elements_build_fetch_shader(rctx, v)) { 251 FREE(v); 252 return NULL; 253 } 254 255 return v; 256} 257 258void *r600_create_shader_state(struct pipe_context *ctx, 259 const struct pipe_shader_state *state) 260{ 261 struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader); 262 int r; 263 264 r = r600_pipe_shader_create(ctx, shader, state->tokens); 265 if (r) { 266 return NULL; 267 } 268 return shader; 269} 270 271void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 272{ 273 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 274 275 /* TODO delete old shader */ 276 rctx->ps_shader = (struct r600_pipe_shader *)state; 277 if (state) { 278 r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate); 279 } 280} 281 282void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 283{ 284 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 285 286 /* TODO delete old shader */ 287 rctx->vs_shader = (struct r600_pipe_shader *)state; 288 if (state) { 289 r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate); 290 } 291} 292 293void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 294{ 295 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 296 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 297 298 if (rctx->ps_shader == shader) { 299 rctx->ps_shader = NULL; 300 } 301 302 r600_pipe_shader_destroy(ctx, shader); 303 free(shader); 304} 305 306void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 307{ 308 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 309 struct r600_pipe_shader *shader = (struct r600_pipe_shader *)state; 310 311 if (rctx->vs_shader == shader) { 312 rctx->vs_shader = NULL; 313 } 314 315 r600_pipe_shader_destroy(ctx, shader); 316 free(shader); 317} 318 319/* FIXME optimize away spi update when it's not needed */ 320static void r600_spi_update(struct r600_pipe_context *rctx, unsigned prim) 321{ 322 struct r600_pipe_shader *shader = rctx->ps_shader; 323 struct r600_pipe_state rstate; 324 struct r600_shader *rshader = &shader->shader; 325 unsigned i, tmp; 326 327 rstate.nregs = 0; 328 for (i = 0; i < rshader->ninput; i++) { 329 tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i)); 330 331 if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || 332 rshader->input[i].name == TGSI_SEMANTIC_BCOLOR || 333 rshader->input[i].name == TGSI_SEMANTIC_POSITION) { 334 tmp |= S_028644_FLAT_SHADE(rctx->flatshade); 335 } 336 337 if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC && 338 rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) { 339 tmp |= S_028644_PT_SPRITE_TEX(1); 340 } 341 342 if (rctx->family < CHIP_CEDAR) { 343 if (rshader->input[i].centroid) 344 tmp |= S_028644_SEL_CENTROID(1); 345 346 if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR) 347 tmp |= S_028644_SEL_LINEAR(1); 348 } 349 350 r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL); 351 } 352 353 if (prim == PIPE_PRIM_QUADS || prim == PIPE_PRIM_QUAD_STRIP || prim == PIPE_PRIM_POLYGON) { 354 r600_pipe_state_add_reg(&rstate, R_028814_PA_SU_SC_MODE_CNTL, 355 S_028814_PROVOKING_VTX_LAST(1), 356 S_028814_PROVOKING_VTX_LAST(1), NULL); 357 } 358 r600_context_pipe_state_set(&rctx->ctx, &rstate); 359} 360 361void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 362 struct pipe_resource *buffer) 363{ 364 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 365 struct r600_resource_buffer *rbuffer = r600_buffer(buffer); 366 struct r600_pipe_state *rstate; 367 uint32_t offset; 368 369 /* Note that the state tracker can unbind constant buffers by 370 * passing NULL here. 371 */ 372 if (buffer == NULL) { 373 return; 374 } 375 376 r600_upload_const_buffer(rctx, &rbuffer, &offset); 377 offset += r600_bo_offset(rbuffer->r.bo); 378 379 switch (shader) { 380 case PIPE_SHADER_VERTEX: 381 rctx->vs_const_buffer.nregs = 0; 382 r600_pipe_state_add_reg(&rctx->vs_const_buffer, 383 R_028180_ALU_CONST_BUFFER_SIZE_VS_0, 384 ALIGN_DIVUP(buffer->width0 >> 4, 16), 385 0xFFFFFFFF, NULL); 386 r600_pipe_state_add_reg(&rctx->vs_const_buffer, 387 R_028980_ALU_CONST_CACHE_VS_0, 388 offset >> 8, 0xFFFFFFFF, rbuffer->r.bo); 389 r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_const_buffer); 390 391 rstate = &rctx->vs_const_buffer_resource[index]; 392 rstate->id = R600_PIPE_STATE_RESOURCE; 393 rstate->nregs = 0; 394 if (rctx->family >= CHIP_CEDAR) { 395 evergreen_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); 396 evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index); 397 } else { 398 r600_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); 399 r600_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index); 400 } 401 break; 402 case PIPE_SHADER_FRAGMENT: 403 rctx->ps_const_buffer.nregs = 0; 404 r600_pipe_state_add_reg(&rctx->ps_const_buffer, 405 R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 406 ALIGN_DIVUP(buffer->width0 >> 4, 16), 407 0xFFFFFFFF, NULL); 408 r600_pipe_state_add_reg(&rctx->ps_const_buffer, 409 R_028940_ALU_CONST_CACHE_PS_0, 410 offset >> 8, 0xFFFFFFFF, rbuffer->r.bo); 411 r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_const_buffer); 412 413 rstate = &rctx->ps_const_buffer_resource[index]; 414 rstate->id = R600_PIPE_STATE_RESOURCE; 415 rstate->nregs = 0; 416 if (rctx->family >= CHIP_CEDAR) { 417 evergreen_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); 418 evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index); 419 } else { 420 r600_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); 421 r600_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index); 422 } 423 break; 424 default: 425 R600_ERR("unsupported %d\n", shader); 426 return; 427 } 428 429 if (buffer != &rbuffer->r.b.b.b) 430 pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL); 431} 432 433static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) 434{ 435 struct r600_pipe_state *rstate; 436 struct r600_resource *rbuffer; 437 struct pipe_vertex_buffer *vertex_buffer; 438 unsigned i, count, offset; 439 440 if (rctx->vertex_elements->vbuffer_need_offset) { 441 /* one resource per vertex elements */ 442 count = rctx->vertex_elements->count; 443 } else { 444 /* bind vertex buffer once */ 445 count = rctx->vbuf_mgr->nr_real_vertex_buffers; 446 } 447 448 for (i = 0 ; i < count; i++) { 449 rstate = &rctx->fs_resource[i]; 450 rstate->id = R600_PIPE_STATE_RESOURCE; 451 rstate->nregs = 0; 452 453 if (rctx->vertex_elements->vbuffer_need_offset) { 454 /* one resource per vertex elements */ 455 unsigned vbuffer_index; 456 vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index; 457 vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[vbuffer_index]; 458 rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[vbuffer_index]; 459 offset = rctx->vertex_elements->vbuffer_offset[i]; 460 } else { 461 /* bind vertex buffer once */ 462 vertex_buffer = &rctx->vbuf_mgr->vertex_buffer[i]; 463 rbuffer = (struct r600_resource*)rctx->vbuf_mgr->real_vertex_buffer[i]; 464 offset = 0; 465 } 466 if (vertex_buffer == NULL || rbuffer == NULL) 467 continue; 468 offset += vertex_buffer->buffer_offset + r600_bo_offset(rbuffer->bo); 469 470 if (rctx->family >= CHIP_CEDAR) { 471 evergreen_pipe_set_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); 472 evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i); 473 } else { 474 r600_pipe_set_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); 475 r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i); 476 } 477 } 478} 479 480void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) 481{ 482 struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; 483 struct r600_resource *rbuffer; 484 u32 vgt_dma_index_type, vgt_dma_swap_mode, vgt_draw_initiator, mask; 485 struct r600_draw rdraw; 486 struct r600_pipe_state vgt; 487 struct r600_drawl draw = {}; 488 unsigned prim; 489 490 r600_flush_depth_textures(rctx); 491 u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info, NULL, NULL); 492 r600_vertex_buffer_update(rctx); 493 494 draw.info = *info; 495 draw.ctx = ctx; 496 if (info->indexed && rctx->index_buffer.buffer) { 497 draw.info.start += rctx->index_buffer.offset / rctx->index_buffer.index_size; 498 pipe_resource_reference(&draw.index_buffer, rctx->index_buffer.buffer); 499 500 r600_translate_index_buffer(rctx, &draw.index_buffer, 501 &rctx->index_buffer.index_size, 502 &draw.info.start, 503 info->count); 504 505 draw.index_size = rctx->index_buffer.index_size; 506 draw.index_buffer_offset = draw.info.start * draw.index_size; 507 draw.info.start = 0; 508 509 if (u_vbuf_resource(draw.index_buffer)->user_ptr) { 510 r600_upload_index_buffer(rctx, &draw); 511 } 512 } else { 513 draw.info.index_bias = info->start; 514 } 515 516 vgt_dma_swap_mode = 0; 517 switch (draw.index_size) { 518 case 2: 519 vgt_draw_initiator = 0; 520 vgt_dma_index_type = 0; 521 if (R600_BIG_ENDIAN) { 522 vgt_dma_swap_mode = ENDIAN_8IN16; 523 } 524 break; 525 case 4: 526 vgt_draw_initiator = 0; 527 vgt_dma_index_type = 1; 528 if (R600_BIG_ENDIAN) { 529 vgt_dma_swap_mode = ENDIAN_8IN32; 530 } 531 break; 532 case 0: 533 vgt_draw_initiator = 2; 534 vgt_dma_index_type = 0; 535 break; 536 default: 537 R600_ERR("unsupported index size %d\n", draw.index_size); 538 return; 539 } 540 if (r600_conv_pipe_prim(draw.info.mode, &prim)) 541 return; 542 if (unlikely(rctx->ps_shader == NULL)) { 543 R600_ERR("missing vertex shader\n"); 544 return; 545 } 546 if (unlikely(rctx->vs_shader == NULL)) { 547 R600_ERR("missing vertex shader\n"); 548 return; 549 } 550 /* there should be enough input */ 551 if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) { 552 R600_ERR("%d resources provided, expecting %d\n", 553 rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource); 554 return; 555 } 556 557 r600_spi_update(rctx, draw.info.mode); 558 559 mask = 0; 560 for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) { 561 mask |= (0xF << (i * 4)); 562 } 563 564 vgt.id = R600_PIPE_STATE_VGT; 565 vgt.nregs = 0; 566 r600_pipe_state_add_reg(&vgt, R_008958_VGT_PRIMITIVE_TYPE, prim, 0xFFFFFFFF, NULL); 567 r600_pipe_state_add_reg(&vgt, R_028408_VGT_INDX_OFFSET, draw.info.index_bias, 0xFFFFFFFF, NULL); 568 r600_pipe_state_add_reg(&vgt, R_028400_VGT_MAX_VTX_INDX, draw.info.max_index, 0xFFFFFFFF, NULL); 569 r600_pipe_state_add_reg(&vgt, R_028404_VGT_MIN_VTX_INDX, draw.info.min_index, 0xFFFFFFFF, NULL); 570 r600_pipe_state_add_reg(&vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL); 571 r600_pipe_state_add_reg(&vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL); 572 r600_pipe_state_add_reg(&vgt, R_03CFF4_SQ_VTX_START_INST_LOC, draw.info.start_instance, 0xFFFFFFFF, NULL); 573 r600_context_pipe_state_set(&rctx->ctx, &vgt); 574 575 rdraw.vgt_num_indices = draw.info.count; 576 rdraw.vgt_num_instances = draw.info.instance_count; 577 rdraw.vgt_index_type = vgt_dma_index_type | (vgt_dma_swap_mode << 2); 578 rdraw.vgt_draw_initiator = vgt_draw_initiator; 579 rdraw.indices = NULL; 580 if (draw.index_buffer) { 581 rbuffer = (struct r600_resource*)draw.index_buffer; 582 rdraw.indices = rbuffer->bo; 583 rdraw.indices_bo_offset = draw.index_buffer_offset; 584 } 585 586 if (rctx->family >= CHIP_CEDAR) { 587 evergreen_context_draw(&rctx->ctx, &rdraw); 588 } else { 589 r600_context_draw(&rctx->ctx, &rdraw); 590 } 591 592 if (rctx->framebuffer.zsbuf) 593 { 594 struct pipe_resource *tex = rctx->framebuffer.zsbuf->texture; 595 ((struct r600_resource_texture *)tex)->dirty_db = TRUE; 596 } 597 598 pipe_resource_reference(&draw.index_buffer, NULL); 599 600 u_vbuf_mgr_draw_end(rctx->vbuf_mgr); 601} 602