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
,
15 &nv40_state_blend_colour
,
22 static struct nv40_state_entry
*swtnl_states
[] = {
23 &nv40_state_framebuffer
,
24 &nv40_state_rasterizer
,
32 &nv40_state_blend_colour
,
40 nv40_state_do_validate(struct nv40_context
*nv40
,
41 struct nv40_state_entry
**states
)
43 const struct pipe_framebuffer_state
*fb
= &nv40
->framebuffer
;
46 for (i
= 0; i
< fb
->num_cbufs
; i
++)
47 fb
->cbufs
[i
]->status
= PIPE_SURFACE_STATUS_DEFINED
;
49 fb
->zsbuf
->status
= PIPE_SURFACE_STATUS_DEFINED
;
52 struct nv40_state_entry
*e
= *states
;
54 if (nv40
->dirty
& e
->dirty
.pipe
) {
55 if (e
->validate(nv40
))
56 nv40
->state
.dirty
|= (1ULL << e
->dirty
.hw
);
65 nv40_state_emit(struct nv40_context
*nv40
)
67 struct nv40_state
*state
= &nv40
->state
;
68 struct nv40_screen
*screen
= nv40
->screen
;
72 if (nv40
->pctx_id
!= screen
->cur_pctx
) {
73 for (i
= 0; i
< NV40_STATE_MAX
; i
++) {
74 if (state
->hw
[i
] && screen
->state
[i
] != state
->hw
[i
])
75 state
->dirty
|= (1ULL << i
);
78 screen
->cur_pctx
= nv40
->pctx_id
;
81 for (i
= 0, states
= state
->dirty
; states
; i
++) {
82 if (!(states
& (1ULL << i
)))
84 so_ref (state
->hw
[i
], &nv40
->screen
->state
[i
]);
85 so_emit(nv40
->nvws
, nv40
->screen
->state
[i
]);
86 states
&= ~(1ULL << i
);
89 if (state
->dirty
& ((1ULL << NV40_STATE_FRAGPROG
) |
90 (1ULL << NV40_STATE_FRAGTEX0
))) {
91 BEGIN_RING(curie
, NV40TCL_TEX_CACHE_CTL
, 1);
93 BEGIN_RING(curie
, NV40TCL_TEX_CACHE_CTL
, 1);
99 so_emit_reloc_markers(nv40
->nvws
, state
->hw
[NV40_STATE_FB
]);
100 for (i
= 0, samplers
= state
->fp_samplers
; i
< 16 && samplers
; i
++) {
101 if (!(samplers
& (1 << i
)))
103 so_emit_reloc_markers(nv40
->nvws
,
104 state
->hw
[NV40_STATE_FRAGTEX0
+i
]);
105 samplers
&= ~(1ULL << i
);
107 so_emit_reloc_markers(nv40
->nvws
, state
->hw
[NV40_STATE_FRAGPROG
]);
108 if (state
->hw
[NV40_STATE_VTXBUF
] && nv40
->render_mode
== HW
)
109 so_emit_reloc_markers(nv40
->nvws
, state
->hw
[NV40_STATE_VTXBUF
]);
113 nv40_state_validate(struct nv40_context
*nv40
)
115 boolean was_sw
= nv40
->fallback_swtnl
? TRUE
: FALSE
;
117 if (nv40
->render_mode
!= HW
) {
118 /* Don't even bother trying to go back to hw if none
119 * of the states that caused swtnl previously have changed.
121 if ((nv40
->fallback_swtnl
& nv40
->dirty
)
122 != nv40
->fallback_swtnl
)
125 /* Attempt to go to hwtnl again */
126 nv40
->pipe
.flush(&nv40
->pipe
, 0);
127 nv40
->dirty
|= (NV40_NEW_VIEWPORT
|
131 nv40
->render_mode
= HW
;
134 nv40_state_do_validate(nv40
, render_states
);
135 if (nv40
->fallback_swtnl
|| nv40
->fallback_swrast
)
139 NOUVEAU_ERR("swtnl->hw\n");
145 nv40_state_validate_swtnl(struct nv40_context
*nv40
)
147 /* Setup for swtnl */
148 if (nv40
->render_mode
== HW
) {
149 NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40
->fallback_swtnl
);
150 nv40
->pipe
.flush(&nv40
->pipe
, 0);
151 nv40
->dirty
|= (NV40_NEW_VIEWPORT
|
155 nv40
->render_mode
= SWTNL
;
158 nv40_state_do_validate(nv40
, swtnl_states
);
159 if (nv40
->fallback_swrast
) {
160 NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40
->fallback_swrast
);