Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / nv10 / nv10_state_emit.c
1 #include "nv10_context.h"
2 #include "nv10_state.h"
3
4 static void nv10_state_emit_blend(struct nv10_context* nv10)
5 {
6 struct nv10_blend_state *b = nv10->blend;
7 struct nv10_screen *screen = nv10->screen;
8 struct nouveau_channel *chan = screen->base.channel;
9 struct nouveau_grobj *celsius = screen->celsius;
10
11 BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1);
12 OUT_RING (chan, b->d_enable);
13
14 BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 3);
15 OUT_RING (chan, b->b_enable);
16 OUT_RING (chan, b->b_srcfunc);
17 OUT_RING (chan, b->b_dstfunc);
18
19 BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1);
20 OUT_RING (chan, b->c_mask);
21 }
22
23 static void nv10_state_emit_blend_color(struct nv10_context* nv10)
24 {
25 struct pipe_blend_color *c = nv10->blend_color;
26 struct nv10_screen *screen = nv10->screen;
27 struct nouveau_channel *chan = screen->base.channel;
28 struct nouveau_grobj *celsius = screen->celsius;
29
30 BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1);
31 OUT_RING (chan,
32 (float_to_ubyte(c->color[3]) << 24)|
33 (float_to_ubyte(c->color[0]) << 16)|
34 (float_to_ubyte(c->color[1]) << 8) |
35 (float_to_ubyte(c->color[2]) << 0));
36 }
37
38 static void nv10_state_emit_rast(struct nv10_context* nv10)
39 {
40 struct nv10_rasterizer_state *r = nv10->rast;
41 struct nv10_screen *screen = nv10->screen;
42 struct nouveau_channel *chan = screen->base.channel;
43 struct nouveau_grobj *celsius = screen->celsius;
44
45 BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 2);
46 OUT_RING (chan, r->shade_model);
47 OUT_RING (chan, r->line_width);
48
49
50 BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1);
51 OUT_RING (chan, r->point_size);
52
53 BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
54 OUT_RING (chan, r->poly_mode_front);
55 OUT_RING (chan, r->poly_mode_back);
56
57
58 BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2);
59 OUT_RING (chan, r->cull_face);
60 OUT_RING (chan, r->front_face);
61
62 BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2);
63 OUT_RING (chan, r->line_smooth_en);
64 OUT_RING (chan, r->poly_smooth_en);
65
66 BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1);
67 OUT_RING (chan, r->cull_face_en);
68 }
69
70 static void nv10_state_emit_dsa(struct nv10_context* nv10)
71 {
72 struct nv10_depth_stencil_alpha_state *d = nv10->dsa;
73 struct nv10_screen *screen = nv10->screen;
74 struct nouveau_channel *chan = screen->base.channel;
75 struct nouveau_grobj *celsius = screen->celsius;
76
77 BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1);
78 OUT_RING (chan, d->depth.func);
79
80 BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
81 OUT_RING (chan, d->depth.write_enable);
82
83 BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
84 OUT_RING (chan, d->depth.test_enable);
85
86 #if 0
87 BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1);
88 OUT_RING (chan, d->stencil.enable);
89 BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 7);
90 OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7);
91 #endif
92
93 BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
94 OUT_RING (chan, d->alpha.enabled);
95
96 BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 1);
97 OUT_RING (chan, d->alpha.func);
98
99 BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_REF, 1);
100 OUT_RING (chan, d->alpha.ref);
101 }
102
103 static void nv10_state_emit_viewport(struct nv10_context* nv10)
104 {
105 }
106
107 static void nv10_state_emit_scissor(struct nv10_context* nv10)
108 {
109 // XXX this is so not working
110 /* struct pipe_scissor_state *s = nv10->scissor;
111 BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2);
112 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
113 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
114 }
115
116 static void nv10_state_emit_framebuffer(struct nv10_context* nv10)
117 {
118 struct pipe_framebuffer_state* fb = nv10->framebuffer;
119 struct nv04_surface *rt, *zeta = NULL;
120 uint32_t rt_format, w, h;
121 int colour_format = 0, zeta_format = 0;
122 struct nv10_miptree *nv10mt = 0;
123
124 struct nv10_screen *screen = nv10->screen;
125 struct nouveau_channel *chan = screen->base.channel;
126 struct nouveau_grobj *celsius = screen->celsius;
127
128 w = fb->cbufs[0]->width;
129 h = fb->cbufs[0]->height;
130 colour_format = fb->cbufs[0]->format;
131 rt = (struct nv04_surface *)fb->cbufs[0];
132
133 if (fb->zsbuf) {
134 if (colour_format) {
135 assert(w == fb->zsbuf->width);
136 assert(h == fb->zsbuf->height);
137 } else {
138 w = fb->zsbuf->width;
139 h = fb->zsbuf->height;
140 }
141
142 zeta_format = fb->zsbuf->format;
143 zeta = (struct nv04_surface *)fb->zsbuf;
144 }
145
146 rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR;
147
148 switch (colour_format) {
149 case PIPE_FORMAT_X8R8G8B8_UNORM:
150 rt_format |= NV10TCL_RT_FORMAT_COLOR_X8R8G8B8;
151 break;
152 case PIPE_FORMAT_A8R8G8B8_UNORM:
153 case 0:
154 rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8;
155 break;
156 case PIPE_FORMAT_R5G6B5_UNORM:
157 rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5;
158 break;
159 default:
160 assert(0);
161 }
162
163 if (zeta) {
164 BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1);
165 OUT_RING (chan, rt->pitch | (zeta->pitch << 16));
166 } else {
167 BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1);
168 OUT_RING (chan, rt->pitch | (rt->pitch << 16));
169 }
170
171 nv10mt = (struct nv10_miptree *)rt->base.texture;
172 nv10->rt[0] = nv10mt->buffer;
173
174 if (zeta_format)
175 {
176 nv10mt = (struct nv10_miptree *)zeta->base.texture;
177 nv10->zeta = nv10mt->buffer;
178 }
179
180 BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 3);
181 OUT_RING (chan, (w << 16) | 0);
182 OUT_RING (chan, (h << 16) | 0);
183 OUT_RING (chan, rt_format);
184 BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2);
185 OUT_RING (chan, ((w - 1) << 16) | 0 | 0x08000800);
186 OUT_RING (chan, ((h - 1) << 16) | 0 | 0x08000800);
187 }
188
189 static void nv10_vertex_layout(struct nv10_context *nv10)
190 {
191 struct nv10_fragment_program *fp = nv10->fragprog.current;
192 uint32_t src = 0;
193 int i;
194 struct vertex_info vinfo;
195
196 memset(&vinfo, 0, sizeof(vinfo));
197
198 for (i = 0; i < fp->info.num_inputs; i++) {
199 switch (fp->info.input_semantic_name[i]) {
200 case TGSI_SEMANTIC_POSITION:
201 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
202 break;
203 case TGSI_SEMANTIC_COLOR:
204 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
205 break;
206 default:
207 case TGSI_SEMANTIC_GENERIC:
208 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
209 break;
210 case TGSI_SEMANTIC_FOG:
211 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
212 break;
213 }
214 }
215 draw_compute_vertex_size(&vinfo);
216 }
217
218 void
219 nv10_emit_hw_state(struct nv10_context *nv10)
220 {
221 struct nv10_screen *screen = nv10->screen;
222 struct nouveau_channel *chan = screen->base.channel;
223 struct nouveau_grobj *celsius = screen->celsius;
224 struct nouveau_bo *rt_bo;
225 int i;
226
227 if (nv10->dirty & NV10_NEW_VERTPROG) {
228 //nv10_vertprog_bind(nv10, nv10->vertprog.current);
229 nv10->dirty &= ~NV10_NEW_VERTPROG;
230 }
231
232 if (nv10->dirty & NV10_NEW_FRAGPROG) {
233 nv10_fragprog_bind(nv10, nv10->fragprog.current);
234 /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */
235 nv10->dirty_samplers |= (1<<10);
236 nv10->dirty_samplers = 0;
237 }
238
239 if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) {
240 nv10_fragtex_bind(nv10);
241 nv10->dirty &= ~NV10_NEW_FRAGPROG;
242 }
243
244 if (nv10->dirty & NV10_NEW_VTXARRAYS) {
245 nv10->dirty &= ~NV10_NEW_VTXARRAYS;
246 nv10_vertex_layout(nv10);
247 nv10_vtxbuf_bind(nv10);
248 }
249
250 if (nv10->dirty & NV10_NEW_BLEND) {
251 nv10->dirty &= ~NV10_NEW_BLEND;
252 nv10_state_emit_blend(nv10);
253 }
254
255 if (nv10->dirty & NV10_NEW_BLENDCOL) {
256 nv10->dirty &= ~NV10_NEW_BLENDCOL;
257 nv10_state_emit_blend_color(nv10);
258 }
259
260 if (nv10->dirty & NV10_NEW_RAST) {
261 nv10->dirty &= ~NV10_NEW_RAST;
262 nv10_state_emit_rast(nv10);
263 }
264
265 if (nv10->dirty & NV10_NEW_DSA) {
266 nv10->dirty &= ~NV10_NEW_DSA;
267 nv10_state_emit_dsa(nv10);
268 }
269
270 if (nv10->dirty & NV10_NEW_VIEWPORT) {
271 nv10->dirty &= ~NV10_NEW_VIEWPORT;
272 nv10_state_emit_viewport(nv10);
273 }
274
275 if (nv10->dirty & NV10_NEW_SCISSOR) {
276 nv10->dirty &= ~NV10_NEW_SCISSOR;
277 nv10_state_emit_scissor(nv10);
278 }
279
280 if (nv10->dirty & NV10_NEW_FRAMEBUFFER) {
281 nv10->dirty &= ~NV10_NEW_FRAMEBUFFER;
282 nv10_state_emit_framebuffer(nv10);
283 }
284
285 /* Emit relocs for every referenced buffer.
286 * This is to ensure the bufmgr has an accurate idea of how
287 * the buffer is used. This isn't very efficient, but we don't
288 * seem to take a significant performance hit. Will be improved
289 * at some point. Vertex arrays are emitted by nv10_vbo.c
290 */
291
292 /* Render target */
293 rt_bo = nouveau_bo(nv10->rt[0]);
294 // XXX figre out who's who for NV10TCL_DMA_* and fill accordingly
295 // BEGIN_RING(chan, celsius, NV10TCL_DMA_COLOR0, 1);
296 // OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
297 BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1);
298 OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
299
300 if (nv10->zeta) {
301 struct nouveau_bo *zeta_bo = nouveau_bo(nv10->zeta);
302 // XXX
303 // BEGIN_RING(chan, celsius, NV10TCL_DMA_ZETA, 1);
304 // OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
305 BEGIN_RING(chan, celsius, NV10TCL_ZETA_OFFSET, 1);
306 OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
307 /* XXX for when we allocate LMA on nv17 */
308 /* BEGIN_RING(chan, celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
309 OUT_RELOCl(chan, nouveau_bo(nv10->zeta + lma_offset));*/
310 }
311
312 /* Vertex buffer */
313 BEGIN_RING(chan, celsius, NV10TCL_DMA_VTXBUF0, 1);
314 OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
315 BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1);
316 OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
317
318 /* Texture images */
319 for (i = 0; i < 2; i++) {
320 if (!(nv10->fp_samplers & (1 << i)))
321 continue;
322 struct nouveau_bo *bo = nouveau_bo(nv10->tex[i].buffer);
323 BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(i), 1);
324 OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM |
325 NOUVEAU_BO_GART | NOUVEAU_BO_RD);
326 BEGIN_RING(chan, celsius, NV10TCL_TX_FORMAT(i), 1);
327 OUT_RELOCd(chan, bo, nv10->tex[i].format,
328 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
329 NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0,
330 NV10TCL_TX_FORMAT_DMA1);
331 }
332 }
333