nv10: fix stuff and things.
[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, 3);
67 OUT_RINGp ((uint32_t *)&d->depth, 3);
68 BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1);
69 OUT_RING (d->stencil.enable);
70 BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7);
71 OUT_RINGp ((uint32_t *)&(d->stencil.wmask), 7);
72 BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3);
73 OUT_RINGp ((uint32_t *)&d->alpha.enabled, 3);
74 }
75
76 static void nv10_state_emit_viewport(struct nv10_context* nv10)
77 {
78 struct pipe_viewport_state *vpt = nv10->viewport;
79
80 /* OUT_RINGf (vpt->translate[0]);
81 OUT_RINGf (vpt->translate[1]);
82 OUT_RINGf (vpt->translate[2]);
83 OUT_RINGf (vpt->translate[3]);*/
84 BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4);
85 OUT_RINGf (vpt->scale[0]);
86 OUT_RINGf (vpt->scale[1]);
87 OUT_RINGf (vpt->scale[2]);
88 OUT_RINGf (vpt->scale[3]);
89 }
90
91 static void nv10_state_emit_scissor(struct nv10_context* nv10)
92 {
93 // XXX this is so not working
94 /* struct pipe_scissor_state *s = nv10->scissor;
95 BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2);
96 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
97 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
98 }
99
100 static void nv10_state_emit_framebuffer(struct nv10_context* nv10)
101 {
102 struct pipe_framebuffer_state* fb = nv10->framebuffer;
103 struct pipe_surface *rt, *zeta;
104 uint32_t rt_format, w, h;
105 int colour_format = 0, zeta_format = 0;
106
107 w = fb->cbufs[0]->width;
108 h = fb->cbufs[0]->height;
109 colour_format = fb->cbufs[0]->format;
110 rt = fb->cbufs[0];
111
112 if (fb->zsbuf) {
113 if (colour_format) {
114 assert(w == fb->zsbuf->width);
115 assert(h == fb->zsbuf->height);
116 } else {
117 w = fb->zsbuf->width;
118 h = fb->zsbuf->height;
119 }
120
121 zeta_format = fb->zsbuf->format;
122 zeta = fb->zsbuf;
123 }
124
125 rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR;
126
127 switch (colour_format) {
128 case PIPE_FORMAT_A8R8G8B8_UNORM:
129 case 0:
130 rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8;
131 break;
132 case PIPE_FORMAT_R5G6B5_UNORM:
133 rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5;
134 break;
135 default:
136 assert(0);
137 }
138
139 BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1);
140 OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) );
141 nv10->rt[0] = rt->buffer;
142
143 if (zeta_format)
144 {
145 nv10->zeta = zeta->buffer;
146 }
147
148 BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3);
149 OUT_RING ((w << 16) | 0);
150 OUT_RING ((h << 16) | 0);
151 OUT_RING (rt_format);
152 BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2);
153 OUT_RING (((w - 1) << 16) | 0);
154 OUT_RING (((h - 1) << 16) | 0);
155 }
156
157 void
158 nv10_emit_hw_state(struct nv10_context *nv10)
159 {
160 int i;
161
162 if (nv10->dirty & NV10_NEW_VERTPROG) {
163 //nv10_vertprog_bind(nv10, nv10->vertprog.current);
164 nv10->dirty &= ~NV10_NEW_VERTPROG;
165 }
166
167 if (nv10->dirty & NV10_NEW_FRAGPROG) {
168 nv10_fragprog_bind(nv10, nv10->fragprog.current);
169 /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */
170 nv10->dirty_samplers |= (1<<10);
171 nv10->dirty_samplers = 0;
172 }
173
174 if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) {
175 nv10_fragtex_bind(nv10);
176 nv10->dirty &= ~NV10_NEW_FRAGPROG;
177 }
178
179 if (nv10->dirty & NV10_NEW_ARRAYS) {
180 nv10->dirty &= ~NV10_NEW_ARRAYS;
181 // array state will be put here once it's not emitted at each frame
182 }
183
184 if (nv10->dirty & NV10_NEW_VTXFMT) {
185 nv10->dirty &= ~NV10_NEW_VTXFMT;
186 nv10_vtxbuf_bind(nv10);
187 }
188
189 if (nv10->dirty & NV10_NEW_BLEND) {
190 nv10->dirty &= ~NV10_NEW_BLEND;
191 nv10_state_emit_blend(nv10);
192 }
193
194 if (nv10->dirty & NV10_NEW_BLENDCOL) {
195 nv10->dirty &= ~NV10_NEW_BLENDCOL;
196 nv10_state_emit_blend_color(nv10);
197 }
198
199 if (nv10->dirty & NV10_NEW_RAST) {
200 nv10->dirty &= ~NV10_NEW_RAST;
201 nv10_state_emit_rast(nv10);
202 }
203
204 if (nv10->dirty & NV10_NEW_DSA) {
205 nv10->dirty &= ~NV10_NEW_DSA;
206 nv10_state_emit_dsa(nv10);
207 }
208
209 if (nv10->dirty & NV10_NEW_VIEWPORT) {
210 nv10->dirty &= ~NV10_NEW_VIEWPORT;
211 nv10_state_emit_viewport(nv10);
212 }
213
214 if (nv10->dirty & NV10_NEW_SCISSOR) {
215 nv10->dirty &= ~NV10_NEW_SCISSOR;
216 nv10_state_emit_scissor(nv10);
217 }
218
219 if (nv10->dirty & NV10_NEW_FRAMEBUFFER) {
220 nv10->dirty &= ~NV10_NEW_FRAMEBUFFER;
221 nv10_state_emit_framebuffer(nv10);
222 }
223
224 /* Emit relocs for every referenced buffer.
225 * This is to ensure the bufmgr has an accurate idea of how
226 * the buffer is used. This isn't very efficient, but we don't
227 * seem to take a significant performance hit. Will be improved
228 * at some point. Vertex arrays are emitted by nv10_vbo.c
229 */
230
231 /* Render target */
232 // XXX figre out who's who for NV10TCL_DMA_* and fill accordingly
233 // BEGIN_RING(celsius, NV10TCL_DMA_COLOR0, 1);
234 // OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
235 BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1);
236 OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
237
238 if (nv10->zeta) {
239 // XXX
240 // BEGIN_RING(celsius, NV10TCL_DMA_ZETA, 1);
241 // OUT_RELOCo(nv10->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
242 BEGIN_RING(celsius, NV10TCL_ZETA_OFFSET, 1);
243 OUT_RELOCl(nv10->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
244 /* XXX for when we allocate LMA on nv17 */
245 /* BEGIN_RING(celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1);
246 OUT_RELOCl(nv10->zeta + lma_offset);*/
247 }
248
249 /* Vertex buffer */
250 BEGIN_RING(celsius, NV10TCL_DMA_VTXBUF0, 1);
251 OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
252 BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1);
253 OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
254
255 /* Texture images */
256 for (i = 0; i < 2; i++) {
257 if (!(nv10->fp_samplers & (1 << i)))
258 continue;
259 BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 1);
260 OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
261 NOUVEAU_BO_GART | NOUVEAU_BO_RD);
262 BEGIN_RING(celsius, NV10TCL_TX_FORMAT(i), 1);
263 OUT_RELOCd(nv10->tex[i].buffer, nv10->tex[i].format,
264 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
265 NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0,
266 NV10TCL_TX_FORMAT_DMA1);
267 }
268 }
269