Merge remote branch 'main/master' into radeon-rewrite
[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 nv04_surface *rt, *zeta;
97 uint32_t rt_format, w, h;
98 int colour_format = 0, zeta_format = 0;
99 struct nv04_miptree *nv04mt = 0;
100
101 w = fb->cbufs[0]->width;
102 h = fb->cbufs[0]->height;
103 colour_format = fb->cbufs[0]->format;
104 rt = (struct nv04_surface *)fb->cbufs[0];
105
106 if (fb->zsbuf) {
107 if (colour_format) {
108 assert(w == fb->zsbuf->width);
109 assert(h == fb->zsbuf->height);
110 } else {
111 w = fb->zsbuf->width;
112 h = fb->zsbuf->height;
113 }
114
115 zeta_format = fb->zsbuf->format;
116 zeta = (struct nv04_surface *)fb->zsbuf;
117 }
118
119 switch (colour_format) {
120 case PIPE_FORMAT_A8R8G8B8_UNORM:
121 case 0:
122 rt_format = 0x108;
123 break;
124 case PIPE_FORMAT_R5G6B5_UNORM:
125 rt_format = 0x103;
126 break;
127 default:
128 assert(0);
129 }
130
131 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
132 OUT_RING(rt_format);
133
134 nv04mt = (struct nv04_miptree *)rt->base.texture;
135 /* FIXME pitches have to be aligned ! */
136 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
137 OUT_RING(rt->pitch|(zeta->pitch<<16));
138 OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
139 if (fb->zsbuf) {
140 nv04mt = (struct nv04_miptree *)zeta->base.texture;
141 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
142 OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
143 }
144 }
145
146 void
147 nv04_emit_hw_state(struct nv04_context *nv04)
148 {
149 int i;
150
151 if (nv04->dirty & NV04_NEW_VERTPROG) {
152 //nv04_vertprog_bind(nv04, nv04->vertprog.current);
153 nv04->dirty &= ~NV04_NEW_VERTPROG;
154 }
155
156 if (nv04->dirty & NV04_NEW_FRAGPROG) {
157 nv04_fragprog_bind(nv04, nv04->fragprog.current);
158 nv04->dirty &= ~NV04_NEW_FRAGPROG;
159 nv04->dirty_samplers |= (1<<10);
160 nv04->dirty_samplers = 0;
161 }
162
163 if (nv04->dirty & NV04_NEW_CONTROL) {
164 nv04->dirty &= ~NV04_NEW_CONTROL;
165
166 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
167 OUT_RING(nv04->dsa->control);
168 }
169
170 if (nv04->dirty & NV04_NEW_BLEND) {
171 nv04->dirty &= ~NV04_NEW_BLEND;
172
173 nv04_emit_blend(nv04);
174 }
175
176 if (nv04->dirty & NV04_NEW_VTXARRAYS) {
177 nv04->dirty &= ~NV04_NEW_VTXARRAYS;
178 nv04_vertex_layout(nv04);
179 }
180
181 if (nv04->dirty & NV04_NEW_SAMPLER) {
182 nv04->dirty &= ~NV04_NEW_SAMPLER;
183
184 nv04_emit_sampler(nv04, 0);
185 }
186
187 if (nv04->dirty & NV04_NEW_VIEWPORT) {
188 nv04->dirty &= ~NV04_NEW_VIEWPORT;
189 // nv04_state_emit_viewport(nv04);
190 }
191
192 if (nv04->dirty & NV04_NEW_FRAMEBUFFER) {
193 nv04->dirty &= ~NV04_NEW_FRAMEBUFFER;
194 nv04_state_emit_framebuffer(nv04);
195 }
196
197 /* Emit relocs for every referenced buffer.
198 * This is to ensure the bufmgr has an accurate idea of how
199 * the buffer is used. This isn't very efficient, but we don't
200 * seem to take a significant performance hit. Will be improved
201 * at some point. Vertex arrays are emitted by nv04_vbo.c
202 */
203
204 /* Render target */
205 unsigned rt_pitch = ((struct nv04_surface *)nv04->rt)->pitch;
206 unsigned zeta_pitch = ((struct nv04_surface *)nv04->zeta)->pitch;
207
208 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
209 OUT_RING(rt_pitch|(zeta_pitch<<16));
210 OUT_RELOCl(nv04->rt, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
211 if (nv04->zeta) {
212 BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
213 OUT_RELOCl(nv04->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
214 }
215
216 /* Texture images */
217 for (i = 0; i < 1; i++) {
218 if (!(nv04->fp_samplers & (1 << i)))
219 continue;
220 struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
221 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2);
222 OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
223 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*/);
224 }
225 }
226