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 "nvc0_resource.h"
9
10
 
11
12
 
13
   struct nouveau_pushbuf *push;
14
15
 
16
17
 
18
   uint32_t packet_vertex_limit;
19
20
 
21
22
 
23
   boolean need_vertex_id;
24
   uint32_t prim;
25
   uint32_t restart_index;
26
   uint32_t instance_id;
27
28
 
29
      int buffer;
30
      float value;
31
      uint8_t *data;
32
      unsigned offset;
33
      unsigned stride;
34
   } edgeflag;
35
};
36
37
 
38
init_push_context(struct nvc0_context *nvc0, struct push_context *ctx)
39
{
40
   struct pipe_vertex_element *ve;
41
42
 
43
   ctx->translate = nvc0->vertex->translate;
44
45
 
46
      ctx->need_vertex_id = nvc0->vertprog->vp.need_vertex_id;
47
   else
48
      ctx->need_vertex_id = FALSE;
49
50
 
51
   ctx->edgeflag.value = 0.5f;
52
53
 
54
      ve = &nvc0->vertex->element[nvc0->vertprog->vp.edgeflag].pipe;
55
      ctx->edgeflag.buffer = ve->vertex_buffer_index;
56
      ctx->edgeflag.offset = ve->src_offset;
57
      ctx->packet_vertex_limit = 1;
58
   } else {
59
      ctx->packet_vertex_limit = nvc0->vertex->vtx_per_packet_max;
60
      if (unlikely(ctx->need_vertex_id))
61
         ctx->packet_vertex_limit = 1;
62
   }
63
64
 
65
}
66
67
 
68
set_edgeflag(struct push_context *ctx, unsigned vtx_id)
69
{
70
   float f = *(float *)(ctx->edgeflag.data + vtx_id * ctx->edgeflag.stride);
71
72
 
73
      ctx->edgeflag.value = f;
74
      IMMED_NVC0(ctx->push, NVC0_3D(EDGEFLAG), f ? 1 : 0);
75
   }
76
}
77
78
 
79
set_vertexid(struct push_context *ctx, uint32_t vtx_id)
80
{
81
#if 0
82
   BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_ID), 1); /* broken on nvc0 */
83
#else
84
   BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_DATA), 1); /* as last attribute */
85
#endif
86
   PUSH_DATA (ctx->push, vtx_id);
87
}
88
89
 
90
prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index)
91
{
92
   unsigned i;
93
   for (i = 0; i < push; ++i)
94
      if (elts[i] == index)
95
         break;
96
   return i;
97
}
98
99
 
100
prim_restart_search_i16(uint16_t *elts, unsigned push, uint16_t index)
101
{
102
   unsigned i;
103
   for (i = 0; i < push; ++i)
104
      if (elts[i] == index)
105
         break;
106
   return i;
107
}
108
109
 
110
prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index)
111
{
112
   unsigned i;
113
   for (i = 0; i < push; ++i)
114
      if (elts[i] == index)
115
         break;
116
   return i;
117
}
118
119
 
120
emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
121
{
122
   uint8_t *restrict elts = (uint8_t *)ctx->idxbuf + start;
123
124
 
125
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
126
      unsigned size, nr;
127
128
 
129
      if (ctx->primitive_restart)
130
         nr = prim_restart_search_i08(elts, push, ctx->restart_index);
131
132
 
133
         set_edgeflag(ctx, elts[0]);
134
135
 
136
137
 
138
139
 
140
                                ctx->push->cur);
141
      ctx->push->cur += size;
142
143
 
144
         set_vertexid(ctx, elts[0]);
145
146
 
147
      elts += nr;
148
149
 
150
         count--;
151
         elts++;
152
         BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
153
         PUSH_DATA (ctx->push, 0);
154
         PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
155
                    (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
156
      }
157
   }
158
}
159
160
 
161
emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
162
{
163
   uint16_t *restrict elts = (uint16_t *)ctx->idxbuf + start;
164
165
 
166
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
167
      unsigned size, nr;
168
169
 
170
      if (ctx->primitive_restart)
171
         nr = prim_restart_search_i16(elts, push, ctx->restart_index);
172
173
 
174
         set_edgeflag(ctx, elts[0]);
175
176
 
177
178
 
179
180
 
181
                                 ctx->push->cur);
182
      ctx->push->cur += size;
183
184
 
185
         set_vertexid(ctx, elts[0]);
186
187
 
188
      elts += nr;
189
190
 
191
         count--;
192
         elts++;
193
         BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
194
         PUSH_DATA (ctx->push, 0);
195
         PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
196
                    (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
197
      }
198
   }
199
}
200
201
 
202
emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
203
{
204
   uint32_t *restrict elts = (uint32_t *)ctx->idxbuf + start;
205
206
 
207
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
208
      unsigned size, nr;
209
210
 
211
      if (ctx->primitive_restart)
212
         nr = prim_restart_search_i32(elts, push, ctx->restart_index);
213
214
 
215
         set_edgeflag(ctx, elts[0]);
216
217
 
218
219
 
220
221
 
222
                               ctx->push->cur);
223
      ctx->push->cur += size;
224
225
 
226
         set_vertexid(ctx, elts[0]);
227
228
 
229
      elts += nr;
230
231
 
232
         count--;
233
         elts++;
234
         BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
235
         PUSH_DATA (ctx->push, 0);
