1 #include "draw/draw_context.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_winsys.h"
4 #include "pipe/p_util.h"
6 #include "nv40_context.h"
7 #include "nv40_screen.h"
9 #define NV4X_GRCLASS4097_CHIPSETS 0x00000baf
10 #define NV4X_GRCLASS4497_CHIPSETS 0x00005450
11 #define NV6X_GRCLASS4497_CHIPSETS 0x00000088
14 nv40_flush(struct pipe_context
*pipe
, unsigned flags
)
16 struct nv40_context
*nv40
= nv40_context(pipe
);
17 struct nouveau_winsys
*nvws
= nv40
->nvws
;
19 if (flags
& PIPE_FLUSH_TEXTURE_CACHE
) {
20 BEGIN_RING(curie
, 0x1fd8, 1);
22 BEGIN_RING(curie
, 0x1fd8, 1);
26 if (flags
& PIPE_FLUSH_WAIT
) {
27 nvws
->notifier_reset(nv40
->hw
->sync
, 0);
28 BEGIN_RING(curie
, 0x104, 1);
30 BEGIN_RING(curie
, 0x100, 1);
36 if (flags
& PIPE_FLUSH_WAIT
)
37 nvws
->notifier_wait(nv40
->hw
->sync
, 0, 0, 2000);
41 nv40_channel_takedown(struct nv40_channel_context
*cnv40
)
43 struct nouveau_winsys
*nvws
= cnv40
->nvws
;
45 nvws
->res_free(&cnv40
->vp_exec_heap
);
46 nvws
->res_free(&cnv40
->vp_data_heap
);
47 nvws
->res_free(&cnv40
->query_heap
);
48 nvws
->notifier_free(&cnv40
->query
);
49 nvws
->notifier_free(&cnv40
->sync
);
50 nvws
->grobj_free(&cnv40
->curie
);
54 static struct nv40_channel_context
*
55 nv40_channel_init(struct pipe_winsys
*ws
, struct nouveau_winsys
*nvws
,
58 struct nv40_channel_context
*cnv40
= NULL
;
59 struct nouveau_stateobj
*so
;
60 unsigned curie_class
= 0;
63 switch (chipset
& 0xf0) {
65 if (NV4X_GRCLASS4097_CHIPSETS
& (1 << (chipset
& 0x0f)))
66 curie_class
= NV40TCL
;
68 if (NV4X_GRCLASS4497_CHIPSETS
& (1 << (chipset
& 0x0f)))
69 curie_class
= NV44TCL
;
72 if (NV6X_GRCLASS4497_CHIPSETS
& (1 << (chipset
& 0x0f)))
73 curie_class
= NV44TCL
;
80 NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset
);
84 cnv40
= CALLOC(1, sizeof(struct nv40_channel_context
));
87 cnv40
->chipset
= chipset
;
90 /* Notifier for sync purposes */
91 ret
= nvws
->notifier_alloc(nvws
, 1, &cnv40
->sync
);
93 NOUVEAU_ERR("Error creating notifier object: %d\n", ret
);
94 nv40_channel_takedown(cnv40
);
99 ret
= nvws
->notifier_alloc(nvws
, 32, &cnv40
->query
);
101 NOUVEAU_ERR("Error initialising query objects: %d\n", ret
);
102 nv40_channel_takedown(cnv40
);
106 ret
= nvws
->res_init(&cnv40
->query_heap
, 0, 32);
108 NOUVEAU_ERR("Error initialising query object heap: %d\n", ret
);
109 nv40_channel_takedown(cnv40
);
113 /* Vtxprog resources */
114 if (nvws
->res_init(&cnv40
->vp_exec_heap
, 0, 512) ||
115 nvws
->res_init(&cnv40
->vp_data_heap
, 0, 256)) {
116 nv40_channel_takedown(cnv40
);
121 ret
= nvws
->grobj_alloc(nvws
, curie_class
, &cnv40
->curie
);
123 NOUVEAU_ERR("Error creating 3D object: %d\n", ret
);
127 /* Static curie initialisation */
129 so_method(so
, cnv40
->curie
, NV40TCL_DMA_NOTIFY
, 1);
130 so_data (so
, cnv40
->sync
->handle
);
131 so_method(so
, cnv40
->curie
, NV40TCL_DMA_TEXTURE0
, 2);
132 so_data (so
, nvws
->channel
->vram
->handle
);
133 so_data (so
, nvws
->channel
->gart
->handle
);
134 so_method(so
, cnv40
->curie
, NV40TCL_DMA_COLOR1
, 1);
135 so_data (so
, nvws
->channel
->vram
->handle
);
136 so_method(so
, cnv40
->curie
, NV40TCL_DMA_COLOR0
, 2);
137 so_data (so
, nvws
->channel
->vram
->handle
);
138 so_data (so
, nvws
->channel
->vram
->handle
);
139 so_method(so
, cnv40
->curie
, NV40TCL_DMA_VTXBUF0
, 2);
140 so_data (so
, nvws
->channel
->vram
->handle
);
141 so_data (so
, nvws
->channel
->gart
->handle
);
142 so_method(so
, cnv40
->curie
, NV40TCL_DMA_FENCE
, 2);
144 so_data (so
, cnv40
->query
->handle
);
145 so_method(so
, cnv40
->curie
, NV40TCL_DMA_UNK01AC
, 2);
146 so_data (so
, nvws
->channel
->vram
->handle
);
147 so_data (so
, nvws
->channel
->vram
->handle
);
148 so_method(so
, cnv40
->curie
, NV40TCL_DMA_COLOR2
, 2);
149 so_data (so
, nvws
->channel
->vram
->handle
);
150 so_data (so
, nvws
->channel
->vram
->handle
);
152 so_method(so
, cnv40
->curie
, 0x1ea4, 3);
153 so_data (so
, 0x00000010);
154 so_data (so
, 0x01000100);
155 so_data (so
, 0xff800006);
157 /* vtxprog output routing */
158 so_method(so
, cnv40
->curie
, 0x1fc4, 1);
159 so_data (so
, 0x06144321);
160 so_method(so
, cnv40
->curie
, 0x1fc8, 2);
161 so_data (so
, 0xedcba987);
162 so_data (so
, 0x00000021);
163 so_method(so
, cnv40
->curie
, 0x1fd0, 1);
164 so_data (so
, 0x00171615);
165 so_method(so
, cnv40
->curie
, 0x1fd4, 1);
166 so_data (so
, 0x001b1a19);
168 so_method(so
, cnv40
->curie
, 0x1ef8, 1);
169 so_data (so
, 0x0020ffff);
170 so_method(so
, cnv40
->curie
, 0x1d64, 1);
171 so_data (so
, 0x00d30000);
172 so_method(so
, cnv40
->curie
, 0x1e94, 1);
173 so_data (so
, 0x00000001);
177 nvws
->push_flush(nvws
->channel
, 0);
183 nv40_destroy(struct pipe_context
*pipe
)
185 struct nv40_context
*nv40
= nv40_context(pipe
);
188 draw_destroy(nv40
->draw
);
191 if (--nv40
->hw
->refcount
== 0)
192 nv40_channel_takedown(nv40
->hw
);
198 struct pipe_context
*
199 nv40_create(struct pipe_screen
*pscreen
, struct nouveau_winsys
*nvws
)
201 struct pipe_winsys
*ws
= pscreen
->winsys
;
202 struct nv40_context
*nv40
;
203 unsigned chipset
= nv40_screen(pscreen
)->chipset
;
205 nv40
= CALLOC(1, sizeof(struct nv40_context
));
209 nv40
->hw
= nv40_channel_init(ws
, nvws
, chipset
);
211 nv40_destroy(&nv40
->pipe
);
215 nv40
->chipset
= chipset
;
218 nv40
->pipe
.winsys
= ws
;
219 nv40
->pipe
.screen
= pscreen
;
220 nv40
->pipe
.destroy
= nv40_destroy
;
221 nv40
->pipe
.draw_arrays
= nv40_draw_arrays
;
222 nv40
->pipe
.draw_elements
= nv40_draw_elements
;
223 nv40
->pipe
.clear
= nv40_clear
;
224 nv40
->pipe
.flush
= nv40_flush
;
226 nv40_init_query_functions(nv40
);
227 nv40_init_surface_functions(nv40
);
228 nv40_init_state_functions(nv40
);
229 nv40_init_miptree_functions(nv40
);
231 nv40
->draw
= draw_create();
233 draw_set_rasterize_stage(nv40
->draw
, nv40_draw_render_stage(nv40
));