Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
 
2
#include "pipe/p_state.h"
3
#include "util/u_inlines.h"
4
#include "util/u_format.h"
5
#include "translate/translate.h"
6
7
 
8
#include "nv50_resource.h"
9
10
 
11
12
 
13
   struct nouveau_pushbuf *push;
14
15
 
16
17
 
18
   int edgeflag_attr;
19
20
 
21
   uint32_t packet_vertex_limit;
22
23
 
24
25
 
26
   uint32_t prim;
27
   uint32_t restart_index;
28
   uint32_t instance_id;
29
};
30
31
 
32
prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index)
33
{
34
   unsigned i;
35
   for (i = 0; i < push; ++i)
36
      if (elts[i] == index)
37
         break;
38
   return i;
39
}
40
41
 
42
prim_restart_search_i16(uint16_t *elts, unsigned push, uint16_t index)
43
{
44
   unsigned i;
45
   for (i = 0; i < push; ++i)
46
      if (elts[i] == index)
47
         break;
48
   return i;
49
}
50
51
 
52
prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index)
53
{
54
   unsigned i;
55
   for (i = 0; i < push; ++i)
56
      if (elts[i] == index)
57
         break;
58
   return i;
59
}
60
61
 
62
emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
63
{
64
   uint8_t *elts = (uint8_t *)ctx->idxbuf + start;
65
66
 
67
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
68
      unsigned size, nr;
69
70
 
71
      if (ctx->primitive_restart)
72
         nr = prim_restart_search_i08(elts, push, ctx->restart_index);
73
74
 
75
76
 
77
78
 
79
                                ctx->push->cur);
80
81
 
82
      count -= nr;
83
      elts += nr;
84
85
 
86
         count--;
87
         elts++;
88
         BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
89
         PUSH_DATA (ctx->push, ctx->restart_index);
90
      }
91
   }
92
}
93
94
 
95
emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
96
{
97
   uint16_t *elts = (uint16_t *)ctx->idxbuf + start;
98
99
 
100
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
101
      unsigned size, nr;
102
103
 
104
      if (ctx->primitive_restart)
105
         nr = prim_restart_search_i16(elts, push, ctx->restart_index);
106
107
 
108
109
 
110
111
 
112
                                 ctx->push->cur);
113
114
 
115
      count -= nr;
116
      elts += nr;
117
118
 
119
         count--;
120
         elts++;
121
         BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
122
         PUSH_DATA (ctx->push, ctx->restart_index);
123
      }
124
   }
125
}
126
127
 
128
emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
129
{
130
   uint32_t *elts = (uint32_t *)ctx->idxbuf + start;
131
132
 
133
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
134
      unsigned size, nr;
135
136
 
137
      if (ctx->primitive_restart)
138
         nr = prim_restart_search_i32(elts, push, ctx->restart_index);
139
140
 
141
142
 
143
144
 
145
                               ctx->push->cur);
146
147
 
148
      count -= nr;
149
      elts += nr;
150
151
 
152
         count--;
153
         elts++;
154
         BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
155
         PUSH_DATA (ctx->push, ctx->restart_index);
156
      }
157
   }
158
}
159
160
 
161
emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
162
{
163
   while (count) {
164
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
165
      unsigned size = ctx->vertex_words * push;
166
167
 
168
169
 
170
                          ctx->push->cur);
171
      ctx->push->cur += size;
172
      count -= push;
173
      start += push;
174
   }
175
}
176
177
 
178
 
179
   case PIPE_PRIM_##n: return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
180
181
 
182
nv50_prim_gl(unsigned prim)
183
{
184
   switch (prim) {
185
   NV50_PRIM_GL_CASE(POINTS);
186
   NV50_PRIM_GL_CASE(LINES);
187
   NV50_PRIM_GL_CASE(LINE_LOOP);
188
   NV50_PRIM_GL_CASE(LINE_STRIP);
189
   NV50_PRIM_GL_CASE(TRIANGLES);
190
   NV50_PRIM_GL_CASE(TRIANGLE_STRIP);
191
   NV50_PRIM_GL_CASE(TRIANGLE_FAN);
192
   NV50_PRIM_GL_CASE(QUADS);
193
   NV50_PRIM_GL_CASE(QUAD_STRIP);
194
   NV50_PRIM_GL_CASE(POLYGON);
195
   NV50_PRIM_GL_CASE(LINES_ADJACENCY);
196
   NV50_PRIM_GL_CASE(LINE_STRIP_ADJACENCY);
197
   NV50_PRIM_GL_CASE(TRIANGLES_ADJACENCY);
198
   NV50_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY);
199
   /*
200
   NV50_PRIM_GL_CASE(PATCHES); */
201
   default:
202
      return NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS;
203
      break;
204
   }
