Merge branch 'gallium-wgl-rework' into gallium-0.2
[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
61 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
62 OUT_RING(control);
63 }
64
65 static void nv04_emit_blend(struct nv04_context* nv04)
66 {
67 uint32_t blend;
68
69 blend=0x4; // texture MODULATE_ALPHA
70 blend|=0x20; // alpha is MSB
71 blend|=(2<<6); // flat shading
72 blend|=(1<<8); // persp correct
73 blend|=(0<<16); // no fog
74 blend|=(nv04->blend->b_enable<<20);
75 blend|=(nv04_blend_func(nv04->blend->b_src)<<24);
76 blend|=(nv04_blend_func(nv04->blend->b_dst)<<28);
77
78 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
79 OUT_RING(blend);
80 }
81
82 static void nv04_emit_sampler(struct nv04_context *nv04, int unit)
83 {
84 struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
85 struct pipe_texture *pt = &nv04mt->base;
86
87 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 3);
88 OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
89 OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
90 OUT_RING(nv04->sampler[unit]->filter);
91 }
92
93 static void nv04_state_emit_framebuffer(struct nv04_context* nv04)
94 {
95 struct pipe_framebuffer_state* fb = nv04->framebuffer;
96 struct pipe_surface *rt, *zeta;
97 uint32_t rt_format, w, h;
98 int colour_format = 0, zeta_format = 0;
99
100 w = fb->cbufs[0]->width;
101 h = fb->cbufs[0]->height;
102 colour_format = fb->cbufs[0]->format;
103 rt = fb->cbufs[0];
104
105 if (fb->zsbuf) {
106 if (colour_format) {
107 assert(w == fb->zsbuf->width);
108 assert(h == fb->zsbuf->height);
109 } else {
110 w = fb->zsbuf->width;
111 h = fb->zsbuf->height;
112 }
113
114 zeta_format = fb->zsbuf->format;
115 zeta = fb->zsbuf;
116 }
117
118 switch (colour_format) {
119 case PIPE_FORMAT_A8R8G8B8_UNORM:
120 case 0:
121 rt_format = 0x108;
122 break;
123 case PIPE_FORMAT_R5G6B5_UNORM:
124 rt_format = 0x103;
125 break;
126 default:
127 assert(0);
128 }
129
130 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
131 OUT_RING(rt_format);
132
133 /* FIXME pitches have to be aligned ! */
134 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
135 OUT_RING(rt->stride|(zeta->stride<<16));
136 OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
137 if (fb->zsbuf) {
138 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
139 OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
140 }
141 }
142
143 void
144 nv04_emit_hw_state(struct nv04_context *nv04)
145 {
146 int i;
147
148 if (nv04->dirty & NV04_NEW_VERTPROG) {
149 //nv04_vertprog_bind(nv04, nv04->vertprog.current);
150 nv04->dirty &= ~NV04_NEW_VERTPROG;
151 }
152
153 if (nv04->dirty & NV04_NEW_FRAGPROG) {
154 nv04_fragprog_bind(nv04, nv04->fragprog.current);
155 nv04->dirty &= ~NV04_NEW_FRAGPROG;
156 nv04->dirty_samplers |= (1<<10);
157 nv04->dirty_samplers = 0;
158 }
159
160 if (nv04->dirty & NV04_NEW_CONTROL) {
161 nv04->dirty &= ~NV04_NEW_CONTROL;
162
163 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
164 OUT_RING(nv04->dsa->control);
165 }
166
167 if (nv04->dirty & NV04_NEW_BLEND) {
168 nv04->dirty &= ~NV04_NEW_BLEND;
169
170 nv04_emit_blend(nv04);
171 }
172
173 if (nv04->dirty & NV04_NEW_VTXARRAYS) {
174 nv04->dirty &= ~NV04_NEW_VTXARRAYS;
175 nv04_vertex_layout(nv04);
176 }
177
178 if (nv04->dirty & NV04_NEW_SAMPLER) {
179 nv04->dirty &= ~NV04_NEW_SAMPLER;
180
181 nv04_emit_sampler(nv04, 0);
182 }
183
184 if (nv04->dirty & NV04_NEW_VIEWPORT) {
185 nv04->dirty &= ~NV04_NEW_VIEWPORT;
186 // nv04_state_emit_viewport(nv04);
187 }
188
189 if (nv04->dirty & NV04_NEW_FRAMEBUFFER) {
190 nv04->dirty &= ~NV04_NEW_FRAMEBUFFER;
191 nv04_state_emit_framebuffer(nv04);
192 }
193
194 /* Emit relocs for every referenced buffer.
195 * This is to ensure the bufmgr has an accurate idea of how
196 * the buffer is used. This isn't very efficient, but we don't
197 * seem to take a significant performance hit. Will be improved
198 * at some point. Vertex arrays are emitted by nv04_vbo.c
199 */
200
201 /* Render target */
202 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
203 OUT_RING(nv04->rt->stride|(nv04->zeta->stride<<16));
204 OUT_RELOCl(nv04->rt, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
205 if (nv04->zeta) {
206 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
207 OUT_RELOCl(nv04->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
208 }
209
210 /* Texture images */
211 for (i = 0; i < 1; i++) {
212 if (!(nv04->fp_samplers & (1 << i)))
213 continue;
214 struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
215 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2);
216 OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
217 OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
218 }
219 }
220