nv50: import current "state of the art" nv50 code
[mesa.git] / src / gallium / drivers / nv50 / nv50_state_validate.c
1 #include "nv50_context.h"
2 #include "nouveau/nouveau_stateobj.h"
3
4 static void
5 nv50_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
100 boolean
101 nv50_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