nv30: Emit fragtex state using state objects
[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_fragtex,
10 &nv30_state_blend,
11 &nv30_state_blend_colour,
12 &nv30_state_zsa,
13 &nv30_state_viewport,
14 NULL
15 };
16
17 static void
18 nv30_state_do_validate(struct nv30_context *nv30,
19 struct nv30_state_entry **states)
20 {
21 const struct pipe_framebuffer_state *fb = &nv30->framebuffer;
22 unsigned i;
23
24 for (i = 0; i < fb->num_cbufs; i++)
25 fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
26 if (fb->zsbuf)
27 fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED;
28
29 while (*states) {
30 struct nv30_state_entry *e = *states;
31
32 if (nv30->dirty & e->dirty.pipe) {
33 if (e->validate(nv30)) {
34 nv30->state.dirty |= (1ULL << e->dirty.hw);
35 }
36 }
37
38 states++;
39 }
40
41 /* TODO: uncomment when finished converting
42 nv30->dirty = 0;
43 */
44 }
45
46 void
47 nv30_emit_hw_state(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 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 if (nv30->dirty & NV30_NEW_FRAGPROG) {
64 nv30_fragprog_bind(nv30, nv30->fragprog.current);
65 /*XXX: clear NV30_NEW_FRAGPROG if no new program uploaded */
66 }
67
68 for (i = 0, states = state->dirty; states; i++) {
69 if (!(states & (1ULL << i)))
70 continue;
71 so_ref (state->hw[i], &nv30->screen->state[i]);
72 if (state->hw[i])
73 so_emit(nv30->nvws, nv30->screen->state[i]);
74 states &= ~(1ULL << i);
75 }
76
77 if (nv30->dirty & NV30_NEW_VERTPROG) {
78 nv30_vertprog_bind(nv30, nv30->vertprog.current);
79 nv30->dirty &= ~NV30_NEW_VERTPROG;
80 }
81
82 so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
83 for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
84 if (!(samplers & (1 << i)))
85 continue;
86 so_emit_reloc_markers(nv30->nvws,
87 state->hw[NV30_STATE_FRAGTEX0+i]);
88 samplers &= ~(1ULL << i);
89 }
90
91 /* Fragment program */
92 BEGIN_RING(rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1);
93 OUT_RELOC (nv30->fragprog.active->buffer, 0, NOUVEAU_BO_VRAM |
94 NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
95 NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
96 NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
97 }
98
99 boolean
100 nv30_state_validate(struct nv30_context *nv30)
101 {
102 #if 0
103 boolean was_sw = nv30->fallback_swtnl ? TRUE : FALSE;
104
105 if (nv30->render_mode != HW) {
106 /* Don't even bother trying to go back to hw if none
107 * of the states that caused swtnl previously have changed.
108 */
109 if ((nv30->fallback_swtnl & nv30->dirty)
110 != nv30->fallback_swtnl)
111 return FALSE;
112
113 /* Attempt to go to hwtnl again */
114 nv30->pipe.flush(&nv30->pipe, 0, NULL);
115 nv30->dirty |= (NV30_NEW_VIEWPORT |
116 NV30_NEW_VERTPROG |
117 NV30_NEW_ARRAYS);
118 nv30->render_mode = HW;
119 }
120 #endif
121 nv30_state_do_validate(nv30, render_states);
122 #if 0
123 if (nv30->fallback_swtnl || nv30->fallback_swrast)
124 return FALSE;
125
126 if (was_sw)
127 NOUVEAU_ERR("swtnl->hw\n");
128 #endif
129 return TRUE;
130 }