r600_state_common.c revision 64db3cc6ad2d52dec46119e5b80030393cb60bf4
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, 3, 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 } else { 509 pipe_resource_reference(&rctx->index_buffer.buffer, NULL); 510 } 511} 512 513void r600_vertex_buffers_dirty(struct r600_context *rctx) 514{ 515 if (rctx->vertex_buffer_state.dirty_mask) { 516 r600_inval_vertex_cache(rctx); 517 rctx->vertex_buffer_state.atom.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 11) * 518 util_bitcount(rctx->vertex_buffer_state.dirty_mask); 519 r600_atom_dirty(rctx, &rctx->vertex_buffer_state.atom); 520 } 521} 522 523void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, 524 const struct pipe_vertex_buffer *input) 525{ 526 struct r600_context *rctx = (struct r600_context *)ctx; 527 struct r600_vertexbuf_state *state = &rctx->vertex_buffer_state; 528 struct pipe_vertex_buffer *vb = state->vb; 529 unsigned i; 530 /* This sets 1-bit for buffers with index >= count. */ 531 uint32_t disable_mask = ~((1ull << count) - 1); 532 /* These are the new buffers set by this function. */ 533 uint32_t new_buffer_mask = 0; 534 535 /* Set buffers with index >= count to NULL. */ 536 uint32_t remaining_buffers_mask = 537 rctx->vertex_buffer_state.enabled_mask & disable_mask; 538 539 while (remaining_buffers_mask) { 540 i = u_bit_scan(&remaining_buffers_mask); 541 pipe_resource_reference(&vb[i].buffer, NULL); 542 } 543 544 /* Set vertex buffers. */ 545 for (i = 0; i < count; i++) { 546 if (memcmp(&input[i], &vb[i], sizeof(struct pipe_vertex_buffer))) { 547 if (input[i].buffer) { 548 vb[i].stride = input[i].stride; 549 vb[i].buffer_offset = input[i].buffer_offset; 550 pipe_resource_reference(&vb[i].buffer, input[i].buffer); 551 new_buffer_mask |= 1 << i; 552 } else { 553 pipe_resource_reference(&vb[i].buffer, NULL); 554 disable_mask |= 1 << i; 555 } 556 } 557 } 558 559 rctx->vertex_buffer_state.enabled_mask &= ~disable_mask; 560 rctx->vertex_buffer_state.dirty_mask &= rctx->vertex_buffer_state.enabled_mask; 561 rctx->vertex_buffer_state.enabled_mask |= new_buffer_mask; 562 rctx->vertex_buffer_state.dirty_mask |= new_buffer_mask; 563 564 r600_vertex_buffers_dirty(rctx); 565} 566 567void r600_sampler_views_dirty(struct r600_context *rctx, 568 struct r600_samplerview_state *state) 569{ 570 if (state->dirty_mask) { 571 r600_inval_texture_cache(rctx); 572 state->atom.num_dw = (rctx->chip_class >= EVERGREEN ? 14 : 13) * 573 util_bitcount(state->dirty_mask); 574 r600_atom_dirty(rctx, &state->atom); 575 } 576} 577 578void r600_set_sampler_views(struct pipe_context *pipe, 579 unsigned shader, 580 unsigned start, 581 unsigned count, 582 struct pipe_sampler_view **views) 583{ 584 struct r600_context *rctx = (struct r600_context *) pipe; 585 struct r600_textures_info *dst; 586 struct r600_pipe_sampler_view **rviews = (struct r600_pipe_sampler_view **)views; 587 unsigned i; 588 /* This sets 1-bit for textures with index >= count. */ 589 uint32_t disable_mask = ~((1ull << count) - 1); 590 /* These are the new textures set by this function. */ 591 uint32_t new_mask = 0; 592 593 /* Set textures with index >= count to NULL. */ 594 uint32_t remaining_mask; 595 596 assert(start == 0); /* XXX fix below */ 597 598 switch (shader) { 599 case PIPE_SHADER_VERTEX: 600 dst = &rctx->vs_samplers; 601 break; 602 case PIPE_SHADER_FRAGMENT: 603 dst = &rctx->ps_samplers; 604 break; 605 default: 606 debug_error("bad shader in r600_set_sampler_views()"); 607 return; 608 } 609 610 remaining_mask = dst->views.enabled_mask & disable_mask; 611 612 while (remaining_mask) { 613 i = u_bit_scan(&remaining_mask); 614 assert(dst->views.views[i]); 615 616 pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], NULL); 617 } 618 619 for (i = 0; i < count; i++) { 620 if (rviews[i] == dst->views.views[i]) { 621 continue; 622 } 623 624 if (rviews[i]) { 625 struct r600_texture *rtex = 626 (struct r600_texture*)rviews[i]->base.texture; 627 628 if (rtex->is_depth && !rtex->is_flushing_texture) { 629 dst->views.compressed_depthtex_mask |= 1 << i; 630 } else { 631 dst->views.compressed_depthtex_mask &= ~(1 << i); 632 } 633 634 /* Track compressed colorbuffers for Evergreen (Cayman doesn't need this). */ 635 if (rctx->chip_class != CAYMAN && rtex->cmask_size && rtex->fmask_size) { 636 dst->views.compressed_colortex_mask |= 1 << i; 637 } else { 638 dst->views.compressed_colortex_mask &= ~(1 << i); 639 } 640 641 /* Changing from array to non-arrays textures and vice 642 * versa requires updating TEX_ARRAY_OVERRIDE on R6xx-R7xx. */ 643 if (rctx->chip_class <= R700 && 644 (rviews[i]->base.texture->target == PIPE_TEXTURE_1D_ARRAY || 645 rviews[i]->base.texture->target == PIPE_TEXTURE_2D_ARRAY) != dst->is_array_sampler[i]) { 646 r600_atom_dirty(rctx, &dst->atom_sampler); 647 } 648 649 pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], views[i]); 650 new_mask |= 1 << i; 651 } else { 652 pipe_sampler_view_reference((struct pipe_sampler_view **)&dst->views.views[i], NULL); 653 disable_mask |= 1 << i; 654 } 655 } 656 657 dst->views.enabled_mask &= ~disable_mask; 658 dst->views.dirty_mask &= dst->views.enabled_mask; 659 dst->views.enabled_mask |= new_mask; 660 dst->views.dirty_mask |= new_mask; 661 dst->views.compressed_depthtex_mask &= dst->views.enabled_mask; 662 dst->views.compressed_colortex_mask &= dst->views.enabled_mask; 663 664 r600_sampler_views_dirty(rctx, &dst->views); 665} 666 667void *r600_create_vertex_elements(struct pipe_context *ctx, 668 unsigned count, 669 const struct pipe_vertex_element *elements) 670{ 671 struct r600_context *rctx = (struct r600_context *)ctx; 672 struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); 673 674 assert(count < 32); 675 if (!v) 676 return NULL; 677 678 v->count = count; 679 memcpy(v->elements, elements, sizeof(struct pipe_vertex_element) * count); 680 681 if (r600_vertex_elements_build_fetch_shader(rctx, v)) { 682 FREE(v); 683 return NULL; 684 } 685 686 return v; 687} 688 689/* Compute the key for the hw shader variant */ 690static INLINE unsigned r600_shader_selector_key(struct pipe_context * ctx, 691 struct r600_pipe_shader_selector * sel) 692{ 693 struct r600_context *rctx = (struct r600_context *)ctx; 694 unsigned key; 695 696 if (sel->type == PIPE_SHADER_FRAGMENT) { 697 key = rctx->two_side | 698 ((rctx->alpha_to_one && rctx->multisample_enable && !rctx->cb0_is_integer) << 1) | 699 (MIN2(sel->nr_ps_max_color_exports, rctx->nr_cbufs + rctx->dual_src_blend) << 2); 700 } else 701 key = 0; 702 703 return key; 704} 705 706/* Select the hw shader variant depending on the current state. 707 * (*dirty) is set to 1 if current variant was changed */ 708static int r600_shader_select(struct pipe_context *ctx, 709 struct r600_pipe_shader_selector* sel, 710 unsigned *dirty) 711{ 712 unsigned key; 713 struct r600_context *rctx = (struct r600_context *)ctx; 714 struct r600_pipe_shader * shader = NULL; 715 int r; 716 717 key = r600_shader_selector_key(ctx, sel); 718 719 /* Check if we don't need to change anything. 720 * This path is also used for most shaders that don't need multiple 721 * variants, it will cost just a computation of the key and this 722 * test. */ 723 if (likely(sel->current && sel->current->key == key)) { 724 return 0; 725 } 726 727 /* lookup if we have other variants in the list */ 728 if (sel->num_shaders > 1) { 729 struct r600_pipe_shader *p = sel->current, *c = p->next_variant; 730 731 while (c && c->key != key) { 732 p = c; 733 c = c->next_variant; 734 } 735 736 if (c) { 737 p->next_variant = c->next_variant; 738 shader = c; 739 } 740 } 741 742 if (unlikely(!shader)) { 743 shader = CALLOC(1, sizeof(struct r600_pipe_shader)); 744 shader->selector = sel; 745 746 r = r600_pipe_shader_create(ctx, shader); 747 if (unlikely(r)) { 748 R600_ERR("Failed to build shader variant (type=%u, key=%u) %d\n", 749 sel->type, key, r); 750 sel->current = NULL; 751 return r; 752 } 753 754 /* We don't know the value of nr_ps_max_color_exports until we built 755 * at least one variant, so we may need to recompute the key after 756 * building first variant. */ 757 if (sel->type == PIPE_SHADER_FRAGMENT && 758 sel->num_shaders == 0) { 759 sel->nr_ps_max_color_exports = shader->shader.nr_ps_max_color_exports; 760 key = r600_shader_selector_key(ctx, sel); 761 } 762 763 shader->key = key; 764 sel->num_shaders++; 765 } 766 767 if (dirty) 768 *dirty = 1; 769 770 shader->next_variant = sel->current; 771 sel->current = shader; 772 773 if (rctx->chip_class < EVERGREEN && rctx->ps_shader && rctx->vs_shader) { 774 r600_adjust_gprs(rctx); 775 } 776 777 if (rctx->ps_shader && 778 rctx->cb_misc_state.nr_ps_color_outputs != rctx->ps_shader->current->nr_ps_color_outputs) { 779 rctx->cb_misc_state.nr_ps_color_outputs = rctx->ps_shader->current->nr_ps_color_outputs; 780 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 781 } 782 return 0; 783} 784 785static void *r600_create_shader_state(struct pipe_context *ctx, 786 const struct pipe_shader_state *state, 787 unsigned pipe_shader_type) 788{ 789 struct r600_pipe_shader_selector *sel = CALLOC_STRUCT(r600_pipe_shader_selector); 790 int r; 791 792 sel->type = pipe_shader_type; 793 sel->tokens = tgsi_dup_tokens(state->tokens); 794 sel->so = state->stream_output; 795 796 r = r600_shader_select(ctx, sel, NULL); 797 if (r) 798 return NULL; 799 800 return sel; 801} 802 803void *r600_create_shader_state_ps(struct pipe_context *ctx, 804 const struct pipe_shader_state *state) 805{ 806 return r600_create_shader_state(ctx, state, PIPE_SHADER_FRAGMENT); 807} 808 809void *r600_create_shader_state_vs(struct pipe_context *ctx, 810 const struct pipe_shader_state *state) 811{ 812 return r600_create_shader_state(ctx, state, PIPE_SHADER_VERTEX); 813} 814 815void r600_bind_ps_shader(struct pipe_context *ctx, void *state) 816{ 817 struct r600_context *rctx = (struct r600_context *)ctx; 818 819 if (!state) 820 state = rctx->dummy_pixel_shader; 821 822 rctx->ps_shader = (struct r600_pipe_shader_selector *)state; 823 r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate); 824 825 if (rctx->chip_class <= R700) { 826 bool multiwrite = rctx->ps_shader->current->shader.fs_write_all; 827 828 if (rctx->cb_misc_state.multiwrite != multiwrite) { 829 rctx->cb_misc_state.multiwrite = multiwrite; 830 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 831 } 832 833 if (rctx->vs_shader) 834 r600_adjust_gprs(rctx); 835 } 836 837 if (rctx->cb_misc_state.nr_ps_color_outputs != rctx->ps_shader->current->nr_ps_color_outputs) { 838 rctx->cb_misc_state.nr_ps_color_outputs = rctx->ps_shader->current->nr_ps_color_outputs; 839 r600_atom_dirty(rctx, &rctx->cb_misc_state.atom); 840 } 841} 842 843void r600_bind_vs_shader(struct pipe_context *ctx, void *state) 844{ 845 struct r600_context *rctx = (struct r600_context *)ctx; 846 847 rctx->vs_shader = (struct r600_pipe_shader_selector *)state; 848 if (state) { 849 r600_context_pipe_state_set(rctx, &rctx->vs_shader->current->rstate); 850 851 if (rctx->chip_class < EVERGREEN && rctx->ps_shader) 852 r600_adjust_gprs(rctx); 853 } 854} 855 856static void r600_delete_shader_selector(struct pipe_context *ctx, 857 struct r600_pipe_shader_selector *sel) 858{ 859 struct r600_pipe_shader *p = sel->current, *c; 860 while (p) { 861 c = p->next_variant; 862 r600_pipe_shader_destroy(ctx, p); 863 free(p); 864 p = c; 865 } 866 867 free(sel->tokens); 868 free(sel); 869} 870 871 872void r600_delete_ps_shader(struct pipe_context *ctx, void *state) 873{ 874 struct r600_context *rctx = (struct r600_context *)ctx; 875 struct r600_pipe_shader_selector *sel = (struct r600_pipe_shader_selector *)state; 876 877 if (rctx->ps_shader == sel) { 878 rctx->ps_shader = NULL; 879 } 880 881 r600_delete_shader_selector(ctx, sel); 882} 883 884void r600_delete_vs_shader(struct pipe_context *ctx, void *state) 885{ 886 struct r600_context *rctx = (struct r600_context *)ctx; 887 struct r600_pipe_shader_selector *sel = (struct r600_pipe_shader_selector *)state; 888 889 if (rctx->vs_shader == sel) { 890 rctx->vs_shader = NULL; 891 } 892 893 r600_delete_shader_selector(ctx, sel); 894} 895 896void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state) 897{ 898 if (state->dirty_mask) { 899 r600_inval_shader_cache(rctx); 900 state->atom.num_dw = rctx->chip_class >= EVERGREEN ? util_bitcount(state->dirty_mask)*20 901 : util_bitcount(state->dirty_mask)*19; 902 r600_atom_dirty(rctx, &state->atom); 903 } 904} 905 906void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, 907 struct pipe_constant_buffer *input) 908{ 909 struct r600_context *rctx = (struct r600_context *)ctx; 910 struct r600_constbuf_state *state; 911 struct pipe_constant_buffer *cb; 912 const uint8_t *ptr; 913 914 switch (shader) { 915 case PIPE_SHADER_VERTEX: 916 state = &rctx->vs_constbuf_state; 917 break; 918 case PIPE_SHADER_FRAGMENT: 919 state = &rctx->ps_constbuf_state; 920 break; 921 default: 922 return; 923 } 924 925 /* Note that the state tracker can unbind constant buffers by 926 * passing NULL here. 927 */ 928 if (unlikely(!input)) { 929 state->enabled_mask &= ~(1 << index); 930 state->dirty_mask &= ~(1 << index); 931 pipe_resource_reference(&state->cb[index].buffer, NULL); 932 return; 933 } 934 935 cb = &state->cb[index]; 936 cb->buffer_size = input->buffer_size; 937 938 ptr = input->user_buffer; 939 940 if (ptr) { 941 /* Upload the user buffer. */ 942 if (R600_BIG_ENDIAN) { 943 uint32_t *tmpPtr; 944 unsigned i, size = input->buffer_size; 945 946 if (!(tmpPtr = malloc(size))) { 947 R600_ERR("Failed to allocate BE swap buffer.\n"); 948 return; 949 } 950 951 for (i = 0; i < size / 4; ++i) { 952 tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]); 953 } 954 955 u_upload_data(rctx->uploader, 0, size, tmpPtr, &cb->buffer_offset, &cb->buffer); 956 free(tmpPtr); 957 } else { 958 u_upload_data(rctx->uploader, 0, input->buffer_size, ptr, &cb->buffer_offset, &cb->buffer); 959 } 960 } else { 961 /* Setup the hw buffer. */ 962 cb->buffer_offset = input->buffer_offset; 963 pipe_resource_reference(&cb->buffer, input->buffer); 964 } 965 966 state->enabled_mask |= 1 << index; 967 state->dirty_mask |= 1 << index; 968 r600_constant_buffers_dirty(rctx, state); 969} 970 971struct pipe_stream_output_target * 972r600_create_so_target(struct pipe_context *ctx, 973 struct pipe_resource *buffer, 974 unsigned buffer_offset, 975 unsigned buffer_size) 976{ 977 struct r600_context *rctx = (struct r600_context *)ctx; 978 struct r600_so_target *t; 979 void *ptr; 980 981 t = CALLOC_STRUCT(r600_so_target); 982 if (!t) { 983 return NULL; 984 } 985 986 t->b.reference.count = 1; 987 t->b.context = ctx; 988 pipe_resource_reference(&t->b.buffer, buffer); 989 t->b.buffer_offset = buffer_offset; 990 t->b.buffer_size = buffer_size; 991 992 t->filled_size = (struct r600_resource*) 993 pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, 4); 994 ptr = rctx->ws->buffer_map(t->filled_size->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); 995 memset(ptr, 0, t->filled_size->buf->size); 996 rctx->ws->buffer_unmap(t->filled_size->cs_buf); 997 998 return &t->b; 999} 1000 1001void r600_so_target_destroy(struct pipe_context *ctx, 1002 struct pipe_stream_output_target *target) 1003{ 1004 struct r600_so_target *t = (struct r600_so_target*)target; 1005 pipe_resource_reference(&t->b.buffer, NULL); 1006 pipe_resource_reference((struct pipe_resource**)&t->filled_size, NULL); 1007 FREE(t); 1008} 1009 1010void r600_set_so_targets(struct pipe_context *ctx, 1011 unsigned num_targets, 1012 struct pipe_stream_output_target **targets, 1013 unsigned append_bitmask) 1014{ 1015 struct r600_context *rctx = (struct r600_context *)ctx; 1016 unsigned i; 1017 1018 /* Stop streamout. */ 1019 if (rctx->num_so_targets && !rctx->streamout_start) { 1020 r600_context_streamout_end(rctx); 1021 } 1022 1023 /* Set the new targets. */ 1024 for (i = 0; i < num_targets; i++) { 1025 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], targets[i]); 1026 } 1027 for (; i < rctx->num_so_targets; i++) { 1028 pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->so_targets[i], NULL); 1029 } 1030 1031 rctx->num_so_targets = num_targets; 1032 rctx->streamout_start = num_targets != 0; 1033 rctx->streamout_append_bitmask = append_bitmask; 1034} 1035 1036void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) 1037{ 1038 struct r600_context *rctx = (struct r600_context*)pipe; 1039 1040 if (rctx->sample_mask.sample_mask == (uint16_t)sample_mask) 1041 return; 1042 1043 rctx->sample_mask.sample_mask = sample_mask; 1044 r600_atom_dirty(rctx, &rctx->sample_mask.atom); 1045} 1046 1047static void r600_update_derived_state(struct r600_context *rctx) 1048{ 1049 struct pipe_context * ctx = (struct pipe_context*)rctx; 1050 unsigned ps_dirty = 0, blend_override; 1051 1052 if (!rctx->blitter->running) { 1053 /* Decompress textures if needed. */ 1054 if (rctx->vs_samplers.views.compressed_depthtex_mask) { 1055 r600_decompress_depth_textures(rctx, &rctx->vs_samplers.views); 1056 } 1057 if (rctx->ps_samplers.views.compressed_depthtex_mask) { 1058 r600_decompress_depth_textures(rctx, &rctx->ps_samplers.views); 1059 } 1060 if (rctx->vs_samplers.views.compressed_colortex_mask) { 1061 r600_decompress_color_textures(rctx, &rctx->vs_samplers.views); 1062 } 1063 if (rctx->ps_samplers.views.compressed_colortex_mask) { 1064 r600_decompress_color_textures(rctx, &rctx->ps_samplers.views); 1065 } 1066 } 1067 1068 r600_shader_select(ctx, rctx->ps_shader, &ps_dirty); 1069 1070 if (rctx->ps_shader && ((rctx->sprite_coord_enable && 1071 (rctx->ps_shader->current->sprite_coord_enable != rctx->sprite_coord_enable)) || 1072 (rctx->rasterizer && rctx->rasterizer->flatshade != rctx->ps_shader->current->flatshade))) { 1073 1074 if (rctx->chip_class >= EVERGREEN) 1075 evergreen_pipe_shader_ps(ctx, rctx->ps_shader->current); 1076 else 1077 r600_pipe_shader_ps(ctx, rctx->ps_shader->current); 1078 1079 ps_dirty = 1; 1080 } 1081 1082 if (ps_dirty) 1083 r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate); 1084 1085 blend_override = (rctx->dual_src_blend && 1086 rctx->ps_shader->current->nr_ps_color_outputs < 2); 1087 1088 if (blend_override != rctx->blend_override) { 1089 rctx->blend_override = blend_override; 1090 r600_bind_blend_state_internal(rctx, 1091 blend_override ? rctx->no_blend : rctx->blend); 1092 } 1093 1094 if (rctx->chip_class >= EVERGREEN) { 1095 evergreen_update_dual_export_state(rctx); 1096 } else { 1097 r600_update_dual_export_state(rctx); 1098 } 1099} 1100 1101static unsigned r600_conv_prim_to_gs_out(unsigned mode) 1102{ 1103 static const int prim_conv[] = { 1104 V_028A6C_OUTPRIM_TYPE_POINTLIST, 1105 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1106 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1107 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1108 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1109 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1110 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1111 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1112 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1113 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1114 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1115 V_028A6C_OUTPRIM_TYPE_LINESTRIP, 1116 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1117 V_028A6C_OUTPRIM_TYPE_TRISTRIP, 1118 V_028A6C_OUTPRIM_TYPE_TRISTRIP 1119 }; 1120 assert(mode < Elements(prim_conv)); 1121 1122 return prim_conv[mode]; 1123} 1124 1125void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) 1126{ 1127 struct r600_context *rctx = (struct r600_context *)ctx; 1128 struct pipe_draw_info info = *dinfo; 1129 struct pipe_index_buffer ib = {}; 1130 unsigned prim, ls_mask = 0; 1131 struct r600_block *dirty_block = NULL, *next_block = NULL; 1132 struct r600_atom *state = NULL, *next_state = NULL; 1133 struct radeon_winsys_cs *cs = rctx->cs; 1134 uint64_t va; 1135 uint8_t *ptr; 1136 1137 if ((!info.count && (info.indexed || !info.count_from_stream_output)) || 1138 !r600_conv_pipe_prim(info.mode, &prim)) { 1139 assert(0); 1140 return; 1141 } 1142 1143 if (!rctx->vs_shader) { 1144 assert(0); 1145 return; 1146 } 1147 1148 r600_update_derived_state(rctx); 1149 1150 /* partial flush triggered by border color change */ 1151 if (rctx->flags & R600_PARTIAL_FLUSH) { 1152 rctx->flags &= ~R600_PARTIAL_FLUSH; 1153 r600_write_value(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); 1154 r600_write_value(cs, EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4)); 1155 } 1156 1157 if (info.indexed) { 1158 /* Initialize the index buffer struct. */ 1159 pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer); 1160 ib.user_buffer = rctx->index_buffer.user_buffer; 1161 ib.index_size = rctx->index_buffer.index_size; 1162 ib.offset = rctx->index_buffer.offset + info.start * ib.index_size; 1163 1164 /* Translate or upload, if needed. */ 1165 r600_translate_index_buffer(rctx, &ib, info.count); 1166 1167 ptr = (uint8_t*)ib.user_buffer; 1168 if (!ib.buffer && ptr) { 1169 u_upload_data(rctx->uploader, 0, info.count * ib.index_size, 1170 ptr, &ib.offset, &ib.buffer); 1171 } 1172 } else { 1173 info.index_bias = info.start; 1174 } 1175 1176 if (rctx->vgt.id != R600_PIPE_STATE_VGT) { 1177 rctx->vgt.id = R600_PIPE_STATE_VGT; 1178 rctx->vgt.nregs = 0; 1179 r600_pipe_state_add_reg(&rctx->vgt, R_008958_VGT_PRIMITIVE_TYPE, prim); 1180 r600_pipe_state_add_reg(&rctx->vgt, R_028A6C_VGT_GS_OUT_PRIM_TYPE, 0); 1181 r600_pipe_state_add_reg(&rctx->vgt, R_028408_VGT_INDX_OFFSET, info.index_bias); 1182 r600_pipe_state_add_reg(&rctx->vgt, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info.restart_index); 1183 r600_pipe_state_add_reg(&rctx->vgt, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info.primitive_restart); 1184 r600_pipe_state_add_reg(&rctx->vgt, R_03CFF4_SQ_VTX_START_INST_LOC, info.start_instance); 1185 r600_pipe_state_add_reg(&rctx->vgt, R_028A0C_PA_SC_LINE_STIPPLE, 0); 1186 r600_pipe_state_add_reg(&rctx->vgt, R_02881C_PA_CL_VS_OUT_CNTL, 0); 1187 r600_pipe_state_add_reg(&rctx->vgt, R_028810_PA_CL_CLIP_CNTL, 0); 1188 } 1189 1190 rctx->vgt.nregs = 0; 1191 r600_pipe_state_mod_reg(&rctx->vgt, prim); 1192 r600_pipe_state_mod_reg(&rctx->vgt, r600_conv_prim_to_gs_out(info.mode)); 1193 r600_pipe_state_mod_reg(&rctx->vgt, info.index_bias); 1194 r600_pipe_state_mod_reg(&rctx->vgt, info.restart_index); 1195 r600_pipe_state_mod_reg(&rctx->vgt, info.primitive_restart); 1196 r600_pipe_state_mod_reg(&rctx->vgt, info.start_instance); 1197 1198 if (prim == V_008958_DI_PT_LINELIST) 1199 ls_mask = 1; 1200 else if (prim == V_008958_DI_PT_LINESTRIP || 1201 prim == V_008958_DI_PT_LINELOOP) 1202 ls_mask = 2; 1203 r600_pipe_state_mod_reg(&rctx->vgt, S_028A0C_AUTO_RESET_CNTL(ls_mask) | rctx->pa_sc_line_stipple); 1204 r600_pipe_state_mod_reg(&rctx->vgt, 1205 rctx->vs_shader->current->pa_cl_vs_out_cntl | 1206 (rctx->rasterizer->clip_plane_enable & rctx->vs_shader->current->shader.clip_dist_write)); 1207 r600_pipe_state_mod_reg(&rctx->vgt, 1208 rctx->pa_cl_clip_cntl | 1209 (rctx->vs_shader->current->shader.clip_dist_write || 1210 rctx->vs_shader->current->shader.vs_prohibit_ucps ? 1211 0 : rctx->rasterizer->clip_plane_enable & 0x3F)); 1212 1213 r600_context_pipe_state_set(rctx, &rctx->vgt); 1214 1215 /* Enable stream out if needed. */ 1216 if (rctx->streamout_start) { 1217 r600_context_streamout_begin(rctx); 1218 rctx->streamout_start = FALSE; 1219 } 1220 1221 /* Emit states (the function expects that we emit at most 17 dwords here). */ 1222 r600_need_cs_space(rctx, 0, TRUE); 1223 1224 LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) { 1225 r600_emit_atom(rctx, state); 1226 } 1227 LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &rctx->dirty,list) { 1228 r600_context_block_emit_dirty(rctx, dirty_block, 0 /* pkt_flags */); 1229 } 1230 rctx->pm4_dirty_cdwords = 0; 1231 1232 /* draw packet */ 1233 cs->buf[cs->cdw++] = PKT3(PKT3_NUM_INSTANCES, 0, rctx->predicate_drawing); 1234 cs->buf[cs->cdw++] = info.instance_count; 1235 if (info.indexed) { 1236 cs->buf[cs->cdw++] = PKT3(PKT3_INDEX_TYPE, 0, rctx->predicate_drawing); 1237 cs->buf[cs->cdw++] = ib.index_size == 4 ? 1238 (VGT_INDEX_32 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_32_BIT : 0)) : 1239 (VGT_INDEX_16 | (R600_BIG_ENDIAN ? VGT_DMA_SWAP_16_BIT : 0)); 1240 1241 va = r600_resource_va(ctx->screen, ib.buffer); 1242 va += ib.offset; 1243 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX, 3, rctx->predicate_drawing); 1244 cs->buf[cs->cdw++] = va; 1245 cs->buf[cs->cdw++] = (va >> 32UL) & 0xFF; 1246 cs->buf[cs->cdw++] = info.count; 1247 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_DMA; 1248 cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, rctx->predicate_drawing); 1249 cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, (struct r600_resource*)ib.buffer, RADEON_USAGE_READ); 1250 } else { 1251 if (info.count_from_stream_output) { 1252 struct r600_so_target *t = (struct r600_so_target*)info.count_from_stream_output; 1253 uint64_t va = r600_resource_va(&rctx->screen->screen, (void*)t->filled_size); 1254 1255 r600_write_context_reg(cs, R_028B30_VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE, t->stride_in_dw); 1256 1257 cs->buf[cs->cdw++] = PKT3(PKT3_COPY_DW, 4, 0); 1258 cs->buf[cs->cdw++] = COPY_DW_SRC_IS_MEM | COPY_DW_DST_IS_REG; 1259 cs->buf[cs->cdw++] = va & 0xFFFFFFFFUL; /* src address lo */ 1260 cs->buf[cs->cdw++] = (va >> 32UL) & 0xFFUL; /* src address hi */ 1261 cs->buf[cs->cdw++] = R_028B2C_VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE >> 2; /* dst register */ 1262 cs->buf[cs->cdw++] = 0; /* unused */ 1263 1264 cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0); 1265 cs->buf[cs->cdw++] = r600_context_bo_reloc(rctx, t->filled_size, RADEON_USAGE_READ); 1266 } 1267 1268 cs->buf[cs->cdw++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, rctx->predicate_drawing); 1269 cs->buf[cs->cdw++] = info.count; 1270 cs->buf[cs->cdw++] = V_0287F0_DI_SRC_SEL_AUTO_INDEX | 1271 (info.count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0); 1272 } 1273 1274 rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY | R600_CONTEXT_DRAW_PENDING; 1275 1276 /* Set the depth buffer as dirty. */ 1277 if (rctx->framebuffer.zsbuf) { 1278 struct pipe_surface *surf = rctx->framebuffer.zsbuf; 1279 struct r600_texture *rtex = (struct r600_texture *)surf->texture; 1280 1281 rtex->dirty_level_mask |= 1 << surf->u.tex.level; 1282 } 1283 if (rctx->compressed_cb_mask) { 1284 struct pipe_surface *surf; 1285 struct r600_texture *rtex; 1286 unsigned mask = rctx->compressed_cb_mask; 1287 1288 do { 1289 unsigned i = u_bit_scan(&mask); 1290 surf = rctx->framebuffer.cbufs[i]; 1291 rtex = (struct r600_texture*)surf->texture; 1292 1293 rtex->dirty_level_mask |= 1 << surf->u.tex.level; 1294 1295 } while (mask); 1296 } 1297 1298 pipe_resource_reference(&ib.buffer, NULL); 1299} 1300 1301void r600_draw_rectangle(struct blitter_context *blitter, 1302 unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth, 1303 enum blitter_attrib_type type, const union pipe_color_union *attrib) 1304{ 1305 struct r600_context *rctx = (struct r600_context*)util_blitter_get_pipe(blitter); 1306 struct pipe_viewport_state viewport; 1307 struct pipe_resource *buf = NULL; 1308 unsigned offset = 0; 1309 float *vb; 1310 1311 if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) { 1312 util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, type, attrib); 1313 return; 1314 } 1315 1316 /* Some operations (like color resolve on r6xx) don't work 1317 * with the conventional primitive types. 1318 * One that works is PT_RECTLIST, which we use here. */ 1319 1320 /* setup viewport */ 1321 viewport.scale[0] = 1.0f; 1322 viewport.scale[1] = 1.0f; 1323 viewport.scale[2] = 1.0f; 1324 viewport.scale[3] = 1.0f; 1325 viewport.translate[0] = 0.0f; 1326 viewport.translate[1] = 0.0f; 1327 viewport.translate[2] = 0.0f; 1328 viewport.translate[3] = 0.0f; 1329 rctx->context.set_viewport_state(&rctx->context, &viewport); 1330 1331 /* Upload vertices. The hw rectangle has only 3 vertices, 1332 * I guess the 4th one is derived from the first 3. 1333 * The vertex specification should match u_blitter's vertex element state. */ 1334 u_upload_alloc(rctx->uploader, 0, sizeof(float) * 24, &offset, &buf, (void**)&vb); 1335 vb[0] = x1; 1336 vb[1] = y1; 1337 vb[2] = depth; 1338 vb[3] = 1; 1339 1340 vb[8] = x1; 1341 vb[9] = y2; 1342 vb[10] = depth; 1343 vb[11] = 1; 1344 1345 vb[16] = x2; 1346 vb[17] = y1; 1347 vb[18] = depth; 1348 vb[19] = 1; 1349 1350 if (attrib) { 1351 memcpy(vb+4, attrib->f, sizeof(float)*4); 1352 memcpy(vb+12, attrib->f, sizeof(float)*4); 1353 memcpy(vb+20, attrib->f, sizeof(float)*4); 1354 } 1355 1356 /* draw */ 1357 util_draw_vertex_buffer(&rctx->context, NULL, buf, offset, 1358 R600_PRIM_RECTANGLE_LIST, 3, 2); 1359 pipe_resource_reference(&buf, NULL); 1360} 1361 1362void _r600_pipe_state_add_reg_bo(struct r600_context *ctx, 1363 struct r600_pipe_state *state, 1364 uint32_t offset, uint32_t value, 1365 uint32_t range_id, uint32_t block_id, 1366 struct r600_resource *bo, 1367 enum radeon_bo_usage usage) 1368 1369{ 1370 struct r600_range *range; 1371 struct r600_block *block; 1372 1373 if (bo) assert(usage); 1374 1375 range = &ctx->range[range_id]; 1376 block = range->blocks[block_id]; 1377 state->regs[state->nregs].block = block; 1378 state->regs[state->nregs].id = (offset - block->start_offset) >> 2; 1379 1380 state->regs[state->nregs].value = value; 1381 state->regs[state->nregs].bo = bo; 1382 state->regs[state->nregs].bo_usage = usage; 1383 1384 state->nregs++; 1385 assert(state->nregs < R600_BLOCK_MAX_REG); 1386} 1387 1388void _r600_pipe_state_add_reg(struct r600_context *ctx, 1389 struct r600_pipe_state *state, 1390 uint32_t offset, uint32_t value, 1391 uint32_t range_id, uint32_t block_id) 1392{ 1393 _r600_pipe_state_add_reg_bo(ctx, state, offset, value, 1394 range_id, block_id, NULL, 0); 1395} 1396 1397void r600_pipe_state_add_reg_noblock(struct r600_pipe_state *state, 1398 uint32_t offset, uint32_t value, 1399 struct r600_resource *bo, 1400 enum radeon_bo_usage usage) 1401{ 1402 if (bo) assert(usage); 1403 1404 state->regs[state->nregs].id = offset; 1405 state->regs[state->nregs].block = NULL; 1406 state->regs[state->nregs].value = value; 1407 state->regs[state->nregs].bo = bo; 1408 state->regs[state->nregs].bo_usage = usage; 1409 1410 state->nregs++; 1411 assert(state->nregs < R600_BLOCK_MAX_REG); 1412} 1413 1414uint32_t r600_translate_stencil_op(int s_op) 1415{ 1416 switch (s_op) { 1417 case PIPE_STENCIL_OP_KEEP: 1418 return V_028800_STENCIL_KEEP; 1419 case PIPE_STENCIL_OP_ZERO: 1420 return V_028800_STENCIL_ZERO; 1421 case PIPE_STENCIL_OP_REPLACE: 1422 return V_028800_STENCIL_REPLACE; 1423 case PIPE_STENCIL_OP_INCR: 1424 return V_028800_STENCIL_INCR; 1425 case PIPE_STENCIL_OP_DECR: 1426 return V_028800_STENCIL_DECR; 1427 case PIPE_STENCIL_OP_INCR_WRAP: 1428 return V_028800_STENCIL_INCR_WRAP; 1429 case PIPE_STENCIL_OP_DECR_WRAP: 1430 return V_028800_STENCIL_DECR_WRAP; 1431 case PIPE_STENCIL_OP_INVERT: 1432 return V_028800_STENCIL_INVERT; 1433 default: 1434 R600_ERR("Unknown stencil op %d", s_op); 1435 assert(0); 1436 break; 1437 } 1438 return 0; 1439} 1440 1441uint32_t r600_translate_fill(uint32_t func) 1442{ 1443 switch(func) { 1444 case PIPE_POLYGON_MODE_FILL: 1445 return 2; 1446 case PIPE_POLYGON_MODE_LINE: 1447 return 1; 1448 case PIPE_POLYGON_MODE_POINT: 1449 return 0; 1450 default: 1451 assert(0); 1452 return 0; 1453 } 1454} 1455 1456unsigned r600_tex_wrap(unsigned wrap) 1457{ 1458 switch (wrap) { 1459 default: 1460 case PIPE_TEX_WRAP_REPEAT: 1461 return V_03C000_SQ_TEX_WRAP; 1462 case PIPE_TEX_WRAP_CLAMP: 1463 return V_03C000_SQ_TEX_CLAMP_HALF_BORDER; 1464 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: 1465 return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL; 1466 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: 1467 return V_03C000_SQ_TEX_CLAMP_BORDER; 1468 case PIPE_TEX_WRAP_MIRROR_REPEAT: 1469 return V_03C000_SQ_TEX_MIRROR; 1470 case PIPE_TEX_WRAP_MIRROR_CLAMP: 1471 return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER; 1472 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: 1473 return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; 1474 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: 1475 return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER; 1476 } 1477} 1478 1479unsigned r600_tex_filter(unsigned filter) 1480{ 1481 switch (filter) { 1482 default: 1483 case PIPE_TEX_FILTER_NEAREST: 1484 return V_03C000_SQ_TEX_XY_FILTER_POINT; 1485 case PIPE_TEX_FILTER_LINEAR: 1486 return V_03C000_SQ_TEX_XY_FILTER_BILINEAR; 1487 } 1488} 1489 1490unsigned r600_tex_mipfilter(unsigned filter) 1491{ 1492 switch (filter) { 1493 case PIPE_TEX_MIPFILTER_NEAREST: 1494 return V_03C000_SQ_TEX_Z_FILTER_POINT; 1495 case PIPE_TEX_MIPFILTER_LINEAR: 1496 return V_03C000_SQ_TEX_Z_FILTER_LINEAR; 1497 default: 1498 case PIPE_TEX_MIPFILTER_NONE: 1499 return V_03C000_SQ_TEX_Z_FILTER_NONE; 1500 } 1501} 1502 1503unsigned r600_tex_compare(unsigned compare) 1504{ 1505 switch (compare) { 1506 default: 1507 case PIPE_FUNC_NEVER: 1508 return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER; 1509 case PIPE_FUNC_LESS: 1510 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS; 1511 case PIPE_FUNC_EQUAL: 1512 return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL; 1513 case PIPE_FUNC_LEQUAL: 1514 return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; 1515 case PIPE_FUNC_GREATER: 1516 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER; 1517 case PIPE_FUNC_NOTEQUAL: 1518 return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; 1519 case PIPE_FUNC_GEQUAL: 1520 return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; 1521 case PIPE_FUNC_ALWAYS: 1522 return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS; 1523 } 1524} 1525