nv50_state_validate.c revision 47771bcd2fb5bcfecfa076c19360436351c21c95
1#include "nv50_context.h"
2#include "nouveau/nouveau_stateobj.h"
3
4static void
5nv50_state_validate_fb(struct nv50_context *nv50)
6{
7	struct nouveau_grobj *tesla = nv50->screen->tesla;
8	struct nouveau_stateobj *so = so_new(128, 18);
9	struct pipe_framebuffer_state *fb = &nv50->framebuffer;
10	unsigned i, w, h, gw = 0;
11
12	for (i = 0; i < fb->num_cbufs; i++) {
13		if (!gw) {
14			w = fb->cbufs[i]->width;
15			h = fb->cbufs[i]->height;
16			gw = 1;
17		} else {
18			assert(w == fb->cbufs[i]->width);
19			assert(h == fb->cbufs[i]->height);
20		}
21
22		so_method(so, tesla, NV50TCL_RT_HORIZ(i), 2);
23		so_data  (so, fb->cbufs[i]->width);
24		so_data  (so, fb->cbufs[i]->height);
25
26		so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5);
27		so_reloc (so, fb->cbufs[i]->buffer, fb->cbufs[i]->offset,
28			  NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0);
29		so_reloc (so, fb->cbufs[i]->buffer, fb->cbufs[i]->offset,
30			  NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0);
31		switch (fb->cbufs[i]->format) {
32		case PIPE_FORMAT_A8R8G8B8_UNORM:
33			so_data(so, 0xcf);
34			break;
35		case PIPE_FORMAT_R5G6B5_UNORM:
36			so_data(so, 0xe8);
37			break;
38		default:
39			{
40				char fmt[128];
41				pf_sprint_name(fmt, fb->cbufs[i]->format);
42				NOUVEAU_ERR("AIIII unknown format %s\n", fmt);
43			}
44			so_data(so, 0xe6);
45			break;
46		}
47		so_data(so, 0x00000040);
48		so_data(so, 0x00000000);
49
50		so_method(so, tesla, 0x1224, 1);
51		so_data  (so, 1);
52	}
53
54	if (fb->zsbuf) {
55		if (!gw) {
56			w = fb->zsbuf->width;
57			h = fb->zsbuf->height;
58			gw = 1;
59		} else {
60			assert(w == fb->zsbuf->width);
61			assert(h == fb->zsbuf->height);
62		}
63
64		so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5);
65		so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset,
66			  NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH, 0, 0);
67		so_reloc (so, fb->zsbuf->buffer, fb->zsbuf->offset,
68			  NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW, 0, 0);
69		switch (fb->zsbuf->format) {
70		case PIPE_FORMAT_Z24S8_UNORM:
71			so_data(so, 0x16);
72			break;
73		case PIPE_FORMAT_Z16_UNORM:
74			so_data(so, 0x15);
75			break;
76		default:
77			{
78				char fmt[128];
79				pf_sprint_name(fmt, fb->zsbuf->format);
80				NOUVEAU_ERR("AIIII unknown format %s\n", fmt);
81			}
82			so_data(so, 0x16);
83			break;
84		}
85		so_data(so, 0x00000040);
86		so_data(so, 0x00000000);
87
88		so_method(so, tesla, 0x1538, 1);
89		so_data  (so, 1);
90		so_method(so, tesla, 0x1228, 3);
91		so_data  (so, fb->zsbuf->width);
92		so_data  (so, fb->zsbuf->height);
93		so_data  (so, 0x00010001);
94	}
95
96	so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2);
97	so_data  (so, w << 16);
98	so_data  (so, h << 16);
99	so_method(so, tesla, 0xff4, 2);
100	so_data  (so, w << 16);
101	so_data  (so, h << 16);
102	so_method(so, tesla, 0xdf8, 2);
103	so_data  (so, 0);
104	so_data  (so, h);
105
106	so_ref(so, &nv50->state.fb);
107}
108
109static void
110nv50_state_emit(struct nv50_context *nv50)
111{
112	struct nv50_screen *screen = nv50->screen;
113	struct nouveau_winsys *nvws = screen->nvws;
114
115	if (nv50->pctx_id != screen->cur_pctx) {
116		nv50->state.dirty |= 0xffffffff;
117		screen->cur_pctx = nv50->pctx_id;
118	}
119
120	if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER)
121		so_emit(nvws, nv50->state.fb);
122	if (nv50->state.dirty & NV50_NEW_BLEND)
123		so_emit(nvws, nv50->state.blend);
124	if (nv50->state.dirty & NV50_NEW_ZSA)
125		so_emit(nvws, nv50->state.zsa);
126	if (nv50->state.dirty & NV50_NEW_VERTPROG)
127		so_emit(nvws, nv50->state.vertprog);
128	if (nv50->state.dirty & NV50_NEW_FRAGPROG)
129		so_emit(nvws, nv50->state.fragprog);
130	if (nv50->state.dirty & NV50_NEW_RASTERIZER)
131		so_emit(nvws, nv50->state.rast);
132	if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
133		so_emit(nvws, nv50->state.blend_colour);
134	if (nv50->state.dirty & NV50_NEW_STIPPLE)
135		so_emit(nvws, nv50->state.stipple);
136	if (nv50->state.dirty & NV50_NEW_SCISSOR)
137		so_emit(nvws, nv50->state.scissor);
138	if (nv50->state.dirty & NV50_NEW_VIEWPORT)
139		so_emit(nvws, nv50->state.viewport);
140	if (nv50->state.dirty & NV50_NEW_SAMPLER)
141		so_emit(nvws, nv50->state.tsc_upload);
142	if (nv50->state.dirty & NV50_NEW_TEXTURE)
143		so_emit(nvws, nv50->state.tic_upload);
144	if (nv50->state.dirty & NV50_NEW_ARRAYS) {
145		so_emit(nvws, nv50->state.vtxfmt);
146		so_emit(nvws, nv50->state.vtxbuf);
147	}
148	nv50->state.dirty = 0;
149
150	so_emit_reloc_markers(nvws, nv50->state.fb);
151	so_emit_reloc_markers(nvws, nv50->state.vertprog);
152	so_emit_reloc_markers(nvws, nv50->state.fragprog);
153	so_emit_reloc_markers(nvws, nv50->state.vtxbuf);
154	so_emit_reloc_markers(nvws, nv50->screen->static_init);
155}
156
157boolean
158nv50_state_validate(struct nv50_context *nv50)
159{
160	const struct pipe_framebuffer_state *fb = &nv50->framebuffer;
161	struct nouveau_grobj *tesla = nv50->screen->tesla;
162	struct nouveau_stateobj *so;
163	unsigned i;
164
165	for (i = 0; i < fb->num_cbufs; i++)
166		fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
167
168	if (fb->zsbuf)
169		fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED;
170
171	if (nv50->dirty & NV50_NEW_FRAMEBUFFER)
172		nv50_state_validate_fb(nv50);
173
174	if (nv50->dirty & NV50_NEW_BLEND)
175		so_ref(nv50->blend->so, &nv50->state.blend);
176
177	if (nv50->dirty & NV50_NEW_ZSA)
178		so_ref(nv50->zsa->so, &nv50->state.zsa);
179
180	if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB))
181		nv50_vertprog_validate(nv50);
182
183	if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
184		nv50_fragprog_validate(nv50);
185
186	if (nv50->dirty & NV50_NEW_RASTERIZER)
187		so_ref(nv50->rasterizer->so, &nv50->state.rast);
188
189	if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
190		so = so_new(5, 0);
191		so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
192		so_data  (so, fui(nv50->blend_colour.color[0]));
193		so_data  (so, fui(nv50->blend_colour.color[1]));
194		so_data  (so, fui(nv50->blend_colour.color[2]));
195		so_data  (so, fui(nv50->blend_colour.color[3]));
196		so_ref(so, &nv50->state.blend_colour);
197	}
198
199	if (nv50->dirty & NV50_NEW_STIPPLE) {
200		so = so_new(33, 0);
201		so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
202		for (i = 0; i < 32; i++)
203			so_data(so, nv50->stipple.stipple[i]);
204		so_ref(so, &nv50->state.stipple);
205	}
206
207	if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) {
208		struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe;
209		struct pipe_scissor_state *s = &nv50->scissor;
210
211		if (nv50->state.scissor &&
212		    (rast->scissor == 0 && nv50->state.scissor_enabled == 0))
213			goto scissor_uptodate;
214		nv50->state.scissor_enabled = rast->scissor;
215
216		so = so_new(3, 0);
217		so_method(so, tesla, 0xff4, 2); //NV50TCL_SCISSOR_HORIZ, 2);
218		if (nv50->state.scissor_enabled) {
219			so_data(so, ((s->maxx - s->minx) << 16) | s->minx);
220			so_data(so, ((s->maxy - s->miny) << 16) | s->miny);
221		} else {
222			so_data(so, (8192 << 16));
223			so_data(so, (8192 << 16));
224		}
225		so_ref(so, &nv50->state.scissor);
226		nv50->state.dirty |= NV50_NEW_SCISSOR;
227	}
228scissor_uptodate:
229
230	if (nv50->dirty & NV50_NEW_VIEWPORT) {
231		so = so_new(8, 0);
232		so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3);
233		so_data  (so, fui(nv50->viewport.translate[0]));
234		so_data  (so, fui(nv50->viewport.translate[1]));
235		so_data  (so, fui(nv50->viewport.translate[2]));
236		so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3);
237		so_data  (so, fui(nv50->viewport.scale[0]));
238		so_data  (so, fui(-nv50->viewport.scale[1]));
239		so_data  (so, fui(nv50->viewport.scale[2]));
240		so_ref(so, &nv50->state.viewport);
241	}
242
243	if (nv50->dirty & NV50_NEW_SAMPLER) {
244		int i;
245
246		so = so_new(nv50->sampler_nr * 8 + 3, 0);
247		so_method(so, tesla, 0x0f00, 1);
248		so_data  (so, NV50_CB_TSC);
249		so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8);
250		for (i = 0; i < nv50->sampler_nr; i++)
251			so_datap (so, nv50->sampler[i], 8);
252		so_ref(so, &nv50->state.tsc_upload);
253	}
254
255	if (nv50->dirty & NV50_NEW_TEXTURE) {
256		int i;
257
258		so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2);
259		so_method(so, tesla, 0x0f00, 1);
260		so_data  (so, NV50_CB_TIC);
261		so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8);
262		for (i = 0; i < nv50->miptree_nr; i++) {
263			struct nv50_miptree *mt = nv50->miptree[i];
264
265			so_data (so, 0x2a712488);
266			so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM |
267				     NOUVEAU_BO_LOW, 0, 0);
268			so_data (so, 0xd0c05000);
269			so_data (so, 0x00300000);
270			so_data (so, mt->base.width[0]);
271			so_data (so, (mt->base.depth[0] << 16) |
272				      mt->base.height[0]);
273			so_data (so, 0x03000000);
274			so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM |
275				     NOUVEAU_BO_HIGH, 0, 0);
276		}
277
278		so_ref(so, &nv50->state.tic_upload);
279	}
280
281	if (nv50->dirty & NV50_NEW_ARRAYS)
282		nv50_vbo_validate(nv50);
283
284	nv50->state.dirty |= nv50->dirty;
285	nv50->dirty = 0;
286	nv50_state_emit(nv50);
287
288	return TRUE;
289}
290
291