1 #include "nv40_context.h"
2 #include "nv40_state.h"
4 /* Emit relocs for every referenced buffer.
6 * This is to ensure the bufmgr has an accurate idea of how
7 * the buffer is used. These relocs appear in the push buffer as
8 * NOPs, and will only be turned into state changes if a buffer
12 nv40_state_emit_dummy_relocs(struct nv40_context
*nv40
)
16 so_emit_reloc_markers(nv40
->nvws
, nv40
->so_framebuffer
);
17 for (i
= 0; i
< 16; i
++) {
18 if (!(nv40
->fp_samplers
& (1 << i
)))
20 so_emit_reloc_markers(nv40
->nvws
, nv40
->so_fragtex
[i
]);
22 so_emit_reloc_markers(nv40
->nvws
, nv40
->fragprog
.active
->so
);
26 nv40_state_scissor_validate(struct nv40_context
*nv40
)
28 struct pipe_rasterizer_state
*rast
= &nv40
->rasterizer
->pipe
;
29 struct pipe_scissor_state
*s
= &nv40
->pipe_state
.scissor
;
30 struct nouveau_stateobj
*so
;
32 if (nv40
->state
.scissor
.so
&&
33 (rast
->scissor
== 0 && nv40
->state
.scissor
.enabled
== 0))
37 so_method(so
, nv40
->hw
->curie
, NV40TCL_SCISSOR_HORIZ
, 2);
39 so_data (so
, ((s
->maxx
- s
->minx
) << 16) | s
->minx
);
40 so_data (so
, ((s
->maxy
- s
->miny
) << 16) | s
->miny
);
42 so_data (so
, 4096 << 16);
43 so_data (so
, 4096 << 16);
46 so_ref(so
, &nv40
->state
.scissor
.so
);
52 nv40_state_stipple_validate(struct nv40_context
*nv40
)
54 struct pipe_rasterizer_state
*rast
= &nv40
->rasterizer
->pipe
;
55 struct nouveau_grobj
*curie
= nv40
->hw
->curie
;
56 struct nouveau_stateobj
*so
;
58 if (nv40
->state
.stipple
.so
&& (rast
->poly_stipple_enable
== 0 &&
59 nv40
->state
.stipple
.enabled
== 0))
62 if (rast
->poly_stipple_enable
) {
66 so_method(so
, curie
, NV40TCL_POLYGON_STIPPLE_ENABLE
, 1);
68 so_method(so
, curie
, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32);
69 for (i
= 0; i
< 32; i
++)
70 so_data(so
, nv40
->pipe_state
.stipple
[i
]);
73 so_method(so
, curie
, NV40TCL_POLYGON_STIPPLE_ENABLE
, 1);
77 so_ref(so
, &nv40
->state
.stipple
.so
);
83 nv40_state_clip_validate(struct nv40_context
*nv40
)
85 if (nv40
->pipe_state
.clip
.nr
)
86 nv40
->fallback
|= NV40_FALLBACK_TNL
;
90 static struct nv40_state_entry states
[] = {
92 .validate
= nv40_state_scissor_validate
,
94 .pipe
= NV40_NEW_SCISSOR
| NV40_NEW_RAST
,
95 .hw
= NV40_NEW_SCISSOR
,
99 .validate
= nv40_state_stipple_validate
,
101 .pipe
= NV40_NEW_STIPPLE
| NV40_NEW_RAST
,
102 .hw
= NV40_NEW_STIPPLE
,
106 .validate
= nv40_state_clip_validate
,
108 .pipe
= NV40_NEW_UCP
,
115 nv40_state_validate(struct nv40_context
*nv40
)
117 unsigned i
, last_fallback
;
119 last_fallback
= nv40
->fallback
;
122 for (i
= 0; i
< sizeof(states
) / sizeof(states
[0]); i
++) {
123 if (nv40
->dirty
& states
[i
].dirty
.pipe
) {
124 if (states
[i
].validate(nv40
))
125 nv40
->hw_dirty
|= states
[i
].dirty
.hw
;
129 if (nv40
->fallback
& NV40_FALLBACK_TNL
&&
130 !(last_fallback
& NV40_FALLBACK_TNL
)) {
131 NOUVEAU_ERR("XXX: hwtnl->swtnl\n");
133 if (last_fallback
& NV40_FALLBACK_TNL
&&
134 !(nv40
->fallback
& NV40_FALLBACK_TNL
)) {
135 NOUVEAU_ERR("XXX: swtnl->hwtnl\n");
140 nv40_emit_hw_state(struct nv40_context
*nv40
)
142 nv40_state_validate(nv40
);
144 if (nv40
->dirty
& NV40_NEW_FB
)
145 so_emit(nv40
->nvws
, nv40
->so_framebuffer
);
147 if (nv40
->dirty
& NV40_NEW_BLEND
)
148 so_emit(nv40
->nvws
, nv40
->so_blend
);
150 if (nv40
->dirty
& NV40_NEW_RAST
)
151 so_emit(nv40
->nvws
, nv40
->so_rast
);
153 if (nv40
->dirty
& NV40_NEW_ZSA
)
154 so_emit(nv40
->nvws
, nv40
->so_zsa
);
156 if (nv40
->dirty
& NV40_NEW_BCOL
)
157 so_emit(nv40
->nvws
, nv40
->so_bcol
);
159 if (nv40
->hw_dirty
& NV40_NEW_SCISSOR
) {
160 so_emit(nv40
->nvws
, nv40
->state
.scissor
.so
);
161 nv40
->hw_dirty
&= ~NV40_NEW_SCISSOR
;
164 if (nv40
->dirty
& NV40_NEW_VIEWPORT
)
165 so_emit(nv40
->nvws
, nv40
->so_viewport
);
167 if (nv40
->hw_dirty
& NV40_NEW_STIPPLE
) {
168 so_emit(nv40
->nvws
, nv40
->state
.stipple
.so
);
169 nv40
->hw_dirty
&= ~NV40_NEW_STIPPLE
;
172 if (nv40
->dirty
& NV40_NEW_FRAGPROG
) {
173 nv40_fragprog_bind(nv40
, nv40
->fragprog
.current
);
174 /*XXX: clear NV40_NEW_FRAGPROG if no new program uploaded */
177 if (nv40
->dirty_samplers
|| (nv40
->dirty
& NV40_NEW_FRAGPROG
)) {
178 nv40_fragtex_bind(nv40
);
180 BEGIN_RING(curie
, NV40TCL_TEX_CACHE_CTL
, 1);
182 BEGIN_RING(curie
, NV40TCL_TEX_CACHE_CTL
, 1);
184 nv40
->dirty
&= ~NV40_NEW_FRAGPROG
;
187 if (nv40
->dirty
& NV40_NEW_VERTPROG
) {
188 nv40_vertprog_bind(nv40
, nv40
->vertprog
.current
);
189 nv40
->dirty
&= ~NV40_NEW_VERTPROG
;
192 nv40
->dirty_samplers
= 0;
195 nv40_state_emit_dummy_relocs(nv40
);