1 #include "nvfx_context.h"
2 #include "nvfx_state.h"
3 #include "draw/draw_context.h"
6 nvfx_state_validate_common(struct nvfx_context
*nvfx
)
8 struct nouveau_channel
* chan
= nvfx
->screen
->base
.channel
;
9 unsigned dirty
= nvfx
->dirty
;
11 if(nvfx
!= nvfx
->screen
->cur_ctx
)
14 if(nvfx
->render_mode
== HW
)
16 if(dirty
& (NVFX_NEW_VERTPROG
| NVFX_NEW_VERTCONST
| NVFX_NEW_UCP
))
18 if(!nvfx_vertprog_validate(nvfx
))
22 if(dirty
& (NVFX_NEW_ARRAYS
))
24 if(!nvfx_vbo_validate(nvfx
))
30 /* TODO: this looks a bit misdesigned */
31 if(dirty
& (NVFX_NEW_VERTPROG
| NVFX_NEW_UCP
))
32 nvfx_vertprog_validate(nvfx
);
34 if(dirty
& (NVFX_NEW_ARRAYS
| NVFX_NEW_FRAGPROG
))
35 nvfx_vtxfmt_validate(nvfx
);
38 if(dirty
& NVFX_NEW_FB
)
39 nvfx_state_framebuffer_validate(nvfx
);
41 if(dirty
& NVFX_NEW_RAST
)
42 sb_emit(chan
, nvfx
->rasterizer
->sb
, nvfx
->rasterizer
->sb_len
);
44 if(dirty
& NVFX_NEW_SCISSOR
)
45 nvfx_state_scissor_validate(nvfx
);
47 if(dirty
& NVFX_NEW_STIPPLE
)
48 nvfx_state_stipple_validate(nvfx
);
50 if(dirty
& (NVFX_NEW_FRAGPROG
| NVFX_NEW_FRAGCONST
))
51 nvfx_fragprog_validate(nvfx
);
53 if(dirty
& NVFX_NEW_SAMPLER
)
54 nvfx_fragtex_validate(nvfx
);
56 if(dirty
& NVFX_NEW_BLEND
)
57 sb_emit(chan
, nvfx
->blend
->sb
, nvfx
->blend
->sb_len
);
59 if(dirty
& NVFX_NEW_BCOL
)
60 nvfx_state_blend_colour_validate(nvfx
);
62 if(dirty
& NVFX_NEW_ZSA
)
63 sb_emit(chan
, nvfx
->zsa
->sb
, nvfx
->zsa
->sb_len
);
65 if(dirty
& NVFX_NEW_SR
)
66 nvfx_state_sr_validate(nvfx
);
68 /* Having this depend on FB looks wrong, but it seems
69 necessary to make this work on nv3x
70 TODO: find the right fix
72 if(dirty
& (NVFX_NEW_VIEWPORT
| NVFX_NEW_FB
))
73 nvfx_state_viewport_validate(nvfx
);
75 /* TODO: could nv30 need this or something similar too? */
76 if((dirty
& (NVFX_NEW_FRAGPROG
| NVFX_NEW_SAMPLER
)) && nvfx
->is_nv4x
) {
78 OUT_RING(chan
, RING_3D(NV40TCL_TEX_CACHE_CTL
, 1));
80 OUT_RING(chan
, RING_3D(NV40TCL_TEX_CACHE_CTL
, 1));
88 nvfx_state_emit(struct nvfx_context
*nvfx
)
90 struct nouveau_channel
* chan
= nvfx
->screen
->base
.channel
;
91 /* we need to ensure there is enough space to output relocations in one go */
92 unsigned max_relocs
= 0
93 + 16 /* vertex buffers, incl. dma flag */
94 + 2 /* index buffer plus format+dma flag */
95 + 2 * 5 /* 4 cbufs + zsbuf, plus dma objects */
96 + 2 * 16 /* fragment textures plus format+dma flag */
97 + 2 * 4 /* vertex textures plus format+dma flag */
98 + 1 /* fragprog incl dma flag */
100 MARK_RING(chan
, max_relocs
* 2, max_relocs
* 2);
101 nvfx_state_relocate(nvfx
);
105 nvfx_state_relocate(struct nvfx_context
*nvfx
)
107 nvfx_framebuffer_relocate(nvfx
);
108 nvfx_fragtex_relocate(nvfx
);
109 nvfx_fragprog_relocate(nvfx
);
110 if (nvfx
->render_mode
== HW
)
111 nvfx_vbo_relocate(nvfx
);
115 nvfx_state_validate(struct nvfx_context
*nvfx
)
117 boolean was_sw
= nvfx
->fallback_swtnl
? TRUE
: FALSE
;
119 if (nvfx
->render_mode
!= HW
) {
120 /* Don't even bother trying to go back to hw if none
121 * of the states that caused swtnl previously have changed.
123 if ((nvfx
->fallback_swtnl
& nvfx
->dirty
)
124 != nvfx
->fallback_swtnl
)
127 /* Attempt to go to hwtnl again */
128 nvfx
->dirty
|= (NVFX_NEW_VIEWPORT
|
131 nvfx
->render_mode
= HW
;
134 if(!nvfx_state_validate_common(nvfx
))
138 NOUVEAU_ERR("swtnl->hw\n");
144 nvfx_state_validate_swtnl(struct nvfx_context
*nvfx
)
146 struct draw_context
*draw
= nvfx
->draw
;
148 /* Setup for swtnl */
149 if (nvfx
->render_mode
== HW
) {
150 NOUVEAU_ERR("hw->swtnl 0x%08x\n", nvfx
->fallback_swtnl
);
151 nvfx
->pipe
.flush(&nvfx
->pipe
, 0, NULL
);
152 nvfx
->dirty
|= (NVFX_NEW_VIEWPORT
|
155 nvfx
->render_mode
= SWTNL
;
158 if (nvfx
->draw_dirty
& NVFX_NEW_VERTPROG
)
159 draw_bind_vertex_shader(draw
, nvfx
->vertprog
->draw
);
161 if (nvfx
->draw_dirty
& NVFX_NEW_RAST
)
162 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
);
176 nvfx_state_validate_common(nvfx
);
178 nvfx
->draw_dirty
= 0;