Merge commit 'origin/master' into gallium-0.2
[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_viewport,
16 &nv30_state_vbo,
17 NULL
18 };
19
20 static void
21 nv30_state_do_validate(struct nv30_context *nv30,
22 struct nv30_state_entry **states)
23 {
24 const struct pipe_framebuffer_state *fb = &nv30->framebuffer;
25 unsigned i;
26
27 for (i = 0; i < fb->num_cbufs; i++)
28 fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
29 if (fb->zsbuf)
30 fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED;
31
32 while (*states) {
33 struct nv30_state_entry *e = *states;
34
35 if (nv30->dirty & e->dirty.pipe) {
36 if (e->validate(nv30)) {
37 nv30->state.dirty |= (1ULL << e->dirty.hw);
38 }
39 }
40
41 states++;
42 }
43 nv30->dirty = 0;
44 }
45
46 void
47 nv30_state_emit(struct nv30_context *nv30)
48 {
49 struct nv30_state *state = &nv30->state;
50 struct nv30_screen *screen = nv30->screen;
51 unsigned i, samplers;
52 uint64_t states;
53
54 if (nv30->pctx_id != screen->cur_pctx) {
55 for (i = 0; i < NV30_STATE_MAX; i++) {
56 if (state->hw[i] && screen->state[i] != state->hw[i])
57 state->dirty |= (1ULL << i);
58 }
59
60 screen->cur_pctx = nv30->pctx_id;
61 }
62
63 for (i = 0, states = state->dirty; states; i++) {
64 if (!(states & (1ULL << i)))
65 continue;
66 so_ref (state->hw[i], &nv30->screen->state[i]);
67 if (state->hw[i])
68 so_emit(nv30->nvws, nv30->screen->state[i]);
69 states &= ~(1ULL << i);
70 }
71
72 state->dirty = 0;
73
74 so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
75 for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
76 if (!(samplers & (1 << i)))
77 continue;
78 so_emit_reloc_markers(nv30->nvws,
79 state->hw[NV30_STATE_FRAGTEX0+i]);
80 samplers &= ~(1ULL << i);
81 }
82 so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FRAGPROG]);
83 if (state->hw[NV30_STATE_VTXBUF] /*&& nv30->render_mode == HW*/)
84 so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_VTXBUF]);
85 }
86
87 boolean
88 nv30_state_validate(struct nv30_context *nv30)
89 {
90 #if 0
91 boolean was_sw = nv30->fallback_swtnl ? TRUE : FALSE;
92
93 if (nv30->render_mode != HW) {
94 /* Don't even bother trying to go back to hw if none
95 * of the states that caused swtnl previously have changed.
96 */
97 if ((nv30->fallback_swtnl & nv30->dirty)
98 != nv30->fallback_swtnl)
99 return FALSE;
100
101 /* Attempt to go to hwtnl again */
102 nv30->pipe.flush(&nv30->pipe, 0, NULL);
103 nv30->dirty |= (NV30_NEW_VIEWPORT |
104 NV30_NEW_VERTPROG |
105 NV30_NEW_ARRAYS);
106 nv30->render_mode = HW;
107 }
108 #endif
109 nv30_state_do_validate(nv30, render_states);
110 #if 0
111 if (nv30->fallback_swtnl || nv30->fallback_swrast)
112 return FALSE;
113
114 if (was_sw)
115 NOUVEAU_ERR("swtnl->hw\n");
116 #endif
117 return TRUE;
118 }