Merge remote branch 'upstream/gallium-0.1' into gallium-0.1
[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_blend,
10 &nv30_state_blend_colour,
11 &nv30_state_zsa,
12 &nv30_state_viewport,
13 NULL
14 };
15
16 static void
17 nv30_state_do_validate(struct nv30_context *nv30,
18 struct nv30_state_entry **states)
19 {
20 const struct pipe_framebuffer_state *fb = &nv30->framebuffer;
21 unsigned i;
22
23 for (i = 0; i < fb->num_cbufs; i++)
24 fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
25 if (fb->zsbuf)
26 fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED;
27
28 while (*states) {
29 struct nv30_state_entry *e = *states;
30
31 if (nv30->dirty & e->dirty.pipe) {
32 if (e->validate(nv30)) {
33 nv30->state.dirty |= (1ULL << e->dirty.hw);
34 }
35 }
36
37 states++;
38 }
39
40 /* TODO: uncomment when finished converting
41 nv30->dirty = 0;
42 */
43 }
44
45 void
46 nv30_emit_hw_state(struct nv30_context *nv30)
47 {
48 struct nv30_state *state = &nv30->state;
49 struct nv30_screen *screen = nv30->screen;
50 unsigned i;
51 uint64 states;
52
53 if (nv30->pctx_id != screen->cur_pctx) {
54 for (i = 0; i < NV30_STATE_MAX; i++) {
55 if (state->hw[i] && screen->state[i] != state->hw[i])
56 state->dirty |= (1ULL << i);
57 }
58
59 screen->cur_pctx = nv30->pctx_id;
60 }
61
62 for (i = 0, states = state->dirty; states; i++) {
63 if (!(states & (1ULL << i)))
64 continue;
65 so_ref (state->hw[i], &nv30->screen->state[i]);
66 if (state->hw[i])
67 so_emit(nv30->nvws, nv30->screen->state[i]);
68 states &= ~(1ULL << i);
69 }
70
71 if (nv30->dirty & NV30_NEW_FRAGPROG) {
72 nv30_fragprog_bind(nv30, nv30->fragprog.current);
73 /*XXX: clear NV30_NEW_FRAGPROG if no new program uploaded */
74 }
75
76 if (nv30->dirty_samplers || (nv30->dirty & NV30_NEW_FRAGPROG)) {
77 nv30_fragtex_bind(nv30);
78 /*
79 BEGIN_RING(rankine, NV34TCL_TX_CACHE_CTL, 1);
80 OUT_RING (2);
81 BEGIN_RING(rankine, NV34TCL_TX_CACHE_CTL, 1);
82 OUT_RING (1);*/
83 nv30->dirty &= ~NV30_NEW_FRAGPROG;
84 }
85
86 if (nv30->dirty & NV30_NEW_VERTPROG) {
87 nv30_vertprog_bind(nv30, nv30->vertprog.current);
88 nv30->dirty &= ~NV30_NEW_VERTPROG;
89 }
90
91 nv30->dirty_samplers = 0;
92
93 so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
94
95 /* Texture images, emitted in nv30_fragtex_build */
96 #if 0
97 for (i = 0; i < 16; i++) {
98 if (!(nv30->fp_samplers & (1 << i)))
99 continue;
100 BEGIN_RING(rankine, NV34TCL_TX_OFFSET(i), 2);
101 OUT_RELOCl(nv30->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
102 NOUVEAU_BO_GART | NOUVEAU_BO_RD);
103 OUT_RELOCd(nv30->tex[i].buffer, nv30->tex[i].format,
104 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
105 NOUVEAU_BO_OR, NV34TCL_TX_FORMAT_DMA0,
106 NV34TCL_TX_FORMAT_DMA1);
107 }
108 #endif
109
110 /* Fragment program */
111 BEGIN_RING(rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1);
112 OUT_RELOC (nv30->fragprog.active->buffer, 0, NOUVEAU_BO_VRAM |
113 NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
114 NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
115 NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
116 }
117
118 boolean
119 nv30_state_validate(struct nv30_context *nv30)
120 {
121 #if 0
122 boolean was_sw = nv30->fallback_swtnl ? TRUE : FALSE;
123
124 if (nv30->render_mode != HW) {
125 /* Don't even bother trying to go back to hw if none
126 * of the states that caused swtnl previously have changed.
127 */
128 if ((nv30->fallback_swtnl & nv30->dirty)
129 != nv30->fallback_swtnl)
130 return FALSE;
131
132 /* Attempt to go to hwtnl again */
133 nv30->pipe.flush(&nv30->pipe, 0, NULL);
134 nv30->dirty |= (NV30_NEW_VIEWPORT |
135 NV30_NEW_VERTPROG |
136 NV30_NEW_ARRAYS);
137 nv30->render_mode = HW;
138 }
139 #endif
140 nv30_state_do_validate(nv30, render_states);
141 #if 0
142 if (nv30->fallback_swtnl || nv30->fallback_swrast)
143 return FALSE;
144
145 if (was_sw)
146 NOUVEAU_ERR("swtnl->hw\n");
147 #endif
148 return TRUE;
149 }