nv50_state_validate.c revision 714cb4a86c1f503334b37ca6c24272fa1bdf7899
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	struct nouveau_grobj *tesla = nv50->screen->tesla;
161	struct nouveau_stateobj *so;
162	unsigned i;
163
164	if (nv50->dirty & NV50_NEW_FRAMEBUFFER)
165		nv50_state_validate_fb(nv50);
166
167	if (nv50->dirty & NV50_NEW_BLEND)
168		so_ref(nv50->blend->so, &nv50->state.blend);
169
170	if (nv50->dirty & NV50_NEW_ZSA)
171		so_ref(nv50->zsa->so, &nv50->state.zsa);
172
173	if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB))
174		nv50_vertprog_validate(nv50);
175
176	if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
177		nv50_fragprog_validate(nv50);
178
179	if (nv50->dirty & NV50_NEW_RASTERIZER)
180		so_ref(nv50->rasterizer->so, &nv50->state.rast);
181
182	if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
183		so = so_new(5, 0);
184		so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
185		so_data  (so, fui(nv50->blend_colour.color[0]));
186		so_data  (so, fui(nv50->blend_colour.color[1]));
187		so_data  (so, fui(nv50->blend_colour.color[2]));
188		so_data  (so, fui(nv50->blend_colour.color[3]));
189		so_ref(so, &nv50->state.blend_colour);
190	}
191
192	if (nv50->dirty & NV50_NEW_STIPPLE) {
193		so = so_new(33, 0);
194		so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
195		for (i = 0; i < 32; i++)
196			so_data(so, nv50->stipple.stipple[i]);
197		so_ref(so, &nv50->state.stipple);
198	}
199
200	if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) {
201		struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe;
202		struct pipe_scissor_state *s = &nv50->scissor;
203
204		if (nv50->state.scissor &&
205		    (rast->scissor == 0 && nv50->state.scissor_enabled == 0))
206			goto scissor_uptodate;
207		nv50->state.scissor_enabled = rast->scissor;
208
209		so = so_new(3, 0);
210		so_method(so, tesla, 0xff4, 2); //NV50TCL_SCISSOR_HORIZ, 2);
211		if (nv50->state.scissor_enabled) {
212			so_data(so, ((s->maxx - s->minx) << 16) | s->minx);
213			so_data(so, ((s->maxy - s->miny) << 16) | s->miny);
214		} else {
215			so_data(so, (8192 << 16));
216			so_data(so, (8192 << 16));
217		}
218		so_ref(so, &nv50->state.scissor);
219		nv50->state.dirty |= NV50_NEW_SCISSOR;
220	}
221scissor_uptodate:
222
223	if (nv50->dirty & NV50_NEW_VIEWPORT) {
224		so = so_new(8, 0);
225		so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3);
226		so_data  (so, fui(nv50->viewport.translate[0]));
227		so_data  (so, fui(nv50->viewport.translate[1]));
228		so_data  (so, fui(nv50->viewport.translate[2]));
229		so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3);
230		so_data  (so, fui(nv50->viewport.scale[0]));
231		so_data  (so, fui(-nv50->viewport.scale[1]));
232		so_data  (so, fui(nv50->viewport.scale[2]));
233		so_ref(so, &nv50->state.viewport);
234	}
235
236	if (nv50->dirty & NV50_NEW_SAMPLER) {
237		int i;
238
239		so = so_new(nv50->sampler_nr * 8 + 3, 0);
240		so_method(so, tesla, 0x0f00, 1);
241		so_data  (so, NV50_CB_TSC);
242		so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8);
243		for (i = 0; i < nv50->sampler_nr; i++)
244			so_datap (so, nv50->sampler[i], 8);
245		so_ref(so, &nv50->state.tsc_upload);
246	}
247
248	if (nv50->dirty & NV50_NEW_TEXTURE) {
249		int i;
250
251		so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2);
252		so_method(so, tesla, 0x0f00, 1);
253		so_data  (so, NV50_CB_TIC);
254		so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8);
255		for (i = 0; i < nv50->miptree_nr; i++) {
256			struct nv50_miptree *mt = nv50->miptree[i];
257
258			so_data (so, 0x2a712488);
259			so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM |
260				     NOUVEAU_BO_LOW, 0, 0);
261			so_data (so, 0xd0c05000);
262			so_data (so, 0x00300000);
263			so_data (so, mt->base.width[0]);
264			so_data (so, (mt->base.depth[0] << 16) |
265				      mt->base.height[0]);
266			so_data (so, 0x03000000);
267			so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM |
268				     NOUVEAU_BO_HIGH, 0, 0);
269		}
270
271		so_ref(so, &nv50->state.tic_upload);
272	}
273
274	if (nv50->dirty & NV50_NEW_ARRAYS)
275		nv50_vbo_validate(nv50);
276
277	nv50->state.dirty |= nv50->dirty;
278	nv50->dirty = 0;
279	nv50_state_emit(nv50);
280
281	return TRUE;
282}
283
284