236
         PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
237
                    (ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
238
      }
239
   }
240
}
241
242
 
243
emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
244
{
245
   while (count) {
246
      unsigned push = MIN2(count, ctx->packet_vertex_limit);
247
      unsigned size = ctx->vertex_words * push;
248
249
 
250
         set_edgeflag(ctx, start);
251
252
 
253
254
 
255
                          ctx->push->cur);
256
      ctx->push->cur += size;
257
258
 
259
         set_vertexid(ctx, start);
260
261
 
262
      start += push;
263
   }
264
}
265
266
 
267
 
268
   case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
269
270
 
271
nvc0_prim_gl(unsigned prim)
272
{
273
   switch (prim) {
274
   NVC0_PRIM_GL_CASE(POINTS);
275
   NVC0_PRIM_GL_CASE(LINES);
276
   NVC0_PRIM_GL_CASE(LINE_LOOP);
277
   NVC0_PRIM_GL_CASE(LINE_STRIP);
278
   NVC0_PRIM_GL_CASE(TRIANGLES);
279
   NVC0_PRIM_GL_CASE(TRIANGLE_STRIP);
280
   NVC0_PRIM_GL_CASE(TRIANGLE_FAN);
281
   NVC0_PRIM_GL_CASE(QUADS);
282
   NVC0_PRIM_GL_CASE(QUAD_STRIP);
283
   NVC0_PRIM_GL_CASE(POLYGON);
284
   NVC0_PRIM_GL_CASE(LINES_ADJACENCY);
285
   NVC0_PRIM_GL_CASE(LINE_STRIP_ADJACENCY);
286
   NVC0_PRIM_GL_CASE(TRIANGLES_ADJACENCY);
287
   NVC0_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY);
288
   /*
289
   NVC0_PRIM_GL_CASE(PATCHES); */
290
   default:
291
      return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS;
292
      break;
293
   }
294
}
295
296
 
297
nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
298
{
299
   struct push_context ctx;
300
   unsigned i, index_size;
301
   unsigned inst_count = info->instance_count;
302
   unsigned vert_count = info->count;
303
   boolean apply_bias = info->indexed && info->index_bias;
304
305
 
306
307
 
308
      uint8_t *data;
309
      struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[i];
310
      struct nv04_resource *res = nv04_resource(vb->buffer);
311
312
 
313
                                         vb->buffer_offset, NOUVEAU_BO_RD);
314
315
 
316
         data += info->index_bias * vb->stride;
317
318
 
319
320
 
321
         ctx.edgeflag.data = data + ctx.edgeflag.offset;
322
         ctx.edgeflag.stride = vb->stride;
323
      }
324
   }
325
326
 
327
      ctx.idxbuf =
328
         nouveau_resource_map_offset(&nvc0->base,
329
                                     nv04_resource(nvc0->idxbuf.buffer),
330
                                     nvc0->idxbuf.offset, NOUVEAU_BO_RD);
331
      if (!ctx.idxbuf)
332
         return;
333
      index_size = nvc0->idxbuf.index_size;
334
      ctx.primitive_restart = info->primitive_restart;
335
      ctx.restart_index = info->restart_index;
336
   } else {
337
      ctx.idxbuf = NULL;
338
      index_size = 0;
339
      ctx.primitive_restart = FALSE;
340
      ctx.restart_index = 0;
341
342
 
343
         struct pipe_context *pipe = &nvc0->base.pipe;
344
         struct nvc0_so_target *targ;
345
         targ = nvc0_so_target(info->count_from_stream_output);
346
         pipe->get_query_result(pipe, targ->pq, TRUE, (void*)&vert_count);
347
         vert_count /= targ->stride;
348
      }
349
   }
350
351
 
352
   ctx.prim = nvc0_prim_gl(info->mode);
353
354
 
355
      const unsigned a = nvc0->vertex->num_elements;
356
      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
357
      PUSH_DATA (ctx.push, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
358
                 NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
359
                 NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
360
      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 1);
361
      PUSH_DATA (ctx.push, (((0x80 + a * 0x10) / 4) << 4) | 1);
362
   }
363
364
 
365
      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_BEGIN_GL), 1);
366
      PUSH_DATA (ctx.push, ctx.prim);
367
      switch (index_size) {
368
      case 0:
369
         emit_vertices_seq(&ctx, info->start, vert_count);
370
         break;
371
      case 1:
372
         emit_vertices_i08(&ctx, info->start, vert_count);
373
         break;
374
      case 2:
375
         emit_vertices_i16(&ctx, info->start, vert_count);
376
         break;
377
      case 4:
378
         emit_vertices_i32(&ctx, info->start, vert_count);
379
         break;
380
      default:
381
         assert(0);
382
         break;
383
      }
384
      IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_END_GL), 0);
385
386
 
387
      ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
388
   }
389
390
 
391
      IMMED_NVC0(ctx.push, NVC0_3D(EDGEFLAG), 1);
392
393
 
394
      const unsigned a = nvc0->vertex->num_elements;
395
      IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 0);
396
      BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
397
      PUSH_DATA (ctx.push,
398
                 NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST |
399
                 NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
400
                 NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
401
   }
402
403
 
404
      nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer));
405
406
 
407
      nouveau_resource_unmap(nv04_resource(nvc0->vtxbuf[i].buffer));
408
}
409