nv40: maintain pipe_surface status field
[mesa.git] / src / gallium / drivers / nv40 / nv40_state_emit.c
1 #include "nv40_context.h"
2 #include "nv40_state.h"
3 #include "draw/draw_context.h"
4
5 static struct nv40_state_entry *render_states[] = {
6 &nv40_state_framebuffer,
7 &nv40_state_rasterizer,
8 &nv40_state_clip,
9 &nv40_state_scissor,
10 &nv40_state_stipple,
11 &nv40_state_fragprog,
12 &nv40_state_fragtex,
13 &nv40_state_vertprog,
14 &nv40_state_blend,
15 &nv40_state_blend_colour,
16 &nv40_state_zsa,
17 &nv40_state_viewport,
18 &nv40_state_vbo,
19 NULL
20 };
21
22 static struct nv40_state_entry *swtnl_states[] = {
23 &nv40_state_framebuffer,
24 &nv40_state_rasterizer,
25 &nv40_state_clip,
26 &nv40_state_scissor,
27 &nv40_state_stipple,
28 &nv40_state_fragprog,
29 &nv40_state_fragtex,
30 &nv40_state_vertprog,
31 &nv40_state_blend,
32 &nv40_state_blend_colour,
33 &nv40_state_zsa,
34 &nv40_state_viewport,
35 &nv40_state_vtxfmt,
36 NULL
37 };
38
39 static void
40 nv40_state_do_validate(struct nv40_context *nv40,
41 struct nv40_state_entry **states)
42 {
43 const struct pipe_framebuffer_state *fb = &nv40->framebuffer;
44 unsigned i;
45
46 for (i = 0; i < fb->num_cbufs; i++)
47 fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
48 if (fb->zsbuf)
49 fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED;
50
51 while (*states) {
52 struct nv40_state_entry *e = *states;
53
54 if (nv40->dirty & e->dirty.pipe) {
55 if (e->validate(nv40))
56 nv40->state.dirty |= (1ULL << e->dirty.hw);
57 }
58
59 states++;
60 }
61 nv40->dirty = 0;
62 }
63
64 void
65 nv40_state_emit(struct nv40_context *nv40)
66 {
67 struct nv40_state *state = &nv40->state;
68 struct nv40_screen *screen = nv40->screen;
69 unsigned i, samplers;
70 uint64 states;
71
72 if (nv40->pctx_id != screen->cur_pctx) {
73 for (i = 0; i < NV40_STATE_MAX; i++) {
74 if (state->hw[i] && screen->state[i] != state->hw[i])
75 state->dirty |= (1ULL << i);
76 }
77
78 screen->cur_pctx = nv40->pctx_id;
79 }
80
81 for (i = 0, states = state->dirty; states; i++) {
82 if (!(states & (1ULL << i)))
83 continue;
84 so_ref (state->hw[i], &nv40->screen->state[i]);
85 so_emit(nv40->nvws, nv40->screen->state[i]);
86 states &= ~(1ULL << i);
87 }
88
89 if (state->dirty & ((1ULL << NV40_STATE_FRAGPROG) |
90 (1ULL << NV40_STATE_FRAGTEX0))) {
91 BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
92 OUT_RING (2);
93 BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1);
94 OUT_RING (1);
95 }
96
97 state->dirty = 0;
98
99 so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]);
100 for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
101 if (!(samplers & (1 << i)))
102 continue;
103 so_emit_reloc_markers(nv40->nvws,
104 state->hw[NV40_STATE_FRAGTEX0+i]);
105 samplers &= ~(1ULL << i);
106 }
107 so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]);
108 if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW)
109 so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]);
110 }
111
112 boolean
113 nv40_state_validate(struct nv40_context *nv40)
114 {
115 boolean was_sw = nv40->fallback_swtnl ? TRUE : FALSE;
116
117 if (nv40->render_mode != HW) {
118 /* Don't even bother trying to go back to hw if none
119 * of the states that caused swtnl previously have changed.
120 */
121 if ((nv40->fallback_swtnl & nv40->dirty)
122 != nv40->fallback_swtnl)
123 return FALSE;
124
125 /* Attempt to go to hwtnl again */
126 nv40->pipe.flush(&nv40->pipe, 0);
127 nv40->dirty |= (NV40_NEW_VIEWPORT |
128 NV40_NEW_VERTPROG |
129 NV40_NEW_ARRAYS |
130 NV40_NEW_UCP);
131 nv40->render_mode = HW;
132 }
133
134 nv40_state_do_validate(nv40, render_states);
135 if (nv40->fallback_swtnl || nv40->fallback_swrast)
136 return FALSE;
137
138 if (was_sw)
139 NOUVEAU_ERR("swtnl->hw\n");
140
141 return TRUE;
142 }
143
144 boolean
145 nv40_state_validate_swtnl(struct nv40_context *nv40)
146 {
147 /* Setup for swtnl */
148 if (nv40->render_mode == HW) {
149 NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl);
150 nv40->pipe.flush(&nv40->pipe, 0);
151 nv40->dirty |= (NV40_NEW_VIEWPORT |
152 NV40_NEW_VERTPROG |
153 NV40_NEW_ARRAYS |
154 NV40_NEW_UCP);
155 nv40->render_mode = SWTNL;
156 }
157
158 nv40_state_do_validate(nv40, swtnl_states);
159 if (nv40->fallback_swrast) {
160 NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast);
161 return FALSE;
162 }
163
164 return TRUE;
165 }
166