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