nv50_state_validate.c revision f722fd937db2f3cacf1947d538c66528fd16eb89
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		default:
74			{
75				char fmt[128];
76				pf_sprint_name(fmt, fb->zsbuf->format);
77				NOUVEAU_ERR("AIIII unknown format %s\n", fmt);
78			}
79			so_data(so, 0x16);
80			break;
81		}
82		so_data(so, 0x00000040);
83		so_data(so, 0x00000000);
84	}
85
86	so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2);
87	so_data  (so, w << 16);
88	so_data  (so, h << 16);
89	so_method(so, tesla, 0xff4, 2);
90	so_data  (so, w << 16);
91	so_data  (so, h << 16);
92	so_method(so, tesla, 0xdf8, 2);
93	so_data  (so, 0);
94	so_data  (so, h);
95
96	so_emit(nv50->screen->nvws, so);
97	so_ref(NULL, &so);
98}
99
100boolean
101nv50_state_validate(struct nv50_context *nv50)
102{
103	struct nouveau_winsys *nvws = nv50->screen->nvws;
104	struct nouveau_grobj *tesla = nv50->screen->tesla;
105	struct nouveau_stateobj *so;
106	unsigned i;
107
108	if (nv50->dirty & NV50_NEW_FRAMEBUFFER)
109		nv50_state_validate_fb(nv50);
110
111	if (nv50->dirty & NV50_NEW_BLEND)
112		so_emit(nvws, nv50->blend->so);
113
114	if (nv50->dirty & NV50_NEW_ZSA)
115		so_emit(nvws, nv50->zsa->so);
116
117	if (nv50->dirty & NV50_NEW_VERTPROG)
118		nv50_vertprog_validate(nv50);
119
120	if (nv50->dirty & NV50_NEW_FRAGPROG)
121		nv50_fragprog_validate(nv50);
122
123	if (nv50->dirty & NV50_NEW_RASTERIZER)
124		so_emit(nvws, nv50->rasterizer->so);
125
126	if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
127		so = so_new(5, 0);
128		so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 8);
129		so_data  (so, fui(nv50->blend_colour.color[3]));
130		so_data  (so, fui(nv50->blend_colour.color[0]));
131		so_data  (so, fui(nv50->blend_colour.color[1]));
132		so_data  (so, fui(nv50->blend_colour.color[2]));
133		so_emit(nvws, so);
134		so_ref(NULL, &so);
135	}
136
137	if (nv50->dirty & NV50_NEW_STIPPLE) {
138		so = so_new(33, 0);
139		so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
140		for (i = 0; i < 32; i++)
141			so_data(so, nv50->stipple.stipple[i]);
142		so_emit(nvws, so);
143		so_ref(NULL, &so);
144	}
145
146	if (nv50->dirty & NV50_NEW_SCISSOR) {
147		so = so_new(3, 0);
148		so_method(so, tesla, NV50TCL_SCISSOR_HORIZ, 2);
149		so_data  (so, (nv50->scissor.maxx << 16) |
150			       nv50->scissor.minx);
151		so_data  (so, (nv50->scissor.maxy << 16) |
152			       nv50->scissor.miny);
153		so_emit(nvws, so);
154		so_ref(NULL, &so);
155	}
156
157	if (nv50->dirty & NV50_NEW_VIEWPORT) {
158		so = so_new(8, 0);
159		so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3);
160		so_data  (so, fui(nv50->viewport.translate[0]));
161		so_data  (so, fui(nv50->viewport.translate[1]));
162		so_data  (so, fui(nv50->viewport.translate[2]));
163		so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3);
164		so_data  (so, fui(nv50->viewport.scale[0]));
165		so_data  (so, fui(-nv50->viewport.scale[1]));
166		so_data  (so, fui(nv50->viewport.scale[2]));
167		so_emit(nvws, so);
168		so_ref(NULL, &so);
169	}
170
171	if (nv50->dirty & NV50_NEW_ARRAYS)
172		nv50_vbo_validate(nv50);
173
174	nv50->dirty = 0;
175	return TRUE;
176}
177
178