1 #include "nv40_context.h"
2 #include "nv40_state.h"
3 #include "draw/draw_context.h"
5 static struct nv40_state_entry
*render_states
[] = {
6 &nv40_state_framebuffer
,
7 &nv40_state_rasterizer
,
14 &nv40_state_blend_colour
,
22 static struct nv40_state_entry
*swtnl_states
[] = {
23 &nv40_state_framebuffer
,
24 &nv40_state_rasterizer
,
31 &nv40_state_blend_colour
,
40 nv40_state_do_validate(struct nv40_context
*nv40
,
41 struct nv40_state_entry
**states
)
44 struct nv40_state_entry
*e
= *states
;
46 if (nv40
->dirty
& e
->dirty
.pipe
) {
47 if (e
->validate(nv40
))
48 nv40
->state
.dirty
|= (1ULL << e
->dirty
.hw
);
57 nv40_state_emit(struct nv40_context
*nv40
)
59 struct nv40_state
*state
= &nv40
->state
;
60 struct nv40_screen
*screen
= nv40
->screen
;
61 struct nouveau_channel
*chan
= screen
->base
.channel
;
62 struct nouveau_grobj
*curie
= screen
->curie
;
66 /* XXX: race conditions
68 if (nv40
!= screen
->cur_ctx
) {
69 for (i
= 0; i
< NV40_STATE_MAX
; i
++) {
70 if (state
->hw
[i
] && screen
->state
[i
] != state
->hw
[i
])
71 state
->dirty
|= (1ULL << i
);
74 screen
->cur_ctx
= nv40
;
77 for (i
= 0, states
= state
->dirty
; states
; i
++) {
78 if (!(states
& (1ULL << i
)))
80 so_ref (state
->hw
[i
], &nv40
->screen
->state
[i
]);
82 so_emit(chan
, nv40
->screen
->state
[i
]);
83 states
&= ~(1ULL << i
);
86 if (state
->dirty
& ((1ULL << NV40_STATE_FRAGPROG
) |
87 (1ULL << NV40_STATE_FRAGTEX0
))) {
88 BEGIN_RING(chan
, curie
, NV40TCL_TEX_CACHE_CTL
, 1);
90 BEGIN_RING(chan
, curie
, NV40TCL_TEX_CACHE_CTL
, 1);
98 nv40_state_flush_notify(struct nouveau_channel
*chan
)
100 struct nv40_context
*nv40
= chan
->user_private
;
101 struct nv40_state
*state
= &nv40
->state
;
102 unsigned i
, samplers
;
104 so_emit_reloc_markers(chan
, state
->hw
[NV40_STATE_FB
]);
105 for (i
= 0, samplers
= state
->fp_samplers
; i
< 16 && samplers
; i
++) {
106 if (!(samplers
& (1 << i
)))
108 so_emit_reloc_markers(chan
,
109 state
->hw
[NV40_STATE_FRAGTEX0
+i
]);
110 samplers
&= ~(1ULL << i
);
112 so_emit_reloc_markers(chan
, state
->hw
[NV40_STATE_FRAGPROG
]);
113 if (state
->hw
[NV40_STATE_VTXBUF
] && nv40
->render_mode
== HW
)
114 so_emit_reloc_markers(chan
, state
->hw
[NV40_STATE_VTXBUF
]);
118 nv40_state_validate(struct nv40_context
*nv40
)
120 boolean was_sw
= nv40
->fallback_swtnl
? TRUE
: FALSE
;
122 if (nv40
->render_mode
!= HW
) {
123 /* Don't even bother trying to go back to hw if none
124 * of the states that caused swtnl previously have changed.
126 if ((nv40
->fallback_swtnl
& nv40
->dirty
)
127 != nv40
->fallback_swtnl
)
130 /* Attempt to go to hwtnl again */
131 nv40
->pipe
.flush(&nv40
->pipe
, 0, NULL
);
132 nv40
->dirty
|= (NV40_NEW_VIEWPORT
|
135 nv40
->render_mode
= HW
;
138 nv40_state_do_validate(nv40
, render_states
);
139 if (nv40
->fallback_swtnl
|| nv40
->fallback_swrast
)
143 NOUVEAU_ERR("swtnl->hw\n");
149 nv40_state_validate_swtnl(struct nv40_context
*nv40
)
151 struct draw_context
*draw
= nv40
->draw
;
153 /* Setup for swtnl */
154 if (nv40
->render_mode
== HW
) {
155 NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40
->fallback_swtnl
);
156 nv40
->pipe
.flush(&nv40
->pipe
, 0, NULL
);
157 nv40
->dirty
|= (NV40_NEW_VIEWPORT
|
160 nv40
->render_mode
= SWTNL
;
163 if (nv40
->draw_dirty
& NV40_NEW_VERTPROG
)
164 draw_bind_vertex_shader(draw
, nv40
->vertprog
->draw
);
166 if (nv40
->draw_dirty
& NV40_NEW_RAST
)
167 draw_set_rasterizer_state(draw
, &nv40
->rasterizer
->pipe
, nv40
->rasterizer
);
169 if (nv40
->draw_dirty
& NV40_NEW_UCP
)
170 draw_set_clip_state(draw
, &nv40
->clip
);
172 if (nv40
->draw_dirty
& NV40_NEW_VIEWPORT
)
173 draw_set_viewport_state(draw
, &nv40
->viewport
);
175 if (nv40
->draw_dirty
& NV40_NEW_ARRAYS
) {
176 draw_set_vertex_buffers(draw
, nv40
->vtxbuf_nr
, nv40
->vtxbuf
);
177 draw_set_vertex_elements(draw
, nv40
->vtxelt_nr
, nv40
->vtxelt
);
180 nv40_state_do_validate(nv40
, swtnl_states
);
181 if (nv40
->fallback_swrast
) {
182 NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40
->fallback_swrast
);
186 nv40
->draw_dirty
= 0;