r300_render.c revision 0b3270b9b72c2ca4fad172752045d8fa93c1ad6e
1ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj/*
2ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
3752f90673ebbb6b2f55fc5e46606dea371313713sewardj * Copyright 2010 Marek Olšák <maraeo@gmail.com>
4ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj *
5ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj * Permission is hereby granted, free of charge, to any person obtaining a
6f8ed9d874a7b8651654591c68c6d431c758d787csewardj * copy of this software and associated documentation files (the "Software"),
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj * to deal in the Software without restriction, including without limitation
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj * on the rights to use, copy, modify, merge, publish, distribute, sub
9f8ed9d874a7b8651654591c68c6d431c758d787csewardj * license, and/or sell copies of the Software, and to permit persons to whom
1025e547391785959e81250091bf76d91ca30ef3bfsewardj * the Software is furnished to do so, subject to the following conditions:
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj *
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj * The above copyright notice and this permission notice (including the next
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj * paragraph) shall be included in all copies or substantial portions of the
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj * Software.
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj *
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj/* r300_render: Vertex and index buffer primitive emission. Contains both
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj * HW TCL fastpath rendering, and SW TCL Draw-assisted rendering. */
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj#include "draw/draw_context.h"
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj#include "draw/draw_vbuf.h"
29f8ed9d874a7b8651654591c68c6d431c758d787csewardj
30f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include "util/u_inlines.h"
31f8ed9d874a7b8651654591c68c6d431c758d787csewardj
32f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include "util/u_format.h"
33f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include "util/u_memory.h"
34f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include "util/u_upload_mgr.h"
35f8ed9d874a7b8651654591c68c6d431c758d787csewardj#include "util/u_prim.h"
36887a11a609f3e61d2ae8fe4e67f176207715da7esewardj
37887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include "r300_cs.h"
38ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj#include "r300_context.h"
39887a11a609f3e61d2ae8fe4e67f176207715da7esewardj#include "r300_screen_buffer.h"
40ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj#include "r300_emit.h"
4157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include "r300_reg.h"
42ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
4357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#include <limits.h>
4457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
4557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj#define IMMD_DWORDS 32
4657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
4757c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic uint32_t r300_translate_primitive(unsigned prim)
4857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{
4957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    static const int prim_conv[] = {
5057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        R300_VAP_VF_CNTL__PRIM_POINTS,
5157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        R300_VAP_VF_CNTL__PRIM_LINES,
5257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        R300_VAP_VF_CNTL__PRIM_LINE_LOOP,
53dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        R300_VAP_VF_CNTL__PRIM_LINE_STRIP,
54dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        R300_VAP_VF_CNTL__PRIM_TRIANGLES,
55dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP,
56dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN,
5757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        R300_VAP_VF_CNTL__PRIM_QUADS,
58dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        R300_VAP_VF_CNTL__PRIM_QUAD_STRIP,
5957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        R300_VAP_VF_CNTL__PRIM_POLYGON,
60dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        -1,
6157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        -1,
62dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        -1,
63dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        -1
64dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    };
65dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    unsigned hwprim = prim_conv[prim];
6657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
6757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    assert(hwprim != -1);
6857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    return hwprim;
6957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}
7057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
7157c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
7257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                                            unsigned mode)
7357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{
7457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    struct r300_rs_state* rs = (struct r300_rs_state*)r300->rs_state.state;
7557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    uint32_t color_control = rs->color_control;
7657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
7757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    /* By default (see r300_state.c:r300_create_rs_state) color_control is
7857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * initialized to provoking the first vertex.
7957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     *
8057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * Triangle fans must be reduced to the second vertex, not the first, in
8157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * Gallium flatshade-first mode, as per the GL spec.
8257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * (http://www.opengl.org/registry/specs/ARB/provoking_vertex.txt)
8357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     *
8457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * Quads never provoke correctly in flatshade-first mode. The first
8557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * vertex is never considered as provoking, so only the second, third,
8657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * and fourth vertices can be selected, and both "third" and "last" modes
8757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * select the fourth vertex. This is probably due to D3D lacking quads.
8857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     *
8957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * Similarly, polygons reduce to the first, not the last, vertex, when in
9057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * "last" mode, and all other modes start from the second vertex.
9157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     *
9257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj     * ~ C.
93dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj     */
94dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj
95dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    if (rs->rs.flatshade_first) {
96dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj        switch (mode) {
97dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            case PIPE_PRIM_TRIANGLE_FAN:
9857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND;
9957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                break;
10057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            case PIPE_PRIM_QUADS:
10157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            case PIPE_PRIM_QUAD_STRIP:
10257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            case PIPE_PRIM_POLYGON:
10357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
10457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                break;
10557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            default:
10657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_FIRST;
1072f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                break;
10857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        }
10957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    } else {
11057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
11157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    }
11257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
11357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    return color_control;
11457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}
11557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
11657c10c89904f7fdc4244fcbf704625e7169aafe6sewardjvoid r500_emit_index_bias(struct r300_context *r300, int index_bias)
11757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{
11857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    CS_LOCALS(r300);
11957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
12057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    BEGIN_CS(2);
12157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    OUT_CS_REG(R500_VAP_INDEX_OFFSET,
12257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj               (index_bias & 0xFFFFFF) | (index_bias < 0 ? 1<<24 : 0));
12357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    END_CS;
12457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}
12557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
12657c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic void r300_emit_draw_init(struct r300_context *r300, unsigned mode,
12757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                                unsigned min_index, unsigned max_index)
12857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{
12957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    CS_LOCALS(r300);
13057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
13157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    BEGIN_CS(5);
13257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    OUT_CS_REG(R300_GA_COLOR_CONTROL,
13357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            r300_provoking_vertex_fixes(r300, mode));
13457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
13557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    OUT_CS(max_index);
13657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    OUT_CS(min_index);
13757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    END_CS;
13857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}
13957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
14057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/* This function splits the index bias value into two parts:
14157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * - buffer_offset: the value that can be safely added to buffer offsets
14257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *   in r300_emit_vertex_arrays (it must yield a positive offset when added to
14357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *   a vertex buffer offset)
14457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * - index_offset: the value that must be manually subtracted from indices
14557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj *   in an index buffer to achieve negative offsets. */
14657c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic void r300_split_index_bias(struct r300_context *r300, int index_bias,
14757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                                  int *buffer_offset, int *index_offset)
14857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{
14957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    struct pipe_vertex_buffer *vb, *vbufs = r300->vbuf_mgr->real_vertex_buffer;
1502f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj    struct pipe_vertex_element *velem = r300->velems->velem;
15157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    unsigned i, size;
15257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    int max_neg_bias;
15357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
15457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    if (index_bias < 0) {
15557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        /* See how large index bias we may subtract. We must be careful
15657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         * here because negative buffer offsets are not allowed
15757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj         * by the DRM API. */
15857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        max_neg_bias = INT_MAX;
15957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        for (i = 0; i < r300->velems->count; i++) {
16057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            vb = &vbufs[velem[i].vertex_buffer_index];
16157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            size = (vb->buffer_offset + velem[i].src_offset) / vb->stride;
16257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            max_neg_bias = MIN2(max_neg_bias, size);
16357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        }
16457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
16557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        /* Now set the minimum allowed value. */
16657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        *buffer_offset = MAX2(-max_neg_bias, index_bias);
16757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    } else {
16857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        /* A positive index bias is OK. */
16957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        *buffer_offset = index_bias;
170dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    }
17157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
17257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    *index_offset = index_bias - *buffer_offset;
17357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}
17457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
17557c10c89904f7fdc4244fcbf704625e7169aafe6sewardjenum r300_prepare_flags {
17657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    PREP_EMIT_STATES    = (1 << 0), /* call emit_dirty_state and friends? */
17757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    PREP_VALIDATE_VBOS  = (1 << 1), /* validate VBOs? */
17857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    PREP_EMIT_VARRAYS       = (1 << 2), /* call emit_vertex_arrays? */
17957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    PREP_EMIT_VARRAYS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */
18057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    PREP_INDEXED        = (1 << 4)  /* is this draw_elements? */
18157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj};
18257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
18357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/**
18457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * Check if the requested number of dwords is available in the CS and
18557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * if not, flush.
18657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * \param r300          The context.
18757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * \param flags         See r300_prepare_flags.
188ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj * \param cs_dwords     The number of dwords to reserve in CS.
189ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj * \return TRUE if the CS was flushed
190ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj */
191496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjstatic boolean r300_reserve_cs_dwords(struct r300_context *r300,
192496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj                                      enum r300_prepare_flags flags,
193496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj                                      unsigned cs_dwords)
194496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj{
195496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    boolean flushed        = FALSE;
196496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    boolean emit_states    = flags & PREP_EMIT_STATES;
197496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    boolean emit_vertex_arrays       = flags & PREP_EMIT_VARRAYS;
198496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL;
199496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
200496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    /* Add dirty state, index offset, and AOS. */
201496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    if (emit_states)
202496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        cs_dwords += r300_get_num_dirty_dwords(r300);
203496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
204dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    if (r300->screen->caps.is_r500)
205496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        cs_dwords += 2; /* emit_index_offset */
206f6c8ebf1294fea43756683ba7089b746168abb8esewardj
207f6c8ebf1294fea43756683ba7089b746168abb8esewardj    if (emit_vertex_arrays)
208496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj        cs_dwords += 55; /* emit_vertex_arrays */
209dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj
210496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    if (emit_vertex_arrays_swtcl)
211f6c8ebf1294fea43756683ba7089b746168abb8esewardj        cs_dwords += 7; /* emit_vertex_arrays_swtcl */
212f6c8ebf1294fea43756683ba7089b746168abb8esewardj
213496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj    cs_dwords += r300_get_num_cs_end_dwords(r300);
214496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj
215c97096c44637ae5775ed305b19f16f0b505f17d8sewardj    /* Reserve requested CS space. */
216e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj    if (cs_dwords > (RADEON_MAX_CMDBUF_DWORDS - r300->cs->cdw)) {
21757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        r300_flush(&r300->context, RADEON_FLUSH_ASYNC, NULL);
21857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        flushed = TRUE;
219e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj    }
220c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
221cfe046e178666280b87da998b1b52ecda03ecd89sewardj    return flushed;
222c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj}
223c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
224c9a43665879a03886b27a65b68af2a2c11b04f59sewardj/**
225c9a43665879a03886b27a65b68af2a2c11b04f59sewardj * Validate buffers and emit dirty state.
226c9a43665879a03886b27a65b68af2a2c11b04f59sewardj * \param r300          The context.
2279b96767debeeb1f78378f0e7e295fe6762c64002sewardj * \param flags         See r300_prepare_flags.
228c9a43665879a03886b27a65b68af2a2c11b04f59sewardj * \param index_buffer  The index buffer to validate. The parameter may be NULL.
229c9a43665879a03886b27a65b68af2a2c11b04f59sewardj * \param buffer_offset The offset passed to emit_vertex_arrays.
230c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj * \param index_bias    The index bias to emit.
231c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj * \param instance_id   Index of instance to render
232c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj * \return TRUE if rendering should be skipped
2332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */
234c4530ae9079b0c3f8d4e8df35073613d718cadecsewardjstatic boolean r300_emit_states(struct r300_context *r300,
235c4530ae9079b0c3f8d4e8df35073613d718cadecsewardj                                enum r300_prepare_flags flags,
236d1725d18b61bf7912a9099686179faef5815dba1sewardj                                struct pipe_resource *index_buffer,
237e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj                                int buffer_offset,
238e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj                                int index_bias, int instance_id)
23957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj{
24035421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj    boolean emit_states    = flags & PREP_EMIT_STATES;
24157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    boolean emit_vertex_arrays       = flags & PREP_EMIT_VARRAYS;
24257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL;
24357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    boolean indexed        = flags & PREP_INDEXED;
244c97096c44637ae5775ed305b19f16f0b505f17d8sewardj    boolean validate_vbos  = flags & PREP_VALIDATE_VBOS;
245e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj
246af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj    /* Validate buffers and emit dirty state if needed. */
247af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj    if (emit_states || (emit_vertex_arrays && validate_vbos)) {
24857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        if (!r300_emit_buffer_validate(r300, validate_vbos,
249af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj                                       index_buffer)) {
250af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj           fprintf(stderr, "r300: CS space validation failed. "
251cfe046e178666280b87da998b1b52ecda03ecd89sewardj                   "(not enough memory?) Skipping rendering.\n");
252c4356f0d3c74fc2622dbeed79c6c1045fc519f72sewardj           return FALSE;
253af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj        }
254af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj    }
255af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj
256af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj    if (emit_states)
257c97096c44637ae5775ed305b19f16f0b505f17d8sewardj        r300_emit_dirty_state(r300);
258ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
25957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    if (r300->screen->caps.is_r500) {
26057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        if (r300->screen->caps.has_tcl)
26157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            r500_emit_index_bias(r300, index_bias);
262ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj        else
263c9a43665879a03886b27a65b68af2a2c11b04f59sewardj            r500_emit_index_bias(r300, 0);
264cfe046e178666280b87da998b1b52ecda03ecd89sewardj    }
265c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
266c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    if (emit_vertex_arrays &&
267c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        (r300->vertex_arrays_dirty ||
268c9a43665879a03886b27a65b68af2a2c11b04f59sewardj         r300->vertex_arrays_indexed != indexed ||
2692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         r300->vertex_arrays_offset != buffer_offset ||
2702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj         r300->vertex_arrays_instance_id != instance_id)) {
2712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id);
2721e6ad745ebafd0524da1da27a4b85524fa84f777sewardj
2731e6ad745ebafd0524da1da27a4b85524fa84f777sewardj        r300->vertex_arrays_dirty = FALSE;
2741e6ad745ebafd0524da1da27a4b85524fa84f777sewardj        r300->vertex_arrays_indexed = indexed;
27537a505b5a6814921fcfff1eac950a9ef7651e42bsewardj        r300->vertex_arrays_offset = buffer_offset;
27657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        r300->vertex_arrays_instance_id = instance_id;
27737a505b5a6814921fcfff1eac950a9ef7651e42bsewardj    }
27837a505b5a6814921fcfff1eac950a9ef7651e42bsewardj
279207557ab2ea38239b670785c976b89d50bbb0eccsewardj    if (emit_vertex_arrays_swtcl)
280ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj        r300_emit_vertex_arrays_swtcl(r300, indexed);
281ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
28257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    return TRUE;
28357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj}
28457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
28557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj/**
286ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj * Check if the requested number of dwords is available in the CS and
287e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj * if not, flush. Then validate buffers and emit dirty state.
288ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj * \param r300          The context.
289ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj * \param flags         See r300_prepare_flags.
290ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj * \param index_buffer  The index buffer to validate. The parameter may be NULL.
291c97096c44637ae5775ed305b19f16f0b505f17d8sewardj * \param cs_dwords     The number of dwords to reserve in CS.
292c97096c44637ae5775ed305b19f16f0b505f17d8sewardj * \param buffer_offset The offset passed to emit_vertex_arrays.
293c97096c44637ae5775ed305b19f16f0b505f17d8sewardj * \param index_bias    The index bias to emit.
294c97096c44637ae5775ed305b19f16f0b505f17d8sewardj * \param instance_id The instance to render.
2952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj * \return TRUE if rendering should be skipped
2962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */
297a58ea668d4725b87a146cf43cc48b8ea6ead84casewardjstatic boolean r300_prepare_for_rendering(struct r300_context *r300,
29817442fe8094d0f82266e5a05509f62cac8f7539esewardj                                          enum r300_prepare_flags flags,
29957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj                                          struct pipe_resource *index_buffer,
30037a505b5a6814921fcfff1eac950a9ef7651e42bsewardj                                          unsigned cs_dwords,
301ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj                                          int buffer_offset,
302ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj                                          int index_bias,
303ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj                                          int instance_id)
304ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj{
30557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    /* Make sure there is enough space in the command stream and emit states. */
306ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj    if (r300_reserve_cs_dwords(r300, flags, cs_dwords))
30717442fe8094d0f82266e5a05509f62cac8f7539esewardj        flags |= PREP_EMIT_STATES;
30817442fe8094d0f82266e5a05509f62cac8f7539esewardj
30917442fe8094d0f82266e5a05509f62cac8f7539esewardj    return r300_emit_states(r300, flags, index_buffer, buffer_offset,
31017442fe8094d0f82266e5a05509f62cac8f7539esewardj                            index_bias, instance_id);
3112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}
3122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
31317442fe8094d0f82266e5a05509f62cac8f7539esewardjstatic boolean immd_is_good_idea(struct r300_context *r300,
31417442fe8094d0f82266e5a05509f62cac8f7539esewardj                                 unsigned count)
3151e6ad745ebafd0524da1da27a4b85524fa84f777sewardj{
31637a505b5a6814921fcfff1eac950a9ef7651e42bsewardj    struct pipe_vertex_element* velem;
317c97096c44637ae5775ed305b19f16f0b505f17d8sewardj    struct pipe_resource *buf;
31857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    boolean checked[PIPE_MAX_ATTRIBS] = {0};
319dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    unsigned vertex_element_count = r300->velems->count;
320695cff9303ef5dc8079117acfd632b44edb1f010sewardj    unsigned i, vbi;
32157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
32235421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj    if (DBG_ON(r300, DBG_NO_IMMD)) {
32357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        return FALSE;
32457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    }
3254345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj
326ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj    if (r300->draw) {
327c97096c44637ae5775ed305b19f16f0b505f17d8sewardj        return FALSE;
3288ea867b06de73d909c29e243407713c291c8414esewardj    }
3298ea867b06de73d909c29e243407713c291c8414esewardj
3308ea867b06de73d909c29e243407713c291c8414esewardj    if (count * r300->velems->vertex_size_dwords > IMMD_DWORDS) {
33177352545d8416a36a4e6310aaea6b0205508aea2sewardj        return FALSE;
3328ea867b06de73d909c29e243407713c291c8414esewardj    }
33303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj
33403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj    /* We shouldn't map buffers referenced by CS, busy buffers,
33503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj     * and ones placed in VRAM. */
33603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj    for (i = 0; i < vertex_element_count; i++) {
33743c56461a667ca81fe29f1db01450d6ff1d62949sewardj        velem = &r300->velems->velem[i];
33843c56461a667ca81fe29f1db01450d6ff1d62949sewardj        vbi = velem->vertex_buffer_index;
33943c56461a667ca81fe29f1db01450d6ff1d62949sewardj
34043c56461a667ca81fe29f1db01450d6ff1d62949sewardj        if (!checked[vbi]) {
34143c56461a667ca81fe29f1db01450d6ff1d62949sewardj            buf = r300->vbuf_mgr->real_vertex_buffer[vbi].buffer;
34243c56461a667ca81fe29f1db01450d6ff1d62949sewardj
34343c56461a667ca81fe29f1db01450d6ff1d62949sewardj            if ((r300_resource(buf)->domain != RADEON_DOMAIN_GTT)) {
3448ea867b06de73d909c29e243407713c291c8414esewardj                return FALSE;
3458ea867b06de73d909c29e243407713c291c8414esewardj            }
3468ea867b06de73d909c29e243407713c291c8414esewardj
3471ff4756e1731485e6bf3cd96717cd8398daec1f2florian            checked[vbi] = TRUE;
3481ff4756e1731485e6bf3cd96717cd8398daec1f2florian        }
3491ff4756e1731485e6bf3cd96717cd8398daec1f2florian    }
3501ff4756e1731485e6bf3cd96717cd8398daec1f2florian    return TRUE;
3518ea867b06de73d909c29e243407713c291c8414esewardj}
3528ea867b06de73d909c29e243407713c291c8414esewardj
3538ea867b06de73d909c29e243407713c291c8414esewardj/*****************************************************************************
35457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj * The HWTCL draw functions.                                                 *
3551ff4756e1731485e6bf3cd96717cd8398daec1f2florian ****************************************************************************/
3568ea867b06de73d909c29e243407713c291c8414esewardj
35757c10c89904f7fdc4244fcbf704625e7169aafe6sewardjstatic void r300_draw_arrays_immediate(struct r300_context *r300,
358dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                                       const struct pipe_draw_info *info)
3598ea867b06de73d909c29e243407713c291c8414esewardj{
36057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    struct pipe_vertex_element* velem;
3618ea867b06de73d909c29e243407713c291c8414esewardj    struct pipe_vertex_buffer* vbuf;
3628ea867b06de73d909c29e243407713c291c8414esewardj    unsigned vertex_element_count = r300->velems->count;
3638ea867b06de73d909c29e243407713c291c8414esewardj    unsigned i, v, vbi;
3642d3f77c12d2911173fd182d0b6e954196dee9135sewardj
3652d3f77c12d2911173fd182d0b6e954196dee9135sewardj    /* Size of the vertex, in dwords. */
36657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    unsigned vertex_size = r300->velems->vertex_size_dwords;
36757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
36857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    /* The number of dwords for this draw operation. */
3692d3f77c12d2911173fd182d0b6e954196dee9135sewardj    unsigned dwords = 4 + info->count * vertex_size;
3702d3f77c12d2911173fd182d0b6e954196dee9135sewardj
37157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    /* Size of the vertex element, in dwords. */
37257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    unsigned size[PIPE_MAX_ATTRIBS];
37357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
3742d3f77c12d2911173fd182d0b6e954196dee9135sewardj    /* Stride to the same attrib in the next vertex in the vertex buffer,
375dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj     * in dwords. */
3762d3f77c12d2911173fd182d0b6e954196dee9135sewardj    unsigned stride[PIPE_MAX_ATTRIBS];
377dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj
3782d3f77c12d2911173fd182d0b6e954196dee9135sewardj    /* Mapped vertex buffers. */
379dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    uint32_t* map[PIPE_MAX_ATTRIBS] = {0};
380695cff9303ef5dc8079117acfd632b44edb1f010sewardj    uint32_t* mapelem[PIPE_MAX_ATTRIBS];
381dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj
382dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj    CS_LOCALS(r300);
3832d3f77c12d2911173fd182d0b6e954196dee9135sewardj
3842d3f77c12d2911173fd182d0b6e954196dee9135sewardj    if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
385c97096c44637ae5775ed305b19f16f0b505f17d8sewardj        return;
386ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj
38757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    /* Calculate the vertex size, offsets, strides etc. and map the buffers. */
38857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    for (i = 0; i < vertex_element_count; i++) {
38957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        velem = &r300->velems->velem[i];
390fbcaf3312f39fb73d54821636c6168db76245f61sewardj        size[i] = r300->velems->format_size[i] / 4;
391ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj        vbi = velem->vertex_buffer_index;
39257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        vbuf = &r300->vbuf_mgr->real_vertex_buffer[vbi];
39335421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj        stride[i] = vbuf->stride / 4;
394c97096c44637ae5775ed305b19f16f0b505f17d8sewardj
39592d168d0f2a985ed9f7ae4e6bba9565a13921b31sewardj        /* Map the buffer. */
396fbcaf3312f39fb73d54821636c6168db76245f61sewardj        if (!map[vbi]) {
397ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj            map[vbi] = (uint32_t*)r300->rws->buffer_map(
39840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj                r300_resource(vbuf->buffer)->buf,
399ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj                r300->cs, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED);
40057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj            map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * info->start;
40157c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        }
40257c10c89904f7fdc4244fcbf704625e7169aafe6sewardj        mapelem[i] = map[vbi] + (velem->src_offset / 4);
40357c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    }
40457c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
40557c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    r300_emit_draw_init(r300, info->mode, 0, info->count-1);
40657c10c89904f7fdc4244fcbf704625e7169aafe6sewardj
40757c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    BEGIN_CS(dwords);
40857c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
40957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, info->count * vertex_size);
410ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (info->count << 16) |
41141f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj            r300_translate_primitive(info->mode));
41271a35e7351fc1202ef2960d3f0315d9181624fe2sewardj
41371a35e7351fc1202ef2960d3f0315d9181624fe2sewardj    /* Emit vertices. */
41471a35e7351fc1202ef2960d3f0315d9181624fe2sewardj    for (v = 0; v < info->count; v++) {
415cfe046e178666280b87da998b1b52ecda03ecd89sewardj        for (i = 0; i < vertex_element_count; i++) {
41666de22767fc526eff52133c18d4a42a9b25d5f18sewardj            OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[i]);
41741f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj        }
41841f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj    }
41941f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj    END_CS;
42041f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj
42141f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj    /* Unmap buffers. */
42241f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj    for (i = 0; i < vertex_element_count; i++) {
42341f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj        vbi = r300->velems->velem[i].vertex_buffer_index;
42441f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj
42541f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj        if (map[vbi]) {
426e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj            r300->rws->buffer_unmap(r300_resource(r300->vbuf_mgr->real_vertex_buffer[vbi].buffer)->buf);
427e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj            map[vbi] = NULL;
428e90ad6abbe540a5b3ffa68ba0c641ced77c20211sewardj        }
42941f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj    }
43041f43bcdee3e150a74a2e8c8e3b5bc5f5fda3215sewardj}
43171a35e7351fc1202ef2960d3f0315d9181624fe2sewardj
4321fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardjstatic void r300_emit_draw_arrays(struct r300_context *r300,
4331fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj                                  unsigned mode,
4341fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj                                  unsigned count)
4351fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj{
4361fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj    boolean alt_num_verts = count > 65535;
4371fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj    CS_LOCALS(r300);
4381fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj
4391fb8c92e9b0882ebbd53c04c69ebad7efb1cd3d8sewardj    if (count >= (1 << 24)) {
440e13074c2c1321d069fb95806bdce64f9a3512341sewardj        fprintf(stderr, "r300: Got a huge number of vertices: %i, "
441e13074c2c1321d069fb95806bdce64f9a3512341sewardj                "refusing to render.\n", count);
442e13074c2c1321d069fb95806bdce64f9a3512341sewardj        return;
443e13074c2c1321d069fb95806bdce64f9a3512341sewardj    }
44471a35e7351fc1202ef2960d3f0315d9181624fe2sewardj
44571a35e7351fc1202ef2960d3f0315d9181624fe2sewardj    r300_emit_draw_init(r300, mode, 0, count-1);
4469690d927540d730525a5f7f14663f3ceaa7818dasewardj
4479b96767debeeb1f78378f0e7e295fe6762c64002sewardj    BEGIN_CS(2 + (alt_num_verts ? 2 : 0));
4489b96767debeeb1f78378f0e7e295fe6762c64002sewardj    if (alt_num_verts) {
4498f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
450ce646f23d71ac432c340667387aa4a5ce7d18099sewardj    }
451f53b7359a342e7d79090615169c6583a1a75fbcesewardj    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
452f53b7359a342e7d79090615169c6583a1a75fbcesewardj    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
453f53b7359a342e7d79090615169c6583a1a75fbcesewardj           r300_translate_primitive(mode) |
454f53b7359a342e7d79090615169c6583a1a75fbcesewardj           (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0));
4558f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj    END_CS;
4568f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj}
457b51f0f4f33256638ed953156a2635aa739b232f1sewardj
4589854007808ab24cad3f971eab63face1cb1e6089sewardjstatic void r300_emit_draw_elements(struct r300_context *r300,
4599854007808ab24cad3f971eab63face1cb1e6089sewardj                                    struct pipe_resource* indexBuffer,
4609854007808ab24cad3f971eab63face1cb1e6089sewardj                                    unsigned indexSize,
4619854007808ab24cad3f971eab63face1cb1e6089sewardj                                    unsigned min_index,
462343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj                                    unsigned max_index,
4630033ddccac6f90789fe2e78e86b8a649931d77b4sewardj                                    unsigned mode,
4640033ddccac6f90789fe2e78e86b8a649931d77b4sewardj                                    unsigned start,
465eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                                    unsigned count,
466eb17e49565dd7867a56c8ba6e45fdca01a576bb3sewardj                                    uint16_t *imm_indices3)
467478646f54befaba01cbceb40fd5e46cdf562fdb5sewardj{
4680033ddccac6f90789fe2e78e86b8a649931d77b4sewardj    uint32_t count_dwords, offset_dwords;
46957c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    boolean alt_num_verts = count > 65535;
47057c10c89904f7fdc4244fcbf704625e7169aafe6sewardj    CS_LOCALS(r300);
471b51f0f4f33256638ed953156a2635aa739b232f1sewardj
472b51f0f4f33256638ed953156a2635aa739b232f1sewardj    if (count >= (1 << 24) || max_index >= (1 << 24)) {
473b51f0f4f33256638ed953156a2635aa739b232f1sewardj        fprintf(stderr, "r300: Got a huge number of vertices: %i, "
474b51f0f4f33256638ed953156a2635aa739b232f1sewardj                "refusing to render (max_index: %i).\n", count, max_index);
4752831b00c4950d6c2b061def05fd67528fe132ececerion        return;
4762831b00c4950d6c2b061def05fd67528fe132ececerion    }
477b51f0f4f33256638ed953156a2635aa739b232f1sewardj
4789690d927540d730525a5f7f14663f3ceaa7818dasewardj    DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
4798f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        count, min_index, max_index);
4805c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion
4815c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion    r300_emit_draw_init(r300, mode, min_index, max_index);
482f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion
483f0de28cf1a762b0d6f74c93d3532c89a230673bbcerion    /* If start is odd, render the first triangle with indices embedded
484e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj     * in the command stream. This will increase start by 3 and make it
485e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj     * even. We can then proceed without a fallback. */
4864aa412af1d8166cc11f39a6e721df49431d23618sewardj    if (indexSize == 2 && (start & 1) &&
487e71e56a90e91ce37b0ee846a4ff94493d59f2095sewardj        mode == PIPE_PRIM_TRIANGLES) {
4885c8a0cbfd7fd3b506f6ba1cb25a6aa20efb59dcbcerion        BEGIN_CS(4);
4899690d927540d730525a5f7f14663f3ceaa7818dasewardj        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 2);
4909690d927540d730525a5f7f14663f3ceaa7818dasewardj        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (3 << 16) |
4919690d927540d730525a5f7f14663f3ceaa7818dasewardj               R300_VAP_VF_CNTL__PRIM_TRIANGLES);
49289d4e9828ce36532c957566ebb46947109a7b53dsewardj        OUT_CS(imm_indices3[1] << 16 | imm_indices3[0]);
493343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj        OUT_CS(imm_indices3[2]);
494343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj        END_CS;
495343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj
496343b9d0f6be20948ab2f4fe87de55835f96fe30asewardj        start += 3;
4972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        count -= 3;
4982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        if (!count)
4992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj           return;
5000033ddccac6f90789fe2e78e86b8a649931d77b4sewardj    }
5010033ddccac6f90789fe2e78e86b8a649931d77b4sewardj
5020033ddccac6f90789fe2e78e86b8a649931d77b4sewardj    offset_dwords = indexSize * start / sizeof(uint32_t);
5030033ddccac6f90789fe2e78e86b8a649931d77b4sewardj
5040033ddccac6f90789fe2e78e86b8a649931d77b4sewardj    BEGIN_CS(8 + (alt_num_verts ? 2 : 0));
5059690d927540d730525a5f7f14663f3ceaa7818dasewardj    if (alt_num_verts) {
5060033ddccac6f90789fe2e78e86b8a649931d77b4sewardj        OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
5070033ddccac6f90789fe2e78e86b8a649931d77b4sewardj    }
5080033ddccac6f90789fe2e78e86b8a649931d77b4sewardj    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
5090033ddccac6f90789fe2e78e86b8a649931d77b4sewardj    if (indexSize == 4) {
5100033ddccac6f90789fe2e78e86b8a649931d77b4sewardj        count_dwords = count;
5110033ddccac6f90789fe2e78e86b8a649931d77b4sewardj        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
5120033ddccac6f90789fe2e78e86b8a649931d77b4sewardj               R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
513a238471814bd386aeb58a76718b41e68b1a794b2sewardj               r300_translate_primitive(mode) |
5140033ddccac6f90789fe2e78e86b8a649931d77b4sewardj               (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0));
515b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj    } else {
516b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj        count_dwords = (count + 1) / 2;
517b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
518b81f8b3e9110a5608094b8ec1a5c6d3c30a8e5aesewardj               r300_translate_primitive(mode) |
5198c7f1abe9e022f6382634efea09c9cac89ec6336sewardj               (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0));
5208c7f1abe9e022f6382634efea09c9cac89ec6336sewardj    }
5218c7f1abe9e022f6382634efea09c9cac89ec6336sewardj
5228c7f1abe9e022f6382634efea09c9cac89ec6336sewardj    OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
5239690d927540d730525a5f7f14663f3ceaa7818dasewardj    OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
5248c7f1abe9e022f6382634efea09c9cac89ec6336sewardj           (0 << R300_INDX_BUFFER_SKIP_SHIFT));
5259690d927540d730525a5f7f14663f3ceaa7818dasewardj    OUT_CS(offset_dwords << 2);
5269690d927540d730525a5f7f14663f3ceaa7818dasewardj    OUT_CS(count_dwords);
5279b96767debeeb1f78378f0e7e295fe6762c64002sewardj    OUT_CS_RELOC(r300_resource(indexBuffer));
5289b96767debeeb1f78378f0e7e295fe6762c64002sewardj    END_CS;
5299b96767debeeb1f78378f0e7e295fe6762c64002sewardj}
5309b96767debeeb1f78378f0e7e295fe6762c64002sewardj
531cf780b4c356a274cc48a6829963f8bc79a1b34e8sewardjstatic void r300_draw_elements_immediate(struct r300_context *r300,
5326e797c5fbd90ecc6531f9d8c4929848664a13714sewardj                                         const struct pipe_draw_info *info)
53384ff0657940e62f38e618ea18bac6f27ce0e741fsewardj{
534291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj    uint8_t *ptr1;
535291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj    uint16_t *ptr2;
53684ff0657940e62f38e618ea18bac6f27ce0e741fsewardj    uint32_t *ptr4;
537291a7e8fa181da2b707a2a7d51fbdccb17908f87sewardj    unsigned index_size = r300->index_buffer.index_size;
538fd33277c458b31596eb4fb15959467ac047c75dasewardj    unsigned i, count_dwords = index_size == 4 ? info->count :
5398eda6304ecfaa1d0aa70773a2c07f996717f8f54sewardj                                                 (info->count + 1) / 2;
540cf7879021370aabcccb1a9347244fcc7d5680141sewardj    CS_LOCALS(r300);
541b5874aa03bb38bf754aa8c1cb1e400f3d7e86b9fsewardj
5428f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj    /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
543baf971ad7f6e005109f3301ec9d19c98066b3840sewardj    if (!r300_prepare_for_rendering(r300,
5448f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
545b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
546cfded9ab7c059881ecdbe967ddfcc1ce207986casewardj        return;
547b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
548b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    r300_emit_draw_init(r300, info->mode, info->min_index, info->max_index);
549b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
55052ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj    BEGIN_CS(2 + count_dwords);
5516c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count_dwords);
5526c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5536c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    switch (index_size) {
554b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    case 1:
555b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        ptr1 = r300_resource(r300->index_buffer.buffer)->b.user_ptr;
556b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        ptr1 += info->start;
557b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
55852ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
559b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj               r300_translate_primitive(info->mode));
560b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
561b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        if (info->index_bias && !r300->screen->caps.is_r500) {
5628f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            for (i = 0; i < info->count-1; i += 2)
5636c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
5646c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                        (ptr1[i]   + info->index_bias));
5656c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
566b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            if (info->count & 1)
567b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                OUT_CS(ptr1[i] + info->index_bias);
5686d52228c83cccffb6cadf7f0cdfe34df057b6fefflorian        } else {
569baf971ad7f6e005109f3301ec9d19c98066b3840sewardj            for (i = 0; i < info->count-1; i += 2)
5706c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                OUT_CS(((ptr1[i+1]) << 16) |
5716c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                        (ptr1[i]  ));
5726c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5738f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            if (info->count & 1)
574883b00b3d97a9873371557d7b1f2ac5db7985e43sewardj                OUT_CS(ptr1[i]);
5758f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        }
5768f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        break;
577883b00b3d97a9873371557d7b1f2ac5db7985e43sewardj
5788f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj    case 2:
5798f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        ptr2 = (uint16_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
5808f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        ptr2 += info->start;
5816c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5828f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
5832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj               r300_translate_primitive(info->mode));
5842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
5858f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        if (info->index_bias && !r300->screen->caps.is_r500) {
5863bca906f6e715c544eb49c278bedef093c14c0d7sewardj            for (i = 0; i < info->count-1; i += 2)
587b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
5886c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                        (ptr2[i]   + info->index_bias));
5896c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
5906c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            if (info->count & 1)
5916c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                OUT_CS(ptr2[i] + info->index_bias);
5928f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        } else {
5938f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj            OUT_CS_TABLE(ptr2, count_dwords);
5948f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        }
5958f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        break;
5968f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
5978f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj    case 4:
5988f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        ptr4 = (uint32_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
5998f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        ptr4 += info->start;
6008f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj
6018f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
6028f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj               R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
6036c299f3acab617581ea504e45fbb6cab24c2b29fsewardj               r300_translate_primitive(info->mode));
6046c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6056c299f3acab617581ea504e45fbb6cab24c2b29fsewardj        if (info->index_bias && !r300->screen->caps.is_r500) {
6066c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            for (i = 0; i < info->count; i++)
6076c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                OUT_CS(ptr4[i] + info->index_bias);
6086c299f3acab617581ea504e45fbb6cab24c2b29fsewardj        } else {
6096c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            OUT_CS_TABLE(ptr4, count_dwords);
6106c299f3acab617581ea504e45fbb6cab24c2b29fsewardj        }
6116c299f3acab617581ea504e45fbb6cab24c2b29fsewardj        break;
6128f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj    }
6138f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj    END_CS;
6148f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj}
6156c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6166c299f3acab617581ea504e45fbb6cab24c2b29fsewardjstatic void r300_draw_elements(struct r300_context *r300,
6176c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                               const struct pipe_draw_info *info,
6186c299f3acab617581ea504e45fbb6cab24c2b29fsewardj                               int instance_id)
6196c299f3acab617581ea504e45fbb6cab24c2b29fsewardj{
6206c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    struct pipe_resource *indexBuffer = r300->index_buffer.buffer;
6216c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    unsigned indexSize = r300->index_buffer.index_size;
6226c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    struct pipe_resource* orgIndexBuffer = indexBuffer;
6233bca906f6e715c544eb49c278bedef093c14c0d7sewardj    unsigned start = info->start;
6243bca906f6e715c544eb49c278bedef093c14c0d7sewardj    unsigned count = info->count;
6253bca906f6e715c544eb49c278bedef093c14c0d7sewardj    boolean alt_num_verts = r300->screen->caps.is_r500 &&
6268f3debf52b76a050bc84997a0358c4aa86dfc88dsewardj                            count > 65536;
6276c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    unsigned short_count;
6286c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
6296c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    uint16_t indices3[3];
6304aa412af1d8166cc11f39a6e721df49431d23618sewardj
6316c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    if (info->index_bias && !r300->screen->caps.is_r500) {
6326c299f3acab617581ea504e45fbb6cab24c2b29fsewardj        r300_split_index_bias(r300, info->index_bias, &buffer_offset, &index_offset);
6336c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    }
6346c299f3acab617581ea504e45fbb6cab24c2b29fsewardj
6356c299f3acab617581ea504e45fbb6cab24c2b29fsewardj    r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset,
63666d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj                                &start, count);
63766d5ef2c2a31fb52cdd4f02304489e30268ea13fsewardj
63852ace3ed99ccb7d0e4c64dc06381e407a8bfcf1dsewardj    /* Fallback for misaligned ushort indices. */
6391c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian    if (indexSize == 2 && (start & 1) &&
6406c299f3acab617581ea504e45fbb6cab24c2b29fsewardj        !r300_resource(indexBuffer)->b.user_ptr) {
6413bca906f6e715c544eb49c278bedef093c14c0d7sewardj        /* If we got here, then orgIndexBuffer == indexBuffer. */
6422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        uint16_t *ptr = r300->rws->buffer_map(r300_resource(orgIndexBuffer)->buf,
6432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                              r300->cs,
6441c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian                                              PIPE_TRANSFER_READ |
6451c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian                                              PIPE_TRANSFER_UNSYNCHRONIZED);
6462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        if (info->mode == PIPE_PRIM_TRIANGLES) {
6482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj           memcpy(indices3, ptr + start, 6);
6492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        } else {
6506c299f3acab617581ea504e45fbb6cab24c2b29fsewardj            /* Copy the mapped index buffer directly to the upload buffer.
6513bca906f6e715c544eb49c278bedef093c14c0d7sewardj             * The start index will be aligned simply from the fact that
6523bca906f6e715c544eb49c278bedef093c14c0d7sewardj             * every sub-buffer in the upload buffer is aligned. */
6534cb918d355cef4e7640d374346852db4556f3524sewardj            r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start,
65417442fe8094d0f82266e5a05509f62cac8f7539esewardj                                     count, (uint8_t*)ptr);
65517442fe8094d0f82266e5a05509f62cac8f7539esewardj        }
656c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        r300->rws->buffer_unmap(r300_resource(orgIndexBuffer)->buf);
657fc1b541264539587f12721ca0b73ef04580ed2bdsewardj    } else {
658b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        if (r300_resource(indexBuffer)->b.user_ptr)
6592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj            r300_upload_index_buffer(r300, &indexBuffer, indexSize,
6602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                     &start, count,
6612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                     r300_resource(indexBuffer)->b.user_ptr);
6622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    }
6632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    /* 19 dwords for emit_draw_elements. Give up if the function fails. */
6652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    if (!r300_prepare_for_rendering(r300,
6662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
6672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj            PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
6682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj            instance_id))
6692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        goto done;
6702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
6712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    if (alt_num_verts || count <= 65535) {
6722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        r300_emit_draw_elements(r300, indexBuffer, indexSize, info->min_index,
6732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                info->max_index, info->mode, start, count,
6742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                indices3);
6751c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian    } else {
6761c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian        do {
6772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj            /* The maximum must be divisible by 4 and 3,
6782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj             * so that quad and triangle lists are split correctly.
6792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj             *
6802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj             * Strips, loops, and fans won't work. */
6812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj            short_count = MIN2(count, 65532);
6821c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian
6831c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian            r300_emit_draw_elements(r300, indexBuffer, indexSize,
6842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                     info->min_index, info->max_index,
6852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                     info->mode, start, short_count, indices3);
6862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
687b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            start += short_count;
688b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            count -= short_count;
689b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
690b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            /* 15 dwords for emit_draw_elements */
691b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            if (count) {
692b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                if (!r300_prepare_for_rendering(r300,
693b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                        PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED,
694b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                        indexBuffer, 19, buffer_offset, info->index_bias,
695b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                        instance_id))
696b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    goto done;
697b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            }
698b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        } while (count);
699b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    }
700b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
701b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjdone:
702b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    if (indexBuffer != orgIndexBuffer) {
703b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        pipe_resource_reference( &indexBuffer, NULL );
704b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    }
705b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj}
706b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
707b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstatic void r300_draw_arrays(struct r300_context *r300,
708b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                             const struct pipe_draw_info *info,
709b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                             int instance_id)
710b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj{
711d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj    boolean alt_num_verts = r300->screen->caps.is_r500 &&
712d15b597a8a006b3fe136cbf6cdf5b46ed532a4d8sewardj                            info->count > 65536;
713b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    unsigned start = info->start;
7142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    unsigned count = info->count;
7152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    unsigned short_count;
7162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj
7172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
7185906a6b242b06c27fdc583d4547eab10b86a9800florian    if (!r300_prepare_for_rendering(r300,
7192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                    PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS,
7202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj                                    NULL, 9, start, 0, instance_id))
721b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        return;
722b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
72340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj    if (alt_num_verts || count <= 65535) {
72440c802659108a96bb87cbc1a30b7b77e2abd0829sewardj        r300_emit_draw_arrays(r300, info->mode, count);
7252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj    } else {
7262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj        do {
72740c802659108a96bb87cbc1a30b7b77e2abd0829sewardj            /* The maximum must be divisible by 4 and 3,
72840c802659108a96bb87cbc1a30b7b77e2abd0829sewardj             * so that quad and triangle lists are split correctly.
72940c802659108a96bb87cbc1a30b7b77e2abd0829sewardj             *
73040c802659108a96bb87cbc1a30b7b77e2abd0829sewardj             * Strips, loops, and fans won't work. */
73140c802659108a96bb87cbc1a30b7b77e2abd0829sewardj            short_count = MIN2(count, 65532);
73240c802659108a96bb87cbc1a30b7b77e2abd0829sewardj            r300_emit_draw_arrays(r300, info->mode, short_count);
73340c802659108a96bb87cbc1a30b7b77e2abd0829sewardj
73440c802659108a96bb87cbc1a30b7b77e2abd0829sewardj            start += short_count;
73540c802659108a96bb87cbc1a30b7b77e2abd0829sewardj            count -= short_count;
736b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
737b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
7380f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj            if (count) {
7390f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj                if (!r300_prepare_for_rendering(r300,
7400f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj                                                PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS, NULL, 9,
7410f1ef86a99d5129e04ed188e44d16a344d2bc42asewardj                                                start, 0, instance_id))
742b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                    return;
743b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj            }
744b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj        } while (count);
745b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj    }
746b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj}
747b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj
748b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardjstatic void r300_draw_arrays_instanced(struct r300_context *r300,
749b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj                                       const struct pipe_draw_info *info)
750b183b8571b4ec98866ce2b3653a9d066cf5f16f4sewardj{
751e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    int i;
752e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
75344ce46d5945ed83d96695d280510cc2a858894dcsewardj    for (i = 0; i < info->instance_count; i++)
75444ce46d5945ed83d96695d280510cc2a858894dcsewardj        r300_draw_arrays(r300, info, i);
75544ce46d5945ed83d96695d280510cc2a858894dcsewardj}
75644ce46d5945ed83d96695d280510cc2a858894dcsewardj
757e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardjstatic void r300_draw_elements_instanced(struct r300_context *r300,
758e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj                                         const struct pipe_draw_info *info)
759e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj{
760e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    int i;
761e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
762e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    for (i = 0; i < info->instance_count; i++)
763e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj        r300_draw_elements(r300, info, i);
764e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj}
765e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
766e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardjstatic void r300_draw_vbo(struct pipe_context* pipe,
767e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj                          const struct pipe_draw_info *dinfo)
768e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj{
769e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    struct r300_context* r300 = r300_context(pipe);
770e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    struct pipe_draw_info info = *dinfo;
771e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
772e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    info.indexed = info.indexed && r300->index_buffer.buffer;
773e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
774e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    if (r300->skip_rendering ||
775e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj        !u_trim_pipe_prim(info.mode, &info.count)) {
776e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj        return;
777e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    }
778e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj
779310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj    r300_update_derived_state(r300);
780310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj
781310d6b2d02c3b22a8e496f3e26f3e9b3eb616ea5sewardj    /* Start the vbuf manager and update buffers if needed. */
782e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    if (u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info) & U_VBUF_BUFFERS_UPDATED) {
783e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj        r300->vertex_arrays_dirty = TRUE;
784e2ea17600e3bbdc4cc0edcd2a03f7d1142666f37sewardj    }
7852fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
7862fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* Draw. */
7872fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (info.indexed) {
7882fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        info.start += r300->index_buffer.offset;
7892fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        info.max_index = MIN2(r300->vbuf_mgr->max_index, info.max_index);
7902fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
7912fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        if (info.instance_count <= 1) {
7922fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            if (info.count <= 8 &&
7932fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                r300_resource(r300->index_buffer.buffer)->b.user_ptr) {
7942fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                r300_draw_elements_immediate(r300, &info);
7952fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            } else {
7962fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                r300_draw_elements(r300, &info, -1);
7972fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            }
7982fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        } else {
7992fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            r300_draw_elements_instanced(r300, &info);
8002fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        }
8012fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    } else {
8022fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        if (info.instance_count <= 1) {
8032fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            if (immd_is_good_idea(r300, info.count)) {
8042fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                r300_draw_arrays_immediate(r300, &info);
8052fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            } else {
8062fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                r300_draw_arrays(r300, &info, -1);
8072fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            }
8082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        } else {
8092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            r300_draw_arrays_instanced(r300, &info);
8102fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        }
8112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    }
8122fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    u_vbuf_mgr_draw_end(r300->vbuf_mgr);
8142fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj}
8152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8162fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj/****************************************************************************
8172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * The rest of this file is for SW TCL rendering only. Please be polite and *
8182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj * keep these functions separated so that they are easier to locate. ~C.    *
8192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj ***************************************************************************/
8202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8212fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj/* SW TCL elements, using Draw. */
8222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjstatic void r300_swtcl_draw_vbo(struct pipe_context* pipe,
8232fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                const struct pipe_draw_info *info)
8242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{
8252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_context* r300 = r300_context(pipe);
8262fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
82738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    struct pipe_transfer *ib_transfer = NULL;
82838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    unsigned count = info->count;
82938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    int i;
8301806918ae2783af5808f00876581e01c7b650a0dsewardj    void *indices = NULL;
83138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    boolean indexed = info->indexed && r300->index_buffer.buffer;
83238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
83338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    if (r300->skip_rendering) {
8342fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        return;
8352fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    }
8362fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8372fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (!u_trim_pipe_prim(info->mode, &count)) {
8382fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        return;
8392fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    }
8402fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8412fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300_update_derived_state(r300);
8422fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8432fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300_reserve_cs_dwords(r300,
8442fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL |
8452fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            (indexed ? PREP_INDEXED : 0),
8462fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            indexed ? 256 : 6);
8472fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8482fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
8492fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
8502fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            void *buf = pipe_buffer_map(pipe,
8512fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                  r300->vbuf_mgr->vertex_buffer[i].buffer,
85238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj                                  PIPE_TRANSFER_READ |
85338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj                                  PIPE_TRANSFER_UNSYNCHRONIZED,
85438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj                                  &vb_transfer[i]);
8552fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            draw_set_mapped_vertex_buffer(r300->draw, i, buf);
8562fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        }
85738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    }
8582fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8592fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (indexed) {
8602fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
8612fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                  PIPE_TRANSFER_READ |
8622fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                  PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer);
8632fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    }
86438a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
86538a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    draw_set_mapped_index_buffer(r300->draw, indices);
8662fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8672fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300->draw_vbo_locked = TRUE;
8682fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300->draw_first_emitted = FALSE;
8692fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    draw_vbo(r300->draw, info);
8702fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    draw_flush(r300->draw);
8712fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300->draw_vbo_locked = FALSE;
8722fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8732fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
8742fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
8752fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            pipe_buffer_unmap(pipe, vb_transfer[i]);
8762fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj            draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
8772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        }
87838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    }
8795ce5fd60b7690ed8fdbaba9334d4d54929264da2sewardj
88038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    if (indexed) {
88138a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj        pipe_buffer_unmap(pipe, ib_transfer);
88238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj        draw_set_mapped_index_buffer(r300->draw, NULL);
88338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    }
8842fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj}
8852fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8862fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj/* Object for rendering using Draw. */
8872fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjstruct r300_render {
88838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    /* Parent class */
88938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    struct vbuf_render base;
89038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
8912fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* Pipe context */
89238a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    struct r300_context* r300;
89338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
8942fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* Vertex information */
8952fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    size_t vertex_size;
8962fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    unsigned prim;
8972fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    unsigned hwprim;
8982fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
8992fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* VBO */
9002fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    size_t vbo_max_used;
9012fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    void * vbo_ptr;
9022fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9032fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct pipe_transfer *vbo_transfer;
9042fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj};
9052fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
90638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic INLINE struct r300_render*
907d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardjr300_render(struct vbuf_render* render)
9082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{
909d71ba837242cc470f622335b1c650bce8886a533sewardj    return (struct r300_render*)render;
91038a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj}
9112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9122fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjstatic const struct vertex_info*
9132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjr300_render_get_vertex_info(struct vbuf_render* render)
9142fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{
9152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_render* r300render = r300_render(render);
9162fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_context* r300 = r300render->r300;
9172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    return &r300->vertex_info;
9195f438dd73072211989c6d496845bdc9b777ecbecsewardj}
9205f438dd73072211989c6d496845bdc9b777ecbecsewardj
921c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardjstatic boolean r300_render_allocate_vertices(struct vbuf_render* render,
922c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                                   ushort vertex_size,
923c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj                                                   ushort count)
924c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj{
925c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj    struct r300_render* r300render = r300_render(render);
926c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj    struct r300_context* r300 = r300render->r300;
927c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj    struct pipe_screen* screen = r300->context.screen;
928c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj    size_t size = (size_t)vertex_size * (size_t)count;
929c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj
930c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj    DBG(r300, DBG_DRAW, "r300: render_allocate_vertices (size: %d)\n", size);
931c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj
932c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj    if (size + r300->draw_vbo_offset > r300->draw_vbo_size)
933c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj    {
934c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj	pipe_resource_reference(&r300->vbo, NULL);
935c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj        r300->vbo = pipe_buffer_create(screen,
936c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj				       PIPE_BIND_VERTEX_BUFFER,
937c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj				       PIPE_USAGE_STREAM,
938c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj				       R300_MAX_DRAW_VBO_SIZE);
939c9bff7dbb37ba2ee5898ef49aefaa92095ab446bsewardj        r300->draw_vbo_offset = 0;
9405f438dd73072211989c6d496845bdc9b777ecbecsewardj        r300->draw_vbo_size = R300_MAX_DRAW_VBO_SIZE;
9415f438dd73072211989c6d496845bdc9b777ecbecsewardj    }
942ad2c9ea0c360fced134b2dd0d4b28c0be3639cfbsewardj
94338a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj    r300render->vertex_size = vertex_size;
9442fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9452fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    return (r300->vbo) ? TRUE : FALSE;
94638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj}
94738a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
94838a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardjstatic void* r300_render_map_vertices(struct vbuf_render* render)
94938a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj{
9502fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_render* r300render = r300_render(render);
9512fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_context* r300 = r300render->r300;
9522fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9532fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    assert(!r300render->vbo_transfer);
9542fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9552fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    DBG(r300, DBG_DRAW, "r300: render_map_vertices\n");
95638a3f868aebe4ade7279d7168e0efb6a98eaed5fsewardj
957d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj    r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context,
958d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj					  r300->vbo,
959d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj                                          PIPE_TRANSFER_WRITE |
960d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj                                          PIPE_TRANSFER_UNSYNCHRONIZED,
9612fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj					  &r300render->vbo_transfer);
9622fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9632fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    assert(r300render->vbo_ptr);
9642fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9652fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    return ((uint8_t*)r300render->vbo_ptr + r300->draw_vbo_offset);
9662fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj}
9672fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9682fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjstatic void r300_render_unmap_vertices(struct vbuf_render* render,
9692fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                             ushort min,
9702fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                             ushort max)
9712fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{
9722fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_render* r300render = r300_render(render);
9732fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct pipe_context* context = &r300render->r300->context;
9742fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_context* r300 = r300render->r300;
9752fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9762fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    assert(r300render->vbo_transfer);
9772fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9782fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    DBG(r300, DBG_DRAW, "r300: render_unmap_vertices\n");
9792fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9802fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
9812fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                                    r300render->vertex_size * (max + 1));
9822fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    pipe_buffer_unmap(context, r300render->vbo_transfer);
9832fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9842fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300render->vbo_transfer = NULL;
9852fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj}
9862fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
9872fdd41628b79039a9586c7a601cc7ddcd376fccfsewardjstatic void r300_render_release_vertices(struct vbuf_render* render)
9882fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{
9892fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    struct r300_render* r300render = r300_render(render);
990d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj    struct r300_context* r300 = r300render->r300;
991d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj
992d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj    DBG(r300, DBG_DRAW, "r300: render_release_vertices\n");
993d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj
994d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj    r300->draw_vbo_offset += r300render->vbo_max_used;
995d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj    r300render->vbo_max_used = 0;
996d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj}
997d166e2874e0d9a9e567a281d7f1f6e8ef8127196sewardj
998e13074c2c1321d069fb95806bdce64f9a3512341sewardjstatic boolean r300_render_set_primitive(struct vbuf_render* render,
999e13074c2c1321d069fb95806bdce64f9a3512341sewardj                                               unsigned prim)
1000e13074c2c1321d069fb95806bdce64f9a3512341sewardj{
1001e13074c2c1321d069fb95806bdce64f9a3512341sewardj    struct r300_render* r300render = r300_render(render);
10022fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
10032fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300render->prim = prim;
10042fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300render->hwprim = r300_translate_primitive(prim);
10052fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1006c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    return TRUE;
1007c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj}
1008c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
1009c6bbd470e9bd9898b84959227a406d3972d95f3bsewardjstatic void r300_render_draw_arrays(struct vbuf_render* render,
1010c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                    unsigned start,
1011c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj                                    unsigned count)
1012c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj{
1013c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    struct r300_render* r300render = r300_render(render);
1014c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    struct r300_context* r300 = r300render->r300;
1015c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    uint8_t* ptr;
1016c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    unsigned i;
1017c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    unsigned dwords = 6;
1018c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
1019c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj    CS_LOCALS(r300);
102026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    (void) i; (void) ptr;
102126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
102226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count);
102326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
102426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    if (r300->draw_first_emitted) {
102526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj        if (!r300_prepare_for_rendering(r300,
1026cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL,
1027cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                NULL, dwords, 0, 0, -1))
102826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj            return;
102926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    } else {
103026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj        if (!r300_emit_states(r300,
103126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL,
103226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                NULL, 0, 0, -1))
103326217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj            return;
103426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    }
103526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
103626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    BEGIN_CS(dwords);
103726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    OUT_CS_REG(R300_GA_COLOR_CONTROL,
103826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj            r300_provoking_vertex_fixes(r300, r300render->prim));
103926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
104026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
104126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
1042b17e16fb3709b8282646009caffa2ead7bcf363fflorian           r300render->hwprim);
1043b17e16fb3709b8282646009caffa2ead7bcf363fflorian    END_CS;
1044b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1045b17e16fb3709b8282646009caffa2ead7bcf363fflorian    r300->draw_first_emitted = TRUE;
1046b17e16fb3709b8282646009caffa2ead7bcf363fflorian}
1047b17e16fb3709b8282646009caffa2ead7bcf363fflorian
104826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardjstatic void r300_render_draw_elements(struct vbuf_render* render,
104926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                                      const ushort* indices,
105026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                                      uint count)
1051b17e16fb3709b8282646009caffa2ead7bcf363fflorian{
1052b17e16fb3709b8282646009caffa2ead7bcf363fflorian    struct r300_render* r300render = r300_render(render);
1053b17e16fb3709b8282646009caffa2ead7bcf363fflorian    struct r300_context* r300 = r300render->r300;
105426217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    int i;
105526217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    unsigned end_cs_dwords;
105626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    unsigned max_index = (r300->draw_vbo_size - r300->draw_vbo_offset) /
105726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                         (r300render->r300->vertex_info.size * 4) - 1;
105826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    unsigned short_count;
105926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    unsigned free_dwords;
1060b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1061b17e16fb3709b8282646009caffa2ead7bcf363fflorian    CS_LOCALS(r300);
1062b17e16fb3709b8282646009caffa2ead7bcf363fflorian    DBG(r300, DBG_DRAW, "r300: render_draw_elements (count: %d)\n", count);
1063b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1064b17e16fb3709b8282646009caffa2ead7bcf363fflorian    if (r300->draw_first_emitted) {
1065b17e16fb3709b8282646009caffa2ead7bcf363fflorian        if (!r300_prepare_for_rendering(r300,
106626217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
106726217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj                NULL, 256, 0, 0, -1))
106826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj            return;
1069b17e16fb3709b8282646009caffa2ead7bcf363fflorian    } else {
1070b17e16fb3709b8282646009caffa2ead7bcf363fflorian        if (!r300_emit_states(r300,
1071b17e16fb3709b8282646009caffa2ead7bcf363fflorian                PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
1072b17e16fb3709b8282646009caffa2ead7bcf363fflorian                NULL, 0, 0, -1))
1073b17e16fb3709b8282646009caffa2ead7bcf363fflorian            return;
1074b17e16fb3709b8282646009caffa2ead7bcf363fflorian    }
1075b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1076b17e16fb3709b8282646009caffa2ead7bcf363fflorian    /* Below we manage the CS space manually because there may be more
1077b17e16fb3709b8282646009caffa2ead7bcf363fflorian     * indices than it can fit in CS. */
107826217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
107926217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj    end_cs_dwords = r300_get_num_cs_end_dwords(r300);
108026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj
1081b17e16fb3709b8282646009caffa2ead7bcf363fflorian    while (count) {
1082b17e16fb3709b8282646009caffa2ead7bcf363fflorian        free_dwords = RADEON_MAX_CMDBUF_DWORDS - r300->cs->cdw;
1083b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1084b17e16fb3709b8282646009caffa2ead7bcf363fflorian        short_count = MIN2(count, (free_dwords - end_cs_dwords - 6) * 2);
1085b17e16fb3709b8282646009caffa2ead7bcf363fflorian
1086b17e16fb3709b8282646009caffa2ead7bcf363fflorian        BEGIN_CS(6 + (short_count+1)/2);
1087b17e16fb3709b8282646009caffa2ead7bcf363fflorian        OUT_CS_REG(R300_GA_COLOR_CONTROL,
1088b17e16fb3709b8282646009caffa2ead7bcf363fflorian                r300_provoking_vertex_fixes(r300, r300render->prim));
1089b17e16fb3709b8282646009caffa2ead7bcf363fflorian        OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index);
109026217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (short_count+1)/2);
109126217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (short_count << 16) |
109226217b09205cc1801b842ba5ba8f0d83aabca1b4sewardj               r300render->hwprim);
1093b17e16fb3709b8282646009caffa2ead7bcf363fflorian        for (i = 0; i < short_count-1; i += 2) {
1094b17e16fb3709b8282646009caffa2ead7bcf363fflorian            OUT_CS(indices[i+1] << 16 | indices[i]);
1095b17e16fb3709b8282646009caffa2ead7bcf363fflorian        }
1096cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj        if (short_count % 2) {
1097cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            OUT_CS(indices[short_count-1]);
1098cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll        }
1099cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll        END_CS;
1100cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1101cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj        /* OK now subtract the emitted indices and see if we need to emit
1102cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj         * another draw packet. */
1103cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj        indices += short_count;
1104cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj        count -= short_count;
1105cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1106cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj        if (count) {
1107cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            if (!r300_prepare_for_rendering(r300,
1108cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                    PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
1109cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                    NULL, 256, 0, 0, -1))
1110daa4084cffd771efef294a484e64868f3eeeb0e4florian                return;
1111cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1112cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj            end_cs_dwords = r300_get_num_cs_end_dwords(r300);
111320c6bca02d9b3c985607b4639ffc70eb504cc237florian        }
111420c6bca02d9b3c985607b4639ffc70eb504cc237florian    }
111520c6bca02d9b3c985607b4639ffc70eb504cc237florian
111620c6bca02d9b3c985607b4639ffc70eb504cc237florian    r300->draw_first_emitted = TRUE;
111720c6bca02d9b3c985607b4639ffc70eb504cc237florian}
111820c6bca02d9b3c985607b4639ffc70eb504cc237florian
111920c6bca02d9b3c985607b4639ffc70eb504cc237florianstatic void r300_render_destroy(struct vbuf_render* render)
1120cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj{
1121cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    FREE(render);
1122cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj}
1123cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1124cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardjstatic struct vbuf_render* r300_render_create(struct r300_context* r300)
1125cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj{
1126cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    struct r300_render* r300render = CALLOC_STRUCT(r300_render);
1127cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1128cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->r300 = r300;
1129cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1130cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.max_vertex_buffer_bytes = 1024 * 1024;
1131cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.max_indices = 16 * 1024;
1132cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1133cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.get_vertex_info = r300_render_get_vertex_info;
1134cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.allocate_vertices = r300_render_allocate_vertices;
1135cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.map_vertices = r300_render_map_vertices;
1136cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.unmap_vertices = r300_render_unmap_vertices;
1137cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.set_primitive = r300_render_set_primitive;
1138cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.draw_elements = r300_render_draw_elements;
1139cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.draw_arrays = r300_render_draw_arrays;
1140cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.release_vertices = r300_render_release_vertices;
1141cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300render->base.destroy = r300_render_destroy;
1142cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1143cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    return &r300render->base;
1144cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj}
1145cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1146cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardjstruct draw_stage* r300_draw_stage(struct r300_context* r300)
1147cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj{
1148cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    struct vbuf_render* render;
1149cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    struct draw_stage* stage;
1150cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1151cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    render = r300_render_create(r300);
1152cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1153cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    if (!render) {
11544bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian        return NULL;
11554bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian    }
11564bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian
11574bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian    stage = draw_vbuf_stage(r300->draw, render);
11584bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian
11594bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian    if (!stage) {
11604bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian        render->destroy(render);
11614bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian        return NULL;
11624bbd3ecf31fdd592d2114e148821ea8150e77e4aflorian    }
1163cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll
1164cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    draw_set_render(r300->draw, render);
1165cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1166cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    return stage;
1167cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj}
1168cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj
1169cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardjvoid r300_draw_flush_vbuf(struct r300_context *r300)
1170cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj{
1171cea07ccbe9aa9b5fd8e9b318471c6c74aa147acbcarll    pipe_resource_reference(&r300->vbo, NULL);
1172cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj    r300->draw_vbo_size = 0;
1173cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj}
1174c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj
1175c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj/****************************************************************************
1176c6bbd470e9bd9898b84959227a406d3972d95f3bsewardj *                         End of SW TCL functions                          *
11774c96e61dd85c172b999d6afc88ce6640aeba9962sewardj ***************************************************************************/
11784c96e61dd85c172b999d6afc88ce6640aeba9962sewardj
11794c96e61dd85c172b999d6afc88ce6640aeba9962sewardj/* This functions is used to draw a rectangle for the blitter module.
11804c96e61dd85c172b999d6afc88ce6640aeba9962sewardj *
11814c96e61dd85c172b999d6afc88ce6640aeba9962sewardj * If we rendered a quad, the pixels on the main diagonal
11824c96e61dd85c172b999d6afc88ce6640aeba9962sewardj * would be computed and stored twice, which makes the clear/copy codepaths
11834c96e61dd85c172b999d6afc88ce6640aeba9962sewardj * somewhat inefficient. Instead we use a rectangular point sprite. */
11844c96e61dd85c172b999d6afc88ce6640aeba9962sewardjstatic void r300_blitter_draw_rectangle(struct blitter_context *blitter,
11854c96e61dd85c172b999d6afc88ce6640aeba9962sewardj                                        unsigned x1, unsigned y1,
11864c96e61dd85c172b999d6afc88ce6640aeba9962sewardj                                        unsigned x2, unsigned y2,
1187cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                        float depth,
1188cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                        enum blitter_attrib_type type,
1189cdc376dcb5a4560b0a35d4abcb2146c499756f0dsewardj                                        const union pipe_color_union *attrib)
11905eff1c502e995d1f9668cc9def72d5db59f21b13sewardj{
11915eff1c502e995d1f9668cc9def72d5db59f21b13sewardj    struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter));
11925eff1c502e995d1f9668cc9def72d5db59f21b13sewardj    unsigned last_sprite_coord_enable = r300->sprite_coord_enable;
1193164f9275c465cd09ecd09276b8542282f5def250sewardj    unsigned width = x2 - x1;
1194c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    unsigned height = y2 - y1;
1195c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    unsigned vertex_size =
1196c9a43665879a03886b27a65b68af2a2c11b04f59sewardj            type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4;
1197c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    unsigned dwords = 13 + vertex_size +
1198c9a43665879a03886b27a65b68af2a2c11b04f59sewardj                      (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0);
1199c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    static const union pipe_color_union zeros;
12002fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    CS_LOCALS(r300);
12012fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1202f294eb389e8e703e2d4476aea7ca579a160a0a89cerion    if (r300->skip_rendering)
12032fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        return;
1204206c36410bd92f385b972e36a3a40e38675294e2cerion
1205c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    r300->context.set_vertex_buffers(&r300->context, 0, NULL);
12062fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
12072fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
12082fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        r300->sprite_coord_enable = 1;
12092fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
12102fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300_update_derived_state(r300);
12112fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1212c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    /* Mark some states we don't care about as non-dirty. */
12132fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300->clip_state.dirty = FALSE;
12142fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    r300->viewport_state.dirty = FALSE;
12152fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
12162fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
12172fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        goto done;
12182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
12192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
12202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
12212fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    BEGIN_CS(dwords);
12222fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* Set up GA. */
12232fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
12242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
12252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
12262fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        /* Set up the GA to generate texcoords. */
12272fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
12282fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj                   (R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT));
12292fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
12302fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        OUT_CS_32F(attrib->f[0]);
12312fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        OUT_CS_32F(attrib->f[3]);
12322fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        OUT_CS_32F(attrib->f[2]);
12332fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        OUT_CS_32F(attrib->f[1]);
12342fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    }
1235f294eb389e8e703e2d4476aea7ca579a160a0a89cerion
1236f294eb389e8e703e2d4476aea7ca579a160a0a89cerion    /* Set up VAP controls. */
1237f294eb389e8e703e2d4476aea7ca579a160a0a89cerion    OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
1238f294eb389e8e703e2d4476aea7ca579a160a0a89cerion    OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
12392fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
12402fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
12412fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS(1);
1242f294eb389e8e703e2d4476aea7ca579a160a0a89cerion    OUT_CS(0);
1243f294eb389e8e703e2d4476aea7ca579a160a0a89cerion
12442fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* Draw. */
12452fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size);
12462fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) |
12472fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj           R300_VAP_VF_CNTL__PRIM_POINTS);
12482fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
12492fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS_32F(x1 + width * 0.5f);
12502fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS_32F(y1 + height * 0.5f);
12515f438dd73072211989c6d496845bdc9b777ecbecsewardj    OUT_CS_32F(depth);
12522fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    OUT_CS_32F(1);
1253f294eb389e8e703e2d4476aea7ca579a160a0a89cerion
1254c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    if (vertex_size == 8) {
1255c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        if (!attrib)
1256c9a43665879a03886b27a65b68af2a2c11b04f59sewardj            attrib = &zeros;
1257b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion        OUT_CS_TABLE(attrib->f, 4);
1258c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    }
1259c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    END_CS;
1260c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1261c9a43665879a03886b27a65b68af2a2c11b04f59sewardjdone:
1262636ad762e49597ef608323f27c7b8eb66962cd90sewardj    /* Restore the state. */
1263c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    r300_mark_atom_dirty(r300, &r300->clip_state);
1264c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    r300_mark_atom_dirty(r300, &r300->rs_state);
1265c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    r300_mark_atom_dirty(r300, &r300->viewport_state);
1266636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1267636ad762e49597ef608323f27c7b8eb66962cd90sewardj    r300->sprite_coord_enable = last_sprite_coord_enable;
1268636ad762e49597ef608323f27c7b8eb66962cd90sewardj}
1269636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1270636ad762e49597ef608323f27c7b8eb66962cd90sewardjstatic void r300_resource_resolve(struct pipe_context *pipe,
1271636ad762e49597ef608323f27c7b8eb66962cd90sewardj                                  const struct pipe_resolve_info *info)
1272636ad762e49597ef608323f27c7b8eb66962cd90sewardj{
1273636ad762e49597ef608323f27c7b8eb66962cd90sewardj    struct r300_context *r300 = r300_context(pipe);
1274636ad762e49597ef608323f27c7b8eb66962cd90sewardj    struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
1275636ad762e49597ef608323f27c7b8eb66962cd90sewardj    struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
1276636ad762e49597ef608323f27c7b8eb66962cd90sewardj    static const union pipe_color_union color;
1277636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1278636ad762e49597ef608323f27c7b8eb66962cd90sewardj    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
1279636ad762e49597ef608323f27c7b8eb66962cd90sewardj    surf_tmpl.format = info->src.res->format;
1280b85e8bba97fdae7d892f7bfd12e4601307e4721dcerion    surf_tmpl.u.tex.first_layer =
1281636ad762e49597ef608323f27c7b8eb66962cd90sewardj    surf_tmpl.u.tex.last_layer = info->src.layer;
1282636ad762e49597ef608323f27c7b8eb66962cd90sewardj    srcsurf = pipe->create_surface(pipe, info->src.res, &surf_tmpl);
1283636ad762e49597ef608323f27c7b8eb66962cd90sewardj    /* XXX Offset both surfaces by x0,y1. */
1284636ad762e49597ef608323f27c7b8eb66962cd90sewardj
1285636ad762e49597ef608323f27c7b8eb66962cd90sewardj    surf_tmpl.format = info->dst.res->format;
1286636ad762e49597ef608323f27c7b8eb66962cd90sewardj    surf_tmpl.u.tex.level = info->dst.level;
1287636ad762e49597ef608323f27c7b8eb66962cd90sewardj    surf_tmpl.u.tex.first_layer =
1288636ad762e49597ef608323f27c7b8eb66962cd90sewardj    surf_tmpl.u.tex.last_layer = info->dst.layer;
1289c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    dstsurf = pipe->create_surface(pipe, info->dst.res, &surf_tmpl);
1290c9a43665879a03886b27a65b68af2a2c11b04f59sewardj
1291c9a43665879a03886b27a65b68af2a2c11b04f59sewardj    DBG(r300, DBG_DRAW, "r300: Resolving resource...\n");
1292f0c1c58d6e47608ce166058997f795f1d7d45127sewardj
1293f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    /* Enable AA resolve. */
1294f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    aa->dest = r300_surface(dstsurf);
1295f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    aa->aaresolve_ctl =
1296c9a43665879a03886b27a65b68af2a2c11b04f59sewardj        R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE |
1297f0c1c58d6e47608ce166058997f795f1d7d45127sewardj        R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE;
1298f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    r300->aa_state.size = 10;
1299164f9275c465cd09ecd09276b8542282f5def250sewardj    r300_mark_atom_dirty(r300, &r300->aa_state);
1300f0c1c58d6e47608ce166058997f795f1d7d45127sewardj
1301f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    /* Resolve the surface. */
1302f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    /* XXX: y1 < 0 ==> Y flip */
1303f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    r300->context.clear_render_target(pipe,
130470f676d62218657de2d230d495ccd775909e107dsewardj                                      srcsurf, &color, 0, 0,
1305164f9275c465cd09ecd09276b8542282f5def250sewardj                                      info->dst.x1 - info->dst.x0,
1306164f9275c465cd09ecd09276b8542282f5def250sewardj                                      info->dst.y1 - info->dst.y0);
1307164f9275c465cd09ecd09276b8542282f5def250sewardj
1308f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    /* Disable AA resolve. */
1309f0c1c58d6e47608ce166058997f795f1d7d45127sewardj    aa->aaresolve_ctl = 0;
1310164f9275c465cd09ecd09276b8542282f5def250sewardj    r300->aa_state.size = 4;
1311f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion    r300_mark_atom_dirty(r300, &r300->aa_state);
1312f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion
1313f887b3e44be206c5aad8039dc33e8e3102aaae7ecerion    pipe_surface_reference(&srcsurf, NULL);
13142e38386d2f5902feed6ec276c2c2292a137717b9sewardj    pipe_surface_reference(&dstsurf, NULL);
13152e38386d2f5902feed6ec276c2c2292a137717b9sewardj}
131670f676d62218657de2d230d495ccd775909e107dsewardj
1317164f9275c465cd09ecd09276b8542282f5def250sewardjvoid r300_init_render_functions(struct r300_context *r300)
13182fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj{
13192fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* Set draw functions based on presence of HW TCL. */
13202fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (r300->screen->caps.has_tcl) {
1321164f9275c465cd09ecd09276b8542282f5def250sewardj        r300->context.draw_vbo = r300_draw_vbo;
1322164f9275c465cd09ecd09276b8542282f5def250sewardj    } else {
13232fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj        r300->context.draw_vbo = r300_swtcl_draw_vbo;
13242fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    }
13252fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
1326164f9275c465cd09ecd09276b8542282f5def250sewardj    r300->context.resource_resolve = r300_resource_resolve;
1327164f9275c465cd09ecd09276b8542282f5def250sewardj    r300->blitter->draw_rectangle = r300_blitter_draw_rectangle;
13282fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj
13292fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    /* Plug in the two-sided stencil reference value fallback if needed. */
13302fdd41628b79039a9586c7a601cc7ddcd376fccfsewardj    if (!r300->screen->caps.is_r500)
133124d06f124e3325e8edcc1c495d15736d5adcda96cerion        r300_plug_in_stencil_ref_fallback(r300);
13321ac656a3b8eead55eeb0fb9090efec1c6719f989cerion}
13331ac656a3b8eead55eeb0fb9090efec1c6719f989cerion