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