nv10_render.c revision a09b7f7f150d1687a614fd59cf09ec5e3c3a13fd
1/*
2 * Copyright (C) 2009-2010 Francisco Jerez.
3 * All Rights Reserved.
4 *
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:
12 *
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.
16 *
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.
24 *
25 */
26
27#include "nouveau_driver.h"
28#include "nouveau_context.h"
29#include "nv10_3d.xml.h"
30#include "nv10_driver.h"
31
32#define NUM_VERTEX_ATTRS 8
33
34static void
35nv10_emit_material(struct gl_context *ctx, struct nouveau_array *a,
36		   const void *v);
37
38/* Vertex attribute format. */
39static struct nouveau_attr_info nv10_vertex_attrs[VERT_ATTRIB_MAX] = {
40	[VERT_ATTRIB_POS] = {
41		.vbo_index = 0,
42		.imm_method = NV10_3D_VERTEX_POS_4F_X,
43		.imm_fields = 4,
44	},
45	[VERT_ATTRIB_COLOR0] = {
46		.vbo_index = 1,
47		.imm_method = NV10_3D_VERTEX_COL_4F_R,
48		.imm_fields = 4,
49	},
50	[VERT_ATTRIB_COLOR1] = {
51		.vbo_index = 2,
52		.imm_method = NV10_3D_VERTEX_COL2_3F_R,
53		.imm_fields = 3,
54	},
55	[VERT_ATTRIB_TEX0] = {
56		.vbo_index = 3,
57		.imm_method = NV10_3D_VERTEX_TX0_4F_S,
58		.imm_fields = 4,
59	},
60	[VERT_ATTRIB_TEX1] = {
61		.vbo_index = 4,
62		.imm_method = NV10_3D_VERTEX_TX1_4F_S,
63		.imm_fields = 4,
64	},
65	[VERT_ATTRIB_NORMAL] = {
66		.vbo_index = 5,
67		.imm_method = NV10_3D_VERTEX_NOR_3F_X,
68		.imm_fields = 3,
69	},
70	[VERT_ATTRIB_FOG] = {
71		.vbo_index = 7,
72		.imm_method = NV10_3D_VERTEX_FOG_1F,
73		.imm_fields = 1,
74	},
75	[VERT_ATTRIB_GENERIC0] = {
76		.emit = nv10_emit_material,
77	},
78	[VERT_ATTRIB_GENERIC2] = {
79		.emit = nv10_emit_material,
80	},
81	[VERT_ATTRIB_GENERIC4] = {
82		.emit = nv10_emit_material,
83	},
84	[VERT_ATTRIB_GENERIC6] = {
85		.emit = nv10_emit_material,
86	},
87	[VERT_ATTRIB_GENERIC8] = {
88		.emit = nv10_emit_material,
89	},
90};
91
92static int
93get_hw_format(int type)
94{
95	switch (type) {
96	case GL_FLOAT:
97		return NV10_3D_VTXBUF_FMT_TYPE_V32_FLOAT;
98	case GL_SHORT:
99	case GL_UNSIGNED_SHORT:
100		return NV10_3D_VTXBUF_FMT_TYPE_V16_SNORM;
101	case GL_UNSIGNED_BYTE:
102		return NV10_3D_VTXBUF_FMT_TYPE_U8_UNORM;
103	default:
104		assert(0);
105	}
106}
107
108static void
109nv10_render_set_format(struct gl_context *ctx)
110{
111	struct nouveau_render_state *render = to_render_state(ctx);
112	struct nouveau_channel *chan = context_chan(ctx);
113	struct nouveau_grobj *celsius = context_eng3d(ctx);
114	int i, attr, hw_format;
115
116	FOR_EACH_ATTR(render, i, attr) {
117		if (attr >= 0) {
118			struct nouveau_array *a = &render->attrs[attr];
119
120			hw_format = a->stride << 8 |
121				a->fields << 4 |
122				get_hw_format(a->type);
123
124			if (attr == VERT_ATTRIB_POS && a->fields == 4)
125				hw_format |= NV10_3D_VTXBUF_FMT_HOMOGENEOUS;
126		} else {
127			/* Unused attribute. */
128			hw_format = NV10_3D_VTXBUF_FMT_TYPE_V32_FLOAT;
129		}
130
131		BEGIN_RING(chan, celsius, NV10_3D_VTXBUF_FMT(i), 1);
132		OUT_RING(chan, hw_format);
133	}
134}
135
136static void
137nv10_render_bind_vertices(struct gl_context *ctx)
138{
139	struct nouveau_render_state *render = to_render_state(ctx);
140	struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX);
141	struct nouveau_grobj *celsius = context_eng3d(ctx);
142	int i, attr;
143
144	FOR_EACH_BOUND_ATTR(render, i, attr) {
145		struct nouveau_array *a = &render->attrs[attr];
146
147		nouveau_bo_markl(bctx, celsius,
148				 NV10_3D_VTXBUF_OFFSET(i),
149				 a->bo, a->offset,
150				 NOUVEAU_BO_GART | NOUVEAU_BO_RD);
151	}
152}
153
154/* Vertex array rendering defs. */
155#define RENDER_LOCALS(ctx)					\
156	struct nouveau_grobj *celsius = context_eng3d(ctx)
157
158#define BATCH_VALIDATE()						\
159	BEGIN_RING(chan, celsius, NV10_3D_VTXBUF_VALIDATE, 1);	\
160	OUT_RING(chan, 0)
161
162#define BATCH_BEGIN(prim)						\
163	BEGIN_RING(chan, celsius, NV10_3D_VTXBUF_BEGIN_END, 1);	\
164	OUT_RING(chan, prim)
165#define BATCH_END()							\
166	BEGIN_RING(chan, celsius, NV10_3D_VTXBUF_BEGIN_END, 1);	\
167	OUT_RING(chan, 0)
168
169#define MAX_PACKET 0x400
170
171#define MAX_OUT_L 0x100
172#define BATCH_PACKET_L(n)						\
173	BEGIN_RING_NI(chan, celsius, NV10_3D_VTXBUF_BATCH, n)
174#define BATCH_OUT_L(i, n)			\
175	OUT_RING(chan, ((n) - 1) << 24 | (i))
176
177#define MAX_OUT_I16 0x2
178#define BATCH_PACKET_I16(n)						\
179	BEGIN_RING_NI(chan, celsius, NV10_3D_VTXBUF_ELEMENT_U16, n)
180#define BATCH_OUT_I16(i0, i1)			\
181	OUT_RING(chan, (i1) << 16 | (i0))
182
183#define MAX_OUT_I32 0x1
184#define BATCH_PACKET_I32(n)						\
185	BEGIN_RING_NI(chan, celsius, NV10_3D_VTXBUF_ELEMENT_U32, n)
186#define BATCH_OUT_I32(i)			\
187	OUT_RING(chan, i)
188
189#define IMM_PACKET(m, n)			\
190	BEGIN_RING(chan, celsius, m, n)
191#define IMM_OUT(x)				\
192	OUT_RINGf(chan, x)
193
194#define TAG(x) nv10_##x
195#include "nouveau_render_t.c"
196#include "nouveau_vbo_t.c"
197#include "nouveau_swtnl_t.c"
198