1 #include "nv50_context.h"
2 #include "nouveau/nouveau_stateobj.h"
5 nv50_state_validate_fb(struct nv50_context
*nv50
)
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;
12 for (i
= 0; i
< fb
->num_cbufs
; i
++) {
14 w
= fb
->cbufs
[i
]->width
;
15 h
= fb
->cbufs
[i
]->height
;
18 assert(w
== fb
->cbufs
[i
]->width
);
19 assert(h
== fb
->cbufs
[i
]->height
);
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
);
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
:
35 case PIPE_FORMAT_R5G6B5_UNORM
:
41 pf_sprint_name(fmt
, fb
->cbufs
[i
]->format
);
42 NOUVEAU_ERR("AIIII unknown format %s\n", fmt
);
47 so_data(so
, 0x00000040);
48 so_data(so
, 0x00000000);
50 so_method(so
, tesla
, 0x1224, 1);
57 h
= fb
->zsbuf
->height
;
60 assert(w
== fb
->zsbuf
->width
);
61 assert(h
== fb
->zsbuf
->height
);
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
:
73 case PIPE_FORMAT_Z16_UNORM
:
79 pf_sprint_name(fmt
, fb
->zsbuf
->format
);
80 NOUVEAU_ERR("AIIII unknown format %s\n", fmt
);
85 so_data(so
, 0x00000040);
86 so_data(so
, 0x00000000);
88 so_method(so
, tesla
, 0x1538, 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);
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);
106 so_ref(so
, &nv50
->state
.fb
);
110 nv50_state_emit(struct nv50_context
*nv50
)
112 struct nv50_screen
*screen
= nv50
->screen
;
113 struct nouveau_winsys
*nvws
= screen
->nvws
;
115 if (nv50
->pctx_id
!= screen
->cur_pctx
) {
116 nv50
->state
.dirty
|= 0xffffffff;
117 screen
->cur_pctx
= nv50
->pctx_id
;
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
);
148 nv50
->state
.dirty
= 0;
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
);
157 nv50_state_validate(struct nv50_context
*nv50
)
159 struct nouveau_grobj
*tesla
= nv50
->screen
->tesla
;
160 struct nouveau_stateobj
*so
;
163 if (nv50
->dirty
& NV50_NEW_FRAMEBUFFER
)
164 nv50_state_validate_fb(nv50
);
166 if (nv50
->dirty
& NV50_NEW_BLEND
)
167 so_ref(nv50
->blend
->so
, &nv50
->state
.blend
);
169 if (nv50
->dirty
& NV50_NEW_ZSA
)
170 so_ref(nv50
->zsa
->so
, &nv50
->state
.zsa
);
172 if (nv50
->dirty
& (NV50_NEW_VERTPROG
| NV50_NEW_VERTPROG_CB
))
173 nv50_vertprog_validate(nv50
);
175 if (nv50
->dirty
& (NV50_NEW_FRAGPROG
| NV50_NEW_FRAGPROG_CB
))
176 nv50_fragprog_validate(nv50
);
178 if (nv50
->dirty
& NV50_NEW_RASTERIZER
)
179 so_ref(nv50
->rasterizer
->so
, &nv50
->state
.rast
);
181 if (nv50
->dirty
& NV50_NEW_BLEND_COLOUR
) {
183 so_method(so
, tesla
, NV50TCL_BLEND_COLOR(0), 4);
184 so_data (so
, fui(nv50
->blend_colour
.color
[0]));
185 so_data (so
, fui(nv50
->blend_colour
.color
[1]));
186 so_data (so
, fui(nv50
->blend_colour
.color
[2]));
187 so_data (so
, fui(nv50
->blend_colour
.color
[3]));
188 so_ref(so
, &nv50
->state
.blend_colour
);
191 if (nv50
->dirty
& NV50_NEW_STIPPLE
) {
193 so_method(so
, tesla
, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
194 for (i
= 0; i
< 32; i
++)
195 so_data(so
, nv50
->stipple
.stipple
[i
]);
196 so_ref(so
, &nv50
->state
.stipple
);
199 if (nv50
->dirty
& (NV50_NEW_SCISSOR
| NV50_NEW_RASTERIZER
)) {
200 struct pipe_rasterizer_state
*rast
= &nv50
->rasterizer
->pipe
;
201 struct pipe_scissor_state
*s
= &nv50
->scissor
;
203 if (nv50
->state
.scissor
&&
204 (rast
->scissor
== 0 && nv50
->state
.scissor_enabled
== 0))
205 goto scissor_uptodate
;
206 nv50
->state
.scissor_enabled
= rast
->scissor
;
209 so_method(so
, tesla
, 0xff4, 2); //NV50TCL_SCISSOR_HORIZ, 2);
210 if (nv50
->state
.scissor_enabled
) {
211 so_data(so
, ((s
->maxx
- s
->minx
) << 16) | s
->minx
);
212 so_data(so
, ((s
->maxy
- s
->miny
) << 16) | s
->miny
);
214 so_data(so
, (8192 << 16));
215 so_data(so
, (8192 << 16));
217 so_ref(so
, &nv50
->state
.scissor
);
218 nv50
->state
.dirty
|= NV50_NEW_SCISSOR
;
222 if (nv50
->dirty
& NV50_NEW_VIEWPORT
) {
224 so_method(so
, tesla
, NV50TCL_VIEWPORT_UNK0(0), 3);
225 so_data (so
, fui(nv50
->viewport
.translate
[0]));
226 so_data (so
, fui(nv50
->viewport
.translate
[1]));
227 so_data (so
, fui(nv50
->viewport
.translate
[2]));
228 so_method(so
, tesla
, NV50TCL_VIEWPORT_UNK1(0), 3);
229 so_data (so
, fui(nv50
->viewport
.scale
[0]));
230 so_data (so
, fui(-nv50
->viewport
.scale
[1]));
231 so_data (so
, fui(nv50
->viewport
.scale
[2]));
232 so_ref(so
, &nv50
->state
.viewport
);
235 if (nv50
->dirty
& NV50_NEW_SAMPLER
) {
238 so
= so_new(nv50
->sampler_nr
* 8 + 3, 0);
239 so_method(so
, tesla
, 0x0f00, 1);
240 so_data (so
, NV50_CB_TSC
);
241 so_method(so
, tesla
, 0x40000f04, nv50
->sampler_nr
* 8);
242 for (i
= 0; i
< nv50
->sampler_nr
; i
++)
243 so_datap (so
, nv50
->sampler
[i
], 8);
244 so_ref(so
, &nv50
->state
.tsc_upload
);
247 if (nv50
->dirty
& NV50_NEW_TEXTURE
) {
250 so
= so_new(nv50
->miptree_nr
* 8 + 3, nv50
->miptree_nr
* 2);
251 so_method(so
, tesla
, 0x0f00, 1);
252 so_data (so
, NV50_CB_TIC
);
253 so_method(so
, tesla
, 0x40000f04, nv50
->miptree_nr
* 8);
254 for (i
= 0; i
< nv50
->miptree_nr
; i
++) {
255 struct nv50_miptree
*mt
= nv50
->miptree
[i
];
257 so_data (so
, 0x2a712488);
258 so_reloc(so
, mt
->buffer
, 0, NOUVEAU_BO_VRAM
|
259 NOUVEAU_BO_LOW
, 0, 0);
260 so_data (so
, 0xd0c05000);
261 so_data (so
, 0x00300000);
262 so_data (so
, mt
->base
.width
[0]);
263 so_data (so
, (mt
->base
.depth
[0] << 16) |
265 so_data (so
, 0x03000000);
266 so_reloc(so
, mt
->buffer
, 0, NOUVEAU_BO_VRAM
|
267 NOUVEAU_BO_HIGH
, 0, 0);
270 so_ref(so
, &nv50
->state
.tic_upload
);
273 if (nv50
->dirty
& NV50_NEW_ARRAYS
)
274 nv50_vbo_validate(nv50
);
276 nv50
->state
.dirty
|= nv50
->dirty
;
278 nv50_state_emit(nv50
);