r300g,radeong: finish and enable the immediate mode
[mesa.git] / src / gallium / drivers / nv04 / nv04_state_emit.c
1 #include "nv04_context.h"
2 #include "nv04_state.h"
3
4 static void nv04_vertex_layout(struct pipe_context* pipe)
5 {
6 struct nv04_context *nv04 = nv04_context(pipe);
7 struct nv04_fragment_program *fp = nv04->fragprog.current;
8 uint32_t src = 0;
9 int i;
10 struct vertex_info vinfo;
11
12 memset(&vinfo, 0, sizeof(vinfo));
13
14 for (i = 0; i < fp->info.num_inputs; i++) {
15 int isn = fp->info.input_semantic_name[i];
16 int isi = fp->info.input_semantic_index[i];
17 switch (isn) {
18 case TGSI_SEMANTIC_POSITION:
19 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
20 break;
21 case TGSI_SEMANTIC_COLOR:
22 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
23 break;
24 default:
25 case TGSI_SEMANTIC_GENERIC:
26 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
27 break;
28 case TGSI_SEMANTIC_FOG:
29 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
30 break;
31 }
32 }
33
34 printf("%d vertex input\n",fp->info.num_inputs);
35 draw_compute_vertex_size(&vinfo);
36 }
37
38 static uint32_t nv04_blend_func(uint32_t f)
39 {
40 switch ( f ) {
41 case PIPE_BLENDFACTOR_ZERO: return 0x1;
42 case PIPE_BLENDFACTOR_ONE: return 0x2;
43 case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3;
44 case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4;
45 case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5;
46 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6;
47 case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7;
48 case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8;
49 case PIPE_BLENDFACTOR_DST_COLOR: return 0x9;
50 case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA;
51 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB;
52 }
53 NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f);
54 return 0;
55 }
56
57 static void nv04_emit_control(struct nv04_context* nv04)
58 {
59 uint32_t control = nv04->dsa->control;
60 struct nv04_screen *screen = nv04->screen;
61 struct nouveau_channel *chan = screen->base.channel;
62 struct nouveau_grobj *fahrenheit = screen->fahrenheit;
63
64 BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
65 OUT_RING(chan, control);
66 }
67
68 static void nv04_emit_blend(struct nv04_context* nv04)
69 {
70 struct nv04_screen *screen = nv04->screen;
71 struct nouveau_channel *chan = screen->base.channel;
72 struct nouveau_grobj *fahrenheit = screen->fahrenheit;
73 uint32_t blend;
74
75 blend=0x4; // texture MODULATE_ALPHA
76 blend|=0x20; // alpha is MSB
77 blend|=(2<<6); // flat shading
78 blend|=(1<<8); // persp correct
79 blend|=(0<<16); // no fog
80 blend|=(nv04->blend->b_enable<<20);
81 blend|=(nv04_blend_func(nv04->blend->b_src)<<24);
82 blend|=(nv04_blend_func(nv04->blend->b_dst)<<28);
83
84 BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1);
85 OUT_RING(chan, blend);
86 }
87
88 static void nv04_emit_sampler(struct nv04_context *nv04, int unit)
89 {
90 struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
91 struct pipe_texture *pt = &nv04mt->base;
92 struct nv04_screen *screen = nv04->screen;
93 struct nouveau_channel *chan = screen->base.channel;
94 struct nouveau_grobj *fahrenheit = screen->fahrenheit;
95 struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer);
96
97 BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 3);
98 OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
99 OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
100 OUT_RING(chan, nv04->sampler[unit]->filter);
101 }
102
103 static void nv04_state_emit_framebuffer(struct nv04_context* nv04)
104 {
105 struct pipe_framebuffer_state* fb = nv04->framebuffer;
106 struct nv04_surface *rt, *zeta;
107 uint32_t rt_format, w, h;
108 int colour_format = 0, zeta_format = 0;
109 struct nv04_miptree *nv04mt = 0;
110 struct nv04_screen *screen = nv04->screen;
111 struct nouveau_channel *chan = screen->base.channel;
112 struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d;
113 struct nouveau_bo *bo;
114
115 w = fb->cbufs[0]->width;
116 h = fb->cbufs[0]->height;
117 colour_format = fb->cbufs[0]->format;
118 rt = (struct nv04_surface *)fb->cbufs[0];
119
120 if (fb->zsbuf) {
121 if (colour_format) {
122 assert(w == fb->zsbuf->width);
123 assert(h == fb->zsbuf->height);
124 } else {
125 w = fb->zsbuf->width;
126 h = fb->zsbuf->height;
127 }
128
129 zeta_format = fb->zsbuf->format;
130 zeta = (struct nv04_surface *)fb->zsbuf;
131 }
132
133 switch (colour_format) {
134 case PIPE_FORMAT_A8R8G8B8_UNORM:
135 case 0:
136 rt_format = 0x108;
137 break;
138 case PIPE_FORMAT_R5G6B5_UNORM:
139 rt_format = 0x103;
140 break;
141 default:
142 assert(0);
143 }
144
145 BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
146 OUT_RING(chan, rt_format);
147
148 nv04mt = (struct nv04_miptree *)rt->base.texture;
149 bo = nouveau_bo(nv04mt->buffer);
150 /* FIXME pitches have to be aligned ! */
151 BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
152 OUT_RING(chan, rt->pitch|(zeta->pitch<<16));
153 OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
154 if (fb->zsbuf) {
155 nv04mt = (struct nv04_miptree *)zeta->base.texture;
156 BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
157 OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
158 }
159 }
160
161 void
162 nv04_emit_hw_state(struct nv04_context *nv04)
163 {
164 struct nv04_screen *screen = nv04->screen;
165 struct nouveau_channel *chan = screen->base.channel;
166 struct nouveau_grobj *fahrenheit = screen->fahrenheit;
167 struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d;
168 int i;
169
170 if (nv04->dirty & NV04_NEW_VERTPROG) {
171 //nv04_vertprog_bind(nv04, nv04->vertprog.current);
172 nv04->dirty &= ~NV04_NEW_VERTPROG;
173 }
174
175 if (nv04->dirty & NV04_NEW_FRAGPROG) {
176 nv04_fragprog_bind(nv04, nv04->fragprog.current);
177 nv04->dirty &= ~NV04_NEW_FRAGPROG;
178 nv04->dirty_samplers |= (1<<10);
179 nv04->dirty_samplers = 0;
180 }
181
182 if (nv04->dirty & NV04_NEW_CONTROL) {
183 nv04->dirty &= ~NV04_NEW_CONTROL;
184
185 BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1);
186 OUT_RING(chan, nv04->dsa->control);
187 }
188
189 if (nv04->dirty & NV04_NEW_BLEND) {
190 nv04->dirty &= ~NV04_NEW_BLEND;
191
192 nv04_emit_blend(nv04);
193 }
194
195 if (nv04->dirty & NV04_NEW_VTXARRAYS) {
196 nv04->dirty &= ~NV04_NEW_VTXARRAYS;
197 nv04_vertex_layout(nv04);
198 }
199
200 if (nv04->dirty & NV04_NEW_SAMPLER) {
201 nv04->dirty &= ~NV04_NEW_SAMPLER;
202
203 nv04_emit_sampler(nv04, 0);
204 }
205
206 if (nv04->dirty & NV04_NEW_VIEWPORT) {
207 nv04->dirty &= ~NV04_NEW_VIEWPORT;
208 // nv04_state_emit_viewport(nv04);
209 }
210
211 if (nv04->dirty & NV04_NEW_FRAMEBUFFER) {
212 nv04->dirty &= ~NV04_NEW_FRAMEBUFFER;
213 nv04_state_emit_framebuffer(nv04);
214 }
215
216 /* Emit relocs for every referenced buffer.
217 * This is to ensure the bufmgr has an accurate idea of how
218 * the buffer is used. This isn't very efficient, but we don't
219 * seem to take a significant performance hit. Will be improved
220 * at some point. Vertex arrays are emitted by nv04_vbo.c
221 */
222
223 /* Render target */
224 unsigned rt_pitch = ((struct nv04_surface *)nv04->rt)->pitch;
225 unsigned zeta_pitch = ((struct nv04_surface *)nv04->zeta)->pitch;
226
227 BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
228 OUT_RING(chan, rt_pitch|(zeta_pitch<<16));
229 OUT_RELOCl(chan, nouveau_bo(nv04->rt), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
230 if (nv04->zeta) {
231 BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
232 OUT_RELOCl(chan, nouveau_bo(nv04->zeta), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
233 }
234
235 /* Texture images */
236 for (i = 0; i < 1; i++) {
237 if (!(nv04->fp_samplers & (1 << i)))
238 continue;
239 struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
240 struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer);
241 BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 2);
242 OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
243 OUT_RELOCd(chan, bo, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
244 }
245 }
246