nv20: adjust initial hw context
[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 #if 0
77 BEGIN_RING(kelvin, NV20TCL_STENCIL_ENABLE, 1);
78 OUT_RING (d->stencil.enable);
79 BEGIN_RING(kelvin, NV20TCL_STENCIL_MASK, 7);
80 OUT_RINGp ((uint32_t *)&(d->stencil.wmask), 7);
81 #endif
82
83 BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
84 OUT_RING (d->alpha.enabled);
85
86 BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_FUNC, 1);
87 OUT_RING (d->alpha.func);
88
89 BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_REF, 1);
90 OUT_RING (d->alpha.ref);
91 }
92
93 static void nv20_state_emit_viewport(struct nv20_context* nv20)
94 {
95 }
96
97 static void nv20_state_emit_scissor(struct nv20_context* nv20)
98 {
99 /* NV20TCL_SCISSOR_* is probably a software method */
100 /* struct pipe_scissor_state *s = nv20->scissor;
101 BEGIN_RING(kelvin, NV20TCL_SCISSOR_HORIZ, 2);
102 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
103 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
104 }
105
106 static void nv20_state_emit_framebuffer(struct nv20_context* nv20)
107 {
108 struct pipe_framebuffer_state* fb = nv20->framebuffer;
109 struct pipe_surface *rt, *zeta = NULL;
110 uint32_t rt_format, w, h;
111 int colour_format = 0, zeta_format = 0;
112
113 w = fb->cbufs[0]->width;
114 h = fb->cbufs[0]->height;
115 colour_format = fb->cbufs[0]->format;
116 rt = fb->cbufs[0];
117
118 if (fb->zsbuf) {
119 if (colour_format) {
120 assert(w == fb->zsbuf->width);
121 assert(h == fb->zsbuf->height);
122 } else {
123 w = fb->zsbuf->width;
124 h = fb->zsbuf->height;
125 }
126
127 zeta_format = fb->zsbuf->format;
128 zeta = fb->zsbuf;
129 }
130
131 rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR | 0x20;
132
133 switch (colour_format) {
134 case PIPE_FORMAT_A8R8G8B8_UNORM:
135 case 0:
136 rt_format |= NV20TCL_RT_FORMAT_COLOR_A8R8G8B8;
137 break;
138 case PIPE_FORMAT_R5G6B5_UNORM:
139 rt_format |= NV20TCL_RT_FORMAT_COLOR_R5G6B5;
140 break;
141 default:
142 assert(0);
143 }
144
145 if (zeta) {
146 BEGIN_RING(kelvin, NV20TCL_RT_PITCH, 1);
147 OUT_RING (rt->stride | (zeta->stride << 16));
148 } else {
149 BEGIN_RING(kelvin, NV20TCL_RT_PITCH, 1);
150 OUT_RING (rt->stride | (rt->stride << 16));
151 }
152
153 nv20->rt[0] = rt->buffer;
154
155 if (zeta_format)
156 {
157 nv20->zeta = zeta->buffer;
158 }
159
160 BEGIN_RING(kelvin, NV20TCL_RT_HORIZ, 3);
161 OUT_RING ((w << 16) | 0);
162 OUT_RING ((h << 16) | 0);
163 OUT_RING (rt_format);
164 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2);
165 OUT_RING (((w - 1) << 16) | 0);
166 OUT_RING (((h - 1) << 16) | 0);
167 }
168
169 static void nv20_vertex_layout(struct nv20_context *nv20)
170 {
171 struct nv20_fragment_program *fp = nv20->fragprog.current;
172 struct draw_context *dc = nv20->draw;
173 uint32_t src;
174 int i;
175 struct vertex_info *vinfo = &nv20->vertex_info;
176 const enum interp_mode colorInterp = INTERP_LINEAR;
177 boolean colors[2] = { FALSE };
178 boolean generics[4] = { FALSE };
179 boolean fog = FALSE;
180
181 memset(vinfo, 0, sizeof(*vinfo));
182
183 /*
184 * NV10 hardware vertex attribute order:
185 * fog, weight, normal, tex1, tex0, 2nd color, color, position
186 * vinfo->hwfmt[0] has a used-bit corresponding to each of these.
187 * relation to TGSI_SEMANTIC_*:
188 * - POSITION: position (always used)
189 * - COLOR: 2nd color, color
190 * - GENERIC: weight, normal, tex1, tex0
191 * - FOG: fog
192 */
193
194 for (i = 0; i < fp->info.num_inputs; i++) {
195 int isn = fp->info.input_semantic_name[i];
196 int isi = fp->info.input_semantic_index[i];
197 switch (isn) {
198 case TGSI_SEMANTIC_POSITION:
199 break;
200 case TGSI_SEMANTIC_COLOR:
201 assert(isi < 2);
202 colors[isi] = TRUE;
203 break;
204 case TGSI_SEMANTIC_GENERIC:
205 assert(isi < 4);
206 generics[isi] = TRUE;
207 break;
208 case TGSI_SEMANTIC_FOG:
209 fog = TRUE;
210 break;
211 default:
212 assert(0 && "unknown input_semantic_name");
213 }
214 }
215
216 if (fog) {
217 int src = draw_find_vs_output(dc, TGSI_SEMANTIC_FOG, 0);
218 draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
219 vinfo->hwfmt[0] |= (1 << 7);
220 }
221
222 for (i = 3; i >= 0; i--) {
223 int src;
224 if (!generics[i])
225 continue;
226 src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
227 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
228 vinfo->hwfmt[0] |= (1 << (i + 3));
229 }
230
231 if (colors[1]) {
232 int src = draw_find_vs_output(dc, TGSI_SEMANTIC_COLOR, 1);
233 draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
234 vinfo->hwfmt[0] |= (1 << 2);
235 }
236
237 if (colors[0]) {
238 int src = draw_find_vs_output(dc, TGSI_SEMANTIC_COLOR, 0);
239 draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
240 vinfo->hwfmt[0] |= (1 << 1);
241 }
242
243 /* always do position */
244 src = draw_find_vs_output(dc, TGSI_SEMANTIC_POSITION, 0);
245 draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
246 vinfo->hwfmt[0] |= (1 << 0);
247
248 draw_compute_vertex_size(vinfo);
249 }
250
251 void
252 nv20_emit_hw_state(struct nv20_context *nv20)
253 {
254 int i;
255
256 if (nv20->dirty & NV20_NEW_VERTPROG) {
257 //nv20_vertprog_bind(nv20, nv20->vertprog.current);
258 nv20->dirty &= ~NV20_NEW_VERTPROG;
259 }
260
261 if (nv20->dirty & NV20_NEW_FRAGPROG) {
262 nv20_fragprog_bind(nv20, nv20->fragprog.current);
263 /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */
264 nv20->dirty_samplers |= (1<<10);
265 nv20->dirty_samplers = 0;
266 }
267
268 if (nv20->dirty_samplers || (nv20->dirty & NV20_NEW_FRAGPROG)) {
269 nv20_fragtex_bind(nv20);
270 nv20->dirty &= ~NV20_NEW_FRAGPROG;
271 }
272
273 if (nv20->dirty & NV20_NEW_VTXARRAYS) {
274 nv20->dirty &= ~NV20_NEW_VTXARRAYS;
275 nv20_vertex_layout(nv20);
276 nv20_vtxbuf_bind(nv20);
277 }
278
279 if (nv20->dirty & NV20_NEW_BLEND) {
280 nv20->dirty &= ~NV20_NEW_BLEND;
281 nv20_state_emit_blend(nv20);
282 }
283
284 if (nv20->dirty & NV20_NEW_BLENDCOL) {
285 nv20->dirty &= ~NV20_NEW_BLENDCOL;
286 nv20_state_emit_blend_color(nv20);
287 }
288
289 if (nv20->dirty & NV20_NEW_RAST) {
290 nv20->dirty &= ~NV20_NEW_RAST;
291 nv20_state_emit_rast(nv20);
292 }
293
294 if (nv20->dirty & NV20_NEW_DSA) {
295 nv20->dirty &= ~NV20_NEW_DSA;
296 nv20_state_emit_dsa(nv20);
297 }
298
299 if (nv20->dirty & NV20_NEW_VIEWPORT) {
300 nv20->dirty &= ~NV20_NEW_VIEWPORT;
301 nv20_state_emit_viewport(nv20);
302 }
303
304 if (nv20->dirty & NV20_NEW_SCISSOR) {
305 nv20->dirty &= ~NV20_NEW_SCISSOR;
306 nv20_state_emit_scissor(nv20);
307 }
308
309 if (nv20->dirty & NV20_NEW_FRAMEBUFFER) {
310 nv20->dirty &= ~NV20_NEW_FRAMEBUFFER;
311 nv20_state_emit_framebuffer(nv20);
312 }
313
314 /* Emit relocs for every referenced buffer.
315 * This is to ensure the bufmgr has an accurate idea of how
316 * the buffer is used. This isn't very efficient, but we don't
317 * seem to take a significant performance hit. Will be improved
318 * at some point. Vertex arrays are emitted by nv20_vbo.c
319 */
320
321 /* Render target */
322 /* XXX figre out who's who for NV10TCL_DMA_* and fill accordingly
323 * BEGIN_RING(kelvin, NV20TCL_DMA_COLOR0, 1);
324 * OUT_RELOCo(nv20->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); */
325 BEGIN_RING(kelvin, NV20TCL_COLOR_OFFSET, 1);
326 OUT_RELOCl(nv20->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
327
328 if (nv20->zeta) {
329 /* XXX
330 * BEGIN_RING(kelvin, NV20TCL_DMA_ZETA, 1);
331 * OUT_RELOCo(nv20->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); */
332 BEGIN_RING(kelvin, NV20TCL_ZETA_OFFSET, 1);
333 OUT_RELOCl(nv20->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
334 /* XXX for when we allocate LMA on nv17 */
335 /* BEGIN_RING(kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
336 OUT_RELOCl(nv20->zeta + lma_offset);*/
337 }
338
339 /* Vertex buffer */
340 BEGIN_RING(kelvin, NV20TCL_DMA_VTXBUF0, 1);
341 OUT_RELOCo(nv20->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
342 BEGIN_RING(kelvin, NV20TCL_COLOR_OFFSET, 1);
343 OUT_RELOCl(nv20->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
344
345 /* Texture images */
346 for (i = 0; i < 2; i++) {
347 if (!(nv20->fp_samplers & (1 << i)))
348 continue;
349 BEGIN_RING(kelvin, NV20TCL_TX_OFFSET(i), 1);
350 OUT_RELOCl(nv20->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
351 NOUVEAU_BO_GART | NOUVEAU_BO_RD);
352 BEGIN_RING(kelvin, NV20TCL_TX_FORMAT(i), 1);
353 OUT_RELOCd(nv20->tex[i].buffer, nv20->tex[i].format,
354 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
355 NOUVEAU_BO_OR, NV20TCL_TX_FORMAT_DMA0,
356 NV20TCL_TX_FORMAT_DMA1);
357 }
358 }
359