1857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs/*
2f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller * Copyright 2010 Christoph Bumiller
3857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs *
4857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * Permission is hereby granted, free of charge, to any person obtaining a
5857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * copy of this software and associated documentation files (the "Software"),
6857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * to deal in the Software without restriction, including without limitation
7857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * and/or sell copies of the Software, and to permit persons to whom the
9857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * Software is furnished to do so, subject to the following conditions:
10857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs *
11857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * The above copyright notice and this permission notice shall be included in
12857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * all copies or substantial portions of the Software.
13857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs *
14857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs * SOFTWARE.
21857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs */
22857a3294a959015bf893241199f7fd7f7882a6abBen Skeggs
2347b418b8fa5fd242e9021503d6ec329ac3d56fb0Ben Skeggs#include "pipe/p_context.h"
2447b418b8fa5fd242e9021503d6ec329ac3d56fb0Ben Skeggs#include "pipe/p_state.h"
2528486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
2672befaaae5fd9555e1f6ccbd6a74c0d640fc2929Michal Krol#include "util/u_format.h"
27f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller#include "translate/translate.h"
2872befaaae5fd9555e1f6ccbd6a74c0d640fc2929Michal Krol
2947b418b8fa5fd242e9021503d6ec329ac3d56fb0Ben Skeggs#include "nv50_context.h"
30287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell#include "nv50_resource.h"
3147b418b8fa5fd242e9021503d6ec329ac3d56fb0Ben Skeggs
32f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller#include "nv50_3d.xml.h"
331448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller
34f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillervoid
35f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_vertex_state_delete(struct pipe_context *pipe,
36f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                         void *hwcso)
37621c4609f871d3e84d5f7fd98f11ee9ddf2a1f7cBen Skeggs{
38f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   struct nv50_vertex_stateobj *so = hwcso;
39f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
40f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (so->translate)
41f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      so->translate->release(so->translate);
42f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   FREE(hwcso);
431448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller}
441448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller
45f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillervoid *
46f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_vertex_state_create(struct pipe_context *pipe,
47f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                         unsigned num_elements,
48f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                         const struct pipe_vertex_element *elements)
491448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller{
50f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    struct nv50_vertex_stateobj *so;
51f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    struct translate_key transkey;
52f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    unsigned i;
53f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
54f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so = MALLOC(sizeof(*so) +
55c448a556e9f97dd059de99048b75ebf6d51e1d7cChristoph Bumiller                num_elements * sizeof(struct nv50_vertex_element));
56f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    if (!so)
57f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        return NULL;
58f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so->num_elements = num_elements;
59f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so->instance_elts = 0;
60f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so->instance_bufs = 0;
61f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so->need_conversion = FALSE;
62f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
630e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller    memset(so->vb_access_size, 0, sizeof(so->vb_access_size));
640e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller
65e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller    for (i = 0; i < PIPE_MAX_ATTRIBS; ++i)
66e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller       so->min_instance_div[i] = 0xffffffff;
67e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller
68f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    transkey.nr_elements = 0;
69f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    transkey.output_stride = 0;
70f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
71f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    for (i = 0; i < num_elements; ++i) {
72f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        const struct pipe_vertex_element *ve = &elements[i];
73f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        const unsigned vbi = ve->vertex_buffer_index;
740e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller        unsigned size;
75f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        enum pipe_format fmt = ve->src_format;
76f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
77f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        so->element[i].pipe = elements[i];
78f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        so->element[i].state = nv50_format_table[fmt].vtx;
79f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
80f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        if (!so->element[i].state) {
81f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            switch (util_format_get_nr_components(fmt)) {
82f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            case 1: fmt = PIPE_FORMAT_R32_FLOAT; break;
83f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            case 2: fmt = PIPE_FORMAT_R32G32_FLOAT; break;
84f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            case 3: fmt = PIPE_FORMAT_R32G32B32_FLOAT; break;
85f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            case 4: fmt = PIPE_FORMAT_R32G32B32A32_FLOAT; break;
86f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            default:
87f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                assert(0);
88f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                return NULL;
89f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            }
90f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            so->element[i].state = nv50_format_table[fmt].vtx;
91f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            so->need_conversion = TRUE;
92f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        }
93f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        so->element[i].state |= i;
94f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
950e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller        size = util_format_get_blocksize(fmt);
960e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller        if (so->vb_access_size[vbi] < (ve->src_offset + size))
970e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller           so->vb_access_size[vbi] = ve->src_offset + size;
980e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller
99f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        if (1) {
100f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            unsigned j = transkey.nr_elements++;
101f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
102f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.element[j].type = TRANSLATE_ELEMENT_NORMAL;
103f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.element[j].input_format = ve->src_format;
104f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.element[j].input_buffer = vbi;
105f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.element[j].input_offset = ve->src_offset;
106f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.element[j].instance_divisor = ve->instance_divisor;
107f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
108f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.element[j].output_format = fmt;
109f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.element[j].output_offset = transkey.output_stride;
110f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            transkey.output_stride += (util_format_get_stride(fmt, 1) + 3) & ~3;
111f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
112f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            if (unlikely(ve->instance_divisor)) {
113f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller               so->instance_elts |= 1 << i;
114f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller               so->instance_bufs |= 1 << vbi;
115e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller               if (ve->instance_divisor < so->min_instance_div[vbi])
116e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller                  so->min_instance_div[vbi] = ve->instance_divisor;
117f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            }
118f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller        }
119f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    }
120f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
121f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so->translate = translate_create(&transkey);
122f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so->vertex_size = transkey.output_stride / 4;
123f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    so->packet_vertex_limit = NV04_PFIFO_MAX_PACKET_LEN /
124f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller       MAX2(so->vertex_size, 1);
125f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
126f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    return so;
1271448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller}
1281448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller
129f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller#define NV50_3D_VERTEX_ATTRIB_INACTIVE              \
130f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_3D_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT |         \
131f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_3D_VERTEX_ARRAY_ATTRIB_FORMAT_32_32_32_32 | \
132f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_3D_VERTEX_ARRAY_ATTRIB_CONST
133f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
134a57f84251926045a3358822d0fd92ca95a4f0fdeChia-I Wustatic void
135f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
136f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                  struct pipe_vertex_element *ve, unsigned attr)
1371448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller{
1386d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv50->base.pushbuf;
139e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   const void *data = (const uint8_t *)vb->user_buffer + ve->src_offset;
140f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   float v[4];
141f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   const unsigned nc = util_format_get_nr_components(ve->src_format);
142f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
143e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   assert(vb->user_buffer);
144f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
145f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1);
146f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
147f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   switch (nc) {
148f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   case 4:
1496d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VTX_ATTR_4F_X(attr)), 4);
1506d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[0]);
1516d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[1]);
1526d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[2]);
1536d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[3]);
154f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      break;
155f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   case 3:
1566d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(attr)), 3);
1576d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[0]);
1586d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[1]);
1596d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[2]);
160f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      break;
161f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   case 2:
1626d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(attr)), 2);
1636d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[0]);
1646d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[1]);
165f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      break;
166f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   case 1:
167f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      if (attr == nv50->vertprog->vp.edgeflag) {
1686d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
1696d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, v[0] ? 1 : 0);
170f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
1716d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VTX_ATTR_1F(attr)), 1);
1726d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAf(push, v[0]);
173f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      break;
174f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   default:
175f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      assert(0);
176f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      break;
177f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
1781448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller}
1791448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller
180f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic INLINE void
181e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumillernv50_user_vbuf_range(struct nv50_context *nv50, int vbi,
182e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller                     uint32_t *base, uint32_t *size)
183f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller{
184f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (unlikely(nv50->vertex->instance_bufs & (1 << vbi))) {
185f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      /* TODO: use min and max instance divisor to get a proper range */
186f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      *base = 0;
187f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      *size = nv50->vtxbuf[vbi].buffer->width0;
188f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   } else {
1890e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller      /* NOTE: if there are user buffers, we *must* have index bounds */
1900e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller      assert(nv50->vb_elt_limit != ~0);
1910e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller      *base = nv50->vb_elt_first * nv50->vtxbuf[vbi].stride;
1920e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller      *size = nv50->vb_elt_limit * nv50->vtxbuf[vbi].stride +
1930e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller         nv50->vertex->vb_access_size[vbi];
194f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
195f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller}
19675f0b38d9ea4a7318b0d661712dda15e24707395Ben Skeggs
1970842829c1813d47e6fdf3de09167d243c029cc90Ben Skeggsstatic void
198e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumillernv50_upload_user_buffers(struct nv50_context *nv50,
199e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller                         uint64_t addrs[], uint32_t limits[])
2000842829c1813d47e6fdf3de09167d243c029cc90Ben Skeggs{
201e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   unsigned b;
202f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
203e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   for (b = 0; b < nv50->num_vtxbufs; ++b) {
204e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      struct nouveau_bo *bo;
205e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      const struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b];
206e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      uint32_t base, size;
207f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
208e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (!(nv50->vbo_user & (1 << b)) || !vb->stride)
209f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         continue;
210e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      nv50_user_vbuf_range(nv50, b, &base, &size);
211e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller
212e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      limits[b] = base + size - 1;
213e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      addrs[b] = nouveau_scratch_data(&nv50->base, vb->user_buffer, base, size,
214e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller                                      &bo);
215e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (addrs[b])
216e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         BCTX_REFN_bo(nv50->bufctx_3d, VERTEX_TMP, NOUVEAU_BO_GART |
217e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller                      NOUVEAU_BO_RD, bo);
218f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
219e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   nv50->base.vbo_dirty = TRUE;
220027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs}
221027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs
2220842829c1813d47e6fdf3de09167d243c029cc90Ben Skeggsstatic void
223f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_update_user_vbufs(struct nv50_context *nv50)
224027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs{
225e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   uint64_t address[PIPE_MAX_ATTRIBS];
2266d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv50->base.pushbuf;
227e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   unsigned i;
228f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   uint32_t written = 0;
229f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
230f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   for (i = 0; i < nv50->vertex->num_elements; ++i) {
231f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      struct pipe_vertex_element *ve = &nv50->vertex->element[i].pipe;
232e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      const unsigned b = ve->vertex_buffer_index;
233f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b];
234e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      uint32_t base, size;
235f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
2362206a7f5132905bb1b53d8343d11847010f6b63aChristoph Bumiller      if (!(nv50->vbo_user & (1 << b)))
237f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         continue;
238f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
239f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      if (!vb->stride) {
240f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         nv50_emit_vtxattr(nv50, vb, ve, i);
241f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         continue;
242f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
243e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      nv50_user_vbuf_range(nv50, b, &base, &size);
244f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
245f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      if (!(written & (1 << b))) {
246e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         struct nouveau_bo *bo;
247e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         const uint32_t bo_flags = NOUVEAU_BO_GART | NOUVEAU_BO_RD;
248f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         written |= 1 << b;
249e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         address[b] = nouveau_scratch_data(&nv50->base, vb->user_buffer,
250e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller                                           base, size, &bo);
251e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         if (address[b])
2522206a7f5132905bb1b53d8343d11847010f6b63aChristoph Bumiller            BCTX_REFN_bo(nv50->bufctx_3d, VERTEX_TMP, bo_flags, bo);
253f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
254f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
2556d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
256e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATAh(push, address[b] + base + size - 1);
257e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATA (push, address[b] + base + size - 1);
2586d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
259e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATAh(push, address[b] + ve->src_offset);
260e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATA (push, address[b] + ve->src_offset);
261f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
2621ba8e9510812f155359d380bda6876cdee5ba21eBen Skeggs   nv50->base.vbo_dirty = TRUE;
263027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs}
264027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs
265f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic INLINE void
266f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_release_user_vbufs(struct nv50_context *nv50)
267027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs{
2682206a7f5132905bb1b53d8343d11847010f6b63aChristoph Bumiller   if (nv50->vbo_user) {
2692206a7f5132905bb1b53d8343d11847010f6b63aChristoph Bumiller      nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX_TMP);
2702206a7f5132905bb1b53d8343d11847010f6b63aChristoph Bumiller      nouveau_scratch_done(&nv50->base);
271f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
2720842829c1813d47e6fdf3de09167d243c029cc90Ben Skeggs}
273027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs
274f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillervoid
275f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_vertex_arrays_validate(struct nv50_context *nv50)
2760842829c1813d47e6fdf3de09167d243c029cc90Ben Skeggs{
277e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   uint64_t addrs[PIPE_MAX_ATTRIBS];
278e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   uint32_t limits[PIPE_MAX_ATTRIBS];
2796d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv50->base.pushbuf;
280f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   struct nv50_vertex_stateobj *vertex = nv50->vertex;
281f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   struct pipe_vertex_buffer *vb;
282f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   struct nv50_vertex_element *ve;
283e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   uint32_t mask;
284e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   uint32_t refd = 0;
285f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   unsigned i;
286e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   const unsigned n = MAX2(vertex->num_elements, nv50->state.num_vtxelts);
287f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
288e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   if (unlikely(vertex->need_conversion))
289f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      nv50->vbo_fifo = ~0;
290e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   else
291e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   if (nv50->vbo_user & ~nv50->vbo_constant)
292e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      nv50->vbo_fifo = nv50->vbo_push_hint ? ~0 : 0;
293e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   else
294e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      nv50->vbo_fifo = 0;
295e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller
29619fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz   if (!nv50->vbo_fifo) {
29719fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz      /* if vertex buffer was written by GPU - flush VBO cache */
29819fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz      for (i = 0; i < nv50->num_vtxbufs; ++i) {
29919fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz         struct nv04_resource *buf = nv04_resource(nv50->vtxbuf[i].buffer);
30019fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz         if (buf && buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
30119fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz            buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
30219fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz            nv50->base.vbo_dirty = TRUE;
30319fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz            break;
30419fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz         }
30519fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz      }
30619fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz   }
30719fd04f5eaf76f6ea5effa69d91c415bba75ba8eMarcin Slusarz
308e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   /* update vertex format state */
309e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(0)), n);
310e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   if (nv50->vbo_fifo) {
311e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      nv50->state.num_vtxelts = vertex->num_elements;
312e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      for (i = 0; i < vertex->num_elements; ++i)
313e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, vertex->element[i].state);
314e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      for (; i < n; ++i)
315e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, NV50_3D_VERTEX_ATTRIB_INACTIVE);
316e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      for (i = 0; i < n; ++i) {
317e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
318e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, 0);
319e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      }
320e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      return;
321f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
322f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   for (i = 0; i < vertex->num_elements; ++i) {
323e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      const unsigned b = vertex->element[i].pipe.vertex_buffer_index;
324f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      ve = &vertex->element[i];
325e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      vb = &nv50->vtxbuf[b];
326f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
327e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (likely(vb->stride) || !(nv50->vbo_user & (1 << b)))
3286d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA(push, ve->state);
329e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      else
3306d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA(push, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
331f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
332e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   for (; i < n; ++i)
333e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATA(push, NV50_3D_VERTEX_ATTRIB_INACTIVE);
334e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller
335e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   /* update per-instance enables */
336e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   mask = vertex->instance_elts ^ nv50->state.instance_elts;
337e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   while (mask) {
338e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      const int i = ffs(mask) - 1;
339e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      mask &= ~(1 << i);
340e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
341e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATA (push, (vertex->instance_elts >> i) & 1);
342e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   }
343e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   nv50->state.instance_elts = vertex->instance_elts;
344f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
345e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   if (nv50->vbo_user & ~nv50->vbo_constant)
346e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      nv50_upload_user_buffers(nv50, addrs, limits);
347e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller
348e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   /* update buffers and set constant attributes */
349f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   for (i = 0; i < vertex->num_elements; ++i) {
350e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      uint64_t address, limit;
351e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      const unsigned b = vertex->element[i].pipe.vertex_buffer_index;
352f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      ve = &vertex->element[i];
353e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      vb = &nv50->vtxbuf[b];
354f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
355e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (unlikely(nv50->vbo_constant & (1 << b))) {
3566d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
3576d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, 0);
358e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         nv50_emit_vtxattr(nv50, vb, &ve->pipe, i);
359f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         continue;
360e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      } else
361e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (nv50->vbo_user & (1 << b)) {
362e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         address = addrs[b] + ve->pipe.src_offset;
363e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         limit = addrs[b] + limits[b];
364e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      } else {
365e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         struct nv04_resource *buf = nv04_resource(vb->buffer);
366e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         if (!(refd & (1 << b))) {
367e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller            refd |= 1 << b;
368e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller            BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
369e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         }
370e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         address = buf->address + vb->buffer_offset + ve->pipe.src_offset;
371e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         limit = buf->address + buf->base.width0 - 1;
372f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
373f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
374e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (unlikely(ve->pipe.instance_divisor)) {
375e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 4);
376e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
377e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATAh(push, address);
378e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, address);
379e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, ve->pipe.instance_divisor);
380e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      } else {
381e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 3);
382e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
383e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATAh(push, address);
384e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         PUSH_DATA (push, address);
385e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      }
3866d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
387e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATAh(push, limit);
388e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      PUSH_DATA (push, limit);
389f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
390f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   for (; i < nv50->state.num_vtxelts; ++i) {
3916d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
3926d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0);
393f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
394f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   nv50->state.num_vtxelts = vertex->num_elements;
395f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller}
396f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
397f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller#define NV50_PRIM_GL_CASE(n) \
398f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   case PIPE_PRIM_##n: return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
399027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs
400f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic INLINE unsigned
401f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_prim_gl(unsigned prim)
402f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller{
403f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   switch (prim) {
404f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(POINTS);
405f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(LINES);
406f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(LINE_LOOP);
407f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(LINE_STRIP);
408f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(TRIANGLES);
409f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(TRIANGLE_STRIP);
410f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(TRIANGLE_FAN);
411f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(QUADS);
412f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(QUAD_STRIP);
413f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(POLYGON);
414f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(LINES_ADJACENCY);
415f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(LINE_STRIP_ADJACENCY);
416f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(TRIANGLES_ADJACENCY);
417f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   NV50_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY);
418f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   default:
419f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS;
420f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      break;
421f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
422027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs}
423027ed25c12f69b39e205d3bbd26b68e9a02bea81Ben Skeggs
42402fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller/* For pre-nva0 transform feedback. */
42502fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumillerstatic const uint8_t nv50_pipe_prim_to_prim_size[PIPE_PRIM_MAX + 1] =
42602fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller{
42702fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_POINTS] = 1,
42802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_LINES] = 2,
42902fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_LINE_LOOP] = 2,
43002fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_LINE_STRIP] = 2,
43102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_TRIANGLES] = 3,
43202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_TRIANGLE_STRIP] = 3,
43302fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_TRIANGLE_FAN] = 3,
43402fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_QUADS] = 3,
43502fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_QUAD_STRIP] = 3,
43602fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_POLYGON] = 3,
43702fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_LINES_ADJACENCY] = 2,
43802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_LINE_STRIP_ADJACENCY] = 2,
43902fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_TRIANGLES_ADJACENCY] = 3,
44002fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY] = 3
44102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller};
44202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller
443621c4609f871d3e84d5f7fd98f11ee9ddf2a1f7cBen Skeggsstatic void
444f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_draw_arrays(struct nv50_context *nv50,
445f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                 unsigned mode, unsigned start, unsigned count,
446f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                 unsigned instance_count)
4471448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller{
4486d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv50->base.pushbuf;
449f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   unsigned prim;
450f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
4516994b57a509cff1a1d0d013c0b175ec4d83117a0Christoph Bumiller   if (nv50->state.index_bias) {
4526d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
4536d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0);
4546994b57a509cff1a1d0d013c0b175ec4d83117a0Christoph Bumiller      nv50->state.index_bias = 0;
4556994b57a509cff1a1d0d013c0b175ec4d83117a0Christoph Bumiller   }
4566994b57a509cff1a1d0d013c0b175ec4d83117a0Christoph Bumiller
457f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   prim = nv50_prim_gl(mode);
458f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
459f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   while (instance_count--) {
4606d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
4616d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, prim);
4626d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_BUFFER_FIRST), 2);
4636d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, start);
4646d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, count);
4656d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
4666d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0);
467f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
468f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
469f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
4701448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller}
4711448d2f252efc1ab8d3175c7fd9701dfe3079577Christoph Bumiller
472f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic void
473ef7bb281292c17b762b57779306e874704c87328Christoph Bumillernv50_draw_elements_inline_u08(struct nouveau_pushbuf *push, const uint8_t *map,
474f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                              unsigned start, unsigned count)
47547b418b8fa5fd242e9021503d6ec329ac3d56fb0Ben Skeggs{
476f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   map += start;
477f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
478f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (count & 3) {
479f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      unsigned i;
4806d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), count & 3);
481f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      for (i = 0; i < (count & 3); ++i)
4826d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA(push, *map++);
483f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      count &= ~3;
484f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
485f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   while (count) {
486f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4;
487f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
4886d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U8), nr);
489f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      for (i = 0; i < nr; ++i) {
4906d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA(push,
4916d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller                   (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
492f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         map += 4;
493f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
494f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      count -= nr * 4;
495f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
49647b418b8fa5fd242e9021503d6ec329ac3d56fb0Ben Skeggs}
49747b418b8fa5fd242e9021503d6ec329ac3d56fb0Ben Skeggs
498f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic void
499ef7bb281292c17b762b57779306e874704c87328Christoph Bumillernv50_draw_elements_inline_u16(struct nouveau_pushbuf *push, const uint16_t *map,
500f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                              unsigned start, unsigned count)
501d7c55555ac6b6bf60cf7fd54dfea0e62ce57542cChristoph Bumiller{
502f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   map += start;
503f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
504f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (count & 1) {
505f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      count &= ~1;
5066d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
5076d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, *map++);
508f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
509f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   while (count) {
510f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
511f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
5126d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
513f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      for (i = 0; i < nr; ++i) {
5146d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA(push, (map[1] << 16) | map[0]);
515f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         map += 2;
516f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
517f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      count -= nr * 2;
518f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
519d7c55555ac6b6bf60cf7fd54dfea0e62ce57542cChristoph Bumiller}
520d7c55555ac6b6bf60cf7fd54dfea0e62ce57542cChristoph Bumiller
521f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic void
522ef7bb281292c17b762b57779306e874704c87328Christoph Bumillernv50_draw_elements_inline_u32(struct nouveau_pushbuf *push, const uint32_t *map,
523f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                              unsigned start, unsigned count)
524f2656c3e3cc91edcbf572d175efe9346a30b1da2Christoph Bumiller{
525f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   map += start;
526f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
527f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   while (count) {
528f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
529f2656c3e3cc91edcbf572d175efe9346a30b1da2Christoph Bumiller
5306d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), nr);
5316d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAp(push, map, nr);
532f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
533f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      map += nr;
534f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      count -= nr;
535f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
536f2656c3e3cc91edcbf572d175efe9346a30b1da2Christoph Bumiller}
537f2656c3e3cc91edcbf572d175efe9346a30b1da2Christoph Bumiller
538f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic void
539ef7bb281292c17b762b57779306e874704c87328Christoph Bumillernv50_draw_elements_inline_u32_short(struct nouveau_pushbuf *push,
540ef7bb281292c17b762b57779306e874704c87328Christoph Bumiller                                    const uint32_t *map,
541f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                                    unsigned start, unsigned count)
542f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
543f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   map += start;
544f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
545f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (count & 1) {
546f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      count--;
5476d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
5486d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, *map++);
549f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
550f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   while (count) {
551f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
552f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
5536d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
554f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      for (i = 0; i < nr; ++i) {
5556d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA(push, (map[1] << 16) | map[0]);
556f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         map += 2;
557f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
558f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      count -= nr * 2;
559f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
560f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
561f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
562f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillerstatic void
563f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_draw_elements(struct nv50_context *nv50, boolean shorten,
564f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                   unsigned mode, unsigned start, unsigned count,
565f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                   unsigned instance_count, int32_t index_bias)
566f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller{
5676d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv50->base.pushbuf;
568f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   unsigned prim;
569f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   const unsigned index_size = nv50->idxbuf.index_size;
570f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
571f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   prim = nv50_prim_gl(mode);
572f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
573f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (index_bias != nv50->state.index_bias) {
5746d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
5756d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, index_bias);
576f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      nv50->state.index_bias = index_bias;
577f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
578f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
579ef7bb281292c17b762b57779306e874704c87328Christoph Bumiller   if (nv50->idxbuf.buffer) {
580ef7bb281292c17b762b57779306e874704c87328Christoph Bumiller      struct nv04_resource *buf = nv04_resource(nv50->idxbuf.buffer);
5816d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      unsigned pb_start;
5826d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      unsigned pb_bytes;
583a054fd8268876048a7ce45a2ebfc40a3dd1e8540Christoph Bumiller      const unsigned base = (buf->offset + nv50->idxbuf.offset) & ~3;
584a054fd8268876048a7ce45a2ebfc40a3dd1e8540Christoph Bumiller
585a054fd8268876048a7ce45a2ebfc40a3dd1e8540Christoph Bumiller      start += ((buf->offset + nv50->idxbuf.offset) & 3) >> (index_size >> 1);
5860c0e996d59380af2d247336e3e9cfae58a80791aChristoph Bumiller
587ef7bb281292c17b762b57779306e874704c87328Christoph Bumiller      assert(nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer));
588f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
589f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      while (instance_count--) {
5906d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
5916d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, prim);
5926d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
5936d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         nouveau_pushbuf_space(push, 8, 0, 1);
594f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
595f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         switch (index_size) {
596f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         case 4:
5976d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U32), count);
5986d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            nouveau_pushbuf_data(push, buf->bo, base + start * 4, count * 4);
599f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            break;
600f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         case 2:
6016d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            pb_start = (start & ~1) * 2;
6026d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            pb_bytes = ((start + count + 1) & ~1) * 2 - pb_start;
6036d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
6046d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
6056d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, (start << 31) | count);
6066d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U16), pb_bytes / 4);
6076d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
6086d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
6096d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, 0);
610f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            break;
611f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         default:
6126d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            assert(index_size == 1);
6136d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            pb_start = start & ~3;
6146d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            pb_bytes = ((start + count + 3) & ~3) - pb_start;
6156d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
6166d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
6176d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, (start << 30) | count);
6186d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U8), pb_bytes / 4);
6196d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
6206d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
6216d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, 0);
6226d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            break;
623f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         }
6246d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
6256d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, 0);
626f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
6276d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
628f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
629f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   } else {
630ef7bb281292c17b762b57779306e874704c87328Christoph Bumiller      const void *data = nv50->idxbuf.user_buffer;
631f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
632f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      while (instance_count--) {
6336d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
6346d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, prim);
635f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         switch (index_size) {
636f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         case 1:
6376d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            nv50_draw_elements_inline_u08(push, data, start, count);
638f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            break;
639f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         case 2:
6406d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            nv50_draw_elements_inline_u16(push, data, start, count);
641f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            break;
642f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         case 4:
643f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            if (shorten)
6446d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller               nv50_draw_elements_inline_u32_short(push, data, start, count);
645f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            else
6466d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller               nv50_draw_elements_inline_u32(push, data, start, count);
647f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            break;
648f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         default:
649f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            assert(0);
650f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            return;
651f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         }
6526d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
6536d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, 0);
654f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
655f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
656f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
657f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
658f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller}
659c0e80cf0e97cec526bb2ff0f94d9142e33374c20Christoph Bumiller
6606d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumillerstatic void
66102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumillernva0_draw_stream_output(struct nv50_context *nv50,
66202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller                        const struct pipe_draw_info *info)
66302fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller{
66402fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   struct nouveau_pushbuf *push = nv50->base.pushbuf;
66502fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   struct nv50_so_target *so = nv50_so_target(info->count_from_stream_output);
66602fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   struct nv04_resource *res = nv04_resource(so->pipe.buffer);
66702fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   unsigned num_instances = info->instance_count;
66802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   unsigned mode = nv50_prim_gl(info->mode);
66902fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller
67002fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   if (unlikely(nv50->screen->base.class_3d < NVA0_3D_CLASS)) {
67102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      /* A proper implementation without waiting doesn't seem possible,
67202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller       * so don't bother.
67302fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller       */
67402fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      NOUVEAU_ERR("draw_stream_output not supported on pre-NVA0 cards\n");
67502fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      return;
67602fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   }
67702fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller
67802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
67902fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
68002fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_SPACE(push, 4);
68102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
68202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_DATA (push, 0);
68302fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FLUSH), 1);
68402fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_DATA (push, 0);
68502fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   }
68602fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller
68702fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   assert(num_instances);
68802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   do {
68902fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_SPACE(push, 8);
69002fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
69102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_DATA (push, mode);
69202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      BEGIN_NV04(push, NVA0_3D(DRAW_TFB_BASE), 1);
69302fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_DATA (push, 0);
69402fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      BEGIN_NV04(push, NVA0_3D(DRAW_TFB_STRIDE), 1);
69502fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_DATA (push, 0);
69602fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      BEGIN_NV04(push, NVA0_3D(DRAW_TFB_BYTES), 1);
69702fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      nv50_query_pushbuf_submit(push, so->pq, 0x4);
69802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
69902fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      PUSH_DATA (push, 0);
70002fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller
70102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
70202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   } while (--num_instances);
70302fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller}
70402fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller
70502fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumillerstatic void
7066d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumillernv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
7076d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller{
7086d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nv50_screen *screen = chan->user_priv;
7096d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
7106d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_fence_update(&screen->base, TRUE);
7116d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
7126d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, TRUE);
7136d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller}
7146d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
715f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillervoid
716f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumillernv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
717f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller{
718f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   struct nv50_context *nv50 = nv50_context(pipe);
7196d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv50->base.pushbuf;
720f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
7210e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller   /* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
7220e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller   nv50->vb_elt_first = info->min_index + info->index_bias;
7230e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller   nv50->vb_elt_limit = info->max_index - info->min_index;
724e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   nv50->instance_off = info->start_instance;
725e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   nv50->instance_max = info->instance_count - 1;
7260e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller
727f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   /* For picking only a few vertices from a large user buffer, push is better,
728f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    * if index count is larger and we expect repeated vertices, suggest upload.
729f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller    */
730f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   nv50->vbo_push_hint = /* the 64 is heuristic */
7310e8ad4cc749626eebbc7f916e551bbfd80b75023Christoph Bumiller      !(info->indexed && ((nv50->vb_elt_limit + 64) < info->count));
732f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
733e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   if (nv50->vbo_user && !(nv50->dirty & (NV50_NEW_ARRAYS | NV50_NEW_VERTEX))) {
734e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (!!nv50->vbo_fifo != nv50->vbo_push_hint)
735e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         nv50->dirty |= NV50_NEW_ARRAYS;
736e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      else
737e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller      if (!nv50->vbo_fifo)
738e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller         nv50_update_user_vbufs(nv50);
739e6caafd9d7fbfcb5906d22be9d6a3c1714e078acChristoph Bumiller   }
740f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
74102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   if (unlikely(nv50->num_so_targets && !nv50->gmtyprog))
74202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      nv50->state.prim_size = nv50_pipe_prim_to_prim_size[info->mode];
74302fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller
744222b3ea653e5525a4afa57e6a2353335953012d4Christoph Bumiller   nv50_state_validate(nv50, ~0, 8); /* 8 as minimum, we use flush_notify */
745f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
7466d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   push->kick_notify = nv50_draw_vbo_kick_notify;
7479c5d15e929f47f517f90977f5420e11dfbd3db67Christoph Bumiller
748f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (nv50->vbo_fifo) {
749f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      nv50_push_vbo(nv50, info);
7506d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      push->kick_notify = nv50_default_kick_notify;
7516d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      nouveau_pushbuf_bufctx(push, NULL);
752f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      return;
753f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
754f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
755f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   if (nv50->state.instance_base != info->start_instance) {
756f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      nv50->state.instance_base = info->start_instance;
757f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      /* NOTE: this does not affect the shader input, should it ? */
7586d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VB_INSTANCE_BASE), 1);
7596d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, info->start_instance);
760f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
761f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
7621ba8e9510812f155359d380bda6876cdee5ba21eBen Skeggs   if (nv50->base.vbo_dirty) {
7636d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FLUSH), 1);
7646d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0);
7651ba8e9510812f155359d380bda6876cdee5ba21eBen Skeggs      nv50->base.vbo_dirty = FALSE;
766f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
767f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
76802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   if (info->indexed) {
769f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      boolean shorten = info->max_index <= 65535;
770f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
771f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      if (info->primitive_restart != nv50->state.prim_restart) {
772f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         if (info->primitive_restart) {
7736d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 2);
7746d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, 1);
7756d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, info->restart_index);
776f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
777f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            if (info->restart_index > 65535)
778f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller               shorten = FALSE;
779f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         } else {
7806d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 1);
7816d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller            PUSH_DATA (push, 0);
782f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         }
783f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         nv50->state.prim_restart = info->primitive_restart;
784f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      } else
785f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      if (info->primitive_restart) {
7866d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NV04(push, NV50_3D(PRIM_RESTART_INDEX), 1);
7876d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, info->restart_index);
788f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
789f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller         if (info->restart_index > 65535)
790f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller            shorten = FALSE;
791f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      }
792f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
793f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller      nv50_draw_elements(nv50, shorten,
794f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                         info->mode, info->start, info->count,
795f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller                         info->instance_count, info->index_bias);
79602fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   } else
79702fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   if (unlikely(info->count_from_stream_output)) {
79802fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      nva0_draw_stream_output(nv50, info);
79902fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller   } else {
80002fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller      nv50_draw_arrays(nv50,
80102fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller                       info->mode, info->start, info->count,
80202fac2930581b9bea9f6d221eb6d6b471fc3b9c6Christoph Bumiller                       info->instance_count);
803f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   }
8046d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   push->kick_notify = nv50_default_kick_notify;
805f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller
806f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller   nv50_release_user_vbufs(nv50);
8076d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
8086d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_bufctx(push, NULL);
809f80c03e1875fe96ff2f4c022e3cb76357828140dChristoph Bumiller}
810