Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / nouveau / nv20_render.c
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 "nv20_3d.xml.h"
30 #include "nv20_driver.h"
31
32 #define NUM_VERTEX_ATTRS 16
33
34 static void
35 nv20_emit_material(struct gl_context *ctx, struct nouveau_array *a,
36                    const void *v);
37
38 /* Vertex attribute format. */
39 static struct nouveau_attr_info nv20_vertex_attrs[VERT_ATTRIB_MAX] = {
40         [VERT_ATTRIB_POS] = {
41                 .vbo_index = 0,
42                 .imm_method = NV20_3D_VERTEX_POS_4F_X,
43                 .imm_fields = 4,
44         },
45         [VERT_ATTRIB_NORMAL] = {
46                 .vbo_index = 2,
47                 .imm_method = NV20_3D_VERTEX_NOR_3F_X,
48                 .imm_fields = 3,
49         },
50         [VERT_ATTRIB_COLOR0] = {
51                 .vbo_index = 3,
52                 .imm_method = NV20_3D_VERTEX_COL_4F,
53                 .imm_fields = 4,
54         },
55         [VERT_ATTRIB_COLOR1] = {
56                 .vbo_index = 4,
57                 .imm_method = NV20_3D_VERTEX_COL2_3F,
58                 .imm_fields = 3,
59         },
60         [VERT_ATTRIB_FOG] = {
61                 .vbo_index = 5,
62                 .imm_method = NV20_3D_VERTEX_FOG_1F,
63                 .imm_fields = 1,
64         },
65         [VERT_ATTRIB_TEX0] = {
66                 .vbo_index = 9,
67                 .imm_method = NV20_3D_VERTEX_TX0_4F_S,
68                 .imm_fields = 4,
69         },
70         [VERT_ATTRIB_TEX1] = {
71                 .vbo_index = 10,
72                 .imm_method = NV20_3D_VERTEX_TX1_4F_S,
73                 .imm_fields = 4,
74         },
75         [VERT_ATTRIB_TEX2] = {
76                 .vbo_index = 11,
77                 .imm_method = NV20_3D_VERTEX_TX2_4F_S,
78                 .imm_fields = 4,
79         },
80         [VERT_ATTRIB_TEX3] = {
81                 .vbo_index = 12,
82                 .imm_method = NV20_3D_VERTEX_TX3_4F_S,
83                 .imm_fields = 4,
84         },
85         [VERT_ATTRIB_GENERIC0] = {
86                 .emit = nv20_emit_material,
87         },
88         [VERT_ATTRIB_GENERIC1] = {
89                 .emit = nv20_emit_material,
90         },
91         [VERT_ATTRIB_GENERIC2] = {
92                 .emit = nv20_emit_material,
93         },
94         [VERT_ATTRIB_GENERIC3] = {
95                 .emit = nv20_emit_material,
96         },
97         [VERT_ATTRIB_GENERIC4] = {
98                 .emit = nv20_emit_material,
99         },
100         [VERT_ATTRIB_GENERIC5] = {
101                 .emit = nv20_emit_material,
102         },
103         [VERT_ATTRIB_GENERIC6] = {
104                 .emit = nv20_emit_material,
105         },
106         [VERT_ATTRIB_GENERIC7] = {
107                 .emit = nv20_emit_material,
108         },
109         [VERT_ATTRIB_GENERIC8] = {
110                 .emit = nv20_emit_material,
111         },
112         [VERT_ATTRIB_GENERIC9] = {
113                 .emit = nv20_emit_material,
114         },
115 };
116
117 static int
118 get_hw_format(int type)
119 {
120         switch (type) {
121         case GL_FLOAT:
122                 return NV20_3D_VTXBUF_FMT_TYPE_FLOAT;
123         case GL_UNSIGNED_SHORT:
124                 return NV20_3D_VTXBUF_FMT_TYPE_USHORT;
125         case GL_UNSIGNED_BYTE:
126                 return NV20_3D_VTXBUF_FMT_TYPE_UBYTE;
127         default:
128                 assert(0);
129         }
130 }
131
132 static void
133 nv20_render_set_format(struct gl_context *ctx)
134 {
135         struct nouveau_render_state *render = to_render_state(ctx);
136         struct nouveau_channel *chan = context_chan(ctx);
137         struct nouveau_grobj *kelvin = context_eng3d(ctx);
138         int i, attr, hw_format;
139
140         FOR_EACH_ATTR(render, i, attr) {
141                 if (attr >= 0) {
142                         struct nouveau_array *a = &render->attrs[attr];
143
144                         hw_format = a->stride << 8 |
145                                 a->fields << 4 |
146                                 get_hw_format(a->type);
147
148                 } else {
149                         /* Unused attribute. */
150                         hw_format = NV20_3D_VTXBUF_FMT_TYPE_FLOAT;
151                 }
152
153                 BEGIN_RING(chan, kelvin, NV20_3D_VTXBUF_FMT(i), 1);
154                 OUT_RING(chan, hw_format);
155         }
156 }
157
158 static void
159 nv20_render_bind_vertices(struct gl_context *ctx)
160 {
161         struct nouveau_render_state *render = to_render_state(ctx);
162         struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX);
163         struct nouveau_grobj *kelvin = context_eng3d(ctx);
164         int i, attr;
165
166         FOR_EACH_BOUND_ATTR(render, i, attr) {
167                 struct nouveau_array *a = &render->attrs[attr];
168
169                 nouveau_bo_mark(bctx, kelvin,
170                                 NV20_3D_VTXBUF_OFFSET(i),
171                                 a->bo, a->offset, 0,
172                                 0, NV20_3D_VTXBUF_OFFSET_DMA1,
173                                 NOUVEAU_BO_LOW | NOUVEAU_BO_OR |
174                                 NOUVEAU_BO_GART | NOUVEAU_BO_RD);
175         }
176 }
177
178 /* Vertex array rendering defs. */
179 #define RENDER_LOCALS(ctx)                                      \
180         struct nouveau_grobj *kelvin = context_eng3d(ctx)
181
182 #define BATCH_VALIDATE()                                                \
183         BEGIN_RING(chan, kelvin, NV20_3D_VTXBUF_VALIDATE, 1);   \
184         OUT_RING(chan, 0)
185
186 #define BATCH_BEGIN(prim)                                       \
187         BEGIN_RING(chan, kelvin, NV20_3D_VERTEX_BEGIN_END, 1);  \
188         OUT_RING(chan, prim)
189 #define BATCH_END()                                             \
190         BEGIN_RING(chan, kelvin, NV20_3D_VERTEX_BEGIN_END, 1);  \
191         OUT_RING(chan, 0)
192
193 #define MAX_PACKET 0x400
194
195 #define MAX_OUT_L 0x100
196 #define BATCH_PACKET_L(n)                                               \
197         BEGIN_RING_NI(chan, kelvin, NV20_3D_VTXBUF_BATCH, n)
198 #define BATCH_OUT_L(i, n)                       \
199         OUT_RING(chan, ((n) - 1) << 24 | (i))
200
201 #define MAX_OUT_I16 0x2
202 #define BATCH_PACKET_I16(n)                                     \
203         BEGIN_RING_NI(chan, kelvin, NV20_3D_VTXBUF_ELEMENT_U16, n)
204 #define BATCH_OUT_I16(i0, i1)                   \
205         OUT_RING(chan, (i1) << 16 | (i0))
206
207 #define MAX_OUT_I32 0x1
208 #define BATCH_PACKET_I32(n)                                     \
209         BEGIN_RING_NI(chan, kelvin, NV20_3D_VTXBUF_ELEMENT_U32, n)
210 #define BATCH_OUT_I32(i)                        \
211         OUT_RING(chan, i)
212
213 #define IMM_PACKET(m, n)                        \
214         BEGIN_RING(chan, kelvin, m, n)
215 #define IMM_OUT(x)                              \
216         OUT_RINGf(chan, x)
217
218 #define TAG(x) nv20_##x
219 #include "nouveau_render_t.c"
220 #include "nouveau_vbo_t.c"
221 #include "nouveau_swtnl_t.c"