205
}
206
207
 
208
nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
209
{
210
   struct push_context ctx;
211
   unsigned i, index_size;
212
   unsigned inst_count = info->instance_count;
213
   unsigned vert_count = info->count;
214
   boolean apply_bias = info->indexed && info->index_bias;
215
216
 
217
   ctx.translate = nv50->vertex->translate;
218
   ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit;
219
   ctx.vertex_words = nv50->vertex->vertex_size;
220
221
 
222
      const struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
223
      const uint8_t *data;
224
225
 
226
         data = nouveau_resource_map_offset(&nv50->base,
227
            nv04_resource(vb->buffer), vb->buffer_offset, NOUVEAU_BO_RD);
228
      else
229
         data = vb->user_buffer;
230
231
 
232
         data += (ptrdiff_t)info->index_bias * vb->stride;
233
234
 
235
   }
236
237
 
238
      if (nv50->idxbuf.buffer) {
239
         ctx.idxbuf = nouveau_resource_map_offset(&nv50->base,
240
            nv04_resource(nv50->idxbuf.buffer), nv50->idxbuf.offset,
241
            NOUVEAU_BO_RD);
242
      } else {
243
         ctx.idxbuf = nv50->idxbuf.user_buffer;
244
      }
245
      if (!ctx.idxbuf)
246
         return;
247
      index_size = nv50->idxbuf.index_size;
248
      ctx.primitive_restart = info->primitive_restart;
249
      ctx.restart_index = info->restart_index;
250
   } else {
251
      if (unlikely(info->count_from_stream_output)) {
252
         struct pipe_context *pipe = &nv50->base.pipe;
253
         struct nv50_so_target *targ;
254
         targ = nv50_so_target(info->count_from_stream_output);
255
         if (!targ->pq) {
256
            NOUVEAU_ERR("draw_stream_output not supported on pre-NVA0 cards\n");
257
            return;
258
         }
259
         pipe->get_query_result(pipe, targ->pq, TRUE, (void *)&vert_count);
260
         vert_count /= targ->stride;
261
      }
262
      ctx.idxbuf = NULL;
263
      index_size = 0;
264
      ctx.primitive_restart = FALSE;
265
      ctx.restart_index = 0;
266
   }
267
268
 
269
   ctx.prim = nv50_prim_gl(info->mode);
270
271
 
272
      BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 2);
273
      PUSH_DATA (ctx.push, 1);
274
      PUSH_DATA (ctx.push, info->restart_index);
275
   } else
276
   if (nv50->state.prim_restart) {
277
      BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 1);
278
      PUSH_DATA (ctx.push, 0);
279
   }
280
   nv50->state.prim_restart = info->primitive_restart;
281
282
 
283
      BEGIN_NV04(ctx.push, NV50_3D(VERTEX_BEGIN_GL), 1);
284
      PUSH_DATA (ctx.push, ctx.prim);
285
      switch (index_size) {
286
      case 0:
287
         emit_vertices_seq(&ctx, info->start, vert_count);
288
         break;
289
      case 1:
290
         emit_vertices_i08(&ctx, info->start, vert_count);
291
         break;
292
      case 2:
293
         emit_vertices_i16(&ctx, info->start, vert_count);
294
         break;
295
      case 4:
296
         emit_vertices_i32(&ctx, info->start, vert_count);
297
         break;
298
      default:
299
         assert(0);
300
         break;
301
      }
302
      BEGIN_NV04(ctx.push, NV50_3D(VERTEX_END_GL), 1);
303
      PUSH_DATA (ctx.push, 0);
304
305
 
306
      ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
307
   }
308
}
309