r300: respect radeon common code fallbacks
[mesa.git] / src / gallium / drivers / nv30 / nv30_state_emit.c
1 #include "nv30_context.h"
2 #include "nv30_state.h"
3
4 static struct nv30_state_entry *render_states[] = {
5 &nv30_state_framebuffer,
6 &nv30_state_rasterizer,
7 &nv30_state_scissor,
8 &nv30_state_stipple,
9 &nv30_state_fragprog,
10 &nv30_state_fragtex,
11 &nv30_state_vertprog,
12 &nv30_state_blend,
13 &nv30_state_blend_colour,
14 &nv30_state_zsa,
15 &nv30_state_sr,
16 &nv30_state_viewport,
17 &nv30_state_vbo,
18 NULL
19 };
20
21 static void
22 nv30_state_do_validate(struct nv30_context *nv30,
23 struct nv30_state_entry **states)
24 {
25 while (*states) {
26 struct nv30_state_entry *e = *states;
27
28 if (nv30->dirty & e->dirty.pipe) {
29 if (e->validate(nv30)) {
30 nv30->state.dirty |= (1ULL << e->dirty.hw);
31 }
32 }
33
34 states++;
35 }
36 nv30->dirty = 0;
37 }
38
39 void
40 nv30_state_emit(struct nv30_context *nv30)
41 {
42 struct nouveau_channel *chan = nv30->screen->base.channel;
43 struct nv30_state *state = &nv30->state;
44 struct nv30_screen *screen = nv30->screen;
45 unsigned i;
46 uint64_t states;
47
48 /* XXX: racy!
49 */
50 if (nv30 != screen->cur_ctx) {
51 for (i = 0; i < NV30_STATE_MAX; i++) {
52 if (state->hw[i] && screen->state[i] != state->hw[i])
53 state->dirty |= (1ULL << i);
54 }
55
56 screen->cur_ctx = nv30;
57 }
58
59 for (i = 0, states = state->dirty; states; i++) {
60 if (!(states & (1ULL << i)))
61 continue;
62 so_ref (state->hw[i], &nv30->screen->state[i]);
63 if (state->hw[i])
64 so_emit(chan, nv30->screen->state[i]);
65 states &= ~(1ULL << i);
66 }
67
68 state->dirty = 0;
69 }
70
71 void
72 nv30_state_flush_notify(struct nouveau_channel *chan)
73 {
74 struct nv30_context *nv30 = chan->user_private;
75 struct nv30_state *state = &nv30->state;
76 unsigned i, samplers;
77
78 so_emit_reloc_markers(chan, state->hw[NV30_STATE_FB]);
79 for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
80 if (!(samplers & (1 << i)))
81 continue;
82 so_emit_reloc_markers(chan,
83 state->hw[NV30_STATE_FRAGTEX0+i]);
84 samplers &= ~(1ULL << i);
85 }
86 so_emit_reloc_markers(chan, state->hw[NV30_STATE_FRAGPROG]);
87 if (state->hw[NV30_STATE_VTXBUF] /*&& nv30->render_mode == HW*/)
88 so_emit_reloc_markers(chan, state->hw[NV30_STATE_VTXBUF]);
89 }
90
91 boolean
92 nv30_state_validate(struct nv30_context *nv30)
93 {
94 #if 0
95 boolean was_sw = nv30->fallback_swtnl ? TRUE : FALSE;
96
97 if (nv30->render_mode != HW) {
98 /* Don't even bother trying to go back to hw if none
99 * of the states that caused swtnl previously have changed.
100 */
101 if ((nv30->fallback_swtnl & nv30->dirty)
102 != nv30->fallback_swtnl)
103 return FALSE;
104
105 /* Attempt to go to hwtnl again */
106 nv30->pipe.flush(&nv30->pipe, 0, NULL);
107 nv30->dirty |= (NV30_NEW_VIEWPORT |
108 NV30_NEW_VERTPROG |
109 NV30_NEW_ARRAYS);
110 nv30->render_mode = HW;
111 }
112 #endif
113 nv30_state_do_validate(nv30, render_states);
114 #if 0
115 if (nv30->fallback_swtnl || nv30->fallback_swrast)
116 return FALSE;
117
118 if (was_sw)
119 NOUVEAU_ERR("swtnl->hw\n");
120 #endif
121 return TRUE;
122 }