2 #include "pipe/p_context.h"
3 #include "pipe/p_state.h"
4 #include "util/u_inlines.h"
5 #include "util/u_format.h"
6 #include "translate/translate.h"
8 #include "nvc0_context.h"
9 #include "nvc0_resource.h"
11 #include "nvc0_3d.xml.h"
14 struct nvc0_context
*nvc0
;
26 void (*push
)(struct nouveau_channel
*, void *);
35 emit_b32_1(struct nouveau_channel
*chan
, void *data
)
43 emit_b32_2(struct nouveau_channel
*chan
, void *data
)
52 emit_b32_3(struct nouveau_channel
*chan
, void *data
)
62 emit_b32_4(struct nouveau_channel
*chan
, void *data
)
73 emit_b16_1(struct nouveau_channel
*chan
, void *data
)
81 emit_b16_3(struct nouveau_channel
*chan
, void *data
)
85 OUT_RING(chan
, (v
[1] << 16) | v
[0]);
90 emit_b08_1(struct nouveau_channel
*chan
, void *data
)
98 emit_b08_3(struct nouveau_channel
*chan
, void *data
)
102 OUT_RING(chan
, (v
[2] << 16) | (v
[1] << 8) | v
[0]);
106 emit_b64_1(struct nouveau_channel
*chan
, void *data
)
110 OUT_RINGf(chan
, v
[0]);
114 emit_b64_2(struct nouveau_channel
*chan
, void *data
)
118 OUT_RINGf(chan
, v
[0]);
119 OUT_RINGf(chan
, v
[1]);
123 emit_b64_3(struct nouveau_channel
*chan
, void *data
)
127 OUT_RINGf(chan
, v
[0]);
128 OUT_RINGf(chan
, v
[1]);
129 OUT_RINGf(chan
, v
[2]);
133 emit_b64_4(struct nouveau_channel
*chan
, void *data
)
137 OUT_RINGf(chan
, v
[0]);
138 OUT_RINGf(chan
, v
[1]);
139 OUT_RINGf(chan
, v
[2]);
140 OUT_RINGf(chan
, v
[3]);
144 emit_vertex(struct push_context
*ctx
, unsigned n
)
146 struct nouveau_channel
*chan
= ctx
->nvc0
->screen
->base
.channel
;
149 if (ctx
->edgeflag_input
< 32) {
153 BEGIN_RING_NI(chan
, RING_3D(VERTEX_DATA
), ctx
->vertex_size
);
154 for (i
= 0; i
< ctx
->num_attrs
; ++i
)
155 ctx
->attr
[i
].push(chan
,
156 (uint8_t *)ctx
->attr
[i
].map
+ n
* ctx
->attr
[i
].stride
);
160 emit_edgeflag(struct push_context
*ctx
, boolean enabled
)
162 struct nouveau_channel
*chan
= ctx
->nvc0
->screen
->base
.channel
;
164 INLIN_RING(chan
, RING_3D(EDGEFLAG_ENABLE
), enabled
);
168 emit_elt08(struct push_context
*ctx
, unsigned start
, unsigned count
)
170 uint8_t *idxbuf
= ctx
->idxbuf
;
173 emit_vertex(ctx
, idxbuf
[start
++]);
177 emit_elt16(struct push_context
*ctx
, unsigned start
, unsigned count
)
179 uint16_t *idxbuf
= ctx
->idxbuf
;
182 emit_vertex(ctx
, idxbuf
[start
++]);
186 emit_elt32(struct push_context
*ctx
, unsigned start
, unsigned count
)
188 uint32_t *idxbuf
= ctx
->idxbuf
;
191 emit_vertex(ctx
, idxbuf
[start
++]);
195 emit_seq(struct push_context
*ctx
, unsigned start
, unsigned count
)
198 emit_vertex(ctx
, start
++);
201 #define NVC0_PRIM_GL_CASE(n) \
202 case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
204 static INLINE
unsigned
205 nvc0_prim_gl(unsigned prim
)
208 NVC0_PRIM_GL_CASE(POINTS
);
209 NVC0_PRIM_GL_CASE(LINES
);
210 NVC0_PRIM_GL_CASE(LINE_LOOP
);
211 NVC0_PRIM_GL_CASE(LINE_STRIP
);
212 NVC0_PRIM_GL_CASE(TRIANGLES
);
213 NVC0_PRIM_GL_CASE(TRIANGLE_STRIP
);
214 NVC0_PRIM_GL_CASE(TRIANGLE_FAN
);
215 NVC0_PRIM_GL_CASE(QUADS
);
216 NVC0_PRIM_GL_CASE(QUAD_STRIP
);
217 NVC0_PRIM_GL_CASE(POLYGON
);
218 NVC0_PRIM_GL_CASE(LINES_ADJACENCY
);
219 NVC0_PRIM_GL_CASE(LINE_STRIP_ADJACENCY
);
220 NVC0_PRIM_GL_CASE(TRIANGLES_ADJACENCY
);
221 NVC0_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY
);
223 NVC0_PRIM_GL_CASE(PATCHES); */
225 return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS
;
231 nvc0_push_vbo2(struct nvc0_context
*nvc0
, const struct pipe_draw_info
*info
)
233 struct push_context ctx
;
235 unsigned inst
= info
->instance_count
;
236 unsigned prim
= nvc0_prim_gl(info
->mode
);
239 ctx
.vertex_size
= nvc0
->vertex
->vtx_size
;
243 ctx
.edgeflag_input
= 32;
245 for (i
= 0; i
< nvc0
->vertex
->num_elements
; ++i
) {
246 struct pipe_vertex_element
*ve
= &nvc0
->vertex
->element
[i
].pipe
;
247 struct pipe_vertex_buffer
*vb
= &nvc0
->vtxbuf
[ve
->vertex_buffer_index
];
248 struct nouveau_bo
*bo
= nvc0_resource(vb
->buffer
)->bo
;
249 unsigned nr_components
;
251 if (!(nvc0
->vbo_fifo
& (1 << i
)))
255 if (nouveau_bo_map(bo
, NOUVEAU_BO_RD
))
257 ctx
.attr
[n
].map
= (uint8_t *)bo
->map
+ vb
->buffer_offset
+ ve
->src_offset
;
259 nouveau_bo_unmap(bo
);
261 ctx
.attr
[n
].stride
= vb
->stride
;
262 ctx
.attr
[n
].divisor
= ve
->instance_divisor
;
264 nr_components
= util_format_get_nr_components(ve
->src_format
);
265 switch (util_format_get_component_bits(ve
->src_format
,
266 UTIL_FORMAT_COLORSPACE_RGB
, 0)) {
268 switch (nr_components
) {
269 case 1: ctx
.attr
[n
].push
= emit_b08_1
; break;
270 case 2: ctx
.attr
[n
].push
= emit_b16_1
; break;
271 case 3: ctx
.attr
[n
].push
= emit_b08_3
; break;
272 case 4: ctx
.attr
[n
].push
= emit_b32_1
; break;
276 switch (nr_components
) {
277 case 1: ctx
.attr
[n
].push
= emit_b16_1
; break;
278 case 2: ctx
.attr
[n
].push
= emit_b32_1
; break;
279 case 3: ctx
.attr
[n
].push
= emit_b16_3
; break;
280 case 4: ctx
.attr
[n
].push
= emit_b32_2
; break;
284 switch (nr_components
) {
285 case 1: ctx
.attr
[n
].push
= emit_b32_1
; break;
286 case 2: ctx
.attr
[n
].push
= emit_b32_2
; break;
287 case 3: ctx
.attr
[n
].push
= emit_b32_3
; break;
288 case 4: ctx
.attr
[n
].push
= emit_b32_4
; break;
298 struct nvc0_resource
*res
= nvc0_resource(nvc0
->idxbuf
.buffer
);
299 if (!res
|| nouveau_bo_map(res
->bo
, NOUVEAU_BO_RD
))
301 ctx
.idxbuf
= res
->bo
->map
;
302 nouveau_bo_unmap(res
->bo
);
303 ctx
.idxsize
= nvc0
->idxbuf
.index_size
;
309 BEGIN_RING(nvc0
->screen
->base
.channel
, RING_3D(VERTEX_BEGIN_GL
), 1);
310 OUT_RING (nvc0
->screen
->base
.channel
, prim
);
311 switch (ctx
.idxsize
) {
313 emit_seq(&ctx
, info
->start
, info
->count
);
316 emit_elt08(&ctx
, info
->start
, info
->count
);
319 emit_elt16(&ctx
, info
->start
, info
->count
);
322 emit_elt32(&ctx
, info
->start
, info
->count
);
325 INLIN_RING(nvc0
->screen
->base
.channel
, RING_3D(VERTEX_END_GL
), 0);
327 prim
|= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT
;