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