r300_render.c revision d35aeff4bb0b03450b2c3c08bd7f84db5bf43283
1e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson/*
25c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
3eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák * Copyright 2010 Marek Olšák <maraeo@gmail.com>
4e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson *
5e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * Permission is hereby granted, free of charge, to any person obtaining a
6e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * copy of this software and associated documentation files (the "Software"),
7e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * to deal in the Software without restriction, including without limitation
8e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * on the rights to use, copy, modify, merge, publish, distribute, sub
9e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * license, and/or sell copies of the Software, and to permit persons to whom
10e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * the Software is furnished to do so, subject to the following conditions:
11e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson *
12e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * The above copyright notice and this permission notice (including the next
13e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * paragraph) shall be included in all copies or substantial portions of the
14e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * Software.
15e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson *
16e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
246acb26eadfcb3c21fd09d0b22804b49de9a82cf7Maciej Cencora/* r300_render: Vertex and index buffer primitive emission. Contains both
256acb26eadfcb3c21fd09d0b22804b49de9a82cf7Maciej Cencora * HW TCL fastpath rendering, and SW TCL Draw-assisted rendering. */
266acb26eadfcb3c21fd09d0b22804b49de9a82cf7Maciej Cencora
276a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "draw/draw_context.h"
2881daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson#include "draw/draw_vbuf.h"
296a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson
3028486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
316a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson
325fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson#include "util/u_format.h"
33e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson#include "util/u_memory.h"
3468e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "util/u_upload_mgr.h"
35f3d8d534e6f1d102d71338d58fbaa98c382f1858Corbin Simpson#include "util/u_prim.h"
36e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
37f097465bb85d3ca212a23c2dcc9cf73988de9160Corbin Simpson#include "r300_cs.h"
38e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson#include "r300_context.h"
3968e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie#include "r300_screen_buffer.h"
401ddb22675c123fc955ad3ab46bba45d3330d2ec4Nicolai Hähnle#include "r300_emit.h"
41e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson#include "r300_reg.h"
42e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
43eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák#include <limits.h>
44eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
45eb7ef433bbbeabda963e74adf0ef61c47883f292Marek Olšák#define IMMD_DWORDS 32
46eb7ef433bbbeabda963e74adf0ef61c47883f292Marek Olšák
470b4df63609e9fb25319debd56142a90b11d75671Marek Olšákstatic uint32_t r300_translate_primitive(unsigned prim)
481f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson{
491f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson    switch (prim) {
501f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_POINTS:
511f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_POINTS;
521f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_LINES:
531f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_LINES;
541f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_LINE_LOOP:
551f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
561f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_LINE_STRIP:
571f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
581f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_TRIANGLES:
591f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_TRIANGLES;
601f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_TRIANGLE_STRIP:
611f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
621f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_TRIANGLE_FAN:
631f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
641f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_QUADS:
651f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_QUADS;
661f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_QUAD_STRIP:
671f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
681f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        case PIPE_PRIM_POLYGON:
691f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return R300_VAP_VF_CNTL__PRIM_POLYGON;
701f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson        default:
711f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson            return 0;
721f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson    }
731f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson}
741f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson
75f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpsonstatic uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
76f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson                                            unsigned mode)
77f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson{
7846fafdd455bc1f3ee05c076b3c8c541ecd4132dcCorbin Simpson    struct r300_rs_state* rs = (struct r300_rs_state*)r300->rs_state.state;
7946fafdd455bc1f3ee05c076b3c8c541ecd4132dcCorbin Simpson    uint32_t color_control = rs->color_control;
80f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson
81f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson    /* By default (see r300_state.c:r300_create_rs_state) color_control is
82f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson     * initialized to provoking the first vertex.
83f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson     *
84759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * Triangle fans must be reduced to the second vertex, not the first, in
85759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * Gallium flatshade-first mode, as per the GL spec.
86f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson     * (http://www.opengl.org/registry/specs/ARB/provoking_vertex.txt)
87759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     *
88759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * Quads never provoke correctly in flatshade-first mode. The first
89759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * vertex is never considered as provoking, so only the second, third,
90759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * and fourth vertices can be selected, and both "third" and "last" modes
91759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * select the fourth vertex. This is probably due to D3D lacking quads.
92759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     *
93759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * Similarly, polygons reduce to the first, not the last, vertex, when in
94759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * "last" mode, and all other modes start from the second vertex.
95759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     *
96759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     * ~ C.
97759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson     */
98f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson
9946fafdd455bc1f3ee05c076b3c8c541ecd4132dcCorbin Simpson    if (rs->rs.flatshade_first) {
100759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson        switch (mode) {
101759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson            case PIPE_PRIM_TRIANGLE_FAN:
102759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND;
103759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson                break;
104759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson            case PIPE_PRIM_QUADS:
105759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson            case PIPE_PRIM_QUAD_STRIP:
106759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson            case PIPE_PRIM_POLYGON:
107759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
108759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson                break;
109759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson            default:
110759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson                color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_FIRST;
111759fd1f25f33273e0b7c02598bfa5b97d1a82d77Corbin Simpson                break;
112f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson        }
113f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson    } else {
114f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson        color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
115f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson    }
116f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson
117f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson    return color_control;
118f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson}
119f13a904c34cf7ac5aae3d50a1421259895fc9a08Corbin Simpson
120cb925970eeade17016f59497d2123e4e8a447164Marek Olšákvoid r500_emit_index_bias(struct r300_context *r300, int index_bias)
121da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák{
122da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    CS_LOCALS(r300);
123da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
124eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    BEGIN_CS(2);
125eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    OUT_CS_REG(R500_VAP_INDEX_OFFSET,
126eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák               (index_bias & 0xFFFFFF) | (index_bias < 0 ? 1<<24 : 0));
127eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    END_CS;
128eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák}
129eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
1303d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšákstatic void r300_emit_draw_init(struct r300_context *r300, unsigned mode,
1313d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák                                unsigned min_index, unsigned max_index)
1323d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák{
1333d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    CS_LOCALS(r300);
1343d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák
1353d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    BEGIN_CS(5);
1363d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    OUT_CS_REG(R300_GA_COLOR_CONTROL,
1373d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák            r300_provoking_vertex_fixes(r300, mode));
1383d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
1393d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    OUT_CS(max_index);
1403d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    OUT_CS(min_index);
1413d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    END_CS;
1423d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák}
1433d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák
144eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák/* This function splits the index bias value into two parts:
145eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák * - buffer_offset: the value that can be safely added to buffer offsets
14633e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák *   in r300_emit_vertex_arrays (it must yield a positive offset when added to
147eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák *   a vertex buffer offset)
148eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák * - index_offset: the value that must be manually subtracted from indices
149eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák *   in an index buffer to achieve negative offsets. */
150eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšákstatic void r300_split_index_bias(struct r300_context *r300, int index_bias,
151eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák                                  int *buffer_offset, int *index_offset)
152eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák{
153c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    struct pipe_vertex_buffer *vb, *vbufs = r300->vbuf_mgr->vertex_buffer;
154eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    struct pipe_vertex_element *velem = r300->velems->velem;
155eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    unsigned i, size;
156eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    int max_neg_bias;
157eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
158eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    if (index_bias < 0) {
159eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        /* See how large index bias we may subtract. We must be careful
160eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák         * here because negative buffer offsets are not allowed
161eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák         * by the DRM API. */
162eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        max_neg_bias = INT_MAX;
163eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        for (i = 0; i < r300->velems->count; i++) {
164eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák            vb = &vbufs[velem[i].vertex_buffer_index];
165eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák            size = (vb->buffer_offset + velem[i].src_offset) / vb->stride;
166eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák            max_neg_bias = MIN2(max_neg_bias, size);
167da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák        }
168eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
169eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        /* Now set the minimum allowed value. */
170eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        *buffer_offset = MAX2(-max_neg_bias, index_bias);
171eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    } else {
172eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        /* A positive index bias is OK. */
173eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        *buffer_offset = index_bias;
174da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    }
175eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
176eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    *index_offset = index_bias - *buffer_offset;
177da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák}
178da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
179da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšákenum r300_prepare_flags {
180307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    PREP_EMIT_STATES    = (1 << 0), /* call emit_dirty_state and friends? */
181eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    PREP_VALIDATE_VBOS  = (1 << 1), /* validate VBOs? */
18233e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák    PREP_EMIT_AOS       = (1 << 2), /* call emit_vertex_arrays? */
18333e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák    PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */
184eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    PREP_INDEXED        = (1 << 4)  /* is this draw_elements? */
185da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák};
186da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
187eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák/**
188eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák * Check if the requested number of dwords is available in the CS and
1890392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * if not, flush.
190eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák * \param r300          The context.
191eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák * \param flags         See r300_prepare_flags.
192eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák * \param cs_dwords     The number of dwords to reserve in CS.
1930392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \return TRUE if the CS was flushed
194eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák */
1950392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšákstatic boolean r300_reserve_cs_dwords(struct r300_context *r300,
196307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                      enum r300_prepare_flags flags,
197307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                      unsigned cs_dwords)
198e6632b4bf7cba5fe8a77d54635a3b617fa67185fMarek Olšák{
199eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    boolean flushed        = FALSE;
200307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    boolean first_draw     = flags & PREP_EMIT_STATES;
20133e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák    boolean emit_vertex_arrays       = flags & PREP_EMIT_AOS;
20233e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
203da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
204da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    /* Add dirty state, index offset, and AOS. */
205da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    if (first_draw) {
206da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák        cs_dwords += r300_get_num_dirty_dwords(r300);
207da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
208a6314eb47f0c916c51362dfbd0f1db21e72745eeMarek Olšák        if (r300->screen->caps.is_r500)
209da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák            cs_dwords += 2; /* emit_index_offset */
210da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
21133e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák        if (emit_vertex_arrays)
21233e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák            cs_dwords += 55; /* emit_vertex_arrays */
21355a6d3743436fb811dfa1825aabff82fb6610c04Marek Olšák
21433e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák        if (emit_vertex_arrays_swtcl)
21533e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák            cs_dwords += 7; /* emit_vertex_arrays_swtcl */
216da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    }
217da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
2180d699e8ee930c6c7e0f8abff14bf37e7f67807feMarek Olšák    cs_dwords += r300_get_num_cs_end_dwords(r300);
219da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
220da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    /* Reserve requested CS space. */
221d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák    if (cs_dwords > (RADEON_MAX_CMDBUF_DWORDS - r300->cs->cdw)) {
222d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák        r300_flush(&r300->context, RADEON_FLUSH_ASYNC, NULL);
223da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák        flushed = TRUE;
224da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    }
225da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák
2260392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    return flushed;
2270392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák}
2280392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
2290392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák/**
2300392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * Validate buffers and emit dirty state.
2310392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param r300          The context.
2320392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param flags         See r300_prepare_flags.
2330392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param index_buffer  The index buffer to validate. The parameter may be NULL.
23433e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák * \param buffer_offset The offset passed to emit_vertex_arrays.
2350392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param index_bias    The index bias to emit.
23665482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák * \param instance_id   Index of instance to render
2370392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \return TRUE if rendering should be skipped
2380392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák */
2390392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšákstatic boolean r300_emit_states(struct r300_context *r300,
2400392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák                                enum r300_prepare_flags flags,
2410392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák                                struct pipe_resource *index_buffer,
24233e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák                                int buffer_offset,
24365482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                                int index_bias, int instance_id)
2440392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák{
245307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    boolean first_draw     = flags & PREP_EMIT_STATES;
24633e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák    boolean emit_vertex_arrays       = flags & PREP_EMIT_AOS;
24733e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák    boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
2480392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    boolean indexed        = flags & PREP_INDEXED;
2494953ba6a717ad1d3aa4426d147b52d05932c47abMarek Olšák    boolean validate_vbos  = flags & PREP_VALIDATE_VBOS;
2500392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
251da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák    /* Validate buffers and emit dirty state if needed. */
2520392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    if (first_draw) {
253fd8d4b32ede6ebeae332539b71d38c36420e2654Marek Olšák        if (!r300_emit_buffer_validate(r300, validate_vbos,
254fd8d4b32ede6ebeae332539b71d38c36420e2654Marek Olšák                                       index_buffer)) {
255fd8d4b32ede6ebeae332539b71d38c36420e2654Marek Olšák           fprintf(stderr, "r300: CS space validation failed. "
256fd8d4b32ede6ebeae332539b71d38c36420e2654Marek Olšák                   "(not enough memory?) Skipping rendering.\n");
257fd8d4b32ede6ebeae332539b71d38c36420e2654Marek Olšák           return FALSE;
258c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák        }
259c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák
260da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák        r300_emit_dirty_state(r300);
261a6314eb47f0c916c51362dfbd0f1db21e72745eeMarek Olšák        if (r300->screen->caps.is_r500) {
262eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák            if (r300->screen->caps.has_tcl)
263eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák                r500_emit_index_bias(r300, index_bias);
264eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák            else
265eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák                r500_emit_index_bias(r300, 0);
266eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák        }
267eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
2685a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák        if (emit_vertex_arrays &&
2695a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák            (r300->vertex_arrays_dirty ||
2705a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák             r300->vertex_arrays_indexed != indexed ||
27165482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák             r300->vertex_arrays_offset != buffer_offset ||
27265482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák             r300->vertex_arrays_instance_id != instance_id)) {
27365482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák            r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id);
274eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
2755a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák            r300->vertex_arrays_dirty = FALSE;
2765a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák            r300->vertex_arrays_indexed = indexed;
2775a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák            r300->vertex_arrays_offset = buffer_offset;
27865482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák            r300->vertex_arrays_instance_id = instance_id;
2795a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák        }
2805a6ba08c21f24b14458a2084a170ddfbe8f5d793Marek Olšák
28133e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák        if (emit_vertex_arrays_swtcl)
28233e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák            r300_emit_vertex_arrays_swtcl(r300, indexed);
283e6632b4bf7cba5fe8a77d54635a3b617fa67185fMarek Olšák    }
284c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák
285c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák    return TRUE;
286e6632b4bf7cba5fe8a77d54635a3b617fa67185fMarek Olšák}
287e6632b4bf7cba5fe8a77d54635a3b617fa67185fMarek Olšák
2880392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák/**
2890392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * Check if the requested number of dwords is available in the CS and
2900392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * if not, flush. Then validate buffers and emit dirty state.
2910392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param r300          The context.
2920392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param flags         See r300_prepare_flags.
2930392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param index_buffer  The index buffer to validate. The parameter may be NULL.
2940392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param cs_dwords     The number of dwords to reserve in CS.
29533e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák * \param buffer_offset The offset passed to emit_vertex_arrays.
2960392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \param index_bias    The index bias to emit.
29765482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák * \param instance_id The instance to render.
2980392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák * \return TRUE if rendering should be skipped
2990392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák */
3000392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšákstatic boolean r300_prepare_for_rendering(struct r300_context *r300,
3010392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák                                          enum r300_prepare_flags flags,
3020392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák                                          struct pipe_resource *index_buffer,
3030392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák                                          unsigned cs_dwords,
30433e0b726e8837a3456e224d169170ead25ee2fc5Marek Olšák                                          int buffer_offset,
30565482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                                          int index_bias,
30665482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                                          int instance_id)
3070392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák{
308307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    /* Make sure there is enough space in the command stream and emit states. */
3090392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    if (r300_reserve_cs_dwords(r300, flags, cs_dwords))
310307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        flags |= PREP_EMIT_STATES;
3110392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
312c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    return r300_emit_states(r300, flags, index_buffer, buffer_offset,
31365482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                            index_bias, instance_id);
3140392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák}
3150392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
3165fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpsonstatic boolean immd_is_good_idea(struct r300_context *r300,
317bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák                                 unsigned count)
318948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson{
319bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    struct pipe_vertex_element* velem;
320be1af4394e060677b7db6bbb8e3301e38a3363daMarek Olšák    struct pipe_resource *buf;
321bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    boolean checked[PIPE_MAX_ATTRIBS] = {0};
322bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    unsigned vertex_element_count = r300->velems->count;
323bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    unsigned i, vbi;
324bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák
325505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson    if (DBG_ON(r300, DBG_NO_IMMD)) {
326505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson        return FALSE;
327505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson    }
328505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson
329505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson    if (r300->draw) {
330505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson        return FALSE;
331505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson    }
332505bea835501d834b0c999700d06280aa57cb6b1Corbin Simpson
333eb7ef433bbbeabda963e74adf0ef61c47883f292Marek Olšák    if (count * r300->velems->vertex_size_dwords > IMMD_DWORDS) {
334bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák        return FALSE;
335bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    }
336bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák
337bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    /* We shouldn't map buffers referenced by CS, busy buffers,
338bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák     * and ones placed in VRAM. */
339bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    for (i = 0; i < vertex_element_count; i++) {
340bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák        velem = &r300->velems->velem[i];
341bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák        vbi = velem->vertex_buffer_index;
342bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák
343bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák        if (!checked[vbi]) {
344c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák            buf = r300->vbuf_mgr->real_vertex_buffer[vbi];
345bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák
346d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák            if ((r300_resource(buf)->domain != RADEON_DOMAIN_GTT)) {
3470864851e2763291ff1ea2ceaa3c6f16b14abd362Marek Olšák                return FALSE;
3480864851e2763291ff1ea2ceaa3c6f16b14abd362Marek Olšák            }
3490864851e2763291ff1ea2ceaa3c6f16b14abd362Marek Olšák
350bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák            checked[vbi] = TRUE;
351bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák        }
352bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    }
353bcec6d851ce6ec2d948f03e5a1adfb5871e4e627Marek Olšák    return TRUE;
3545fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson}
3555fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
356a955f86b31304a1a0f35faa0e0861e920354e23bMarek Olšák/*****************************************************************************
3570864851e2763291ff1ea2ceaa3c6f16b14abd362Marek Olšák * The HWTCL draw functions.                                                 *
358a955f86b31304a1a0f35faa0e0861e920354e23bMarek Olšák ****************************************************************************/
359a955f86b31304a1a0f35faa0e0861e920354e23bMarek Olšák
360437583ea637ab402a06ae6683af6df35d52512d4Marek Olšákstatic void r300_draw_arrays_immediate(struct r300_context *r300,
361307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                       const struct pipe_draw_info *info)
3625fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson{
3635fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    struct pipe_vertex_element* velem;
3645fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    struct pipe_vertex_buffer* vbuf;
365e9441e1f88cc07365f4d7d9149ccefe128809645Roland Scheidegger    unsigned vertex_element_count = r300->velems->count;
366c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák    unsigned i, v, vbi;
3675fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
3685fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    /* Size of the vertex, in dwords. */
369eb7ef433bbbeabda963e74adf0ef61c47883f292Marek Olšák    unsigned vertex_size = r300->velems->vertex_size_dwords;
3705fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
371c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák    /* The number of dwords for this draw operation. */
372307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    unsigned dwords = 4 + info->count * vertex_size;
373c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák
3745fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    /* Size of the vertex element, in dwords. */
3755fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    unsigned size[PIPE_MAX_ATTRIBS];
3765fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
3775fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    /* Stride to the same attrib in the next vertex in the vertex buffer,
3785fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson     * in dwords. */
3798350d1d6f18d5c48fab4949d8b3c087b8390a49cMarek Olšák    unsigned stride[PIPE_MAX_ATTRIBS];
3805fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
3815fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    /* Mapped vertex buffers. */
38256029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák    uint32_t* map[PIPE_MAX_ATTRIBS] = {0};
3838350d1d6f18d5c48fab4949d8b3c087b8390a49cMarek Olšák    uint32_t* mapelem[PIPE_MAX_ATTRIBS];
3845fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
385fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    CS_LOCALS(r300);
386948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson
38765482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák    if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
388c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák        return;
389c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák
3905fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    /* Calculate the vertex size, offsets, strides etc. and map the buffers. */
3915fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    for (i = 0; i < vertex_element_count; i++) {
392e9441e1f88cc07365f4d7d9149ccefe128809645Roland Scheidegger        velem = &r300->velems->velem[i];
393c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák        size[i] = r300->velems->format_size[i] / 4;
3945fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson        vbi = velem->vertex_buffer_index;
395c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák        vbuf = &r300->vbuf_mgr->vertex_buffer[vbi];
3968350d1d6f18d5c48fab4949d8b3c087b8390a49cMarek Olšák        stride[i] = vbuf->stride / 4;
3975fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
3985fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson        /* Map the buffer. */
39956029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák        if (!map[vbi]) {
40056029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák            map[vbi] = (uint32_t*)r300->rws->buffer_map(
40156029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák                r300_resource(r300->vbuf_mgr->real_vertex_buffer[vbi])->buf,
40256029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák                r300->cs, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED);
403307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * info->start;
4045fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson        }
4058350d1d6f18d5c48fab4949d8b3c087b8390a49cMarek Olšák        mapelem[i] = map[vbi] + (velem->src_offset / 4);
4065fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    }
407948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson
408307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    r300_emit_draw_init(r300, info->mode, 0, info->count-1);
4093d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák
410fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    BEGIN_CS(dwords);
411fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
412307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, info->count * vertex_size);
413307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (info->count << 16) |
414307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            r300_translate_primitive(info->mode));
4155fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
4165fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    /* Emit vertices. */
417307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    for (v = 0; v < info->count; v++) {
4185fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson        for (i = 0; i < vertex_element_count; i++) {
419fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák            OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[i]);
420e4e5acc833d607bdf5cdd728f8a8c5064ea38838Corbin Simpson        }
421948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson    }
422fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    END_CS;
423948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson
4245fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    /* Unmap buffers. */
4255fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    for (i = 0; i < vertex_element_count; i++) {
426e9441e1f88cc07365f4d7d9149ccefe128809645Roland Scheidegger        vbi = r300->velems->velem[i].vertex_buffer_index;
4275fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson
42856029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák        if (map[vbi]) {
42956029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák            r300->rws->buffer_unmap(r300_resource(r300->vbuf_mgr->real_vertex_buffer[vbi])->buf);
43056029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák            map[vbi] = NULL;
4315fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson        }
4325fe71949d9e3790ce38ab616aee29079c6b67721Corbin Simpson    }
433948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson}
434948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson
43576034aaf655134c71e1ec619085c46251d037720Marek Olšákstatic void r300_emit_draw_arrays(struct r300_context *r300,
436e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák                                  unsigned mode,
437e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák                                  unsigned count)
43896b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson{
439233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    boolean alt_num_verts = count > 65535;
44096b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    CS_LOCALS(r300);
44196b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson
442671f1e1229877d459cfd76e2cf5ea89c8d881036Marek Olšák    if (count >= (1 << 24)) {
443671f1e1229877d459cfd76e2cf5ea89c8d881036Marek Olšák        fprintf(stderr, "r300: Got a huge number of vertices: %i, "
444671f1e1229877d459cfd76e2cf5ea89c8d881036Marek Olšák                "refusing to render.\n", count);
445671f1e1229877d459cfd76e2cf5ea89c8d881036Marek Olšák        return;
446671f1e1229877d459cfd76e2cf5ea89c8d881036Marek Olšák    }
447671f1e1229877d459cfd76e2cf5ea89c8d881036Marek Olšák
4483d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    r300_emit_draw_init(r300, mode, 0, count-1);
4493d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák
4503d5ac32f3bf95ceb9f3f03d6dedea5445ed35b18Marek Olšák    BEGIN_CS(2 + (alt_num_verts ? 2 : 0));
451233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    if (alt_num_verts) {
452233290f2031057b37fdadb650873b02be307ebc8Marek Olšák        OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
453233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    }
45496b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
45596b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
456233290f2031057b37fdadb650873b02be307ebc8Marek Olšák           r300_translate_primitive(mode) |
457233290f2031057b37fdadb650873b02be307ebc8Marek Olšák           (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0));
45896b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    END_CS;
45996b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson}
46096b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson
46176034aaf655134c71e1ec619085c46251d037720Marek Olšákstatic void r300_emit_draw_elements(struct r300_context *r300,
462e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák                                    struct pipe_resource* indexBuffer,
463e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák                                    unsigned indexSize,
464307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                    unsigned min_index,
465307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                    unsigned max_index,
466e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák                                    unsigned mode,
467e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák                                    unsigned start,
468aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák                                    unsigned count,
469aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák                                    uint16_t *imm_indices3)
47096b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson{
471aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    uint32_t count_dwords, offset_dwords;
472233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    boolean alt_num_verts = count > 65535;
47396b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    CS_LOCALS(r300);
4747da3cc4241b8550ccc1ec5ba3c93334094f5fb11Corbin Simpson
475307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    if (count >= (1 << 24) || max_index >= (1 << 24)) {
476146879284c6b844f35afe3a3ef3330726afbe8acMarek Olšák        fprintf(stderr, "r300: Got a huge number of vertices: %i, "
477307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                "refusing to render (max_index: %i).\n", count, max_index);
478146879284c6b844f35afe3a3ef3330726afbe8acMarek Olšák        return;
479146879284c6b844f35afe3a3ef3330726afbe8acMarek Olšák    }
480566390bedf4e5f24b5234e9dc08ecb1a6fd4d13bCorbin Simpson
481566390bedf4e5f24b5234e9dc08ecb1a6fd4d13bCorbin Simpson    DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
482307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        count, min_index, max_index);
483566390bedf4e5f24b5234e9dc08ecb1a6fd4d13bCorbin Simpson
484307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    r300_emit_draw_init(r300, mode, min_index, max_index);
485aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák
486aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    /* If start is odd, render the first triangle with indices embedded
487aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák     * in the command stream. This will increase start by 3 and make it
488aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák     * even. We can then proceed without a fallback. */
489aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    if (indexSize == 2 && (start & 1) &&
490aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        mode == PIPE_PRIM_TRIANGLES) {
491aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        BEGIN_CS(4);
492aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 2);
493aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (3 << 16) |
494aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák               R300_VAP_VF_CNTL__PRIM_TRIANGLES);
495aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        OUT_CS(imm_indices3[1] << 16 | imm_indices3[0]);
496aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        OUT_CS(imm_indices3[2]);
497aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        END_CS;
498aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák
499aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        start += 3;
500aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        count -= 3;
501aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        if (!count)
502aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák           return;
503aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    }
504aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák
505aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    offset_dwords = indexSize * start / sizeof(uint32_t);
506aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák
507aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    BEGIN_CS(8 + (alt_num_verts ? 2 : 0));
508aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    if (alt_num_verts) {
509aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
510aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    }
51196b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
51296b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    if (indexSize == 4) {
513902ccfcb40f21e1a5fca2f1bec1cbbabb053d8cfMarek Olšák        count_dwords = count;
51496b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
51596b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson               R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
516233290f2031057b37fdadb650873b02be307ebc8Marek Olšák               r300_translate_primitive(mode) |
517233290f2031057b37fdadb650873b02be307ebc8Marek Olšák               (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0));
51896b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    } else {
519902ccfcb40f21e1a5fca2f1bec1cbbabb053d8cfMarek Olšák        count_dwords = (count + 1) / 2;
52096b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
521233290f2031057b37fdadb650873b02be307ebc8Marek Olšák               r300_translate_primitive(mode) |
522233290f2031057b37fdadb650873b02be307ebc8Marek Olšák               (alt_num_verts ? R500_VAP_VF_CNTL__USE_ALT_NUM_VERTS : 0));
52396b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    }
52496b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson
52596b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
52696b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
52796b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson           (0 << R300_INDX_BUFFER_SKIP_SHIFT));
528233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    OUT_CS(offset_dwords << 2);
529ce9c0d280104c8001a3ee360b07218ad3d260e46Marek Olšák    OUT_CS(count_dwords);
53056ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák    OUT_CS_RELOC(r300_resource(indexBuffer));
53196b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson    END_CS;
53296b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson}
53396b729f926fafeca6479eed0933bc4275fb7843bCorbin Simpson
534a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšákstatic void r300_draw_elements_immediate(struct r300_context *r300,
535307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                         const struct pipe_draw_info *info)
536a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák{
537a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    uint8_t *ptr1;
538a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    uint16_t *ptr2;
539a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    uint32_t *ptr4;
540a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    unsigned index_size = r300->index_buffer.index_size;
541307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    unsigned i, count_dwords = index_size == 4 ? info->count :
542307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                                 (info->count + 1) / 2;
543a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    CS_LOCALS(r300);
544a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
545a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
546a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    if (!r300_prepare_for_rendering(r300,
547307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
54865482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák            PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
549a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        return;
550a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
551307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    r300_emit_draw_init(r300, info->mode, info->min_index, info->max_index);
552a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
553a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    BEGIN_CS(2 + count_dwords);
554a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count_dwords);
555a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
556a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    switch (index_size) {
557a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    case 1:
558a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        ptr1 = r300_resource(r300->index_buffer.buffer)->b.user_ptr;
559307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        ptr1 += info->start;
560a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
561307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
562307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák               r300_translate_primitive(info->mode));
563a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
564307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        if (info->index_bias && !r300->screen->caps.is_r500) {
565307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            for (i = 0; i < info->count-1; i += 2)
566307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
567307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                        (ptr1[i]   + info->index_bias));
568a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
569307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            if (info->count & 1)
570307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                OUT_CS(ptr1[i] + info->index_bias);
571a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        } else {
572307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            for (i = 0; i < info->count-1; i += 2)
573a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák                OUT_CS(((ptr1[i+1]) << 16) |
574a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák                        (ptr1[i]  ));
575a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
576307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            if (info->count & 1)
577a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák                OUT_CS(ptr1[i]);
578a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        }
579a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        break;
580a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
581a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    case 2:
582a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        ptr2 = (uint16_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
583307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        ptr2 += info->start;
584a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
585307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
586307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák               r300_translate_primitive(info->mode));
587a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
588307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        if (info->index_bias && !r300->screen->caps.is_r500) {
589307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            for (i = 0; i < info->count-1; i += 2)
590307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
591307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                        (ptr2[i]   + info->index_bias));
592a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
593307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            if (info->count & 1)
594307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                OUT_CS(ptr2[i] + info->index_bias);
595a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        } else {
596a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák            OUT_CS_TABLE(ptr2, count_dwords);
597a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        }
598a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        break;
599a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
600a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    case 4:
601a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        ptr4 = (uint32_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
602307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        ptr4 += info->start;
603a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
604307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
605a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák               R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
606307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák               r300_translate_primitive(info->mode));
607a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
608307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        if (info->index_bias && !r300->screen->caps.is_r500) {
609307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            for (i = 0; i < info->count; i++)
610307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                OUT_CS(ptr4[i] + info->index_bias);
611a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        } else {
612a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák            OUT_CS_TABLE(ptr4, count_dwords);
613a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        }
614a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        break;
615a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    }
616a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák    END_CS;
617a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák}
618a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák
619307408a4f89be2613cac39c5f0cd776a71039965Marek Olšákstatic void r300_draw_elements(struct r300_context *r300,
62065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                               const struct pipe_draw_info *info,
62165482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                               int instance_id)
6223445f476977ae403cef9ca15661fa0f96ff50ecaMaciej Cencora{
623be1af4394e060677b7db6bbb8e3301e38a3363daMarek Olšák    struct pipe_resource *indexBuffer = r300->index_buffer.buffer;
624be1af4394e060677b7db6bbb8e3301e38a3363daMarek Olšák    unsigned indexSize = r300->index_buffer.index_size;
625287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct pipe_resource* orgIndexBuffer = indexBuffer;
626307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    unsigned start = info->start;
627307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    unsigned count = info->count;
628b71bfc4400e1d7c15a2bebbbd3b26a8770fbf546Marek Olšák    boolean alt_num_verts = r300->screen->caps.is_r500 &&
629a6314eb47f0c916c51362dfbd0f1db21e72745eeMarek Olšák                            count > 65536;
630233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    unsigned short_count;
631eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
632aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    uint16_t indices3[3];
6331f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson
634307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    if (info->index_bias && !r300->screen->caps.is_r500) {
635307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        r300_split_index_bias(r300, info->index_bias, &buffer_offset, &index_offset);
636eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák    }
637eb2a1521cfa1e56f462f035f482e7a99c18a4b5fMarek Olšák
638aa5422327d6f49d8940c2b933c2342ad8968032cMarek Olšák    r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset,
639aa5422327d6f49d8940c2b933c2342ad8968032cMarek Olšák                                &start, count);
640264e548d86ff2e03a097c23e792fe457e77e775cCorbin Simpson
641237880463d5168cad8df0bae6018b5fd76617777Marek Olšák    /* Fallback for misaligned ushort indices. */
6429c448817f7d62ae885019d816a7ecbc2c7bc34c1Marek Olšák    if (indexSize == 2 && (start & 1) &&
64356ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák        !r300_resource(indexBuffer)->b.user_ptr) {
64456029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák        /* If we got here, then orgIndexBuffer == indexBuffer. */
64556029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák        uint16_t *ptr = r300->rws->buffer_map(r300_resource(orgIndexBuffer)->buf,
64656029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák                                              r300->cs,
64756029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák                                              PIPE_TRANSFER_READ |
64856029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák                                              PIPE_TRANSFER_UNSYNCHRONIZED);
649237880463d5168cad8df0bae6018b5fd76617777Marek Olšák
650307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        if (info->mode == PIPE_PRIM_TRIANGLES) {
651aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák           memcpy(indices3, ptr + start, 6);
652aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        } else {
653aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák            /* Copy the mapped index buffer directly to the upload buffer.
654aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák             * The start index will be aligned simply from the fact that
655476cec37d615df7c7329ef74d4a7ea7200b2d8fbMarek Olšák             * every sub-buffer in the upload buffer is aligned. */
656476cec37d615df7c7329ef74d4a7ea7200b2d8fbMarek Olšák            r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start,
657476cec37d615df7c7329ef74d4a7ea7200b2d8fbMarek Olšák                                     count, (uint8_t*)ptr);
658aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák        }
65956029ce52bafbc51b5b6660383767257b7770cd7Marek Olšák        r300->rws->buffer_unmap(r300_resource(orgIndexBuffer)->buf);
660237880463d5168cad8df0bae6018b5fd76617777Marek Olšák    } else {
66156ba7e913fef0ea2b1bead582108f9ab3ab8263dMarek Olšák        if (r300_resource(indexBuffer)->b.user_ptr)
662476cec37d615df7c7329ef74d4a7ea7200b2d8fbMarek Olšák            r300_upload_index_buffer(r300, &indexBuffer, indexSize,
663476cec37d615df7c7329ef74d4a7ea7200b2d8fbMarek Olšák                                     &start, count,
664476cec37d615df7c7329ef74d4a7ea7200b2d8fbMarek Olšák                                     r300_resource(indexBuffer)->b.user_ptr);
665237880463d5168cad8df0bae6018b5fd76617777Marek Olšák    }
66668e58a96e80865878e6881dc4d34fcc3ec24eb19Dave Airlie
667aedbf05d31c1a8d7d3c2742524abf2db2422b2feMarek Olšák    /* 19 dwords for emit_draw_elements. Give up if the function fails. */
668c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák    if (!r300_prepare_for_rendering(r300,
669307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
67065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák            PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
67165482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák            instance_id))
672c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák        goto done;
6733445f476977ae403cef9ca15661fa0f96ff50ecaMaciej Cencora
674233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    if (alt_num_verts || count <= 65535) {
675307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        r300_emit_draw_elements(r300, indexBuffer, indexSize, info->min_index,
676307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                info->max_index, info->mode, start, count,
677307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                indices3);
678233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    } else {
679233290f2031057b37fdadb650873b02be307ebc8Marek Olšák        do {
680d173f1ba8a3d77e46f73ecb00378ea9598fe2c68Marek Olšák            if (indexSize == 2 && (start & 1))
681d173f1ba8a3d77e46f73ecb00378ea9598fe2c68Marek Olšák                short_count = MIN2(count, 65535);
682d173f1ba8a3d77e46f73ecb00378ea9598fe2c68Marek Olšák            else
683d173f1ba8a3d77e46f73ecb00378ea9598fe2c68Marek Olšák                short_count = MIN2(count, 65534);
684d173f1ba8a3d77e46f73ecb00378ea9598fe2c68Marek Olšák
68576034aaf655134c71e1ec619085c46251d037720Marek Olšák            r300_emit_draw_elements(r300, indexBuffer, indexSize,
686307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                     info->min_index, info->max_index,
687307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                     info->mode, start, short_count, indices3);
688233290f2031057b37fdadb650873b02be307ebc8Marek Olšák
689233290f2031057b37fdadb650873b02be307ebc8Marek Olšák            start += short_count;
690233290f2031057b37fdadb650873b02be307ebc8Marek Olšák            count -= short_count;
691e6632b4bf7cba5fe8a77d54635a3b617fa67185fMarek Olšák
692da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák            /* 15 dwords for emit_draw_elements */
693da180a8d34a3d17345d71b215a7d20f24fe4b078Marek Olšák            if (count) {
694c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák                if (!r300_prepare_for_rendering(r300,
695c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák                        PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
69665482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                        indexBuffer, 19, buffer_offset, info->index_bias,
69765482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                        instance_id))
698c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák                    goto done;
699e6632b4bf7cba5fe8a77d54635a3b617fa67185fMarek Olšák            }
700233290f2031057b37fdadb650873b02be307ebc8Marek Olšák        } while (count);
701233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    }
702264e548d86ff2e03a097c23e792fe457e77e775cCorbin Simpson
703c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšákdone:
70460628c65c902f68c600b3d79c06e928aa3286285Łukasz Krotowski    if (indexBuffer != orgIndexBuffer) {
705287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell        pipe_resource_reference( &indexBuffer, NULL );
706264e548d86ff2e03a097c23e792fe457e77e775cCorbin Simpson    }
7071f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson}
7081f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson
709307408a4f89be2613cac39c5f0cd776a71039965Marek Olšákstatic void r300_draw_arrays(struct r300_context *r300,
71065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                             const struct pipe_draw_info *info,
71165482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                             int instance_id)
7121f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson{
713b71bfc4400e1d7c15a2bebbbd3b26a8770fbf546Marek Olšák    boolean alt_num_verts = r300->screen->caps.is_r500 &&
714307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                            info->count > 65536;
715307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    unsigned start = info->start;
716307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    unsigned count = info->count;
717233290f2031057b37fdadb650873b02be307ebc8Marek Olšák    unsigned short_count;
718ef513776b5bdd11968d2ca03862e9d1ac48e099fCorbin Simpson
719437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák    /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
720437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák    if (!r300_prepare_for_rendering(r300,
721307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                                    PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
72265482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                                    NULL, 9, start, 0, instance_id))
723437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák        return;
724437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák
725437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák    if (alt_num_verts || count <= 65535) {
726307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        r300_emit_draw_arrays(r300, info->mode, count);
72772778a9d254f6c9c63d86413936ee7f3e5a6e56eCorbin Simpson    } else {
728437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák        do {
729437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák            short_count = MIN2(count, 65535);
730307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            r300_emit_draw_arrays(r300, info->mode, short_count);
731233290f2031057b37fdadb650873b02be307ebc8Marek Olšák
732437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák            start += short_count;
733437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák            count -= short_count;
734e6632b4bf7cba5fe8a77d54635a3b617fa67185fMarek Olšák
735437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák            /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
736437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák            if (count) {
737437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák                if (!r300_prepare_for_rendering(r300,
738437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák                                                PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
73965482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                                                start, 0, instance_id))
740437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák                    return;
741437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák            }
742437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák        } while (count);
743948b7e97a6d82dc61debc741c2970d9decfdf302Corbin Simpson    }
7441f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson}
7451f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson
74665482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšákstatic void r300_draw_arrays_instanced(struct r300_context *r300,
74765482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                                       const struct pipe_draw_info *info)
74865482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák{
74965482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák    int i;
75065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák
75165482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák    for (i = 0; i < info->instance_count; i++)
75265482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák        r300_draw_arrays(r300, info, i);
75365482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák}
75465482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák
75565482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšákstatic void r300_draw_elements_instanced(struct r300_context *r300,
75665482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                                         const struct pipe_draw_info *info)
75765482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák{
75865482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák    int i;
75965482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák
76065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák    for (i = 0; i < info->instance_count; i++)
76165482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák        r300_draw_elements(r300, info, i);
76265482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák}
76365482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák
7646d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wustatic void r300_draw_vbo(struct pipe_context* pipe,
765307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                          const struct pipe_draw_info *dinfo)
7666d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu{
7676d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu    struct r300_context* r300 = r300_context(pipe);
768307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    struct pipe_draw_info info = *dinfo;
769c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    boolean buffers_updated, uploader_flushed;
770307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák
771307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    info.indexed = info.indexed && r300->index_buffer.buffer;
7726d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu
773437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák    if (r300->skip_rendering ||
774307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        !u_trim_pipe_prim(info.mode, &info.count)) {
775ed7cb289b3d0641a63e7e91374fb29f47321331aMarek Olšák        return;
776ed7cb289b3d0641a63e7e91374fb29f47321331aMarek Olšák    }
777d3ca8a4eddcecced82a41201cf59a732f0b8e18bMarek Olšák
7784609be44106274fa88cfdf935257dfbe51cb6039Marek Olšák    r300_update_derived_state(r300);
7794609be44106274fa88cfdf935257dfbe51cb6039Marek Olšák
780437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák    /* Start the vbuf manager and update buffers if needed. */
781307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info,
782c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák                          &buffers_updated, &uploader_flushed);
783c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    if (buffers_updated) {
784c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák        r300->vertex_arrays_dirty = TRUE;
785c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    }
786c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák
787437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák    /* Draw. */
788307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák    if (info.indexed) {
789307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        info.start += r300->index_buffer.offset;
790307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        info.max_index = MIN2(r300->vbuf_mgr->max_index, info.max_index);
791307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák
792307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        if (info.instance_count <= 1) {
793307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            if (info.count <= 8 &&
794307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                r300_resource(r300->index_buffer.buffer)->b.user_ptr) {
795307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                r300_draw_elements_immediate(r300, &info);
796307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            } else {
79765482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                r300_draw_elements(r300, &info, -1);
798307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            }
799a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        } else {
80065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák            r300_draw_elements_instanced(r300, &info);
801a0c293ec117c8a6f471061076ba87e245759e0f6Marek Olšák        }
802ed7cb289b3d0641a63e7e91374fb29f47321331aMarek Olšák    } else {
803307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák        if (info.instance_count <= 1) {
804307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            if (immd_is_good_idea(r300, info.count)) {
805307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                r300_draw_arrays_immediate(r300, &info);
806307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            } else {
80765482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                r300_draw_arrays(r300, &info, -1);
808307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            }
809437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák        } else {
81065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák            r300_draw_arrays_instanced(r300, &info);
811437583ea637ab402a06ae6683af6df35d52512d4Marek Olšák        }
812ed7cb289b3d0641a63e7e91374fb29f47321331aMarek Olšák    }
813ed7cb289b3d0641a63e7e91374fb29f47321331aMarek Olšák
814c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    u_vbuf_mgr_draw_end(r300->vbuf_mgr);
8156d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu}
8166d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu
8171f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson/****************************************************************************
8181f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson * The rest of this file is for SW TCL rendering only. Please be polite and *
8191f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson * keep these functions separated so that they are easier to locate. ~C.    *
8201f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson ***************************************************************************/
8211f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson
8226d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu/* SW TCL elements, using Draw. */
8236d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wustatic void r300_swtcl_draw_vbo(struct pipe_context* pipe,
8246d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu                                const struct pipe_draw_info *info)
825c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson{
826c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson    struct r300_context* r300 = r300_context(pipe);
827287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
8283f4680d8e229d87e62972d0632c577873944d89dMarek Olšák    struct pipe_transfer *ib_transfer = NULL;
8296d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu    unsigned count = info->count;
830c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson    int i;
8310392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    void *indices = NULL;
8320392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    boolean indexed = info->indexed && r300->index_buffer.buffer;
833c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson
8340179c5a95b604105ead8d642e8313740adc2a686Marek Olšák    if (r300->skip_rendering) {
8350179c5a95b604105ead8d642e8313740adc2a686Marek Olšák        return;
8360179c5a95b604105ead8d642e8313740adc2a686Marek Olšák    }
8370179c5a95b604105ead8d642e8313740adc2a686Marek Olšák
8386d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu    if (!u_trim_pipe_prim(info->mode, &count)) {
83903f212b0d85fed5dec9a855fb6d079e5fdb60ac9Keith Whitwell        return;
840c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson    }
841c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson
842dca9624201319950aa4c78ad5cc7dd7121e2b347Marek Olšák    r300_update_derived_state(r300);
843dca9624201319950aa4c78ad5cc7dd7121e2b347Marek Olšák
8440392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    r300_reserve_cs_dwords(r300,
845307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák            PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL |
8460392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák            (indexed ? PREP_INDEXED : 0),
8470392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák            indexed ? 256 : 6);
8480392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
849c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
850c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák        if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
851d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák            void *buf = pipe_buffer_map(pipe,
852c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák                                  r300->vbuf_mgr->vertex_buffer[i].buffer,
8536ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                  PIPE_TRANSFER_READ |
8546ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                  PIPE_TRANSFER_UNSYNCHRONIZED,
855d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák                                  &vb_transfer[i]);
856d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák            draw_set_mapped_vertex_buffer(r300->draw, i, buf);
857d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák        }
858c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson    }
859c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson
8600392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    if (indexed) {
8616d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu        indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
8626ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                  PIPE_TRANSFER_READ |
8636ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                  PIPE_TRANSFER_UNSYNCHRONIZED, &ib_transfer);
8646d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu    }
8656d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu
86622f6026324f63c142925244ff575fefc29a90389Chia-I Wu    draw_set_mapped_index_buffer(r300->draw, indices);
867c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson
8680392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    r300->draw_vbo_locked = TRUE;
869d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    r300->draw_first_emitted = FALSE;
87022f6026324f63c142925244ff575fefc29a90389Chia-I Wu    draw_vbo(r300->draw, info);
871412cdcd479df13c27242090d6e0727389eb2a0daMarek Olšák    draw_flush(r300->draw);
872428dc6d7d2cf6a5da37a2ea7ce436cf521b009a2Marek Olšák    r300->draw_vbo_locked = FALSE;
873412cdcd479df13c27242090d6e0727389eb2a0daMarek Olšák
874c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák    for (i = 0; i < r300->vbuf_mgr->nr_vertex_buffers; i++) {
875c95bc1224a4b20b9470ddcb37b5f78975991073bMarek Olšák        if (r300->vbuf_mgr->vertex_buffer[i].buffer) {
876ec51092a72e2dff1e9b1362d813fe4691cda89b7Marek Olšák            pipe_buffer_unmap(pipe, vb_transfer[i]);
877d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák            draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
878d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák        }
879c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson    }
8806d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu
8810392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    if (indexed) {
882ec51092a72e2dff1e9b1362d813fe4691cda89b7Marek Olšák        pipe_buffer_unmap(pipe, ib_transfer);
88322f6026324f63c142925244ff575fefc29a90389Chia-I Wu        draw_set_mapped_index_buffer(r300->draw, NULL);
8846d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu    }
885c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson}
886c9167d868cfb2ba821f01e0217e3880c5df4c97bCorbin Simpson
8871f7f9bab8139681e1dcbc6c10fb42965059d1395Corbin Simpson/* Object for rendering using Draw. */
8885c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstruct r300_render {
889e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson    /* Parent class */
89081daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    struct vbuf_render base;
8914b01e6f614052e48971f2b2ff474fb66afc4f752Nicolai Hähnle
89281daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    /* Pipe context */
893e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson    struct r300_context* r300;
89481daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
89581daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    /* Vertex information */
89681daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    size_t vertex_size;
89781daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    unsigned prim;
89881daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    unsigned hwprim;
89981daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
90081daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    /* VBO */
901622b31925b6a68b496cd65c627b8a1ed7e811cc3Cooper Yuan    size_t vbo_max_used;
902622b31925b6a68b496cd65c627b8a1ed7e811cc3Cooper Yuan    void * vbo_ptr;
903287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
904dca9624201319950aa4c78ad5cc7dd7121e2b347Marek Olšák    struct pipe_transfer *vbo_transfer;
905e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson};
906e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
9075c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic INLINE struct r300_render*
9085c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonr300_render(struct vbuf_render* render)
90981daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson{
9105c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    return (struct r300_render*)render;
911e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
912e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
91381daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpsonstatic const struct vertex_info*
9145c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonr300_render_get_vertex_info(struct vbuf_render* render)
915f097465bb85d3ca212a23c2dcc9cf73988de9160Corbin Simpson{
9165c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
91781daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    struct r300_context* r300 = r300render->r300;
91881daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
919942762cd973af0df75040de21d3321cd19829e70Marek Olšák    return &r300->vertex_info;
920f097465bb85d3ca212a23c2dcc9cf73988de9160Corbin Simpson}
921f097465bb85d3ca212a23c2dcc9cf73988de9160Corbin Simpson
9225c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic boolean r300_render_allocate_vertices(struct vbuf_render* render,
92381daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson                                                   ushort vertex_size,
92481daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson                                                   ushort count)
925e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
9265c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
92781daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    struct r300_context* r300 = r300render->r300;
92881daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    struct pipe_screen* screen = r300->context.screen;
92981daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    size_t size = (size_t)vertex_size * (size_t)count;
930f097465bb85d3ca212a23c2dcc9cf73988de9160Corbin Simpson
9310392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    DBG(r300, DBG_DRAW, "r300: render_allocate_vertices (size: %d)\n", size);
9320392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
9330392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    if (size + r300->draw_vbo_offset > r300->draw_vbo_size)
934622b31925b6a68b496cd65c627b8a1ed7e811cc3Cooper Yuan    {
935eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie	pipe_resource_reference(&r300->vbo, NULL);
936eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie        r300->vbo = pipe_buffer_create(screen,
937eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie				       PIPE_BIND_VERTEX_BUFFER,
938eafb7f234d11a290b00dcaf5492b9bdad1cf5148Marek Olšák				       PIPE_USAGE_STREAM,
939eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie				       R300_MAX_DRAW_VBO_SIZE);
9400392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák        r300->draw_vbo_offset = 0;
941eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie        r300->draw_vbo_size = R300_MAX_DRAW_VBO_SIZE;
94245b77830eb6fa1b712b0416a27990ad8b6eaf78bJoakim Sindholt    }
943f097465bb85d3ca212a23c2dcc9cf73988de9160Corbin Simpson
94481daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    r300render->vertex_size = vertex_size;
945f097465bb85d3ca212a23c2dcc9cf73988de9160Corbin Simpson
946eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie    return (r300->vbo) ? TRUE : FALSE;
947e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
948e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
9495c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic void* r300_render_map_vertices(struct vbuf_render* render)
950e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
9515c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
952eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie    struct r300_context* r300 = r300render->r300;
95381daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
954500160a3c9b0a777586c60abd3d136a5c30937f4Marek Olšák    assert(!r300render->vbo_transfer);
955500160a3c9b0a777586c60abd3d136a5c30937f4Marek Olšák
9560392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    DBG(r300, DBG_DRAW, "r300: render_map_vertices\n");
9570392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
958287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context,
959eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie					  r300->vbo,
9606ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                          PIPE_TRANSFER_WRITE |
9616ccab620a0e7364ab6c0d902b3ddf58ee988f7faMarek Olšák                                          PIPE_TRANSFER_UNSYNCHRONIZED,
962287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell					  &r300render->vbo_transfer);
963622b31925b6a68b496cd65c627b8a1ed7e811cc3Cooper Yuan
964d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák    assert(r300render->vbo_ptr);
965d8d7a3e0f9629a220e2394dd7c6634f2d6a93e20Marek Olšák
9660392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    return ((uint8_t*)r300render->vbo_ptr + r300->draw_vbo_offset);
967e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
968e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
9695c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic void r300_render_unmap_vertices(struct vbuf_render* render,
970b003b2f6dd4ddba45910560ab6d495fb01b5301bCorbin Simpson                                             ushort min,
971b003b2f6dd4ddba45910560ab6d495fb01b5301bCorbin Simpson                                             ushort max)
972e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
9735c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
974287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell    struct pipe_context* context = &r300render->r300->context;
975eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie    struct r300_context* r300 = r300render->r300;
97681daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
977500160a3c9b0a777586c60abd3d136a5c30937f4Marek Olšák    assert(r300render->vbo_transfer);
978500160a3c9b0a777586c60abd3d136a5c30937f4Marek Olšák
9790392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    DBG(r300, DBG_DRAW, "r300: render_unmap_vertices\n");
9800392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
981751aa58e01bd2b4f35aa0e1477d77a0dc5490f39Nicolai Hähnle    r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
982622b31925b6a68b496cd65c627b8a1ed7e811cc3Cooper Yuan                                    r300render->vertex_size * (max + 1));
983ec51092a72e2dff1e9b1362d813fe4691cda89b7Marek Olšák    pipe_buffer_unmap(context, r300render->vbo_transfer);
984500160a3c9b0a777586c60abd3d136a5c30937f4Marek Olšák
985500160a3c9b0a777586c60abd3d136a5c30937f4Marek Olšák    r300render->vbo_transfer = NULL;
986e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
987e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
9885c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic void r300_render_release_vertices(struct vbuf_render* render)
989e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
9905c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
9910392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    struct r300_context* r300 = r300render->r300;
99281daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
9930392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    DBG(r300, DBG_DRAW, "r300: render_release_vertices\n");
9940392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
9950392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    r300->draw_vbo_offset += r300render->vbo_max_used;
996622b31925b6a68b496cd65c627b8a1ed7e811cc3Cooper Yuan    r300render->vbo_max_used = 0;
997e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
998e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
9995c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic boolean r300_render_set_primitive(struct vbuf_render* render,
100081daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson                                               unsigned prim)
1001e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
10025c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
100381daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
100406e464c2d57552d5ccde2b98885aeef953d8b2a1Corbin Simpson    r300render->prim = prim;
100506e464c2d57552d5ccde2b98885aeef953d8b2a1Corbin Simpson    r300render->hwprim = r300_translate_primitive(prim);
100681daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
1007fd5411fe362a398ab0506c2becdd5953711476d5Corbin Simpson    return TRUE;
1008e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
1009e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
101076034aaf655134c71e1ec619085c46251d037720Marek Olšákstatic void r300_render_draw_arrays(struct vbuf_render* render,
1011a955f86b31304a1a0f35faa0e0861e920354e23bMarek Olšák                                    unsigned start,
1012a955f86b31304a1a0f35faa0e0861e920354e23bMarek Olšák                                    unsigned count)
1013922000d38a6e90c525328b381f04fea1244f616fCorbin Simpson{
10145c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
1015922000d38a6e90c525328b381f04fea1244f616fCorbin Simpson    struct r300_context* r300 = r300render->r300;
10163bb1724f3796ad799a93c319e03eae48c0114f1eCorbin Simpson    uint8_t* ptr;
10173bb1724f3796ad799a93c319e03eae48c0114f1eCorbin Simpson    unsigned i;
1018c1ef21833a6dfd763fae97cd7f3bf545b8b7e87eMarek Olšák    unsigned dwords = 6;
1019922000d38a6e90c525328b381f04fea1244f616fCorbin Simpson
1020922000d38a6e90c525328b381f04fea1244f616fCorbin Simpson    CS_LOCALS(r300);
1021b224264c9db83a7b8df222ba3625b0f23874e30dVinson Lee    (void) i; (void) ptr;
1022b224264c9db83a7b8df222ba3625b0f23874e30dVinson Lee
102350db6dba65560c1fb598d495d7d4103019bbbea5Marek Olšák    DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count);
1024d265706cd3849679e543797b4ad4edf463cd4586Corbin Simpson
1025d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    if (r300->draw_first_emitted) {
1026d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák        if (!r300_prepare_for_rendering(r300,
1027307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
102865482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                NULL, dwords, 0, 0, -1))
1029d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák            return;
1030d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    } else {
1031d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák        if (!r300_emit_states(r300,
1032307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
103365482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                NULL, 0, 0, -1))
1034d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák            return;
1035d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    }
10360392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
1037c1ef21833a6dfd763fae97cd7f3bf545b8b7e87eMarek Olšák    BEGIN_CS(dwords);
1038ee6255052cd3adb5074916a62c8f59a421c7fa2dMarek Olšák    OUT_CS_REG(R300_GA_COLOR_CONTROL,
1039ee6255052cd3adb5074916a62c8f59a421c7fa2dMarek Olšák            r300_provoking_vertex_fixes(r300, r300render->prim));
1040c1ef21833a6dfd763fae97cd7f3bf545b8b7e87eMarek Olšák    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
10418066edb2a254d15ed92c2d350a7799adf3cca0d7Corbin Simpson    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
1042d265706cd3849679e543797b4ad4edf463cd4586Corbin Simpson    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
104365021162a494cfffd6b0d50d3e93fb1082e90332Corbin Simpson           r300render->hwprim);
1044922000d38a6e90c525328b381f04fea1244f616fCorbin Simpson    END_CS;
1045d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák
1046d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    r300->draw_first_emitted = TRUE;
10478e234d655dc3d8f8edefbf3bffdb726a331da2cdCorbin Simpson}
10488e234d655dc3d8f8edefbf3bffdb726a331da2cdCorbin Simpson
104976034aaf655134c71e1ec619085c46251d037720Marek Olšákstatic void r300_render_draw_elements(struct vbuf_render* render,
1050740e50c60f03d194aafab93d5251699964800979Brian Paul                                      const ushort* indices,
1051740e50c60f03d194aafab93d5251699964800979Brian Paul                                      uint count)
1052e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
10535c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = r300_render(render);
105481daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    struct r300_context* r300 = r300render->r300;
1055a4e0a46a8d6a4f308216c085849305ad82c52f15Corbin Simpson    int i;
10561345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák    unsigned end_cs_dwords;
10570392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    unsigned max_index = (r300->draw_vbo_size - r300->draw_vbo_offset) /
1058c1ef21833a6dfd763fae97cd7f3bf545b8b7e87eMarek Olšák                         (r300render->r300->vertex_info.size * 4) - 1;
10591345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák    unsigned short_count;
1060ae182296ce28f1efc8a08d9ddcf6b8a79b1bc14bMarek Olšák    unsigned free_dwords;
106181daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
106281daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    CS_LOCALS(r300);
106350db6dba65560c1fb598d495d7d4103019bbbea5Marek Olšák    DBG(r300, DBG_DRAW, "r300: render_draw_elements (count: %d)\n", count);
106481daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
1065d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    if (r300->draw_first_emitted) {
1066d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák        if (!r300_prepare_for_rendering(r300,
1067307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
106865482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                NULL, 256, 0, 0, -1))
1069d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák            return;
1070d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    } else {
1071d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák        if (!r300_emit_states(r300,
1072307408a4f89be2613cac39c5f0cd776a71039965Marek Olšák                PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
107365482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                NULL, 0, 0, -1))
1074d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák            return;
1075d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    }
1076c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák
10770392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák    /* Below we manage the CS space manually because there may be more
10780392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák     * indices than it can fit in CS. */
10790392e48867c27f2aa445c5c9b35f4a52ecef2f2dMarek Olšák
10800d699e8ee930c6c7e0f8abff14bf37e7f67807feMarek Olšák    end_cs_dwords = r300_get_num_cs_end_dwords(r300);
10811345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák
10821345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák    while (count) {
1083d35aeff4bb0b03450b2c3c08bd7f84db5bf43283Marek Olšák        free_dwords = RADEON_MAX_CMDBUF_DWORDS - r300->cs->cdw;
10841345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák
1085ae182296ce28f1efc8a08d9ddcf6b8a79b1bc14bMarek Olšák        short_count = MIN2(count, (free_dwords - end_cs_dwords - 6) * 2);
10861345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák
10871345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        BEGIN_CS(6 + (short_count+1)/2);
10881345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        OUT_CS_REG(R300_GA_COLOR_CONTROL,
10891345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák                r300_provoking_vertex_fixes(r300, r300render->prim));
10901345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index);
10911345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (short_count+1)/2);
10921345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (short_count << 16) |
10931345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák               r300render->hwprim);
10941345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        for (i = 0; i < short_count-1; i += 2) {
10951345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák            OUT_CS(indices[i+1] << 16 | indices[i]);
10961345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        }
10971345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        if (short_count % 2) {
10981345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák            OUT_CS(indices[short_count-1]);
10991345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        }
11001345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        END_CS;
1101671f1e1229877d459cfd76e2cf5ea89c8d881036Marek Olšák
11021345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        /* OK now subtract the emitted indices and see if we need to emit
11031345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák         * another draw packet. */
11041345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        indices += short_count;
11051345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        count -= short_count;
11061345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák
11071345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        if (count) {
1108c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák            if (!r300_prepare_for_rendering(r300,
1109c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák                    PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
111065482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák                    NULL, 256, 0, 0, -1))
1111c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák                return;
1112c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák
11130d699e8ee930c6c7e0f8abff14bf37e7f67807feMarek Olšák            end_cs_dwords = r300_get_num_cs_end_dwords(r300);
11141345c5bf94dd848bdb601061c7ae654dadc6e542Marek Olšák        }
1115a4e0a46a8d6a4f308216c085849305ad82c52f15Corbin Simpson    }
1116d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák
1117d4b2de13bc652cd134826801ada48d0bb88a8258Marek Olšák    r300->draw_first_emitted = TRUE;
1118e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
1119e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
11205c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic void r300_render_destroy(struct vbuf_render* render)
1121e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
112281daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    FREE(render);
1123e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
1124e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
11255c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstatic struct vbuf_render* r300_render_create(struct r300_context* r300)
1126e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson{
11275c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    struct r300_render* r300render = CALLOC_STRUCT(r300_render);
112881daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
112981daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    r300render->r300 = r300;
113081daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
1131b10bff11350014e1bb49b0ce18704fdd66e850c0Marek Olšák    r300render->base.max_vertex_buffer_bytes = 1024 * 1024;
113281daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    r300render->base.max_indices = 16 * 1024;
113381daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson
11345c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    r300render->base.get_vertex_info = r300_render_get_vertex_info;
11355c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    r300render->base.allocate_vertices = r300_render_allocate_vertices;
11365c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    r300render->base.map_vertices = r300_render_map_vertices;
11375c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    r300render->base.unmap_vertices = r300_render_unmap_vertices;
11385c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    r300render->base.set_primitive = r300_render_set_primitive;
113976034aaf655134c71e1ec619085c46251d037720Marek Olšák    r300render->base.draw_elements = r300_render_draw_elements;
114076034aaf655134c71e1ec619085c46251d037720Marek Olšák    r300render->base.draw_arrays = r300_render_draw_arrays;
11415c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    r300render->base.release_vertices = r300_render_release_vertices;
11425c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    r300render->base.destroy = r300_render_destroy;
1143e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson
114481daa5323efbe798b11ea73d7ba289f3bb5e24cfCorbin Simpson    return &r300render->base;
1145e5018a5675603ec26e833bc0808e4150a6bba16aCorbin Simpson}
114646ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson
11475c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpsonstruct draw_stage* r300_draw_stage(struct r300_context* r300)
114846ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson{
114946ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    struct vbuf_render* render;
115046ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    struct draw_stage* stage;
115146ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson
11525c50218d009a4c8276aa561bd1483742cf6aa20eCorbin Simpson    render = r300_render_create(r300);
115346ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson
115446ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    if (!render) {
115546ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson        return NULL;
115646ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    }
115746ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson
115846ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    stage = draw_vbuf_stage(r300->draw, render);
115946ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson
116046ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    if (!stage) {
116146ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson        render->destroy(render);
116246ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson        return NULL;
116346ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    }
116446ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson
116546ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    draw_set_render(r300->draw, render);
116646ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson
116746ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson    return stage;
116846ef26eb90a28b009de9349f38f36972d828a575Corbin Simpson}
1169e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák
1170eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlievoid r300_draw_flush_vbuf(struct r300_context *r300)
1171eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie{
1172eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie    pipe_resource_reference(&r300->vbo, NULL);
1173eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie    r300->draw_vbo_size = 0;
1174eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie}
1175eb430b0e948caf02b9f4095d0e1435880073c2aaDave Airlie
1176e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson/****************************************************************************
1177e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson *                         End of SW TCL functions                          *
1178e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson ***************************************************************************/
1179e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson
1180c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák/* This functions is used to draw a rectangle for the blitter module.
1181c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák *
1182c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák * If we rendered a quad, the pixels on the main diagonal
118378e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák * would be computed and stored twice, which makes the clear/copy codepaths
1184f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák * somewhat inefficient. Instead we use a rectangular point sprite. */
118578e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšákstatic void r300_blitter_draw_rectangle(struct blitter_context *blitter,
118678e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák                                        unsigned x1, unsigned y1,
118778e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák                                        unsigned x2, unsigned y2,
118878e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák                                        float depth,
118978e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák                                        enum blitter_attrib_type type,
119078e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák                                        const float attrib[4])
119178e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák{
119278e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter));
1193f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    unsigned last_sprite_coord_enable = r300->sprite_coord_enable;
119478e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    unsigned width = x2 - x1;
119578e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    unsigned height = y2 - y1;
1196f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    unsigned vertex_size =
1197f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák            type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4;
1198f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    unsigned dwords = 13 + vertex_size +
1199f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák                      (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0);
1200f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    const float zeros[4] = {0, 0, 0, 0};
1201fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    CS_LOCALS(r300);
120278e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
12034953ba6a717ad1d3aa4426d147b52d05932c47abMarek Olšák    r300->context.set_vertex_buffers(&r300->context, 0, NULL);
12044953ba6a717ad1d3aa4426d147b52d05932c47abMarek Olšák
120578e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
120678e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák        r300->sprite_coord_enable = 1;
120778e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
120878e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    r300_update_derived_state(r300);
120978e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
121078e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    /* Mark some states we don't care about as non-dirty. */
121178e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    r300->clip_state.dirty = FALSE;
1212f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    r300->viewport_state.dirty = FALSE;
121378e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
121465482f2c2b1c3456d0ca58a38d82c02a5d6d362cMarek Olšák    if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
1215c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšák        goto done;
121678e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
121750db6dba65560c1fb598d495d7d4103019bbbea5Marek Olšák    DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
121850db6dba65560c1fb598d495d7d4103019bbbea5Marek Olšák
1219fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    BEGIN_CS(dwords);
122078e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    /* Set up GA. */
1221fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
122278e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
1223f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
1224f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák        /* Set up the GA to generate texcoords. */
1225fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
1226f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák                   (R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT));
1227fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
1228fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        OUT_CS_32F(attrib[0]);
1229fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        OUT_CS_32F(attrib[3]);
1230fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        OUT_CS_32F(attrib[2]);
1231fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        OUT_CS_32F(attrib[1]);
123278e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    }
123378e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
123478e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    /* Set up VAP controls. */
1235fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
1236fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
1237fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
1238fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
1239fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS(1);
1240fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS(0);
124178e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
124278e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    /* Draw. */
1243fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size);
1244fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) |
124578e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák           R300_VAP_VF_CNTL__PRIM_POINTS);
124678e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
1247fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_32F(x1 + width * 0.5f);
1248fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_32F(y1 + height * 0.5f);
1249fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_32F(depth);
1250fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    OUT_CS_32F(1);
125178e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
1252f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    if (vertex_size == 8) {
1253f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák        if (!attrib)
1254f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák            attrib = zeros;
1255fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák        OUT_CS_TABLE(attrib, 4);
1256f5804e64b41e167bd5578df86e05329dd06c35d6Marek Olšák    }
1257fe3caa91d3f637bf9cf9f9e7adb992aa8c7ef8e4Marek Olšák    END_CS;
125878e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
1259c3c5646b93eb20013d2739c7966da7ddad532877Marek Olšákdone:
126078e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    /* Restore the state. */
126166d45567b4e2c6f2585789b68667e6c00b7567e1Marek Olšák    r300_mark_atom_dirty(r300, &r300->clip_state);
126266d45567b4e2c6f2585789b68667e6c00b7567e1Marek Olšák    r300_mark_atom_dirty(r300, &r300->rs_state);
126366d45567b4e2c6f2585789b68667e6c00b7567e1Marek Olšák    r300_mark_atom_dirty(r300, &r300->viewport_state);
126478e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
126578e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    r300->sprite_coord_enable = last_sprite_coord_enable;
126678e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák}
126778e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák
1268e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpsonstatic void r300_resource_resolve(struct pipe_context* pipe,
1269e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson                                  struct pipe_resource* dest,
12704c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                  unsigned dst_layer,
1271e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson                                  struct pipe_resource* src,
12724c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                  unsigned src_layer)
1273e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson{
1274e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson    struct r300_context* r300 = r300_context(pipe);
12754c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    struct pipe_surface* srcsurf, surf_tmpl;
127669adebf5945d994485c584c183c148fc2c1373edMarek Olšák    struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
127768cefb423a1bd7cb2bee6375cae8e9c46b1211c5Corbin Simpson    float color[] = {0, 0, 0, 0};
1278e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson
12794c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    memset(&surf_tmpl, 0, sizeof(surf_tmpl));
12804c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.format = src->format;
12814c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.usage = 0; /* not really a surface hence no bind flags */
12824c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.u.tex.level = 0; /* msaa resources cannot have mipmaps */
12834c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.u.tex.first_layer = src_layer;
12844c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.u.tex.last_layer = src_layer;
12854c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
12864c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.format = dest->format;
12874c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.u.tex.first_layer = dst_layer;
12884c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    surf_tmpl.u.tex.last_layer = dst_layer;
12894c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
129068cefb423a1bd7cb2bee6375cae8e9c46b1211c5Corbin Simpson    DBG(r300, DBG_DRAW, "r300: Resolving resource...\n");
129168cefb423a1bd7cb2bee6375cae8e9c46b1211c5Corbin Simpson
129269adebf5945d994485c584c183c148fc2c1373edMarek Olšák    /* Enable AA resolve. */
12934c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger    aa->dest = r300_surface(pipe->create_surface(pipe, dest, &surf_tmpl));
1294e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson
129569adebf5945d994485c584c183c148fc2c1373edMarek Olšák    aa->aaresolve_ctl =
1296e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson        R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE |
129769adebf5945d994485c584c183c148fc2c1373edMarek Olšák        R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE;
12985197b09beeb729637b915bc7b5d599227387d81eMarek Olšák    r300->aa_state.size = 10;
129966d45567b4e2c6f2585789b68667e6c00b7567e1Marek Olšák    r300_mark_atom_dirty(r300, &r300->aa_state);
1300e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson
130169adebf5945d994485c584c183c148fc2c1373edMarek Olšák    /* Resolve the surface. */
130268cefb423a1bd7cb2bee6375cae8e9c46b1211c5Corbin Simpson    r300->context.clear_render_target(pipe,
1303e41ad8d2c5cac28cbdc3c1c234f1149c91a8d803Corbin Simpson        srcsurf, color, 0, 0, src->width0, src->height0);
1304e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson
130569adebf5945d994485c584c183c148fc2c1373edMarek Olšák    /* Disable AA resolve. */
130669adebf5945d994485c584c183c148fc2c1373edMarek Olšák    aa->aaresolve_ctl = 0;
130769adebf5945d994485c584c183c148fc2c1373edMarek Olšák    r300->aa_state.size = 4;
130866d45567b4e2c6f2585789b68667e6c00b7567e1Marek Olšák    r300_mark_atom_dirty(r300, &r300->aa_state);
13096771622e22399e8ed2346b830aefadf885fcec10Marek Olšák
13106771622e22399e8ed2346b830aefadf885fcec10Marek Olšák    pipe_surface_reference((struct pipe_surface**)&srcsurf, NULL);
131169adebf5945d994485c584c183c148fc2c1373edMarek Olšák    pipe_surface_reference((struct pipe_surface**)&aa->dest, NULL);
1312e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson}
1313e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson
1314e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšákvoid r300_init_render_functions(struct r300_context *r300)
1315e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák{
131676034aaf655134c71e1ec619085c46251d037720Marek Olšák    /* Set draw functions based on presence of HW TCL. */
1317e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák    if (r300->screen->caps.has_tcl) {
13186d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu        r300->context.draw_vbo = r300_draw_vbo;
1319e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák    } else {
13206d28bf917fb1d741d90fd3f05c22769376021fcaChia-I Wu        r300->context.draw_vbo = r300_swtcl_draw_vbo;
1321e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák    }
132276034aaf655134c71e1ec619085c46251d037720Marek Olšák
1323e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson    r300->context.resource_resolve = r300_resource_resolve;
132478e8a8765f435bf0902d62afbcb3b8d68a0b716fMarek Olšák    r300->blitter->draw_rectangle = r300_blitter_draw_rectangle;
1325e163fc0b15c80172fb2615fc04d7fc7bdc0d25c3Corbin Simpson
1326cb17f5ee752d07d82e9b079c6bda9d89e51c7108Marek Olšák    /* Plug in the two-sided stencil reference value fallback if needed. */
132776034aaf655134c71e1ec619085c46251d037720Marek Olšák    if (!r300->screen->caps.is_r500)
132876034aaf655134c71e1ec619085c46251d037720Marek Olšák        r300_plug_in_stencil_ref_fallback(r300);
1329e1c117d87bd1c77c6093a7a77b7994a8313b084eMarek Olšák}
1330