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