1
#include "nv40_context.h"
2
#include "nv40_state.h"
3
#include "draw/draw_context.h"
5
static struct nv40_state_entry *render_states[] = {
6
&nv40_state_framebuffer,
7
&nv40_state_rasterizer,
14
&nv40_state_blend_colour,
22
static struct nv40_state_entry *swtnl_states[] = {
23
&nv40_state_framebuffer,
24
&nv40_state_rasterizer,
31
&nv40_state_blend_colour,
40
nv40_state_do_validate(struct nv40_context *nv40,
41
struct nv40_state_entry **states)
44
struct nv40_state_entry *e = *states;
46
if (nv40->dirty & e->dirty.pipe) {
47
if (e->validate(nv40))
48
nv40->state.dirty |= (1ULL << e->dirty.hw);
57
nv40_state_emit(struct nv40_context *nv40)
59
struct nv40_state *state = &nv40->state;
60
struct nv40_screen *screen = nv40->screen;
61
struct nouveau_channel *chan = screen->base.channel;
62
struct nouveau_grobj *curie = screen->curie;
66
/* XXX: race conditions
68
if (nv40 != screen->cur_ctx) {
69
for (i = 0; i < NV40_STATE_MAX; i++) {
70
if (state->hw[i] && screen->state[i] != state->hw[i])
71
state->dirty |= (1ULL << i);
74
screen->cur_ctx = nv40;
77
for (i = 0, states = state->dirty; states; i++) {
78
if (!(states & (1ULL << i)))
80
so_ref (state->hw[i], &nv40->screen->state[i]);
82
so_emit(chan, nv40->screen->state[i]);
83
states &= ~(1ULL << i);
86
if (state->dirty & ((1ULL << NV40_STATE_FRAGPROG) |
87
(1ULL << NV40_STATE_FRAGTEX0))) {
88
BEGIN_RING(chan, curie, NV40TCL_TEX_CACHE_CTL, 1);
90
BEGIN_RING(chan, curie, NV40TCL_TEX_CACHE_CTL, 1);
98
nv40_state_flush_notify(struct nouveau_channel *chan)
100
struct nv40_context *nv40 = chan->user_private;
101
struct nv40_state *state = &nv40->state;
102
unsigned i, samplers;
104
so_emit_reloc_markers(chan, state->hw[NV40_STATE_FB]);
105
for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
106
if (!(samplers & (1 << i)))
108
so_emit_reloc_markers(chan,
109
state->hw[NV40_STATE_FRAGTEX0+i]);
110
samplers &= ~(1ULL << i);
112
so_emit_reloc_markers(chan, state->hw[NV40_STATE_FRAGPROG]);
113
if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW)
114
so_emit_reloc_markers(chan, state->hw[NV40_STATE_VTXBUF]);
118
nv40_state_validate(struct nv40_context *nv40)
120
boolean was_sw = nv40->fallback_swtnl ? TRUE : FALSE;
122
if (nv40->render_mode != HW) {
123
/* Don't even bother trying to go back to hw if none
124
* of the states that caused swtnl previously have changed.
126
if ((nv40->fallback_swtnl & nv40->dirty)
127
!= nv40->fallback_swtnl)
130
/* Attempt to go to hwtnl again */
131
nv40->pipe.flush(&nv40->pipe, 0, NULL);
132
nv40->dirty |= (NV40_NEW_VIEWPORT |
135
nv40->render_mode = HW;
138
nv40_state_do_validate(nv40, render_states);
139
if (nv40->fallback_swtnl || nv40->fallback_swrast)
143
NOUVEAU_ERR("swtnl->hw\n");
149
nv40_state_validate_swtnl(struct nv40_context *nv40)
151
struct draw_context *draw = nv40->draw;
153
/* Setup for swtnl */
154
if (nv40->render_mode == HW) {
155
NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl);
156
nv40->pipe.flush(&nv40->pipe, 0, NULL);
157
nv40->dirty |= (NV40_NEW_VIEWPORT |
160
nv40->render_mode = SWTNL;
163
if (nv40->draw_dirty & NV40_NEW_VERTPROG)
164
draw_bind_vertex_shader(draw, nv40->vertprog->draw);
166
if (nv40->draw_dirty & NV40_NEW_RAST)
167
draw_set_rasterizer_state(draw, &nv40->rasterizer->pipe, nv40->rasterizer);
169
if (nv40->draw_dirty & NV40_NEW_UCP)
170
draw_set_clip_state(draw, &nv40->clip);
172
if (nv40->draw_dirty & NV40_NEW_VIEWPORT)
173
draw_set_viewport_state(draw, &nv40->viewport);
175
if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
176
draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
177
draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);
180
nv40_state_do_validate(nv40, swtnl_states);
181
if (nv40->fallback_swrast) {
182
NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast);
186
nv40->draw_dirty = 0;