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