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_draw_quad.h" 31#include "util/u_upload_mgr.h" 32#include "tgsi/tgsi_parse.h" 33#include <byteswap.h> 34 35#define R600_PRIM_RECTANGLE_LIST PIPE_PRIM_MAX 36 37static void r600_emit_command_buffer(struct r600_context *rctx, struct r600_atom *atom) 38{ 39 struct radeon_winsys_cs *cs = rctx->cs; 40 struct r600_command_buffer *cb = (struct r600_command_buffer*)atom; 41 42 assert(cs->cdw + cb->atom.num_dw <= RADEON_MAX_CMDBUF_DWORDS); 43 memcpy(cs->buf + cs->cdw, cb->buf, 4 * cb->atom.num_dw); 44 cs->cdw += cb->atom.num_dw; 45} 46 47void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw, enum r600_atom_flags flags) 48{ 49 cb->atom.emit = r600_emit_command_buffer; 50 cb->atom.num_dw = 0; 51 cb->atom.flags = flags; 52 cb->buf = CALLOC(1, 4 * num_dw); 53 cb->max_num_dw = num_dw; 54} 55 56void r600_release_command_buffer(struct r600_command_buffer *cb) 57{ 58 FREE(cb->buf); 59} 60 61static void r600_emit_surface_sync(struct r600_context *rctx, struct r600_atom *atom) 62{ 63 struct radeon_winsys_cs *cs = rctx->cs; 64 struct r600_surface_sync_cmd *a = (struct r600_surface_sync_cmd*)atom; 65 66 cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0); 67 cs->buf[cs->cdw++] = a->flush_flags; /* CP_COHER_CNTL */ 68 cs->buf[cs->cdw++] = 0xffffffff; /* CP_COHER_SIZE */ 69 cs->buf[cs->cdw++] = 0; /* CP_COHER_BASE */ 70 cs->buf[cs->cdw++] = 0x0000000A; /* POLL_INTERVAL */ 71 72 a->flush_flags = 0; 73} 74 75static void r600_emit_r6xx_flush_and_inv(struct r600_context *rctx, struct r600_atom *atom) 76{ 77 struct radeon_winsys_cs *cs = rctx->cs; 78 cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0); 79 cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0); 80} 81 82void r600_init_atom(struct r600_atom *atom, 83 void (*emit)(struct r600_context *ctx, struct r600_atom *state), 84 unsigned num_dw, enum r600_atom_flags flags) 85{ 86 atom->emit = emit; 87 atom->num_dw = num_dw; 88 atom->flags = flags; 89} 90 91static void r600_emit_alphatest_state(struct r600_context *rctx, struct r600_atom *atom) 92{ 93 struct radeon_winsys_cs *cs = rctx->cs; 94 struct r600_alphatest_state *a = (struct r600_alphatest_state*)atom; 95 unsigned alpha_ref = a->sx_alpha_ref; 96 97 if (rctx->chip_class >= EVERGREEN && a->cb0_export_16bpc) { 98 alpha_ref &= ~0x1FFF; 99 } 100 101 r600_write_context_reg(cs, R_028410_SX_ALPHA_TEST_CONTROL, 102 a->sx_alpha_test_control | 103 S_028410_ALPHA_TEST_BYPASS(a->bypass)); 104 r600_write_context_reg(cs, R_028438_SX_ALPHA_REF, alpha_ref); 105} 106 107void r600_init_common_atoms(struct r600_context *rctx) 108{ 109 r600_init_atom(&rctx->surface_sync_cmd.atom, r600_emit_surface_sync, 5, EMIT_EARLY); 110 r600_init_atom(&rctx->r6xx_flush_and_inv_cmd, r600_emit_r6xx_flush_and_inv, 2, EMIT_EARLY); 111 r600_init_atom(&rctx->alphatest_state.atom, r600_emit_alphatest_state, 6, 0); 112 r600_atom_dirty(rctx, &rctx->alphatest_state.atom); 113} 114 115unsigned r600_get_cb_flush_flags(struct r600_context *rctx) 116{ 117 unsigned flags = 0; 118 119 if (rctx->framebuffer.nr_cbufs) { 120 flags |= S_0085F0_CB_ACTION_ENA(1) | 121 (((1 << rctx->framebuffer.nr_cbufs) - 1) << S_0085F0_CB0_DEST_BASE_ENA_SHIFT); 122 } 123 124 /* Workaround for broken flushing on some R6xx chipsets. */ 125 if (rctx->family == CHIP_RV670 || 126 rctx->family == CHIP_RS780 || 127 rctx->family == CHIP_RS880) { 128 flags |= S_0085F0_CB1_DEST_BASE_ENA(1) | 129 S_0085F0_DEST_BASE_0_ENA(1); 130 } 131 return flags; 132} 133 134void r600_texture_barrier(struct pipe_context *ctx) 135{ 136 struct r600_context *rctx = (struct r600_context *)ctx; 137 138 rctx->surface_sync_cmd.flush_flags |= S_0085F0_TC_ACTION_ENA(1) | r600_get_cb_flush_flags(rctx); 139 r600_atom_dirty(rctx, &rctx->surface_sync_cmd.atom); 140} 141 142static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim) 143{ 144 static const int prim_conv[] = { 145 V_008958_DI_PT_POINTLIST, 146 V_008958_DI_PT_LINELIST, 147 V_008958_DI_PT_LINELOOP, 148 V_008958_DI_PT_LINESTRIP, 149 V_008958_DI_PT_TRILIST, 150 V_008958_DI_PT_TRISTRIP, 151 V_008958_DI_PT_TRIFAN, 152 V_008958_DI_PT_QUADLIST, 153 V_008958_DI_PT_QUADSTRIP, 154 V_008958_DI_PT_POLYGON, 155 -1, 156 -1, 157 -1, 158 -1, 159 V_008958_DI_PT_RECTLIST 160 }; 161 162 *prim = prim_conv[pprim]; 163 if (*prim == -1) { 164 fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); 165 return false; 166 } 167 return true; 168} 169 170/* common state between evergreen and r600 */ 171 172static void r600_bind_blend_state_internal(struct r600_context *rctx, 173 struct r600_pipe_blend *blend) 174{ 175 struct r600_pipe_state *rstate; 176 bool update_cb = false; 177 178 rstate = &blend->rstate; 179 rctx->states[rstate->id] = rstate; 180 r600_context_pipe_state_set(rctx, rstate); 181 182 if (rctx->cb_misc_state.blend_colormask != blend->cb_target_mask) { 183 rctx->cb_misc_state.blend_colormask = blend->cb_target_mask; 184 update_cb = true; 185 } 186 if (rctx->chip_class <= R700 && 187 rctx->cb_misc_state.cb_color_control != blend->cb_color_control) { 188 rctx->cb_misc_state.cb_color_control = blend->cb_color_control; 189 update_cb = true; 190 } 191 if (rctx->cb_misc_state.dual_src_blend != blend->dual_src_blend) { 192 rctx->cb_misc_state.dual_src_blend = blend->dual_src_blend; 193 update_cb = true; 194 } 195 if (update_cb) { 196 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 197 } 198} 199 200void r600_bind_blend_state(struct pipe_context *ctx, void *state) 201{ 202 struct r600_context *rctx = (struct r600_context *)ctx; 203 struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state; 204 205 if (blend == NULL) 206 return; 207 208 rctx->blend = blend; 209 rctx->alpha_to_one = blend->alpha_to_one; 210 rctx->dual_src_blend = blend->dual_src_blend; 211 212 if (!rctx->blend_override) 213 r600_bind_blend_state_internal(rctx, blend); 214} 215 216void r600_set_blend_color(struct pipe_context *ctx, 217 const struct pipe_blend_color *state) 218{ 219 struct r600_context *rctx = (struct r600_context *)ctx; 220 struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); 221 222 if (rstate == NULL) 223 return; 224 225 rstate->id = R600_PIPE_STATE_BLEND_COLOR; 226 r600_pipe_state_add_reg(rstate, R_028414_CB_BLEND_RED, fui(state->color[0])); 227 r600_pipe_state_add_reg(rstate, R_028418_CB_BLEND_GREEN, fui(state->color[1])); 228 r600_pipe_state_add_reg(rstate, R_02841C_CB_BLEND_BLUE, fui(state->color[2])); 229 r600_pipe_state_add_reg(rstate, R_028420_CB_BLEND_ALPHA, fui(state->color[3])); 230 231 free(rctx->states[R600_PIPE_STATE_BLEND_COLOR]); 232 rctx->states[R600_PIPE_STATE_BLEND_COLOR] = rstate; 233 r600_context_pipe_state_set(rctx, rstate); 234} 235 236static void r600_set_stencil_ref(struct pipe_context *ctx, 237 const struct r600_stencil_ref *state) 238{ 239 struct r600_context *rctx = (struct r600_context *)ctx; 240 struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); 241 242 if (rstate == NULL) 243 return; 244 245 rstate->id = R600_PIPE_STATE_STENCIL_REF; 246 r600_pipe_state_add_reg(rstate, 247 R_028430_DB_STENCILREFMASK, 248 S_028430_STENCILREF(state->ref_value[0]) | 249 S_028430_STENCILMASK(state->valuemask[0]) | 250 S_028430_STENCILWRITEMASK(state->writemask[0])); 251 r600_pipe_state_add_reg(rstate, 252 R_028434_DB_STENCILREFMASK_BF, 253 S_028434_STENCILREF_BF(state->ref_value[1]) | 254 S_028434_STENCILMASK_BF(state->valuemask[1]) | 255 S_028434_STENCILWRITEMASK_BF(state->writemask[1])); 256 257 free(rctx->states[R600_PIPE_STATE_STENCIL_REF]); 258 rctx->states[R600_PIPE_STATE_STENCIL_REF] = rstate; 259 r600_context_pipe_state_set(rctx, rstate); 260} 261 262void r600_set_pipe_stencil_ref(struct pipe_context *ctx, 263 const struct pipe_stencil_ref *state) 264{ 265 struct r600_context *rctx = (struct r600_context *)ctx; 266 struct r600_pipe_dsa *dsa = (struct r600_pipe_dsa*)rctx->states[R600_PIPE_STATE_DSA]; 267 struct r600_stencil_ref ref; 268 269 rctx->stencil_ref = *state; 270 271 if (!dsa) 272 return; 273 274 ref.ref_value[0] = state->ref_value[0]; 275 ref.ref_value[1] = state->ref_value[1]; 276 ref.valuemask[0] = dsa->valuemask[0]; 277 ref.valuemask[1] = dsa->valuemask[1]; 278 ref.writemask[0] = dsa->writemask[0]; 279 ref.writemask[1] = dsa->writemask[1]; 280 281 r600_set_stencil_ref(ctx, &ref); 282} 283 284void r600_bind_dsa_state(struct pipe_context *ctx, void *state) 285{ 286 struct r600_context *rctx = (struct r600_context *)ctx; 287 struct r600_pipe_dsa *dsa = state; 288 struct r600_pipe_state *rstate; 289 struct r600_stencil_ref ref; 290 291 if (state == NULL) 292 return; 293 rstate = &dsa->rstate; 294 rctx->states[rstate->id] = rstate; 295 r600_context_pipe_state_set(rctx, rstate); 296 297 ref.ref_value[0] = rctx->stencil_ref.ref_value[0]; 298 ref.ref_value[1] = rctx->stencil_ref.ref_value[1]; 299 ref.valuemask[0] = dsa->valuemask[0]; 300 ref.valuemask[1] = dsa->valuemask[1]; 301 ref.writemask[0] = dsa->writemask[0]; 302 ref.writemask[1] = dsa->writemask[1]; 303 304 r600_set_stencil_ref(ctx, &ref); 305 306 /* Update alphatest state. */ 307 if (rctx->alphatest_state.sx_alpha_test_control != dsa->sx_alpha_test_control || 308 rctx->alphatest_state.sx_alpha_ref != dsa->alpha_ref) { 309 rctx->alphatest_state.sx_alpha_test_control = dsa->sx_alpha_test_control; 310 rctx->alphatest_state.sx_alpha_ref = dsa->alpha_ref; 311 r600_atom_dirty(rctx, &rctx->alphatest_state.atom); 312 } 313} 314 315void r600_set_max_scissor(struct r600_context *rctx) 316{ 317 /* Set a scissor state such that it doesn't do anything. */ 318 struct pipe_scissor_state scissor; 319 scissor.minx = 0; 320 scissor.miny = 0; 321 scissor.maxx = 8192; 322 scissor.maxy = 8192; 323 324 r600_set_scissor_state(rctx, &scissor); 325} 326 327void r600_bind_rs_state(struct pipe_context *ctx, void *state) 328{ 329 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 330 struct r600_context *rctx = (struct r600_context *)ctx; 331 332 if (state == NULL) 333 return; 334 335 rctx->sprite_coord_enable = rs->sprite_coord_enable; 336 rctx->two_side = rs->two_side; 337 rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple; 338 rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl; 339 rctx->multisample_enable = rs->multisample_enable; 340 341 rctx->rasterizer = rs; 342 343 rctx->states[rs->rstate.id] = &rs->rstate; 344 r600_context_pipe_state_set(rctx, &rs->rstate); 345 346 if (rctx->chip_class >= EVERGREEN) { 347 evergreen_polygon_offset_update(rctx); 348 } else { 349 r600_polygon_offset_update(rctx); 350 } 351 352 /* Workaround for a missing scissor enable on r600. */ 353 if (rctx->chip_class == R600) { 354 if (rs->scissor_enable != rctx->scissor_enable) { 355 rctx->scissor_enable = rs->scissor_enable; 356 357 if (rs->scissor_enable) { 358 r600_set_scissor_state(rctx, &rctx->scissor_state); 359 } else { 360 r600_set_max_scissor(rctx); 361 } 362 } 363 } 364} 365 366void r600_delete_rs_state(struct pipe_context *ctx, void *state) 367{ 368 struct r600_context *rctx = (struct r600_context *)ctx; 369 struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; 370 371 if (rctx->rasterizer == rs) { 372 rctx->rasterizer = NULL; 373 } 374 if (rctx->states[rs->rstate.id] == &rs->rstate) { 375 rctx->states[rs->rstate.id] = NULL; 376 } 377 free(rs); 378} 379 380void r600_sampler_view_destroy(struct pipe_context *ctx, 381 struct pipe_sampler_view *state) 382{ 383 struct r600_pipe_sampler_view *resource = (struct r600_pipe_sampler_view *)state; 384 385 pipe_resource_reference(&state->texture, NULL); 386 FREE(resource); 387} 388 389static void r600_bind_samplers(struct pipe_context *pipe, 390 unsigned shader, 391 unsigned start, 392 unsigned count, void **states) 393{ 394 struct r600_context *rctx = (struct r600_context *)pipe; 395 struct r600_textures_info *dst; 396 int seamless_cube_map = -1; 397 unsigned i; 398 399 assert(start == 0); /* XXX fix below */ 400 401 switch (shader) { 402 case PIPE_SHADER_VERTEX: 403 dst = &rctx->vs_samplers; 404 break; 405 case PIPE_SHADER_FRAGMENT: 406 dst = &rctx->ps_samplers; 407 break; 408 default: 409 debug_error("bad shader in r600_bind_samplers()"); 410 return; 411 } 412 413 memcpy(dst->samplers, states, sizeof(void*) * count); 414 dst->n_samplers = count; 415 dst->atom_sampler.num_dw = 0; 416 417 for (i = 0; i < count; i++) { 418 struct r600_pipe_sampler_state *sampler = states[i]; 419 420 if (sampler == NULL) { 421 continue; 422 } 423 if (sampler->border_color_use) { 424 dst->atom_sampler.num_dw += 11; 425 rctx->flags |= R600_PARTIAL_FLUSH; 426 } else { 427 dst->atom_sampler.num_dw += 5; 428 } 429 seamless_cube_map = sampler->seamless_cube_map; 430 } 431 if (rctx->chip_class <= R700 && seamless_cube_map != -1 && seamless_cube_map != rctx->seamless_cube_map.enabled) { 432 /* change in TA_CNTL_AUX need a pipeline flush */ 433 rctx->flags |= R600_PARTIAL_FLUSH; 434 rctx->seamless_cube_map.enabled = seamless_cube_map; 435 r600_atom_dirty(rctx, &rctx->seamless_cube_map.atom); 436 } 437 if (dst->atom_sampler.num_dw) { 438 r600_atom_dirty(rctx, &dst->atom_sampler); 439 } 440} 441 442void r600_bind_vs_samplers(struct pipe_context *ctx, unsigned count, void **states) 443{ 444 r600_bind_samplers(ctx, PIPE_SHADER_VERTEX, 0, count, states); 445} 446 447void r600_bind_ps_samplers(struct pipe_context *ctx, unsigned count, void **states) 448{ 449 r600_bind_samplers(ctx, PIPE_SHADER_FRAGMENT, 0, count, states); 450} 451 452void r600_delete_sampler(struct pipe_context *ctx, void *state) 453{ 454 free(state); 455} 456 457void r600_delete_state(struct pipe_context *ctx, void *state) 458{ 459 struct r600_context *rctx = (struct r600_context *)ctx; 460 struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; 461 462 if (rctx->states[rstate->id] == rstate) { 463 rctx->states[rstate->id] = NULL; 464 } 465 for (int i = 0; i < rstate->nregs; i++) { 466 pipe_resource_reference((struct pipe_resource**)&rstate->regs[i].bo, NULL); 467 } 468 free(rstate); 469} 470 471void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) 472{ 473 struct r600_context *rctx = (struct r600_context *)ctx; 474 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 475 476 rctx->vertex_elements = v; 477 if (v) { 478 r600_inval_shader_cache(rctx); 479 480 rctx->states[v->rstate.id] = &v->rstate; 481 r600_context_pipe_state_set(rctx, &v->rstate); 482 } 483} 484 485void r600_delete_vertex_element(struct pipe_context *ctx, void *state) 486{ 487 struct r600_context *rctx = (struct r600_context *)ctx; 488 struct r600_vertex_element *v = (struct r600_vertex_element*)state; 489 490 if (rctx->states[v->rstate.id] == &v->rstate) { 491 rctx->states[v->rstate.id] = NULL; 492 } 493 if (rctx->vertex_elements == state) 494 rctx->vertex_elements = NULL; 495 496 pipe_resource_reference((struct pipe_resource**)&v->fetch_shader, NULL); 497 FREE(state); 498} 499 500void r600_set_index_buffer(struct pipe_context *ctx, 501 const struct pipe_index_buffer *ib) 502{ 503 struct r600_context *rctx = (struct r600_context *)ctx; 504 505 if (ib) { 506 pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); 507 memcpy(&rctx->index_buffer, ib, sizeof(*ib)); 508 r600_context_add_resource_size(ctx, ib->buffer); 509 } else { 510 pipe_resource_reference(&rctx->index_buffer.buffer, NULL); 511 } 512} 513 514void r600_vertex_buffers_dirty(struct r600_context *rctx) 515{ 516 if (rctx->vertex_buffer_state.dirty_mask) { 517 r600_inval_vertex_cache(rctx); 518 rctx->vertex_buffer_state.atom.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 11) * 519 util_bitcount(rctx->vertex_buffer_state.dirty_mask); 520 r600_atom_dirty(rctx, &rctx->vertex_buffer_state.atom); 521 } 522} 523 524void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 525 const struct pipe_vertex_buffer *input) 526{ 527 struct r600_context *rctx = (struct r600_context *)ctx; 528 struct r600_vertexbuf_state *state = &rctx->vertex_buffer_state; 529 struct pipe_vertex_buffer *vb = state->vb; 530 unsigned i; 531 /* This sets 1-bit for buffers with index >= count. */ 532 uint32_t disable_mask = ~((1ull << count) - 1); 533 /* These are the new buffers set by this function. */ 534 uint32_t new_buffer_mask = 0; 535 536 /* Set buffers with index >= count to NULL. */ 537 uint32_t remaining_buffers_mask = 538 rctx->vertex_buffer_state.enabled_mask & disable_mask; 539 540 while (remaining_buffers_mask) { 541 i = u_bit_scan(&remaining_buffers_mask); 542 pipe_resource_reference(&vb[i].buffer, NULL); 543 } 544 545 /* Set vertex buffers. */ 546 for (i = 0; i < count; i++) { 547 if (memcmp(&input[i], &vb[i], sizeof(struct pipe_vertex_buffer))) { 548 if (input[i].buffer) { 549 vb[i].stride = input[i].stride; 550 vb[i].buffer_offset = input[i].buffer_offset; 551 pipe_resource_reference(&vb[i].buffer, input[i].buffer); 552 new_buffer_mask |= 1 << i; 553 r600_context_add_resource_size(ctx, input[i].buffer); 554 } else { 555 pipe_resource_reference(&vb[i].buffer, NULL); 556 disable_mask |= 1 << i; 557 } 558 } 559 } 560 561 rctx->vertex_buffer_state.enabled_mask &= ~disable_mask; 562 rctx->vertex_buffer_state.dirty_mask &= rctx->vertex_buffer_state.enabled_mask; 563 rctx->vertex_buffer_state.enabled_mask |= new_buffer_mask; 564 rctx->vertex_buffer_state.dirty_mask |= new_buffer_mask; 565 566 r600_vertex_buffers_dirty(rctx); 567} 568 569void r600_sampler_views_dirty(struct r600_context *rctx, 570 struct r600_samplerview_state *state) 571{ 572 if (state->dirty_mask) { 573 r600_inval_texture_cache(rctx); 574 state->atom.num_dw = (rctx->chip_class >= EVERGREEN ? 14 : 13) * 575 util_bitcount(state->dirty_mask); 576 r600_atom_dirty(rctx, &state->atom); 577 } 578} 579 580void r600_set_sampler_views(struct pipe_context *pipe, 581 unsigned shader, 582 unsigned start, 583 unsigned count, 584 struct pipe_sampler_view **views) 585{ 586 struct r600_context *rctx = (struct r600_context *) pipe; 587 struct r600_textures_info *dst; 588 struct r600_pipe_sampler_view **rviews = (struct r600_pipe_sampler_view **)views; 589 unsigned i; 590 /* This sets 1-bit for textures with index >= count. */ 591 uint32_t disable_mask = ~((1ull << count) - 1); 592 /* These are the new textures set by this function. */ 593 uint32_t new_mask = 0; 594 595 /* Set textures with index >= count to NULL. */ 596 uint32_t remaining_mask; 597 598 assert(start == 0); /* XXX fix below */ 599 600 switch (shader) { 601 case PIPE_SHADER_VERTEX: 602 dst = &rctx->vs_samplers; 603 break; 604 case PIPE_SHADER_FRAGMENT: 605 dst = &rctx->ps_samplers; 606 break; 607 default: 608 debug_error("bad shader in r600_set_sampler_views()"); 609 return; 610 } 611 612 remaining_mask = dst->views.enabled_mask & disable_mask; 613 614 while (remaining_mask) { 615 i = u_bit_scan(&remaining_mask); 616 assert(dst->views.views[i]); 617 618 pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], NULL); 619 } 620 621 for (i = 0; i < count; i++) { 622 if (rviews[i] == dst->views.views[i]) { 623 continue; 624 } 625 626 if (rviews[i]) { 627 struct r600_texture *rtex = 628 (struct r600_texture*)rviews[i]->base.texture; 629 630 if (rtex->is_depth && !rtex->is_flushing_texture) { 631 dst->views.compressed_depthtex_mask |= 1 << i; 632 } else { 633 dst->views.compressed_depthtex_mask &= ~(1 << i); 634 } 635 636 /* Track compressed colorbuffers for Evergreen (Cayman doesn't need this). */ 637 if (rctx->chip_class != CAYMAN && rtex->cmask_size && rtex->fmask_size) { 638 dst->views.compressed_colortex_mask |= 1 << i; 639 } else { 640 dst->views.compressed_colortex_mask &= ~(1 << i); 641 } 642 643 /* Changing from array to non-arrays textures and vice 644 * versa requires updating TEX_ARRAY_OVERRIDE on R6xx-R7xx. */ 645 if (rctx->chip_class <= R700 && 646 (rviews[i]->base.texture->target == PIPE_TEXTURE_1D_ARRAY || 647 rviews[i]->base.texture->target == PIPE_TEXTURE_2D_ARRAY) != dst->is_array_sampler[i]) { 648 r600_atom_dirty(rctx, &dst->atom_sampler); 649 } 650 651 pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], views[i]); 652 new_mask |= 1 << i; 653 r600_context_add_resource_size(pipe, views[i]->texture); 654 } else { 655 pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], NULL); 656 disable_mask |= 1 << i; 657 } 658 } 659 660 dst->views.enabled_mask &= ~disable_mask; 661 dst->views.dirty_mask &= dst->views.enabled_mask; 662 dst->views.enabled_mask |= new_mask; 663 dst->views.dirty_mask |= new_mask; 664 dst->views.compressed_depthtex_mask &= dst->views.enabled_mask; 665 dst->views.compressed_colortex_mask &= dst->views.enabled_mask; 666 667 r600_sampler_views_dirty(rctx, &dst->views); 668} 669 670void *r600_create_vertex_elements(struct pipe_context *ctx, 671 unsigned count, 672 const struct pipe_vertex_element *elements) 673{ 674 struct r600_context *rctx = (struct r600_context *)ctx; 675 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 676 677 assert(count < 32); 678 if (!v) 679 return NULL; 680 681 v->count = count; 682 memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count); 683 684 if (r600_vertex_elements_build_fetch_shader(rctx, v)) { 685 FREE(v); 686 return NULL; 687 } 688 689 return v; 690} 691 692/* Compute the key for the hw shader variant */ 693static INLINE unsigned r600_shader_selector_key(struct pipe_context * ctx, 694 struct r600_pipe_shader_selector * sel) 695{ 696 struct r600_context *rctx = (struct r600_context *)ctx; 697 unsigned key; 698 699 if (sel->type == PIPE_SHADER_FRAGMENT) { 700 key = rctx->two_side | 701 ((rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer) << 1) | 702 (MIN2(sel->nr_ps_max_color_exports, rctx->nr_cbufs + rctx->dual_src_blend) << 2); 703 } else 704 key = 0; 705 706 return key; 707} 708 709/* Select the hw shader variant depending on the current state. 710 * (*dirty) is set to 1 if current variant was changed */ 711static int r600_shader_select(struct pipe_context *ctx, 712 struct r600_pipe_shader_selector* sel, 713 unsigned *dirty) 714{ 715 unsigned key; 716 struct r600_context *rctx = (struct r600_context *)ctx; 717 struct r600_pipe_shader * shader = NULL; 718 int r; 719 720 key = r600_shader_selector_key(ctx, sel); 721 722 /* Check if we don't need to change anything. 723 * This path is also used for most shaders that don't need multiple 724 * variants, it will cost just a computation of the key and this 725 * test. */ 726 if (likely(sel->current && sel->current->key == key)) { 727 return 0; 728 } 729 730 /* lookup if we have other variants in the list */ 731 if (sel->num_shaders > 1) { 732 struct r600_pipe_shader *p = sel->current, *c = p->next_variant; 733 734 while (c && c->key != key) { 735 p = c; 736 c = c->next_variant; 737 } 738 739 if (c) { 740 p->next_variant = c->next_variant; 741 shader = c; 742 } 743 } 744 745 if (unlikely(!shader)) { 746 shader = CALLOC(1, sizeof(struct r600_pipe_shader)); 747 shader->selector = sel; 748 749 r = r600_pipe_shader_create(ctx, shader); 750 if (unlikely(r)) { 751 R600_ERR("Failed to build shader variant (type=%u, key=%u) %d\n", 752 sel->type, key, r); 753 sel->current = NULL; 754 return r; 755 } 756 757 /* We don't know the value of nr_ps_max_color_exports until we built 758 * at least one variant, so we may need to recompute the key after 759 * building first variant. */ 760 if (sel->type == PIPE_SHADER_FRAGMENT && 761 sel->num_shaders == 0) { 762 sel->nr_ps_max_color_exports = shader->shader.nr_ps_max_color_exports; 763 key = r600_shader_selector_key(ctx, sel); 764 } 765 766 shader->key = key; 767 sel->num_shaders++; 768 } 769 770 if (dirty) 771 *dirty = 1; 772 773 shader->next_variant = sel->current; 774 sel->current = shader; 775 776 if (rctx->chip_class < EVERGREEN && rctx->ps_shader && rctx->vs_shader) { 777 r600_adjust_gprs(rctx); 778 } 779 780 if (rctx->ps_shader && 781 rctx->cb_misc_state.nr_ps_color_outputs != rctx->ps_shader->current->nr_ps_color_outputs) { 782 rctx->cb_misc_state.nr_ps_color_outputs = rctx->ps_shader->current->nr_ps_color_outputs; 783 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 784 } 785 return 0; 786} 787 788static void *r600_create_shader_state(struct pipe_context *ctx, 789 const struct pipe_shader_state *state, 790 unsigned pipe_shader_type) 791{ 792 struct r600_pipe_shader_selector *sel = CALLOC_STRUCT(r600_pipe_shader_selector); 793 int r; 794 795 sel->type = pipe_shader_type; 796 sel->tokens = tgsi_dup_tokens(state->tokens); 797 sel->so = state->stream_output; 798 799 r = r600_shader_select(ctx, sel, NULL); 800 if (r) 801 return NULL; 802 803 return sel; 804} 805 806void *r600_create_shader_state_ps(struct pipe_context *ctx, 807 const struct pipe_shader_state *state) 808{ 809 return r600_create_shader_state(ctx, state, PIPE_SHADER_FRAGMENT); 810} 811 812void *r600_create_shader_state_vs(struct pipe_context *ctx, 813 const struct pipe_shader_state *state) 814{ 815 return r600_create_shader_state(ctx, state, PIPE_SHADER_VERTEX); 816} 817 818void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 819{ 820 struct r600_context *rctx = (struct r600_context *)ctx; 821 822 if (!state) 823 state = rctx->dummy_pixel_shader; 824 825 rctx->ps_shader = (struct r600_pipe_shader_selector *)state; 826 r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate); 827 828 r600_context_add_resource_size(ctx, (struct pipe_resource *)rctx->ps_shader->current->bo); 829 830 if (rctx->chip_class <= R700) { 831 bool multiwrite = rctx->ps_shader->current->shader.fs_write_all; 832 833 if (rctx->cb_misc_state.multiwrite != multiwrite) { 834 rctx->cb_misc_state.multiwrite = multiwrite; 835 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 836 } 837 838 if (rctx->vs_shader) 839 r600_adjust_gprs(rctx); 840 } 841 842 if (rctx->cb_misc_state.nr_ps_color_outputs != rctx->ps_shader->current->nr_ps_color_outputs) { 843 rctx->cb_misc_state.nr_ps_color_outputs = rctx->ps_shader->current->nr_ps_color_outputs; 844 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 845 } 846} 847 848void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 849{ 850 struct r600_context *rctx = (struct r600_context *)ctx; 851 852 rctx->vs_shader = (struct r600_pipe_shader_selector *)state; 853 if (state) { 854 r600_context_pipe_state_set(rctx, &rctx->vs_shader->current->rstate); 855 856 r600_context_add_resource_size(ctx, (struct pipe_resource *)rctx->vs_shader->current->bo); 857 858 if (rctx->chip_class < EVERGREEN && rctx->ps_shader) 859 r600_adjust_gprs(rctx); 860 } 861} 862 863static void r600_delete_shader_selector(struct pipe_context *ctx, 864 struct r600_pipe_shader_selector *sel) 865{ 866 struct r600_pipe_shader *p = sel->current, *c; 867 while (p) { 868 c = p->next_variant; 869 r600_pipe_shader_destroy(ctx, p); 870 free(p); 871 p = c; 872 } 873 874 free(sel->tokens); 875 free(sel); 876} 877 878 879void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 880{ 881 struct r600_context *rctx = (struct r600_context *)ctx; 882 struct r600_pipe_shader_selector *sel = (struct r600_pipe_shader_selector *)state; 883 884 if (rctx->ps_shader == sel) { 885 rctx->ps_shader = NULL; 886 } 887 888 r600_delete_shader_selector(ctx, sel); 889} 890 891void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 892{ 893 struct r600_context *rctx = (struct r600_context *)ctx; 894 struct r600_pipe_shader_selector *sel = (struct r600_pipe_shader_selector *)state; 895 896 if (rctx->vs_shader == sel) { 897 rctx->vs_shader = NULL; 898 } 899 900 r600_delete_shader_selector(ctx, sel); 901} 902 903void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state) 904{ 905 if (state->dirty_mask) { 906 r600_inval_shader_cache(rctx); 907 state->atom.num_dw = rctx->chip_class >= EVERGREEN ? util_bitcount(state->dirty_mask)*20 908 : util_bitcount(state->dirty_mask)*19; 909 r600_atom_dirty(rctx, &state->atom); 910 } 911} 912 913void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 914 struct pipe_constant_buffer *input) 915{ 916 struct r600_context *rctx = (struct r600_context *)ctx; 917 struct r600_constbuf_state *state; 918 struct pipe_constant_buffer *cb; 919 const uint8_t *ptr; 920 921 switch (shader) { 922 case PIPE_SHADER_VERTEX: 923 state = &rctx->vs_constbuf_state; 924 break; 925 case PIPE_SHADER_FRAGMENT: 926 state = &rctx->ps_constbuf_state; 927 break; 928 default: 929 return; 930 } 931 932 /* Note that the state tracker can unbind constant buffers by 933 * passing NULL here. 934 */ 935 if (unlikely(!input)) { 936 state->enabled_mask &= ~(1 << index); 937 state->dirty_mask &= ~(1 << index); 938 pipe_resource_reference(&state->cb[index].buffer, NULL); 939 return; 940 } 941 942 cb = &state->cb[index]; 943 cb->buffer_size = input->buffer_size; 944 945 ptr = input->user_buffer; 946 947 if (ptr) { 948 /* Upload the user buffer. */ 949 if (R600_BIG_ENDIAN) { 950 uint32_t *tmpPtr; 951 unsigned i, size = input->buffer_size; 952 953 if (!(tmpPtr = malloc(size))) { 954 R600_ERR("Failed to allocate BE swap buffer.\n"); 955 return; 956 } 957 958 for (i = 0; i < size / 4; ++i) { 959 tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]); 960 } 961 962 u_upload_data(rctx->uploader, 0, size, tmpPtr, &cb->buffer_offset, &cb->buffer); 963 free(tmpPtr); 964 } else { 965 u_upload_data(rctx->uploader, 0, input->buffer_size, ptr, &cb->buffer_offset, &cb->buffer); 966 } 967 /* account it in gtt */ 968 rctx->gtt += input->buffer_size; 969 } else { 970 /* Setup the hw buffer. */ 971 cb->buffer_offset = input->buffer_offset; 972 pipe_resource_reference(&cb->buffer, input->buffer); 973 r600_context_add_resource_size(ctx, input->buffer); 974 } 975 976 state->enabled_mask |= 1 << index; 977 state->dirty_mask |= 1 << index; 978 r600_constant_buffers_dirty(rctx, state); 979} 980 981struct pipe_stream_output_target * 982r600_create_so_target(struct pipe_context *ctx, 983 struct pipe_resource *buffer, 984 unsigned buffer_offset, 985 unsigned buffer_size) 986{ 987 struct r600_context *rctx = (struct r600_context *)ctx; 988 struct r600_so_target *t; 989 void *ptr; 990 991 t = CALLOC_STRUCT(r600_so_target); 992 if (!t) { 993 return NULL; 994 } 995 996 t->b.reference.count = 1; 997 t->b.context = ctx; 998 pipe_resource_reference(&t->b.buffer, buffer); 999 t->b.buffer_offset = buffer_offset; 1000 t->b.buffer_size = buffer_size; 1001 1002 t->filled_size = (struct r600_resource*) 1003 pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, 4); 1004 ptr = rctx->ws->buffer_map(t->filled_size->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); 1005 memset(ptr, 0, t->filled_size->buf->size); 1006 rctx->ws->buffer_unmap(t->filled_size->cs_buf); 1007 1008 return &t->b; 1009} 1010 1011void r600_so_target_destroy(struct pipe_context *ctx, 1012 struct pipe_stream_output_target *target) 1013{ 1014 struct r600_so_target *t = (struct r600_so_target*)target; 1015 pipe_resource_reference(&t->b.buffer, NULL); 1016 pipe_resource_reference((struct pipe_resource**)&t->filled_size, NULL); 1017 FREE(t); 1018} 1019 1020void r600_set_so_targets(struct pipe_context *ctx, 1021 unsigned num_targets, 1022 struct pipe_stream_output_target **targets, 1023 unsigned append_bitmask) 1024{ 1025 struct r600_context *rctx = (struct r600_context *)ctx; 1026 unsigned i; 1027 1028 /* Stop streamout. */ 1029 if (rctx->num_so_targets && !rctx->streamout_start) { 1030 r600_context_streamout_end(rctx); 1031 } 1032 1033 /* Set the new targets. */ 1034 for (i = 0; i < num_targets; i++) { 1035 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]); 1036 r600_context_add_resource_size(ctx, targets[i]->buffer); 1037 } 1038 for (; i < rctx->num_so_targets; i++) { 1039 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL); 1040 } 1041 1042 rctx->num_so_targets = num_targets; 1043 rctx->streamout_start = num_targets != 0; 1044 rctx->streamout_append_bitmask = append_bitmask; 1045} 1046 1047void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) 1048{ 1049 struct r600_context *rctx = (struct r600_context*)pipe; 1050 1051 if (rctx->sample_mask.sample_mask == (uint16_t)sample_mask) 1052 return; 1053 1054 rctx->sample_mask.sample_mask = sample_mask; 1055 r600_atom_dirty(rctx, &rctx->sample_mask.atom); 1056} 1057 1058static void r600_update_derived_state(struct r600_context *rctx) 1059{ 1060 struct pipe_context * ctx = (struct pipe_context*)rctx; 1061 unsigned ps_dirty = 0, blend_override; 1062 1063 if (!rctx->blitter->running) { 1064 /* Decompress textures if needed. */ 1065 if (rctx->vs_samplers.views.compressed_depthtex_mask) { 1066 r600_decompress_depth_textures(rctx, &rctx->vs_samplers.views); 1067 } 1068 if (rctx->ps_samplers.views.compressed_depthtex_mask) { 1069 r600_decompress_depth_textures(rctx, &rctx->ps_samplers.views); 1070 } 1071 if (rctx->vs_samplers.views.compressed_colortex_mask) { 1072 r600_decompress_color_textures(rctx, &rctx->vs_samplers.views); 1073 } 1074 if (rctx->ps_samplers.views.compressed_colortex_mask) { 1075 r600_decompress_color_textures(rctx, &rctx->ps_samplers.views); 1076 } 1077 } 1078 1079 r600_shader_select(ctx, rctx->ps_shader, &ps_dirty); 1080 1081 if (rctx->ps_shader && ((rctx->sprite_coord_enable && 1082 (rctx->ps_shader->current->sprite_coord_enable != rctx->sprite_coord_enable)) || 1083 (rctx->rasterizer && rctx->rasterizer->flatshade != rctx->ps_shader->current->flatshade))) { 1084 1085 if (rctx->chip_class >= EVERGREEN) 1086 evergreen_pipe_shader_ps(ctx, rctx->ps_shader->current); 1087 else 1088 r600_pipe_shader_ps(ctx, rctx->ps_shader->current); 1089 1090 ps_dirty = 1; 1091 } 1092 1093 if (ps_dirty) 1094 r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate); 1095 1096 blend_override = (rctx->dual_src_blend && 1097 rctx->ps_shader->current->nr_ps_color_outputs < 2); 1098 1099 if (blend_override != rctx->blend_override) { 1100 rctx->blend_override = blend_override; 1101 r600_bind_blend_state_internal(rctx, 1102 blend_override ? rctx->no_blend : rctx->blend); 1103 } 1104 1105 if (rctx->chip_class >= EVERGREEN) { 1106 evergreen_update_dual_export_state(rctx); 1107 } else { 1108 r600_update_dual_export_state(rctx); 1109 } 1110} 1111 1112static unsigned r600_conv_prim_to_gs_out(unsigned mode) 1113{ 1114 static const int prim_conv[] = { 1115 V_028A6C_OUTPRIM_TYPE_POINTLIST, 1116 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1117 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1118 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1119 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1120 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1121 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1122 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1123 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1124 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1125 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1126 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1127 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1128 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1129 V_028A6C_OUTPRIM_TYPE_TRISTRIP 1130 }; 1131 assert(mode < Elements(prim_conv)); 1132 1133 return prim_conv[mode]; 1134} 1135 1136void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) 1137{ 1138 struct r600_context *rctx = (struct r600_context *)ctx; 1139 struct pipe_draw_info info = *dinfo; 1140 struct pipe_index_buffer ib = {}; 1141 unsigned prim, ls_mask = 0; 1142 struct r600_block *dirty_block = NULL, *next_block = NULL; 1143 struct r600_atom *state = NULL, *next_state = NULL; 1144 struct radeon_winsys_cs *cs = rctx->cs; 1145 uint64_t va; 1146 uint8_t *ptr; 1147 1148 if ((!info.count && (info.indexed || !info.count_from_stream_output)) || 1149 !r600_conv_pipe_prim(info.mode, &prim)) { 1150 assert(0); 1151 return; 1152 } 1153 1154 if (!rctx->vs_shader) { 1155 assert(0); 1156 return; 1157 } 1158 1159 r600_update_derived_state(rctx); 1160 1161 /* partial flush triggered by border color change */ 1162 if (rctx->flags & R600_PARTIAL_FLUSH) { 1163 rctx->flags &= ~R600_PARTIAL_FLUSH; 1164 r600_write_value(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); 1165 r600_write_value(cs, EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4)); 1166 } 1167 1168 if (info.indexed) { 1169 /* Initialize the index buffer struct. */ 1170 pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer); 1171 ib.user_buffer = rctx->index_buffer.user_buffer; 1172 ib.index_size = rctx->index_buffer.index_size; 1173 ib.offset = rctx->index_buffer.offset + info.start * ib.index_size; 1174 1175 /* Translate or upload, if needed. */ 1176 r600_translate_index_buffer(rctx, &ib, info.count); 1177 1178 ptr = (uint8_t*)ib.user_buffer; 1179 if (!ib.buffer && ptr) { 1180 u_upload_data(rctx->uploader, 0, info.count * ib.index_size, 1181 ptr, &ib.offset, &ib.buffer); 1182 } 1183 } else { 1184 info.index_bias = info.start; 1185 } 1186 1187 if (rctx->vgt.id != R600_PIPE_STATE_VGT) { 1188 rctx->vgt.id = R600_PIPE_STATE_VGT; 1189 rctx->vgt.nregs = 0; 1190 r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim); 1191 r600_pipe_state_add_reg(&rctx->vgt, R_028A6C_VGT_GS_OUT_PRIM_TYPE, 0); 1192 r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias); 1193 r600_pipe_state_add_reg(&rctx->vgt, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info.restart_index); 1194 r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info.primitive_restart); 1195 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance); 1196 r600_pipe_state_add_reg(&rctx->vgt, R_028A0C_PA_SC_LINE_STIPPLE, 0); 1197 r600_pipe_state_add_reg(&rctx->vgt, R_02881C_PA_CL_VS_OUT_CNTL, 0); 1198 r600_pipe_state_add_reg(&rctx->vgt, R_028810_PA_CL_CLIP_CNTL, 0); 1199 } 1200 1201 rctx->vgt.nregs = 0; 1202 r600_pipe_state_mod_reg(&rctx->vgt, prim); 1203 r600_pipe_state_mod_reg(&rctx->vgt, r600_conv_prim_to_gs_out(info.mode)); 1204 r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias); 1205 r600_pipe_state_mod_reg(&rctx->vgt, info.restart_index); 1206 r600_pipe_state_mod_reg(&rctx->vgt, info.primitive_restart); 1207 r600_pipe_state_mod_reg(&rctx->vgt, info.start_instance); 1208 1209 if (prim == V_008958_DI_PT_LINELIST) 1210 ls_mask = 1; 1211 else if (prim == V_008958_DI_PT_LINESTRIP || 1212 prim == V_008958_DI_PT_LINELOOP) 1213 ls_mask = 2; 1214 r600_pipe_state_mod_reg(&rctx->vgt, S_028A0C_AUTO_RESET_CNTL(ls_mask) | rctx->pa_sc_line_stipple); 1215 r600_pipe_state_mod_reg(&rctx->vgt, 1216 rctx->vs_shader->current->pa_cl_vs_out_cntl | 1217 (rctx->rasterizer->clip_plane_enable & rctx->vs_shader->current->shader.clip_dist_write)); 1218 r600_pipe_state_mod_reg(&rctx->vgt, 1219 rctx->pa_cl_clip_cntl | 1220 (rctx->vs_shader->current->shader.clip_dist_write || 1221 rctx->vs_shader->current->shader.vs_prohibit_ucps ? 1222 0 : rctx->rasterizer->clip_plane_enable & 0x3F)); 1223 1224 r600_context_pipe_state_set(rctx, &rctx->vgt); 1225 1226 /* Enable stream out if needed. */ 1227 if (rctx->streamout_start) { 1228 r600_context_streamout_begin(rctx); 1229 rctx->streamout_start = FALSE; 1230 } 1231 1232 /* Emit states (the function expects that we emit at most 17 dwords here). */ 1233 r600_need_cs_space(rctx, 0, TRUE); 1234 1235 LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) { 1236 r600_emit_atom(rctx, state); 1237 } 1238 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) { 1239 r600_context_block_emit_dirty(rctx, dirty_block, 0 /* pkt_flags */); 1240 } 1241 rctx->pm4_dirty_cdwords = 0; 1242 1243 /* draw packet */ 1244 cs->buf[cs->cdw++] = PKT3(PKT3_NUM_INSTANCES, 0, rctx->predicate_drawing); 1245 cs->buf[cs->cdw++] = info.instance_count; 1246 if (info.indexed) { 1247 cs->buf[cs->cdw++] = PKT3(PKT3_INDEX_TYPE, 0, rctx->predicate_drawing); 1248 cs->buf[cs->cdw++] = ib.index_size == 4 ? 1249 (VGT_INDEX_32 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_32_BIT : 0)) : 1250 (VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0)); 1251 1252 va = r600_resource_va(ctx->screen, ib.buffer); 1253 va += ib.offset; 1254 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX, 3, rctx->predicate_drawing); 1255 cs->buf[cs->cdw++] = va; 1256 cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 1257 cs->buf[cs->cdw++] = info.count; 1258 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_DMA; 1259 cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, rctx->predicate_drawing); 1260 cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, (struct r600_resource*)ib.buffer, RADEON_USAGE_READ); 1261 } else { 1262 if (info.count_from_stream_output) { 1263 struct r600_so_target *t = (struct r600_so_target*)info.count_from_stream_output; 1264 uint64_t va = r600_resource_va(&rctx->screen->screen, (void*)t->filled_size); 1265 1266 r600_write_context_reg(cs, R_028B30_VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE, t->stride_in_dw); 1267 1268 cs->buf[cs->cdw++] = PKT3(PKT3_COPY_DW, 4, 0); 1269 cs->buf[cs->cdw++] = COPY_DW_SRC_IS_MEM | COPY_DW_DST_IS_REG; 1270 cs->buf[cs->cdw++] = va & 0xFFFFFFFFUL; /* src address lo */ 1271 cs->buf[cs->cdw++] = (va >> 32UL) & 0xFFUL; /* src address hi */ 1272 cs->buf[cs->cdw++] = R_028B2C_VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE >> 2; /* dst register */ 1273 cs->buf[cs->cdw++] = 0; /* unused */ 1274 1275 cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 1276 cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, t->filled_size, RADEON_USAGE_READ); 1277 } 1278 1279 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, rctx->predicate_drawing); 1280 cs->buf[cs->cdw++] = info.count; 1281 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_AUTO_INDEX | 1282 (info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0); 1283 } 1284 1285 rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY | R600_CONTEXT_DRAW_PENDING; 1286 1287 /* Set the depth buffer as dirty. */ 1288 if (rctx->framebuffer.zsbuf) { 1289 struct pipe_surface *surf = rctx->framebuffer.zsbuf; 1290 struct r600_texture *rtex = (struct r600_texture *)surf->texture; 1291 1292 rtex->dirty_level_mask |= 1 << surf->u.tex.level; 1293 } 1294 if (rctx->compressed_cb_mask) { 1295 struct pipe_surface *surf; 1296 struct r600_texture *rtex; 1297 unsigned mask = rctx->compressed_cb_mask; 1298 1299 do { 1300 unsigned i = u_bit_scan(&mask); 1301 surf = rctx->framebuffer.cbufs[i]; 1302 rtex = (struct r600_texture*)surf->texture; 1303 1304 rtex->dirty_level_mask |= 1 << surf->u.tex.level; 1305 1306 } while (mask); 1307 } 1308 1309 pipe_resource_reference(&ib.buffer, NULL); 1310} 1311 1312void r600_draw_rectangle(struct blitter_context *blitter, 1313 unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth, 1314 enum blitter_attrib_type type, const union pipe_color_union *attrib) 1315{ 1316 struct r600_context *rctx = (struct r600_context*)util_blitter_get_pipe(blitter); 1317 struct pipe_viewport_state viewport; 1318 struct pipe_resource *buf = NULL; 1319 unsigned offset = 0; 1320 float *vb; 1321 1322 if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) { 1323 util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, type, attrib); 1324 return; 1325 } 1326 1327 /* Some operations (like color resolve on r6xx) don't work 1328 * with the conventional primitive types. 1329 * One that works is PT_RECTLIST, which we use here. */ 1330 1331 /* setup viewport */ 1332 viewport.scale[0] = 1.0f; 1333 viewport.scale[1] = 1.0f; 1334 viewport.scale[2] = 1.0f; 1335 viewport.scale[3] = 1.0f; 1336 viewport.translate[0] = 0.0f; 1337 viewport.translate[1] = 0.0f; 1338 viewport.translate[2] = 0.0f; 1339 viewport.translate[3] = 0.0f; 1340 rctx->context.set_viewport_state(&rctx->context, &viewport); 1341 1342 /* Upload vertices. The hw rectangle has only 3 vertices, 1343 * I guess the 4th one is derived from the first 3. 1344 * The vertex specification should match u_blitter's vertex element state. */ 1345 u_upload_alloc(rctx->uploader, 0, sizeof(float) * 24, &offset, &buf, (void**)&vb); 1346 vb[0] = x1; 1347 vb[1] = y1; 1348 vb[2] = depth; 1349 vb[3] = 1; 1350 1351 vb[8] = x1; 1352 vb[9] = y2; 1353 vb[10] = depth; 1354 vb[11] = 1; 1355 1356 vb[16] = x2; 1357 vb[17] = y1; 1358 vb[18] = depth; 1359 vb[19] = 1; 1360 1361 if (attrib) { 1362 memcpy(vb+4, attrib->f, sizeof(float)*4); 1363 memcpy(vb+12, attrib->f, sizeof(float)*4); 1364 memcpy(vb+20, attrib->f, sizeof(float)*4); 1365 } 1366 1367 /* draw */ 1368 util_draw_vertex_buffer(&rctx->context, NULL, buf, offset, 1369 R600_PRIM_RECTANGLE_LIST, 3, 2); 1370 pipe_resource_reference(&buf, NULL); 1371} 1372 1373void _r600_pipe_state_add_reg_bo(struct r600_context *ctx, 1374 struct r600_pipe_state *state, 1375 uint32_t offset, uint32_t value, 1376 uint32_t range_id, uint32_t block_id, 1377 struct r600_resource *bo, 1378 enum radeon_bo_usage usage) 1379 1380{ 1381 struct r600_range *range; 1382 struct r600_block *block; 1383 1384 if (bo) assert(usage); 1385 1386 range = &ctx->range[range_id]; 1387 block = range->blocks[block_id]; 1388 state->regs[state->nregs].block = block; 1389 state->regs[state->nregs].id = (offset - block->start_offset) >> 2; 1390 1391 state->regs[state->nregs].value = value; 1392 state->regs[state->nregs].bo = bo; 1393 state->regs[state->nregs].bo_usage = usage; 1394 1395 state->nregs++; 1396 assert(state->nregs < R600_BLOCK_MAX_REG); 1397} 1398 1399void _r600_pipe_state_add_reg(struct r600_context *ctx, 1400 struct r600_pipe_state *state, 1401 uint32_t offset, uint32_t value, 1402 uint32_t range_id, uint32_t block_id) 1403{ 1404 _r600_pipe_state_add_reg_bo(ctx, state, offset, value, 1405 range_id, block_id, NULL, 0); 1406} 1407 1408void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state, 1409 uint32_t offset, uint32_t value, 1410 struct r600_resource *bo, 1411 enum radeon_bo_usage usage) 1412{ 1413 if (bo) assert(usage); 1414 1415 state->regs[state->nregs].id = offset; 1416 state->regs[state->nregs].block = NULL; 1417 state->regs[state->nregs].value = value; 1418 state->regs[state->nregs].bo = bo; 1419 state->regs[state->nregs].bo_usage = usage; 1420 1421 state->nregs++; 1422 assert(state->nregs < R600_BLOCK_MAX_REG); 1423} 1424 1425uint32_t r600_translate_stencil_op(int s_op) 1426{ 1427 switch (s_op) { 1428 case PIPE_STENCIL_OP_KEEP: 1429 return V_028800_STENCIL_KEEP; 1430 case PIPE_STENCIL_OP_ZERO: 1431 return V_028800_STENCIL_ZERO; 1432 case PIPE_STENCIL_OP_REPLACE: 1433 return V_028800_STENCIL_REPLACE; 1434 case PIPE_STENCIL_OP_INCR: 1435 return V_028800_STENCIL_INCR; 1436 case PIPE_STENCIL_OP_DECR: 1437 return V_028800_STENCIL_DECR; 1438 case PIPE_STENCIL_OP_INCR_WRAP: 1439 return V_028800_STENCIL_INCR_WRAP; 1440 case PIPE_STENCIL_OP_DECR_WRAP: 1441 return V_028800_STENCIL_DECR_WRAP; 1442 case PIPE_STENCIL_OP_INVERT: 1443 return V_028800_STENCIL_INVERT; 1444 default: 1445 R600_ERR("Unknown stencil op %d", s_op); 1446 assert(0); 1447 break; 1448 } 1449 return 0; 1450} 1451 1452uint32_t r600_translate_fill(uint32_t func) 1453{ 1454 switch(func) { 1455 case PIPE_POLYGON_MODE_FILL: 1456 return 2; 1457 case PIPE_POLYGON_MODE_LINE: 1458 return 1; 1459 case PIPE_POLYGON_MODE_POINT: 1460 return 0; 1461 default: 1462 assert(0); 1463 return 0; 1464 } 1465} 1466 1467unsigned r600_tex_wrap(unsigned wrap) 1468{ 1469 switch (wrap) { 1470 default: 1471 case PIPE_TEX_WRAP_REPEAT: 1472 return V_03C000_SQ_TEX_WRAP; 1473 case PIPE_TEX_WRAP_CLAMP: 1474 return V_03C000_SQ_TEX_CLAMP_HALF_BORDER; 1475 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 1476 return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL; 1477 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 1478 return V_03C000_SQ_TEX_CLAMP_BORDER; 1479 case PIPE_TEX_WRAP_MIRROR_REPEAT: 1480 return V_03C000_SQ_TEX_MIRROR; 1481 case PIPE_TEX_WRAP_MIRROR_CLAMP: 1482 return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER; 1483 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 1484 return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; 1485 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 1486 return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER; 1487 } 1488} 1489 1490unsigned r600_tex_filter(unsigned filter) 1491{ 1492 switch (filter) { 1493 default: 1494 case PIPE_TEX_FILTER_NEAREST: 1495 return V_03C000_SQ_TEX_XY_FILTER_POINT; 1496 case PIPE_TEX_FILTER_LINEAR: 1497 return V_03C000_SQ_TEX_XY_FILTER_BILINEAR; 1498 } 1499} 1500 1501unsigned r600_tex_mipfilter(unsigned filter) 1502{ 1503 switch (filter) { 1504 case PIPE_TEX_MIPFILTER_NEAREST: 1505 return V_03C000_SQ_TEX_Z_FILTER_POINT; 1506 case PIPE_TEX_MIPFILTER_LINEAR: 1507 return V_03C000_SQ_TEX_Z_FILTER_LINEAR; 1508 default: 1509 case PIPE_TEX_MIPFILTER_NONE: 1510 return V_03C000_SQ_TEX_Z_FILTER_NONE; 1511 } 1512} 1513 1514unsigned r600_tex_compare(unsigned compare) 1515{ 1516 switch (compare) { 1517 default: 1518 case PIPE_FUNC_NEVER: 1519 return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER; 1520 case PIPE_FUNC_LESS: 1521 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS; 1522 case PIPE_FUNC_EQUAL: 1523 return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL; 1524 case PIPE_FUNC_LEQUAL: 1525 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; 1526 case PIPE_FUNC_GREATER: 1527 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER; 1528 case PIPE_FUNC_NOTEQUAL: 1529 return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; 1530 case PIPE_FUNC_GEQUAL: 1531 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; 1532 case PIPE_FUNC_ALWAYS: 1533 return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS; 1534 } 1535} 1536