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