r300_render.c revision fccfb7b16512a36424370dc1942cdedd3d1c208a
1/* 2 * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com> 3 * Copyright 2010 Marek Olšák <maraeo@gmail.com> 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/* r300_render: Vertex and index buffer primitive emission. Contains both 25 * HW TCL fastpath rendering, and SW TCL Draw-assisted rendering. */ 26 27#include "draw/draw_context.h" 28#include "draw/draw_vbuf.h" 29 30#include "util/u_inlines.h" 31 32#include "util/u_format.h" 33#include "util/u_memory.h" 34#include "util/u_upload_mgr.h" 35#include "util/u_prim.h" 36 37#include "r300_cs.h" 38#include "r300_context.h" 39#include "r300_screen_buffer.h" 40#include "r300_emit.h" 41#include "r300_reg.h" 42#include "r300_state_derived.h" 43 44#include <limits.h> 45 46static uint32_t r300_translate_primitive(unsigned prim) 47{ 48 switch (prim) { 49 case PIPE_PRIM_POINTS: 50 return R300_VAP_VF_CNTL__PRIM_POINTS; 51 case PIPE_PRIM_LINES: 52 return R300_VAP_VF_CNTL__PRIM_LINES; 53 case PIPE_PRIM_LINE_LOOP: 54 return R300_VAP_VF_CNTL__PRIM_LINE_LOOP; 55 case PIPE_PRIM_LINE_STRIP: 56 return R300_VAP_VF_CNTL__PRIM_LINE_STRIP; 57 case PIPE_PRIM_TRIANGLES: 58 return R300_VAP_VF_CNTL__PRIM_TRIANGLES; 59 case PIPE_PRIM_TRIANGLE_STRIP: 60 return R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP; 61 case PIPE_PRIM_TRIANGLE_FAN: 62 return R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN; 63 case PIPE_PRIM_QUADS: 64 return R300_VAP_VF_CNTL__PRIM_QUADS; 65 case PIPE_PRIM_QUAD_STRIP: 66 return R300_VAP_VF_CNTL__PRIM_QUAD_STRIP; 67 case PIPE_PRIM_POLYGON: 68 return R300_VAP_VF_CNTL__PRIM_POLYGON; 69 default: 70 return 0; 71 } 72} 73 74static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300, 75 unsigned mode) 76{ 77 struct r300_rs_state* rs = (struct r300_rs_state*)r300->rs_state.state; 78 uint32_t color_control = rs->color_control; 79 80 /* By default (see r300_state.c:r300_create_rs_state) color_control is 81 * initialized to provoking the first vertex. 82 * 83 * Triangle fans must be reduced to the second vertex, not the first, in 84 * Gallium flatshade-first mode, as per the GL spec. 85 * (http://www.opengl.org/registry/specs/ARB/provoking_vertex.txt) 86 * 87 * Quads never provoke correctly in flatshade-first mode. The first 88 * vertex is never considered as provoking, so only the second, third, 89 * and fourth vertices can be selected, and both "third" and "last" modes 90 * select the fourth vertex. This is probably due to D3D lacking quads. 91 * 92 * Similarly, polygons reduce to the first, not the last, vertex, when in 93 * "last" mode, and all other modes start from the second vertex. 94 * 95 * ~ C. 96 */ 97 98 if (rs->rs.flatshade_first) { 99 switch (mode) { 100 case PIPE_PRIM_TRIANGLE_FAN: 101 color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND; 102 break; 103 case PIPE_PRIM_QUADS: 104 case PIPE_PRIM_QUAD_STRIP: 105 case PIPE_PRIM_POLYGON: 106 color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST; 107 break; 108 default: 109 color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_FIRST; 110 break; 111 } 112 } else { 113 color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST; 114 } 115 116 return color_control; 117} 118 119static boolean index_bias_supported(struct r300_context *r300) 120{ 121 return r300->screen->caps.is_r500 && 122 r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); 123} 124 125static void r500_emit_index_bias(struct r300_context *r300, int index_bias) 126{ 127 CS_LOCALS(r300); 128 129 BEGIN_CS(2); 130 OUT_CS_REG(R500_VAP_INDEX_OFFSET, 131 (index_bias & 0xFFFFFF) | (index_bias < 0 ? 1<<24 : 0)); 132 END_CS; 133} 134 135/* This function splits the index bias value into two parts: 136 * - buffer_offset: the value that can be safely added to buffer offsets 137 * in r300_emit_aos (it must yield a positive offset when added to 138 * a vertex buffer offset) 139 * - index_offset: the value that must be manually subtracted from indices 140 * in an index buffer to achieve negative offsets. */ 141static void r300_split_index_bias(struct r300_context *r300, int index_bias, 142 int *buffer_offset, int *index_offset) 143{ 144 struct pipe_vertex_buffer *vb, *vbufs = r300->vertex_buffer; 145 struct pipe_vertex_element *velem = r300->velems->velem; 146 unsigned i, size; 147 int max_neg_bias; 148 149 if (index_bias < 0) { 150 /* See how large index bias we may subtract. We must be careful 151 * here because negative buffer offsets are not allowed 152 * by the DRM API. */ 153 max_neg_bias = INT_MAX; 154 for (i = 0; i < r300->velems->count; i++) { 155 vb = &vbufs[velem[i].vertex_buffer_index]; 156 size = (vb->buffer_offset + velem[i].src_offset) / vb->stride; 157 max_neg_bias = MIN2(max_neg_bias, size); 158 } 159 160 /* Now set the minimum allowed value. */ 161 *buffer_offset = MAX2(-max_neg_bias, index_bias); 162 } else { 163 /* A positive index bias is OK. */ 164 *buffer_offset = index_bias; 165 } 166 167 *index_offset = index_bias - *buffer_offset; 168} 169 170enum r300_prepare_flags { 171 PREP_FIRST_DRAW = (1 << 0), /* call emit_dirty_state and friends? */ 172 PREP_VALIDATE_VBOS = (1 << 1), /* validate VBOs? */ 173 PREP_EMIT_AOS = (1 << 2), /* call emit_aos? */ 174 PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_aos_swtcl? */ 175 PREP_INDEXED = (1 << 4) /* is this draw_elements? */ 176}; 177 178/** 179 * Check if the requested number of dwords is available in the CS and 180 * if not, flush. Then validate buffers and emit dirty state. 181 * \param r300 The context. 182 * \param flags See r300_prepare_flags. 183 * \param index_buffer The index buffer to validate. The parameter may be NULL. 184 * \param cs_dwords The number of dwords to reserve in CS. 185 * \param aos_offset The offset passed to emit_aos. 186 * \param index_bias The index bias to emit. 187 * \param end_cs_dwords The number of free dwords which must be available 188 * at the end of CS after drawing in case the CS space 189 * management is performed by a draw_* function manually. 190 * The parameter may be NULL. 191 */ 192static void r300_prepare_for_rendering(struct r300_context *r300, 193 enum r300_prepare_flags flags, 194 struct pipe_resource *index_buffer, 195 unsigned cs_dwords, 196 int aos_offset, 197 int index_bias, 198 unsigned *end_cs_dwords) 199{ 200 unsigned end_dwords = 0; 201 boolean flushed = FALSE; 202 boolean first_draw = flags & PREP_FIRST_DRAW; 203 boolean emit_aos = flags & PREP_EMIT_AOS; 204 boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL; 205 boolean indexed = flags & PREP_INDEXED; 206 boolean hw_index_bias = index_bias_supported(r300); 207 208 /* Add dirty state, index offset, and AOS. */ 209 if (first_draw) { 210 cs_dwords += r300_get_num_dirty_dwords(r300); 211 212 if (hw_index_bias) 213 cs_dwords += 2; /* emit_index_offset */ 214 215 if (emit_aos) 216 cs_dwords += 55; /* emit_aos */ 217 218 if (emit_aos_swtcl) 219 cs_dwords += 7; /* emit_aos_swtcl */ 220 } 221 222 /* Emitted in flush. */ 223 end_dwords += 26; /* emit_query_end */ 224 225 cs_dwords += end_dwords; 226 227 /* Reserve requested CS space. */ 228 if (!r300_check_cs(r300, cs_dwords)) { 229 r300->context.flush(&r300->context, 0, NULL); 230 flushed = TRUE; 231 } 232 233 /* Validate buffers and emit dirty state if needed. */ 234 if (first_draw || flushed) { 235 r300_emit_buffer_validate(r300, flags & PREP_VALIDATE_VBOS, index_buffer); 236 r300_emit_dirty_state(r300); 237 if (hw_index_bias) { 238 if (r300->screen->caps.has_tcl) 239 r500_emit_index_bias(r300, index_bias); 240 else 241 r500_emit_index_bias(r300, 0); 242 } 243 244 if (emit_aos) 245 r300_emit_aos(r300, aos_offset, indexed); 246 247 if (emit_aos_swtcl) 248 r300_emit_aos_swtcl(r300, indexed); 249 } 250 251 if (end_cs_dwords) 252 *end_cs_dwords = end_dwords; 253} 254 255static boolean immd_is_good_idea(struct r300_context *r300, 256 unsigned count) 257{ 258 struct pipe_vertex_element* velem; 259 struct pipe_vertex_buffer* vbuf; 260 boolean checked[PIPE_MAX_ATTRIBS] = {0}; 261 unsigned vertex_element_count = r300->velems->count; 262 unsigned i, vbi; 263 264 if (DBG_ON(r300, DBG_NO_IMMD)) { 265 return FALSE; 266 } 267 268 if (r300->draw) { 269 return FALSE; 270 } 271 272 if (count > 10) { 273 return FALSE; 274 } 275 276 /* We shouldn't map buffers referenced by CS, busy buffers, 277 * and ones placed in VRAM. */ 278 /* XXX Check for VRAM buffers. */ 279 for (i = 0; i < vertex_element_count; i++) { 280 velem = &r300->velems->velem[i]; 281 vbi = velem->vertex_buffer_index; 282 283 if (!checked[vbi]) { 284 vbuf = &r300->vertex_buffer[vbi]; 285 286 if (r300_buffer_is_referenced(&r300->context, 287 vbuf->buffer, 288 R300_REF_CS | R300_REF_HW)) { 289 /* It's a very bad idea to map it... */ 290 return FALSE; 291 } 292 checked[vbi] = TRUE; 293 } 294 } 295 return TRUE; 296} 297 298/***************************************************************************** 299 * The emission of draw packets for r500. Older GPUs may use these functions * 300 * after resolving fallback issues (e.g. stencil ref two-sided). * 301 ****************************************************************************/ 302 303static void r300_emit_draw_arrays_immediate(struct r300_context *r300, 304 unsigned mode, 305 unsigned start, 306 unsigned count) 307{ 308 struct pipe_vertex_element* velem; 309 struct pipe_vertex_buffer* vbuf; 310 unsigned vertex_element_count = r300->velems->count; 311 unsigned i, v, vbi, dw, elem_offset, dwords; 312 313 /* Size of the vertex, in dwords. */ 314 unsigned vertex_size = 0; 315 316 /* Offsets of the attribute, in dwords, from the start of the vertex. */ 317 unsigned offset[PIPE_MAX_ATTRIBS]; 318 319 /* Size of the vertex element, in dwords. */ 320 unsigned size[PIPE_MAX_ATTRIBS]; 321 322 /* Stride to the same attrib in the next vertex in the vertex buffer, 323 * in dwords. */ 324 unsigned stride[PIPE_MAX_ATTRIBS] = {0}; 325 326 /* Mapped vertex buffers. */ 327 uint32_t* map[PIPE_MAX_ATTRIBS] = {0}; 328 struct pipe_transfer* transfer[PIPE_MAX_ATTRIBS] = {NULL}; 329 330 CS_LOCALS(r300); 331 332 /* Calculate the vertex size, offsets, strides etc. and map the buffers. */ 333 for (i = 0; i < vertex_element_count; i++) { 334 velem = &r300->velems->velem[i]; 335 offset[i] = velem->src_offset / 4; 336 size[i] = r300->velems->hw_format_size[i] / 4; 337 vertex_size += size[i]; 338 vbi = velem->vertex_buffer_index; 339 340 /* Map the buffer. */ 341 if (!map[vbi]) { 342 vbuf = &r300->vertex_buffer[vbi]; 343 map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context, 344 vbuf->buffer, 345 PIPE_TRANSFER_READ, 346 &transfer[vbi]); 347 map[vbi] += vbuf->buffer_offset / 4; 348 stride[vbi] = vbuf->stride / 4; 349 } 350 } 351 352 dwords = 9 + count * vertex_size; 353 354 r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL); 355 356 BEGIN_CS(dwords); 357 OUT_CS_REG(R300_GA_COLOR_CONTROL, 358 r300_provoking_vertex_fixes(r300, mode)); 359 OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); 360 OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); 361 OUT_CS(count - 1); 362 OUT_CS(0); 363 OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size); 364 OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) | 365 r300_translate_primitive(mode)); 366 367 /* Emit vertices. */ 368 for (v = 0; v < count; v++) { 369 for (i = 0; i < vertex_element_count; i++) { 370 velem = &r300->velems->velem[i]; 371 vbi = velem->vertex_buffer_index; 372 elem_offset = offset[i] + stride[vbi] * (v + start); 373 374 for (dw = 0; dw < size[i]; dw++) { 375 OUT_CS(map[vbi][elem_offset + dw]); 376 } 377 } 378 } 379 END_CS; 380 381 /* Unmap buffers. */ 382 for (i = 0; i < vertex_element_count; i++) { 383 vbi = r300->velems->velem[i].vertex_buffer_index; 384 385 if (map[vbi]) { 386 vbuf = &r300->vertex_buffer[vbi]; 387 pipe_buffer_unmap(&r300->context, vbuf->buffer, transfer[vbi]); 388 map[vbi] = NULL; 389 } 390 } 391} 392 393static void r300_emit_draw_arrays(struct r300_context *r300, 394 unsigned mode, 395 unsigned count) 396{ 397 boolean alt_num_verts = count > 65535; 398 CS_LOCALS(r300); 399 400 if (count >= (1 << 24)) { 401 fprintf(stderr, "r300: Got a huge number of vertices: %i, " 402 "refusing to render.\n", count); 403 return; 404 } 405 406 BEGIN_CS(7 + (alt_num_verts ? 2 : 0)); 407 if (alt_num_verts) { 408 OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); 409 } 410 OUT_CS_REG(R300_GA_COLOR_CONTROL, 411 r300_provoking_vertex_fixes(r300, mode)); 412 OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); 413 OUT_CS(count - 1); 414 OUT_CS(0); 415 OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); 416 OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | 417 r300_translate_primitive(mode) | 418 (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); 419 END_CS; 420} 421 422static void r300_emit_draw_elements(struct r300_context *r300, 423 struct pipe_resource* indexBuffer, 424 unsigned indexSize, 425 unsigned minIndex, 426 unsigned maxIndex, 427 unsigned mode, 428 unsigned start, 429 unsigned count) 430{ 431 uint32_t count_dwords; 432 uint32_t offset_dwords = indexSize * start / sizeof(uint32_t); 433 boolean alt_num_verts = count > 65535; 434 CS_LOCALS(r300); 435 436 if (count >= (1 << 24)) { 437 fprintf(stderr, "r300: Got a huge number of vertices: %i, " 438 "refusing to render.\n", count); 439 return; 440 } 441 442 maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); 443 444 DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", 445 count, minIndex, maxIndex); 446 447 BEGIN_CS(13 + (alt_num_verts ? 2 : 0)); 448 if (alt_num_verts) { 449 OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count); 450 } 451 OUT_CS_REG(R300_GA_COLOR_CONTROL, 452 r300_provoking_vertex_fixes(r300, mode)); 453 OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2); 454 OUT_CS(maxIndex); 455 OUT_CS(minIndex); 456 OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0); 457 if (indexSize == 4) { 458 count_dwords = count; 459 OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | 460 R300_VAP_VF_CNTL__INDEX_SIZE_32bit | 461 r300_translate_primitive(mode) | 462 (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); 463 } else { 464 count_dwords = (count + 1) / 2; 465 OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | 466 r300_translate_primitive(mode) | 467 (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0)); 468 } 469 470 /* INDX_BUFFER is a truly special packet3. 471 * Unlike most other packet3, where the offset is after the count, 472 * the order is reversed, so the relocation ends up carrying the 473 * size of the indexbuf instead of the offset. 474 */ 475 OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2); 476 OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) | 477 (0 << R300_INDX_BUFFER_SKIP_SHIFT)); 478 OUT_CS(offset_dwords << 2); 479 OUT_CS_BUF_RELOC(indexBuffer, count_dwords, 480 r300_buffer(indexBuffer)->domain, 0, 0); 481 482 END_CS; 483} 484 485static void r300_shorten_ubyte_elts(struct r300_context* r300, 486 struct pipe_resource** elts, 487 int index_bias, 488 unsigned start, 489 unsigned count) 490{ 491 struct pipe_context* context = &r300->context; 492 struct pipe_screen* screen = r300->context.screen; 493 struct pipe_resource* new_elts; 494 unsigned char *in_map; 495 unsigned short *out_map; 496 struct pipe_transfer *src_transfer, *dst_transfer; 497 unsigned i; 498 499 new_elts = pipe_buffer_create(screen, 500 PIPE_BIND_INDEX_BUFFER, 501 2 * count); 502 503 in_map = pipe_buffer_map(context, *elts, PIPE_TRANSFER_READ, &src_transfer); 504 out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, &dst_transfer); 505 506 in_map += start; 507 508 for (i = 0; i < count; i++) { 509 *out_map = (unsigned short)(*in_map + index_bias); 510 in_map++; 511 out_map++; 512 } 513 514 pipe_buffer_unmap(context, *elts, src_transfer); 515 pipe_buffer_unmap(context, new_elts, dst_transfer); 516 517 *elts = new_elts; 518} 519 520static void r300_rebuild_ushort_elts(struct r300_context *r300, 521 struct pipe_resource **elts, 522 int index_bias, 523 unsigned start, unsigned count) 524{ 525 struct pipe_context *context = &r300->context; 526 struct pipe_transfer *in_transfer = NULL; 527 struct pipe_transfer *out_transfer = NULL; 528 struct pipe_resource *new_elts; 529 unsigned short *in_map; 530 unsigned short *out_map; 531 unsigned i; 532 533 new_elts = pipe_buffer_create(context->screen, 534 PIPE_BIND_INDEX_BUFFER, 535 2 * count); 536 537 in_map = pipe_buffer_map(context, *elts, 538 PIPE_TRANSFER_READ, &in_transfer); 539 out_map = pipe_buffer_map(context, new_elts, 540 PIPE_TRANSFER_WRITE, &out_transfer); 541 542 in_map += start; 543 for (i = 0; i < count; i++) { 544 *out_map = (unsigned short)(*in_map + index_bias); 545 in_map++; 546 out_map++; 547 } 548 549 pipe_buffer_unmap(context, *elts, in_transfer); 550 pipe_buffer_unmap(context, new_elts, out_transfer); 551 552 *elts = new_elts; 553} 554 555static void r300_rebuild_uint_elts(struct r300_context *r300, 556 struct pipe_resource **elts, 557 int index_bias, 558 unsigned start, unsigned count) 559{ 560 struct pipe_context *context = &r300->context; 561 struct pipe_transfer *in_transfer = NULL; 562 struct pipe_transfer *out_transfer = NULL; 563 struct pipe_resource *new_elts; 564 unsigned int *in_map; 565 unsigned int *out_map; 566 unsigned i; 567 568 new_elts = pipe_buffer_create(context->screen, 569 PIPE_BIND_INDEX_BUFFER, 570 2 * count); 571 572 in_map = pipe_buffer_map(context, *elts, 573 PIPE_TRANSFER_READ, &in_transfer); 574 out_map = pipe_buffer_map(context, new_elts, 575 PIPE_TRANSFER_WRITE, &out_transfer); 576 577 in_map += start; 578 for (i = 0; i < count; i++) { 579 *out_map = (unsigned int)(*in_map + index_bias); 580 in_map++; 581 out_map++; 582 } 583 584 pipe_buffer_unmap(context, *elts, in_transfer); 585 pipe_buffer_unmap(context, new_elts, out_transfer); 586 587 *elts = new_elts; 588} 589 590/* This is the fast-path drawing & emission for HW TCL. */ 591static void r300_draw_range_elements(struct pipe_context* pipe, 592 struct pipe_resource* indexBuffer, 593 unsigned indexSize, 594 int indexBias, 595 unsigned minIndex, 596 unsigned maxIndex, 597 unsigned mode, 598 unsigned start, 599 unsigned count) 600{ 601 struct r300_context* r300 = r300_context(pipe); 602 struct pipe_resource* orgIndexBuffer = indexBuffer; 603 boolean alt_num_verts = r300->screen->caps.is_r500 && 604 count > 65536 && 605 r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); 606 unsigned short_count; 607 int buffer_offset = 0, index_offset = 0; /* for index bias emulation */ 608 609 if (r300->skip_rendering) { 610 return; 611 } 612 613 if (r300->incompatible_vb_layout || 614 r300->velems->incompatible_layout) { 615 return; 616 } 617 618 if (!u_trim_pipe_prim(mode, &count)) { 619 return; 620 } 621 622 if (indexBias && !index_bias_supported(r300)) { 623 r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset); 624 } 625 626 /* Rebuild the index buffer if needed. */ 627 switch (indexSize) { 628 case 1: 629 r300_shorten_ubyte_elts(r300, &indexBuffer, index_offset, start, count); 630 indexSize = 2; 631 start = 0; 632 break; 633 634 case 2: 635 if (start % 2 != 0 || index_offset) { 636 r300_rebuild_ushort_elts(r300, &indexBuffer, index_offset, start, count); 637 start = 0; 638 } 639 break; 640 641 case 4: 642 if (index_offset) { 643 r300_rebuild_uint_elts(r300, &indexBuffer, index_offset, start, count); 644 start = 0; 645 } 646 break; 647 } 648 649 r300_update_derived_state(r300); 650 r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count); 651 652 /* 15 dwords for emit_draw_elements */ 653 r300_prepare_for_rendering(r300, 654 PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, 655 indexBuffer, 15, buffer_offset, indexBias, NULL); 656 657 u_upload_flush(r300->upload_vb); 658 u_upload_flush(r300->upload_ib); 659 if (alt_num_verts || count <= 65535) { 660 r300_emit_draw_elements(r300, indexBuffer, indexSize, 661 minIndex, maxIndex, mode, start, count); 662 } else { 663 do { 664 short_count = MIN2(count, 65534); 665 r300_emit_draw_elements(r300, indexBuffer, indexSize, 666 minIndex, maxIndex, 667 mode, start, short_count); 668 669 start += short_count; 670 count -= short_count; 671 672 /* 15 dwords for emit_draw_elements */ 673 if (count) { 674 r300_prepare_for_rendering(r300, 675 PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, 676 indexBuffer, 15, buffer_offset, indexBias, NULL); 677 } 678 } while (count); 679 } 680 681 if (indexBuffer != orgIndexBuffer) { 682 pipe_resource_reference( &indexBuffer, NULL ); 683 } 684} 685 686/* Simple helpers for context setup. Should probably be moved to util. */ 687static void r300_draw_elements(struct pipe_context* pipe, 688 struct pipe_resource* indexBuffer, 689 unsigned indexSize, int indexBias, unsigned mode, 690 unsigned start, unsigned count) 691{ 692 struct r300_context *r300 = r300_context(pipe); 693 694 pipe->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, 695 0, r300->vertex_buffer_max_index, 696 mode, start, count); 697} 698 699static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, 700 unsigned start, unsigned count) 701{ 702 struct r300_context* r300 = r300_context(pipe); 703 boolean alt_num_verts = r300->screen->caps.is_r500 && 704 count > 65536 && 705 r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); 706 unsigned short_count; 707 708 if (r300->skip_rendering) { 709 return; 710 } 711 712 if (r300->incompatible_vb_layout || 713 r300->velems->incompatible_layout) { 714 return; 715 } 716 717 if (!u_trim_pipe_prim(mode, &count)) { 718 return; 719 } 720 721 r300_update_derived_state(r300); 722 723 if (immd_is_good_idea(r300, count)) { 724 r300_emit_draw_arrays_immediate(r300, mode, start, count); 725 } else { 726 /* 9 spare dwords for emit_draw_arrays. */ 727 r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, 728 NULL, 9, start, 0, NULL); 729 730 if (alt_num_verts || count <= 65535) { 731 r300_emit_draw_arrays(r300, mode, count); 732 } else { 733 do { 734 short_count = MIN2(count, 65535); 735 r300_emit_draw_arrays(r300, mode, short_count); 736 737 start += short_count; 738 count -= short_count; 739 740 /* 9 spare dwords for emit_draw_arrays. */ 741 if (count) { 742 r300_prepare_for_rendering(r300, 743 PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, 744 start, 0, NULL); 745 } 746 } while (count); 747 } 748 u_upload_flush(r300->upload_vb); 749 } 750} 751 752/**************************************************************************** 753 * The rest of this file is for SW TCL rendering only. Please be polite and * 754 * keep these functions separated so that they are easier to locate. ~C. * 755 ***************************************************************************/ 756 757/* SW TCL arrays, using Draw. */ 758static void r300_swtcl_draw_arrays(struct pipe_context* pipe, 759 unsigned mode, 760 unsigned start, 761 unsigned count) 762{ 763 struct r300_context* r300 = r300_context(pipe); 764 struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; 765 int i; 766 767 if (r300->skip_rendering) { 768 return; 769 } 770 771 if (!u_trim_pipe_prim(mode, &count)) { 772 return; 773 } 774 775 r300_update_derived_state(r300); 776 777 for (i = 0; i < r300->vertex_buffer_count; i++) { 778 void* buf = pipe_buffer_map(pipe, 779 r300->vertex_buffer[i].buffer, 780 PIPE_TRANSFER_READ, 781 &vb_transfer[i]); 782 draw_set_mapped_vertex_buffer(r300->draw, i, buf); 783 } 784 785 draw_set_mapped_element_buffer(r300->draw, 0, 0, NULL); 786 787 draw_arrays(r300->draw, mode, start, count); 788 789 /* XXX Not sure whether this is the best fix. 790 * It prevents CS from being rejected and weird assertion failures. */ 791 draw_flush(r300->draw); 792 793 for (i = 0; i < r300->vertex_buffer_count; i++) { 794 pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, 795 vb_transfer[i]); 796 draw_set_mapped_vertex_buffer(r300->draw, i, NULL); 797 } 798} 799 800/* SW TCL elements, using Draw. */ 801static void r300_swtcl_draw_range_elements(struct pipe_context* pipe, 802 struct pipe_resource* indexBuffer, 803 unsigned indexSize, 804 int indexBias, 805 unsigned minIndex, 806 unsigned maxIndex, 807 unsigned mode, 808 unsigned start, 809 unsigned count) 810{ 811 struct r300_context* r300 = r300_context(pipe); 812 struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; 813 struct pipe_transfer *ib_transfer; 814 int i; 815 void* indices; 816 817 if (r300->skip_rendering) { 818 return; 819 } 820 821 if (!u_trim_pipe_prim(mode, &count)) { 822 return; 823 } 824 825 r300_update_derived_state(r300); 826 827 for (i = 0; i < r300->vertex_buffer_count; i++) { 828 void* buf = pipe_buffer_map(pipe, 829 r300->vertex_buffer[i].buffer, 830 PIPE_TRANSFER_READ, 831 &vb_transfer[i]); 832 draw_set_mapped_vertex_buffer(r300->draw, i, buf); 833 } 834 835 indices = pipe_buffer_map(pipe, indexBuffer, 836 PIPE_TRANSFER_READ, &ib_transfer); 837 draw_set_mapped_element_buffer_range(r300->draw, indexSize, indexBias, 838 minIndex, maxIndex, indices); 839 840 draw_arrays(r300->draw, mode, start, count); 841 842 /* XXX Not sure whether this is the best fix. 843 * It prevents CS from being rejected and weird assertion failures. */ 844 draw_flush(r300->draw); 845 846 for (i = 0; i < r300->vertex_buffer_count; i++) { 847 pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, 848 vb_transfer[i]); 849 draw_set_mapped_vertex_buffer(r300->draw, i, NULL); 850 } 851 852 pipe_buffer_unmap(pipe, indexBuffer, 853 ib_transfer); 854 draw_set_mapped_element_buffer_range(r300->draw, 0, 0, 855 start, start + count - 1, 856 NULL); 857} 858 859/* Object for rendering using Draw. */ 860struct r300_render { 861 /* Parent class */ 862 struct vbuf_render base; 863 864 /* Pipe context */ 865 struct r300_context* r300; 866 867 /* Vertex information */ 868 size_t vertex_size; 869 unsigned prim; 870 unsigned hwprim; 871 872 /* VBO */ 873 struct pipe_resource* vbo; 874 size_t vbo_size; 875 size_t vbo_offset; 876 size_t vbo_max_used; 877 void * vbo_ptr; 878 879 struct pipe_transfer *vbo_transfer; 880}; 881 882static INLINE struct r300_render* 883r300_render(struct vbuf_render* render) 884{ 885 return (struct r300_render*)render; 886} 887 888static const struct vertex_info* 889r300_render_get_vertex_info(struct vbuf_render* render) 890{ 891 struct r300_render* r300render = r300_render(render); 892 struct r300_context* r300 = r300render->r300; 893 894 return &r300->vertex_info; 895} 896 897static boolean r300_render_allocate_vertices(struct vbuf_render* render, 898 ushort vertex_size, 899 ushort count) 900{ 901 struct r300_render* r300render = r300_render(render); 902 struct r300_context* r300 = r300render->r300; 903 struct pipe_screen* screen = r300->context.screen; 904 size_t size = (size_t)vertex_size * (size_t)count; 905 906 if (size + r300render->vbo_offset > r300render->vbo_size) 907 { 908 pipe_resource_reference(&r300->vbo, NULL); 909 r300render->vbo = pipe_buffer_create(screen, 910 PIPE_BIND_VERTEX_BUFFER, 911 R300_MAX_DRAW_VBO_SIZE); 912 r300render->vbo_offset = 0; 913 r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE; 914 } 915 916 r300render->vertex_size = vertex_size; 917 r300->vbo = r300render->vbo; 918 r300->vbo_offset = r300render->vbo_offset; 919 920 return (r300render->vbo) ? TRUE : FALSE; 921} 922 923static void* r300_render_map_vertices(struct vbuf_render* render) 924{ 925 struct r300_render* r300render = r300_render(render); 926 927 assert(!r300render->vbo_transfer); 928 929 r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context, 930 r300render->vbo, 931 PIPE_TRANSFER_WRITE, 932 &r300render->vbo_transfer); 933 934 return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset); 935} 936 937static void r300_render_unmap_vertices(struct vbuf_render* render, 938 ushort min, 939 ushort max) 940{ 941 struct r300_render* r300render = r300_render(render); 942 struct pipe_context* context = &r300render->r300->context; 943 944 assert(r300render->vbo_transfer); 945 946 r300render->vbo_max_used = MAX2(r300render->vbo_max_used, 947 r300render->vertex_size * (max + 1)); 948 pipe_buffer_unmap(context, r300render->vbo, r300render->vbo_transfer); 949 950 r300render->vbo_transfer = NULL; 951} 952 953static void r300_render_release_vertices(struct vbuf_render* render) 954{ 955 struct r300_render* r300render = r300_render(render); 956 957 r300render->vbo_offset += r300render->vbo_max_used; 958 r300render->vbo_max_used = 0; 959} 960 961static boolean r300_render_set_primitive(struct vbuf_render* render, 962 unsigned prim) 963{ 964 struct r300_render* r300render = r300_render(render); 965 966 r300render->prim = prim; 967 r300render->hwprim = r300_translate_primitive(prim); 968 969 return TRUE; 970} 971 972static void r300_render_draw_arrays(struct vbuf_render* render, 973 unsigned start, 974 unsigned count) 975{ 976 struct r300_render* r300render = r300_render(render); 977 struct r300_context* r300 = r300render->r300; 978 uint8_t* ptr; 979 unsigned i; 980 unsigned dwords = 6; 981 982 CS_LOCALS(r300); 983 984 (void) i; (void) ptr; 985 986 r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, 987 NULL, dwords, 0, 0, NULL); 988 989 DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count); 990 991 /* Uncomment to dump all VBOs rendered through this interface. 992 * Slow and noisy! 993 ptr = pipe_buffer_map(&r300render->r300->context, 994 r300render->vbo, PIPE_TRANSFER_READ, 995 &r300render->vbo_transfer); 996 997 for (i = 0; i < count; i++) { 998 printf("r300: Vertex %d\n", i); 999 draw_dump_emitted_vertex(&r300->vertex_info, ptr); 1000 ptr += r300->vertex_info.size * 4; 1001 printf("\n"); 1002 } 1003 1004 pipe_buffer_unmap(&r300render->r300->context, r300render->vbo, 1005 r300render->vbo_transfer); 1006 */ 1007 1008 BEGIN_CS(dwords); 1009 OUT_CS_REG(R300_GA_COLOR_CONTROL, 1010 r300_provoking_vertex_fixes(r300, r300render->prim)); 1011 OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1); 1012 OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0); 1013 OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) | 1014 r300render->hwprim); 1015 END_CS; 1016} 1017 1018static void r300_render_draw_elements(struct vbuf_render* render, 1019 const ushort* indices, 1020 uint count) 1021{ 1022 struct r300_render* r300render = r300_render(render); 1023 struct r300_context* r300 = r300render->r300; 1024 int i; 1025 unsigned end_cs_dwords; 1026 unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) / 1027 (r300render->r300->vertex_info.size * 4) - 1; 1028 unsigned short_count; 1029 struct r300_cs_info cs_info; 1030 1031 CS_LOCALS(r300); 1032 1033 /* Reserve at least 256 dwords. 1034 * 1035 * Below we manage the CS space manually because there may be more 1036 * indices than it can fit in CS. */ 1037 r300_prepare_for_rendering(r300, 1038 PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, 1039 NULL, 256, 0, 0, &end_cs_dwords); 1040 1041 while (count) { 1042 r300->rws->get_cs_info(r300->rws, &cs_info); 1043 1044 short_count = MIN2(count, (cs_info.free - end_cs_dwords - 6) * 2); 1045 1046 BEGIN_CS(6 + (short_count+1)/2); 1047 OUT_CS_REG(R300_GA_COLOR_CONTROL, 1048 r300_provoking_vertex_fixes(r300, r300render->prim)); 1049 OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index); 1050 OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (short_count+1)/2); 1051 OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (short_count << 16) | 1052 r300render->hwprim); 1053 for (i = 0; i < short_count-1; i += 2) { 1054 OUT_CS(indices[i+1] << 16 | indices[i]); 1055 } 1056 if (short_count % 2) { 1057 OUT_CS(indices[short_count-1]); 1058 } 1059 END_CS; 1060 1061 /* OK now subtract the emitted indices and see if we need to emit 1062 * another draw packet. */ 1063 indices += short_count; 1064 count -= short_count; 1065 1066 if (count) { 1067 r300_prepare_for_rendering(r300, 1068 PREP_EMIT_AOS_SWTCL | PREP_INDEXED, 1069 NULL, 256, 0, 0, &end_cs_dwords); 1070 } 1071 } 1072} 1073 1074static void r300_render_destroy(struct vbuf_render* render) 1075{ 1076 FREE(render); 1077} 1078 1079static struct vbuf_render* r300_render_create(struct r300_context* r300) 1080{ 1081 struct r300_render* r300render = CALLOC_STRUCT(r300_render); 1082 1083 r300render->r300 = r300; 1084 1085 /* XXX find real numbers plz */ 1086 r300render->base.max_vertex_buffer_bytes = 128 * 1024; 1087 r300render->base.max_indices = 16 * 1024; 1088 1089 r300render->base.get_vertex_info = r300_render_get_vertex_info; 1090 r300render->base.allocate_vertices = r300_render_allocate_vertices; 1091 r300render->base.map_vertices = r300_render_map_vertices; 1092 r300render->base.unmap_vertices = r300_render_unmap_vertices; 1093 r300render->base.set_primitive = r300_render_set_primitive; 1094 r300render->base.draw_elements = r300_render_draw_elements; 1095 r300render->base.draw_arrays = r300_render_draw_arrays; 1096 r300render->base.release_vertices = r300_render_release_vertices; 1097 r300render->base.destroy = r300_render_destroy; 1098 1099 r300render->vbo = NULL; 1100 r300render->vbo_size = 0; 1101 r300render->vbo_offset = 0; 1102 1103 return &r300render->base; 1104} 1105 1106struct draw_stage* r300_draw_stage(struct r300_context* r300) 1107{ 1108 struct vbuf_render* render; 1109 struct draw_stage* stage; 1110 1111 render = r300_render_create(r300); 1112 1113 if (!render) { 1114 return NULL; 1115 } 1116 1117 stage = draw_vbuf_stage(r300->draw, render); 1118 1119 if (!stage) { 1120 render->destroy(render); 1121 return NULL; 1122 } 1123 1124 draw_set_render(r300->draw, render); 1125 1126 return stage; 1127} 1128 1129/**************************************************************************** 1130 * Two-sided stencil reference value fallback. It's designed to be as much 1131 * separate from rest of the driver as possible. 1132 ***************************************************************************/ 1133 1134struct r300_stencilref_context { 1135 void (*draw_arrays)(struct pipe_context *pipe, 1136 unsigned mode, unsigned start, unsigned count); 1137 1138 void (*draw_range_elements)( 1139 struct pipe_context *pipe, struct pipe_resource *indexBuffer, 1140 unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex, 1141 unsigned mode, unsigned start, unsigned count); 1142 1143 uint32_t rs_cull_mode; 1144 uint32_t zb_stencilrefmask; 1145 ubyte ref_value_front; 1146}; 1147 1148static boolean r300_stencilref_needed(struct r300_context *r300) 1149{ 1150 struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state; 1151 1152 return dsa->two_sided_stencil_ref || 1153 (dsa->two_sided && 1154 r300->stencil_ref.ref_value[0] != r300->stencil_ref.ref_value[1]); 1155} 1156 1157/* Set drawing for front faces. */ 1158static void r300_stencilref_begin(struct r300_context *r300) 1159{ 1160 struct r300_stencilref_context *sr = r300->stencilref_fallback; 1161 struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state; 1162 struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state; 1163 1164 /* Save state. */ 1165 sr->rs_cull_mode = rs->cull_mode; 1166 sr->zb_stencilrefmask = dsa->stencil_ref_mask; 1167 sr->ref_value_front = r300->stencil_ref.ref_value[0]; 1168 1169 /* We *cull* pixels, therefore no need to mask out the bits. */ 1170 rs->cull_mode |= R300_CULL_BACK; 1171 1172 r300->rs_state.dirty = TRUE; 1173} 1174 1175/* Set drawing for back faces. */ 1176static void r300_stencilref_switch_side(struct r300_context *r300) 1177{ 1178 struct r300_stencilref_context *sr = r300->stencilref_fallback; 1179 struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state; 1180 struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state; 1181 1182 rs->cull_mode = sr->rs_cull_mode | R300_CULL_FRONT; 1183 dsa->stencil_ref_mask = dsa->stencil_ref_bf; 1184 r300->stencil_ref.ref_value[0] = r300->stencil_ref.ref_value[1]; 1185 1186 r300->rs_state.dirty = TRUE; 1187 r300->dsa_state.dirty = TRUE; 1188} 1189 1190/* Restore the original state. */ 1191static void r300_stencilref_end(struct r300_context *r300) 1192{ 1193 struct r300_stencilref_context *sr = r300->stencilref_fallback; 1194 struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state; 1195 struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state; 1196 1197 /* Restore state. */ 1198 rs->cull_mode = sr->rs_cull_mode; 1199 dsa->stencil_ref_mask = sr->zb_stencilrefmask; 1200 r300->stencil_ref.ref_value[0] = sr->ref_value_front; 1201 1202 r300->rs_state.dirty = TRUE; 1203 r300->dsa_state.dirty = TRUE; 1204} 1205 1206static void r300_stencilref_draw_arrays(struct pipe_context *pipe, unsigned mode, 1207 unsigned start, unsigned count) 1208{ 1209 struct r300_context *r300 = r300_context(pipe); 1210 struct r300_stencilref_context *sr = r300->stencilref_fallback; 1211 1212 if (!r300_stencilref_needed(r300)) { 1213 sr->draw_arrays(pipe, mode, start, count); 1214 } else { 1215 r300_stencilref_begin(r300); 1216 sr->draw_arrays(pipe, mode, start, count); 1217 r300_stencilref_switch_side(r300); 1218 sr->draw_arrays(pipe, mode, start, count); 1219 r300_stencilref_end(r300); 1220 } 1221} 1222 1223static void r300_stencilref_draw_range_elements( 1224 struct pipe_context *pipe, struct pipe_resource *indexBuffer, 1225 unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex, 1226 unsigned mode, unsigned start, unsigned count) 1227{ 1228 struct r300_context *r300 = r300_context(pipe); 1229 struct r300_stencilref_context *sr = r300->stencilref_fallback; 1230 1231 if (!r300_stencilref_needed(r300)) { 1232 sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, 1233 minIndex, maxIndex, mode, start, count); 1234 } else { 1235 r300_stencilref_begin(r300); 1236 sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, 1237 minIndex, maxIndex, mode, start, count); 1238 r300_stencilref_switch_side(r300); 1239 sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, 1240 minIndex, maxIndex, mode, start, count); 1241 r300_stencilref_end(r300); 1242 } 1243} 1244 1245static void r300_plug_in_stencil_ref_fallback(struct r300_context *r300) 1246{ 1247 r300->stencilref_fallback = CALLOC_STRUCT(r300_stencilref_context); 1248 1249 /* Save original draw functions. */ 1250 r300->stencilref_fallback->draw_arrays = r300->context.draw_arrays; 1251 r300->stencilref_fallback->draw_range_elements = r300->context.draw_range_elements; 1252 1253 /* Override the draw functions. */ 1254 r300->context.draw_arrays = r300_stencilref_draw_arrays; 1255 r300->context.draw_range_elements = r300_stencilref_draw_range_elements; 1256} 1257 1258void r300_init_render_functions(struct r300_context *r300) 1259{ 1260 /* Set generic functions. */ 1261 r300->context.draw_elements = r300_draw_elements; 1262 1263 /* Set draw functions based on presence of HW TCL. */ 1264 if (r300->screen->caps.has_tcl) { 1265 r300->context.draw_arrays = r300_draw_arrays; 1266 r300->context.draw_range_elements = r300_draw_range_elements; 1267 } else { 1268 r300->context.draw_arrays = r300_swtcl_draw_arrays; 1269 r300->context.draw_range_elements = r300_swtcl_draw_range_elements; 1270 } 1271 1272 /* Plug in two-sided stencil reference value fallback if needed. */ 1273 if (!r300->screen->caps.is_r500) 1274 r300_plug_in_stencil_ref_fallback(r300); 1275} 1276