Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / drivers / nv20 / nv20_state_emit.c
1 #include "nv20_context.h"
2 #include "nv20_state.h"
3 #include "draw/draw_context.h"
4
5 static void nv20_state_emit_blend(struct nv20_context* nv20)
6 {
7 struct nv20_blend_state *b = nv20->blend;
8 struct nv20_screen *screen = nv20->screen;
9 struct nouveau_channel *chan = screen->base.channel;
10 struct nouveau_grobj *kelvin = screen->kelvin;
11
12 BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1);
13 OUT_RING (chan, b->d_enable);
14
15 BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1);
16 OUT_RING (chan, b->b_enable);
17
18 BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 2);
19 OUT_RING (chan, b->b_srcfunc);
20 OUT_RING (chan, b->b_dstfunc);
21
22 BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MASK, 1);
23 OUT_RING (chan, b->c_mask);
24 }
25
26 static void nv20_state_emit_blend_color(struct nv20_context* nv20)
27 {
28 struct pipe_blend_color *c = nv20->blend_color;
29 struct nv20_screen *screen = nv20->screen;
30 struct nouveau_channel *chan = screen->base.channel;
31 struct nouveau_grobj *kelvin = screen->kelvin;
32
33 BEGIN_RING(chan, kelvin, NV20TCL_BLEND_COLOR, 1);
34 OUT_RING (chan,
35 (float_to_ubyte(c->color[3]) << 24)|
36 (float_to_ubyte(c->color[0]) << 16)|
37 (float_to_ubyte(c->color[1]) << 8) |
38 (float_to_ubyte(c->color[2]) << 0));
39 }
40
41 static void nv20_state_emit_rast(struct nv20_context* nv20)
42 {
43 struct nv20_rasterizer_state *r = nv20->rast;
44 struct nv20_screen *screen = nv20->screen;
45 struct nouveau_channel *chan = screen->base.channel;
46 struct nouveau_grobj *kelvin = screen->kelvin;
47
48 BEGIN_RING(chan, kelvin, NV20TCL_SHADE_MODEL, 2);
49 OUT_RING (chan, r->shade_model);
50 OUT_RING (chan, r->line_width);
51
52
53 BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1);
54 OUT_RING (chan, r->point_size);
55
56 BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_MODE_FRONT, 2);
57 OUT_RING (chan, r->poly_mode_front);
58 OUT_RING (chan, r->poly_mode_back);
59
60
61 BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE, 2);
62 OUT_RING (chan, r->cull_face);
63 OUT_RING (chan, r->front_face);
64
65 BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 2);
66 OUT_RING (chan, r->line_smooth_en);
67 OUT_RING (chan, r->poly_smooth_en);
68
69 BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE_ENABLE, 1);
70 OUT_RING (chan, r->cull_face_en);
71 }
72
73 static void nv20_state_emit_dsa(struct nv20_context* nv20)
74 {
75 struct nv20_depth_stencil_alpha_state *d = nv20->dsa;
76 struct nv20_screen *screen = nv20->screen;
77 struct nouveau_channel *chan = screen->base.channel;
78 struct nouveau_grobj *kelvin = screen->kelvin;
79
80 BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1);
81 OUT_RING (chan, d->depth.func);
82
83 BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1);
84 OUT_RING (chan, d->depth.write_enable);
85
86 BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1);
87 OUT_RING (chan, d->depth.test_enable);
88
89 BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1);
90 OUT_RING (chan, 1);
91
92 #if 0
93 BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_ENABLE, 1);
94 OUT_RING (chan, d->stencil.enable);
95 BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7);
96 OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7);
97 #endif
98
99 BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
100 OUT_RING (chan, d->alpha.enabled);
101
102 BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 1);
103 OUT_RING (chan, d->alpha.func);
104
105 BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_REF, 1);
106 OUT_RING (chan, d->alpha.ref);
107 }
108
109 static void nv20_state_emit_viewport(struct nv20_context* nv20)
110 {
111 }
112
113 static void nv20_state_emit_scissor(struct nv20_context* nv20)
114 {
115 /* NV20TCL_SCISSOR_* is probably a software method */
116 /* struct pipe_scissor_state *s = nv20->scissor;
117 struct nv20_screen *screen = nv20->screen;
118 struct nouveau_channel *chan = screen->base.channel;
119 struct nouveau_grobj *kelvin = screen->kelvin;
120
121 BEGIN_RING(chan, kelvin, NV20TCL_SCISSOR_HORIZ, 2);
122 OUT_RING (chan, ((s->maxx - s->minx) << 16) | s->minx);
123 OUT_RING (chan, ((s->maxy - s->miny) << 16) | s->miny);*/
124 }
125
126 static void nv20_state_emit_framebuffer(struct nv20_context* nv20)
127 {
128 struct pipe_framebuffer_state* fb = nv20->framebuffer;
129 struct nv04_surface *rt, *zeta = NULL;
130 uint32_t rt_format, w, h;
131 int colour_format = 0, zeta_format = 0;
132 struct nv20_miptree *nv20mt = 0;
133 struct nv20_screen *screen = nv20->screen;
134 struct nouveau_channel *chan = screen->base.channel;
135 struct nouveau_grobj *kelvin = screen->kelvin;
136
137 w = fb->cbufs[0]->width;
138 h = fb->cbufs[0]->height;
139 colour_format = fb->cbufs[0]->format;
140 rt = (struct nv04_surface *)fb->cbufs[0];
141
142 if (fb->zsbuf) {
143 if (colour_format) {
144 assert(w == fb->zsbuf->width);
145 assert(h == fb->zsbuf->height);
146 } else {
147 w = fb->zsbuf->width;
148 h = fb->zsbuf->height;
149 }
150
151 zeta_format = fb->zsbuf->format;
152 zeta = (struct nv04_surface *)fb->zsbuf;
153 }
154
155 rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR | 0x20;
156
157 switch (colour_format) {
158 case PIPE_FORMAT_X8R8G8B8_UNORM:
159 rt_format |= NV20TCL_RT_FORMAT_COLOR_X8R8G8B8;
160 break;
161 case PIPE_FORMAT_A8R8G8B8_UNORM:
162 case 0:
163 rt_format |= NV20TCL_RT_FORMAT_COLOR_A8R8G8B8;
164 break;
165 case PIPE_FORMAT_R5G6B5_UNORM:
166 rt_format |= NV20TCL_RT_FORMAT_COLOR_R5G6B5;
167 break;
168 default:
169 assert(0);
170 }
171
172 if (zeta) {
173 BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1);
174 OUT_RING (chan, rt->pitch | (zeta->pitch << 16));
175 } else {
176 BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1);
177 OUT_RING (chan, rt->pitch | (rt->pitch << 16));
178 }
179
180 nv20mt = (struct nv20_miptree *)rt->base.texture;
181 nv20->rt[0] = nv20mt->buffer;
182
183 if (zeta_format)
184 {
185 nv20mt = (struct nv20_miptree *)zeta->base.texture;
186 nv20->zeta = nv20mt->buffer;
187 }
188
189 BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 3);
190 OUT_RING (chan, (w << 16) | 0);
191 OUT_RING (chan, (h << 16) | 0); /*NV20TCL_RT_VERT */
192 OUT_RING (chan, rt_format); /* NV20TCL_RT_FORMAT */
193 BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2);
194 OUT_RING (chan, ((w - 1) << 16) | 0);
195 OUT_RING (chan, ((h - 1) << 16) | 0);
196 }
197
198 static void nv20_vertex_layout(struct nv20_context *nv20)
199 {
200 struct nv20_fragment_program *fp = nv20->fragprog.current;
201 struct draw_context *dc = nv20->draw;
202 int src;
203 int i;
204 struct vertex_info *vinfo = &nv20->vertex_info;
205 const enum interp_mode colorInterp = INTERP_LINEAR;
206 boolean colors[2] = { FALSE };
207 boolean generics[12] = { FALSE };
208 boolean fog = FALSE;
209
210 memset(vinfo, 0, sizeof(*vinfo));
211
212 /*
213 * Assumed NV20 hardware vertex attribute order:
214 * 0 position, 1 ?, 2 ?, 3 col0,
215 * 4 col1?, 5 ?, 6 ?, 7 ?,
216 * 8 ?, 9 tex0, 10 tex1, 11 tex2,
217 * 12 tex3, 13 ?, 14 ?, 15 ?
218 * unaccounted: wgh, nor, fog
219 * There are total 16 attrs.
220 * vinfo->hwfmt[0] has a used-bit corresponding to each of these.
221 * relation to TGSI_SEMANTIC_*:
222 * - POSITION: position (always used)
223 * - COLOR: col1, col0
224 * - GENERIC: tex3, tex2, tex1, tex0, normal, weight
225 * - FOG: fog
226 */
227
228 for (i = 0; i < fp->info.num_inputs; i++) {
229 int isn = fp->info.input_semantic_name[i];
230 int isi = fp->info.input_semantic_index[i];
231 switch (isn) {
232 case TGSI_SEMANTIC_POSITION:
233 break;
234 case TGSI_SEMANTIC_COLOR:
235 assert(isi < 2);
236 colors[isi] = TRUE;
237 break;
238 case TGSI_SEMANTIC_GENERIC:
239 assert(isi < 12);
240 generics[isi] = TRUE;
241 break;
242 case TGSI_SEMANTIC_FOG:
243 fog = TRUE;
244 break;
245 default:
246 assert(0 && "unknown input_semantic_name");
247 }
248 }
249
250 /* always do position */ {
251 src = draw_find_shader_output(dc, TGSI_SEMANTIC_POSITION, 0);
252 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
253 vinfo->hwfmt[0] |= (1 << 0);
254 }
255
256 /* two unnamed generics */
257 for (i = 4; i < 6; i++) {
258 if (!generics[i])
259 continue;
260 src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
261 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
262 vinfo->hwfmt[0] |= (1 << (i - 3));
263 }
264
265 if (colors[0]) {
266 src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 0);
267 draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
268 vinfo->hwfmt[0] |= (1 << 3);
269 }
270
271 if (colors[1]) {
272 src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 1);
273 draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
274 vinfo->hwfmt[0] |= (1 << 4);
275 }
276
277 /* four unnamed generics */
278 for (i = 6; i < 10; i++) {
279 if (!generics[i])
280 continue;
281 src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
282 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
283 vinfo->hwfmt[0] |= (1 << (i - 1));
284 }
285
286 /* tex0, tex1, tex2, tex3 */
287 for (i = 0; i < 4; i++) {
288 if (!generics[i])
289 continue;
290 src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
291 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
292 vinfo->hwfmt[0] |= (1 << (i + 9));
293 }
294
295 /* two unnamed generics */
296 for (i = 10; i < 12; i++) {
297 if (!generics[i])
298 continue;
299 src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
300 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
301 vinfo->hwfmt[0] |= (1 << (i + 3));
302 }
303
304 if (fog) {
305 src = draw_find_shader_output(dc, TGSI_SEMANTIC_FOG, 0);
306 draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
307 vinfo->hwfmt[0] |= (1 << 15);
308 }
309
310 draw_compute_vertex_size(vinfo);
311 }
312
313 void
314 nv20_emit_hw_state(struct nv20_context *nv20)
315 {
316 struct nv20_screen *screen = nv20->screen;
317 struct nouveau_channel *chan = screen->base.channel;
318 struct nouveau_grobj *kelvin = screen->kelvin;
319 struct nouveau_bo *rt_bo;
320 int i;
321
322 if (nv20->dirty & NV20_NEW_VERTPROG) {
323 //nv20_vertprog_bind(nv20, nv20->vertprog.current);
324 nv20->dirty &= ~NV20_NEW_VERTPROG;
325 }
326
327 if (nv20->dirty & NV20_NEW_FRAGPROG) {
328 nv20_fragprog_bind(nv20, nv20->fragprog.current);
329 /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */
330 nv20->dirty_samplers |= (1<<10);
331 nv20->dirty_samplers = 0;
332 }
333
334 if (nv20->dirty_samplers || (nv20->dirty & NV20_NEW_FRAGPROG)) {
335 nv20_fragtex_bind(nv20);
336 nv20->dirty &= ~NV20_NEW_FRAGPROG;
337 }
338
339 if (nv20->dirty & NV20_NEW_VTXARRAYS) {
340 nv20->dirty &= ~NV20_NEW_VTXARRAYS;
341 nv20_vertex_layout(nv20);
342 nv20_vtxbuf_bind(nv20);
343 }
344
345 if (nv20->dirty & NV20_NEW_BLEND) {
346 nv20->dirty &= ~NV20_NEW_BLEND;
347 nv20_state_emit_blend(nv20);
348 }
349
350 if (nv20->dirty & NV20_NEW_BLENDCOL) {
351 nv20->dirty &= ~NV20_NEW_BLENDCOL;
352 nv20_state_emit_blend_color(nv20);
353 }
354
355 if (nv20->dirty & NV20_NEW_RAST) {
356 nv20->dirty &= ~NV20_NEW_RAST;
357 nv20_state_emit_rast(nv20);
358 }
359
360 if (nv20->dirty & NV20_NEW_DSA) {
361 nv20->dirty &= ~NV20_NEW_DSA;
362 nv20_state_emit_dsa(nv20);
363 }
364
365 if (nv20->dirty & NV20_NEW_VIEWPORT) {
366 nv20->dirty &= ~NV20_NEW_VIEWPORT;
367 nv20_state_emit_viewport(nv20);
368 }
369
370 if (nv20->dirty & NV20_NEW_SCISSOR) {
371 nv20->dirty &= ~NV20_NEW_SCISSOR;
372 nv20_state_emit_scissor(nv20);
373 }
374
375 if (nv20->dirty & NV20_NEW_FRAMEBUFFER) {
376 nv20->dirty &= ~NV20_NEW_FRAMEBUFFER;
377 nv20_state_emit_framebuffer(nv20);
378 }
379
380 /* Emit relocs for every referenced buffer.
381 * This is to ensure the bufmgr has an accurate idea of how
382 * the buffer is used. This isn't very efficient, but we don't
383 * seem to take a significant performance hit. Will be improved
384 * at some point. Vertex arrays are emitted by nv20_vbo.c
385 */
386
387 /* Render target */
388 rt_bo = nouveau_bo(nv20->rt[0]);
389 BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 1);
390 OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
391 BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1);
392 OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
393
394 if (nv20->zeta) {
395 struct nouveau_bo *zeta_bo = nouveau_bo(nv20->zeta);
396 BEGIN_RING(chan, kelvin, NV20TCL_DMA_ZETA, 1);
397 OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
398 BEGIN_RING(chan, kelvin, NV20TCL_ZETA_OFFSET, 1);
399 OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
400 /* XXX for when we allocate LMA on nv17 */
401 /* BEGIN_RING(chan, kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
402 OUT_RELOCl(chan, nouveau_bo(nv20->zeta + lma_offset));*/
403 }
404
405 /* Vertex buffer */
406 BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 1);
407 OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
408 BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1);
409 OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
410
411 /* Texture images */
412 for (i = 0; i < 2; i++) {
413 if (!(nv20->fp_samplers & (1 << i)))
414 continue;
415 struct nouveau_bo *bo = nouveau_bo(nv20->tex[i].buffer);
416 BEGIN_RING(chan, kelvin, NV20TCL_TX_OFFSET(i), 1);
417 OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM |
418 NOUVEAU_BO_GART | NOUVEAU_BO_RD);
419 BEGIN_RING(chan, kelvin, NV20TCL_TX_FORMAT(i), 1);
420 OUT_RELOCd(chan, bo, nv20->tex[i].format,
421 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
422 NOUVEAU_BO_OR, NV20TCL_TX_FORMAT_DMA0,
423 NV20TCL_TX_FORMAT_DMA1);
424 }
425 }
426