2 * Copyright (C) 2009-2010 Francisco Jerez.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial
15 * portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Vertex submission helper definitions shared among the software and
32 #include "nouveau_gldefs.h"
34 #include "main/light.h"
38 #define OUT_INDICES_L(r, i, d, n) \
39 BATCH_OUT_L(i + d, n); \
41 #define OUT_INDICES_I16(r, i, d, n) \
42 BATCH_OUT_I16(r->ib.extract_u(&r->ib, 0, i) + d, \
43 r->ib.extract_u(&r->ib, 0, i + 1) + d)
44 #define OUT_INDICES_I32(r, i, d, n) \
45 BATCH_OUT_I32(r->ib.extract_u(&r->ib, 0, i) + d)
48 * Emit <n> vertices using BATCH_OUT_<out>, MAX_OUT_<out> at a time,
49 * grouping them in packets of length MAX_PACKET.
51 * out: hardware index data type.
53 * start: element within the index buffer to begin with.
54 * delta: integer correction that will be added to each index found in
57 #define EMIT_VBO(out, ctx, start, delta, n) do { \
58 struct nouveau_render_state *render = to_render_state(ctx); \
62 int npack = MIN2(npush, MAX_PACKET * MAX_OUT_##out); \
65 BATCH_PACKET_##out((npack + MAX_OUT_##out - 1) \
68 int nout = MIN2(npack, MAX_OUT_##out); \
71 OUT_INDICES_##out(render, start, delta, \
79 * Emit the <n>-th element of the array <a>, using IMM_OUT.
81 #define EMIT_IMM(ctx, a, n) do { \
82 struct nouveau_attr_info *info = \
83 &TAG(vertex_attrs)[(a)->attr]; \
87 IMM_PACKET(info->imm_method, info->imm_fields); \
89 for (m = 0; m < (a)->fields; m++) \
90 IMM_OUT((a)->extract_f(a, n, m)); \
92 for (m = (a)->fields; m < info->imm_fields; m++) \
93 IMM_OUT(((float []){0, 0, 0, 1})[m]); \
96 info->emit(ctx, a, (a)->buf + n * (a)->stride); \
101 dispatch_l(struct gl_context
*ctx
, unsigned int start
, int delta
,
104 struct nouveau_pushbuf
*push
= context_push(ctx
);
107 EMIT_VBO(L
, ctx
, start
, delta
, n
);
111 dispatch_i32(struct gl_context
*ctx
, unsigned int start
, int delta
,
114 struct nouveau_pushbuf
*push
= context_push(ctx
);
117 EMIT_VBO(I32
, ctx
, start
, delta
, n
);
121 dispatch_i16(struct gl_context
*ctx
, unsigned int start
, int delta
,
124 struct nouveau_pushbuf
*push
= context_push(ctx
);
127 EMIT_VBO(I32
, ctx
, start
, delta
, n
& 1);
128 EMIT_VBO(I16
, ctx
, start
, delta
, n
& ~1);
132 * Select an appropriate dispatch function for the given index buffer.
135 get_array_dispatch(struct nouveau_array
*a
)
139 else if (a
->type
== GL_UNSIGNED_INT
)
146 * Returns how many vertices you can draw using <n> pushbuf dwords.
148 static inline unsigned
149 get_max_vertices(struct gl_context
*ctx
, const struct _mesa_index_buffer
*ib
,
152 struct nouveau_render_state
*render
= to_render_state(ctx
);
154 if (render
->mode
== IMM
) {
155 return MAX2(0, n
- 4) / (render
->vertex_size
/ 4 +
162 case GL_UNSIGNED_INT
:
163 max_out
= MAX_OUT_I32
;
166 case GL_UNSIGNED_SHORT
:
167 max_out
= MAX_OUT_I16
;
170 case GL_UNSIGNED_BYTE
:
171 max_out
= MAX_OUT_I16
;
183 return MAX2(0, n
- 7) * max_out
* MAX_PACKET
/ (1 + MAX_PACKET
);
188 TAG(emit_material
)(struct gl_context
*ctx
, struct nouveau_array
*a
,
191 int attr
= a
->attr
- VERT_ATTRIB_GENERIC0
;
192 int state
= ((int []) {
193 NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT
,
194 NOUVEAU_STATE_MATERIAL_BACK_AMBIENT
,
195 NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE
,
196 NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE
,
197 NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR
,
198 NOUVEAU_STATE_MATERIAL_BACK_SPECULAR
,
199 NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT
,
200 NOUVEAU_STATE_MATERIAL_BACK_AMBIENT
,
201 NOUVEAU_STATE_MATERIAL_FRONT_SHININESS
,
202 NOUVEAU_STATE_MATERIAL_BACK_SHININESS
205 COPY_4V(ctx
->Light
.Material
.Attrib
[attr
], (float *)v
);
206 _mesa_update_material(ctx
, 1 << attr
);
208 context_drv(ctx
)->emit
[state
](ctx
, state
);