9582ba9648c29d7bcab6ce9ad8041b1f1bea0f79
1 #include "nv30/nv30_context.h"
2 #include "nv40/nv40_context.h"
3 #include "nvfx_state.h"
4 #include "draw/draw_context.h"
6 #define RENDER_STATES(name, nvxx, vbo) \
7 static struct nvfx_state_entry *name##_render_states[] = { \
8 &nvxx##_state_framebuffer, \
9 &nvxx##_state_rasterizer, \
10 &nvxx##_state_scissor, \
11 &nvxx##_state_stipple, \
12 &nvxx##_state_fragprog, \
13 &nvxx##_state_fragtex, \
14 &nvxx##_state_vertprog, \
15 &nvxx##_state_blend, \
16 &nvxx##_state_blend_colour, \
19 &nvxx##_state_viewport, \
20 &nvxx##_state_##vbo, \
24 RENDER_STATES(nv30
, nv30
, vbo
);
25 RENDER_STATES(nv30_swtnl
, nv30
, vbo
); /* TODO: replace with vtxfmt once draw is unified */
26 RENDER_STATES(nv40
, nv40
, vbo
);
27 RENDER_STATES(nv40_swtnl
, nv40
, vtxfmt
);
30 nvfx_state_do_validate(struct nvfx_context
*nvfx
,
31 struct nvfx_state_entry
**states
)
34 struct nvfx_state_entry
*e
= *states
;
36 if (nvfx
->dirty
& e
->dirty
.pipe
) {
37 if (e
->validate(nvfx
))
38 nvfx
->state
.dirty
|= (1ULL << e
->dirty
.hw
);
47 nvfx_state_emit(struct nvfx_context
*nvfx
)
49 struct nvfx_state
*state
= &nvfx
->state
;
50 struct nvfx_screen
*screen
= nvfx
->screen
;
51 struct nouveau_channel
*chan
= screen
->base
.channel
;
52 struct nouveau_grobj
*eng3d
= screen
->eng3d
;
56 /* XXX: race conditions
58 if (nvfx
!= screen
->cur_ctx
) {
59 for (i
= 0; i
< NVFX_STATE_MAX
; i
++) {
60 if (state
->hw
[i
] && screen
->state
[i
] != state
->hw
[i
])
61 state
->dirty
|= (1ULL << i
);
64 screen
->cur_ctx
= nvfx
;
67 for (i
= 0, states
= state
->dirty
; states
; i
++) {
68 if (!(states
& (1ULL << i
)))
70 so_ref (state
->hw
[i
], &nvfx
->screen
->state
[i
]);
72 so_emit(chan
, nvfx
->screen
->state
[i
]);
73 states
&= ~(1ULL << i
);
76 /* TODO: could nv30 need this or something similar too? */
78 if (state
->dirty
& ((1ULL << NVFX_STATE_FRAGPROG
) |
79 (1ULL << NVFX_STATE_FRAGTEX0
))) {
80 BEGIN_RING(chan
, eng3d
, NV40TCL_TEX_CACHE_CTL
, 1);
82 BEGIN_RING(chan
, eng3d
, NV40TCL_TEX_CACHE_CTL
, 1);
90 nvfx_state_flush_notify(struct nouveau_channel
*chan
)
92 struct nvfx_context
*nvfx
= chan
->user_private
;
93 struct nvfx_state
*state
= &nvfx
->state
;
96 so_emit_reloc_markers(chan
, state
->hw
[NVFX_STATE_FB
]);
97 for (i
= 0, samplers
= state
->fp_samplers
; i
< 16 && samplers
; i
++) {
98 if (!(samplers
& (1 << i
)))
100 so_emit_reloc_markers(chan
,
101 state
->hw
[NVFX_STATE_FRAGTEX0
+i
]);
102 samplers
&= ~(1ULL << i
);
104 so_emit_reloc_markers(chan
, state
->hw
[NVFX_STATE_FRAGPROG
]);
105 if (state
->hw
[NVFX_STATE_VTXBUF
] && nvfx
->render_mode
== HW
)
106 so_emit_reloc_markers(chan
, state
->hw
[NVFX_STATE_VTXBUF
]);
110 nvfx_state_validate(struct nvfx_context
*nvfx
)
112 boolean was_sw
= nvfx
->fallback_swtnl
? TRUE
: FALSE
;
114 if (nvfx
->render_mode
!= HW
) {
115 /* Don't even bother trying to go back to hw if none
116 * of the states that caused swtnl previously have changed.
118 if ((nvfx
->fallback_swtnl
& nvfx
->dirty
)
119 != nvfx
->fallback_swtnl
)
122 /* Attempt to go to hwtnl again */
123 nvfx
->pipe
.flush(&nvfx
->pipe
, 0, NULL
);
124 nvfx
->dirty
|= (NVFX_NEW_VIEWPORT
|
127 nvfx
->render_mode
= HW
;
131 nvfx_state_do_validate(nvfx
, nv30_render_states
);
133 nvfx_state_do_validate(nvfx
, nv40_render_states
);
135 if (nvfx
->fallback_swtnl
|| nvfx
->fallback_swrast
)
139 NOUVEAU_ERR("swtnl->hw\n");
145 nvfx_state_validate_swtnl(struct nvfx_context
*nvfx
)
147 struct draw_context
*draw
= nvfx
->draw
;
149 /* Setup for swtnl */
150 if (nvfx
->render_mode
== HW
) {
151 NOUVEAU_ERR("hw->swtnl 0x%08x\n", nvfx
->fallback_swtnl
);
152 nvfx
->pipe
.flush(&nvfx
->pipe
, 0, NULL
);
153 nvfx
->dirty
|= (NVFX_NEW_VIEWPORT
|
156 nvfx
->render_mode
= SWTNL
;
159 if (nvfx
->draw_dirty
& NVFX_NEW_VERTPROG
)
160 draw_bind_vertex_shader(draw
, nvfx
->vertprog
->draw
);
162 if (nvfx
->draw_dirty
& NVFX_NEW_RAST
)
163 draw_set_rasterizer_state(draw
, &nvfx
->rasterizer
->pipe
);
165 if (nvfx
->draw_dirty
& NVFX_NEW_UCP
)
166 draw_set_clip_state(draw
, &nvfx
->clip
);
168 if (nvfx
->draw_dirty
& NVFX_NEW_VIEWPORT
)
169 draw_set_viewport_state(draw
, &nvfx
->viewport
);
171 if (nvfx
->draw_dirty
& NVFX_NEW_ARRAYS
) {
172 draw_set_vertex_buffers(draw
, nvfx
->vtxbuf_nr
, nvfx
->vtxbuf
);
173 draw_set_vertex_elements(draw
, nvfx
->vtxelt
->num_elements
, nvfx
->vtxelt
->pipe
);
177 nvfx_state_do_validate(nvfx
, nv30_swtnl_render_states
);
179 nvfx_state_do_validate(nvfx
, nv40_swtnl_render_states
);
181 if (nvfx
->fallback_swrast
) {
182 NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nvfx
->fallback_swrast
);
186 nvfx
->draw_dirty
= 0;