Merge branch 'gallium-0.2' of git+ssh://marcheu@git.freedesktop.org/git/nouveau/mesa...
[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 switch (i) {
16 case TGSI_SEMANTIC_POSITION:
17 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
18 break;
19 case TGSI_SEMANTIC_COLOR:
20 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
21 break;
22 default:
23 case TGSI_SEMANTIC_GENERIC:
24 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
25 break;
26 case TGSI_SEMANTIC_FOG:
27 draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
28 break;
29 }
30 }
31 draw_compute_vertex_size(&vinfo);
32 }
33
34 static uint32_t nv04_blend_func(uint32_t f)
35 {
36 switch ( f ) {
37 case PIPE_BLENDFACTOR_ZERO: return 0x1;
38 case PIPE_BLENDFACTOR_ONE: return 0x2;
39 case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3;
40 case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4;
41 case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5;
42 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6;
43 case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7;
44 case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8;
45 case PIPE_BLENDFACTOR_DST_COLOR: return 0x9;
46 case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA;
47 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB;
48 }
49 NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f);
50 return 0;
51 }
52
53 static void nv04_emit_control(struct nv04_context* nv04)
54 {
55 uint32_t control = nv04->dsa->control;
56
57 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
58 OUT_RING(control);
59 }
60
61 static void nv04_emit_blend(struct nv04_context* nv04)
62 {
63 uint32_t blend;
64
65 blend=0x4; // texture MODULATE_ALPHA
66 blend|=0x20; // alpha is MSB
67 blend|=(2<<6); // flat shading
68 blend|=(1<<8); // persp correct
69 blend|=(0<<16); // no fog
70 blend|=(nv04->blend->b_enable<<20);
71 blend|=(nv04_blend_func(nv04->blend->b_src)<<24);
72 blend|=(nv04_blend_func(nv04->blend->b_dst)<<28);
73
74 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
75 OUT_RING(blend);
76 }
77
78 static void nv04_emit_sampler(struct nv04_context *nv04, int unit)
79 {
80 struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
81 struct pipe_texture *pt = &nv04mt->base;
82
83 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 3);
84 OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
85 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*/);
86 OUT_RING(nv04->sampler[unit]->filter);
87 }
88
89 void
90 nv04_emit_hw_state(struct nv04_context *nv04)
91 {
92 int i;
93
94 if (nv04->dirty & NV04_NEW_VERTPROG) {
95 //nv04_vertprog_bind(nv04, nv04->vertprog.current);
96 nv04->dirty &= ~NV04_NEW_VERTPROG;
97 }
98
99 if (nv04->dirty & NV04_NEW_FRAGPROG) {
100 nv04_fragprog_bind(nv04, nv04->fragprog.current);
101 /*XXX: clear NV04_NEW_FRAGPROG if no new program uploaded */
102 nv04->dirty_samplers |= (1<<10);
103 nv04->dirty_samplers = 0;
104 }
105
106 if (nv04->dirty & NV04_NEW_CONTROL) {
107 nv04->dirty &= ~NV04_NEW_CONTROL;
108
109 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
110 OUT_RING(nv04->dsa->control);
111 }
112
113 if (nv04->dirty & NV04_NEW_BLEND) {
114 nv04->dirty &= ~NV04_NEW_BLEND;
115
116 nv04_emit_blend(nv04);
117 }
118
119 if (nv04->dirty & NV04_NEW_SAMPLER) {
120 nv04->dirty &= ~NV04_NEW_SAMPLER;
121
122 nv04_emit_sampler(nv04, 0);
123 }
124
125 if (nv04->dirty & NV04_NEW_VIEWPORT) {
126 nv04->dirty &= ~NV04_NEW_VIEWPORT;
127 // nv04_state_emit_viewport(nv04);
128 }
129
130 /* Emit relocs for every referenced buffer.
131 * This is to ensure the bufmgr has an accurate idea of how
132 * the buffer is used. This isn't very efficient, but we don't
133 * seem to take a significant performance hit. Will be improved
134 * at some point. Vertex arrays are emitted by nv04_vbo.c
135 */
136
137 /* Render target */
138 /* BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
139 OUT_RING(rt->stride|(zeta->stride<<16));
140 OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
141 if (fb->zsbuf) {
142 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
143 OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
144 }*/
145
146 /* Texture images */
147 for (i = 0; i < 1; i++) {
148 if (!(nv04->fp_samplers & (1 << i)))
149 continue;
150 struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
151 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2);
152 OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
153 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*/);
154 }
155 }
156