1 #include "pipe/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"
10 nv40_is_format_supported(struct pipe_context
*pipe
, enum pipe_format format
,
16 case PIPE_FORMAT_A8R8G8B8_UNORM
:
17 case PIPE_FORMAT_R5G6B5_UNORM
:
18 case PIPE_FORMAT_Z24S8_UNORM
:
19 case PIPE_FORMAT_Z16_UNORM
:
27 case PIPE_FORMAT_A8R8G8B8_UNORM
:
28 case PIPE_FORMAT_A1R5G5B5_UNORM
:
29 case PIPE_FORMAT_A4R4G4B4_UNORM
:
30 case PIPE_FORMAT_R5G6B5_UNORM
:
31 case PIPE_FORMAT_U_L8
:
32 case PIPE_FORMAT_U_A8
:
33 case PIPE_FORMAT_U_I8
:
34 case PIPE_FORMAT_U_A8_L8
:
35 case PIPE_FORMAT_Z16_UNORM
:
36 case PIPE_FORMAT_Z24S8_UNORM
:
50 nv40_get_name(struct pipe_context
*pipe
)
52 struct nv40_context
*nv40
= (struct nv40_context
*)pipe
;
53 static char buffer
[128];
55 snprintf(buffer
, sizeof(buffer
), "NV%02X", nv40
->chipset
);
60 nv40_get_vendor(struct pipe_context
*pipe
)
66 nv40_get_param(struct pipe_context
*pipe
, int param
)
69 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS
:
71 case PIPE_CAP_NPOT_TEXTURES
:
73 case PIPE_CAP_TWO_SIDED_STENCIL
:
79 case PIPE_CAP_ANISOTROPIC_FILTER
:
81 case PIPE_CAP_POINT_SPRITE
:
83 case PIPE_CAP_MAX_RENDER_TARGETS
:
85 case PIPE_CAP_OCCLUSION_QUERY
:
87 case PIPE_CAP_TEXTURE_SHADOW_MAP
:
89 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS
:
91 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS
:
93 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS
:
96 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param
);
102 nv40_get_paramf(struct pipe_context
*pipe
, int param
)
105 case PIPE_CAP_MAX_LINE_WIDTH
:
106 case PIPE_CAP_MAX_LINE_WIDTH_AA
:
108 case PIPE_CAP_MAX_POINT_WIDTH
:
109 case PIPE_CAP_MAX_POINT_WIDTH_AA
:
111 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY
:
113 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS
:
116 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param
);
122 nv40_flush(struct pipe_context
*pipe
, unsigned flags
)
124 struct nv40_context
*nv40
= (struct nv40_context
*)pipe
;
125 struct nouveau_winsys
*nvws
= nv40
->nvws
;
127 if (flags
& PIPE_FLUSH_TEXTURE_CACHE
) {
128 BEGIN_RING(curie
, 0x1fd8, 1);
130 BEGIN_RING(curie
, 0x1fd8, 1);
134 if (flags
& PIPE_FLUSH_WAIT
) {
135 nvws
->notifier_reset(nv40
->sync
, 0);
136 BEGIN_RING(curie
, 0x104, 1);
138 BEGIN_RING(curie
, 0x100, 1);
144 if (flags
& PIPE_FLUSH_WAIT
)
145 nvws
->notifier_wait(nv40
->sync
, 0, 0, 2000);
149 nv40_destroy(struct pipe_context
*pipe
)
151 struct nv40_context
*nv40
= (struct nv40_context
*)pipe
;
153 draw_destroy(nv40
->draw
);
158 nv40_init_hwctx(struct nv40_context
*nv40
, int curie_class
)
160 struct nouveau_winsys
*nvws
= nv40
->nvws
;
163 if ((ret
= nvws
->notifier_alloc(nvws
, nv40
->num_query_objects
,
165 NOUVEAU_ERR("Error creating query notifier objects: %d\n", ret
);
169 if ((ret
= nvws
->grobj_alloc(nvws
, curie_class
,
171 NOUVEAU_ERR("Error creating 3D object: %d\n", ret
);
175 BEGIN_RING(curie
, NV40TCL_DMA_NOTIFY
, 1);
176 OUT_RING (nv40
->sync
->handle
);
177 BEGIN_RING(curie
, NV40TCL_DMA_TEXTURE0
, 2);
178 OUT_RING (nvws
->channel
->vram
->handle
);
179 OUT_RING (nvws
->channel
->gart
->handle
);
180 BEGIN_RING(curie
, NV40TCL_DMA_COLOR1
, 1);
181 OUT_RING (nvws
->channel
->vram
->handle
);
182 BEGIN_RING(curie
, NV40TCL_DMA_COLOR0
, 2);
183 OUT_RING (nvws
->channel
->vram
->handle
);
184 OUT_RING (nvws
->channel
->vram
->handle
);
185 BEGIN_RING(curie
, NV40TCL_DMA_VTXBUF0
, 2);
186 OUT_RING (nvws
->channel
->vram
->handle
);
187 OUT_RING (nvws
->channel
->gart
->handle
);
188 BEGIN_RING(curie
, NV40TCL_DMA_FENCE
, 2);
190 OUT_RING (nv40
->query
->handle
);
191 BEGIN_RING(curie
, NV40TCL_DMA_UNK01AC
, 2);
192 OUT_RING (nvws
->channel
->vram
->handle
);
193 OUT_RING (nvws
->channel
->vram
->handle
);
194 BEGIN_RING(curie
, NV40TCL_DMA_COLOR2
, 2);
195 OUT_RING (nvws
->channel
->vram
->handle
);
196 OUT_RING (nvws
->channel
->vram
->handle
);
198 BEGIN_RING(curie
, 0x1ea4, 3);
199 OUT_RING (0x00000010);
200 OUT_RING (0x01000100);
201 OUT_RING (0xff800006);
203 /* vtxprog output routing */
204 BEGIN_RING(curie
, 0x1fc4, 1);
205 OUT_RING (0x06144321);
206 BEGIN_RING(curie
, 0x1fc8, 2);
207 OUT_RING (0xedcba987);
208 OUT_RING (0x00000021);
209 BEGIN_RING(curie
, 0x1fd0, 1);
210 OUT_RING (0x00171615);
211 BEGIN_RING(curie
, 0x1fd4, 1);
212 OUT_RING (0x001b1a19);
214 BEGIN_RING(curie
, 0x1ef8, 1);
215 OUT_RING (0x0020ffff);
216 BEGIN_RING(curie
, 0x1d64, 1);
217 OUT_RING (0x00d30000);
218 BEGIN_RING(curie
, 0x1e94, 1);
219 OUT_RING (0x00000001);
225 #define GRCLASS4097_CHIPSETS 0x00000baf
226 #define GRCLASS4497_CHIPSETS 0x00005450
227 struct pipe_context
*
228 nv40_create(struct pipe_winsys
*pipe_winsys
, struct nouveau_winsys
*nvws
,
231 struct nv40_context
*nv40
;
232 int curie_class
, ret
;
234 if ((chipset
& 0xf0) != 0x40) {
235 NOUVEAU_ERR("Not a NV4X chipset\n");
239 if (GRCLASS4097_CHIPSETS
& (1 << (chipset
& 0x0f))) {
240 curie_class
= 0x4097;
242 if (GRCLASS4497_CHIPSETS
& (1 << (chipset
& 0x0f))) {
243 curie_class
= 0x4497;
245 NOUVEAU_ERR("Unknown NV4X chipset: NV%02x\n", chipset
);
249 nv40
= CALLOC_STRUCT(nv40_context
);
252 nv40
->chipset
= chipset
;
255 if ((ret
= nvws
->notifier_alloc(nvws
, 1, &nv40
->sync
))) {
256 NOUVEAU_ERR("Error creating notifier object: %d\n", ret
);
261 nv40
->num_query_objects
= 32;
262 nv40
->query_objects
= calloc(nv40
->num_query_objects
,
263 sizeof(struct pipe_query_object
*));
264 if (!nv40
->query_objects
) {
269 if (nvws
->res_init(&nv40
->vertprog
.exec_heap
, 0, 512) ||
270 nvws
->res_init(&nv40
->vertprog
.data_heap
, 0, 256)) {
271 nvws
->res_free(&nv40
->vertprog
.exec_heap
);
272 nvws
->res_free(&nv40
->vertprog
.data_heap
);
277 if (!nv40_init_hwctx(nv40
, curie_class
)) {
282 nv40
->pipe
.winsys
= pipe_winsys
;
284 nv40
->pipe
.destroy
= nv40_destroy
;
285 nv40
->pipe
.is_format_supported
= nv40_is_format_supported
;
286 nv40
->pipe
.get_name
= nv40_get_name
;
287 nv40
->pipe
.get_vendor
= nv40_get_vendor
;
288 nv40
->pipe
.get_param
= nv40_get_param
;
289 nv40
->pipe
.get_paramf
= nv40_get_paramf
;
291 nv40
->pipe
.draw_arrays
= nv40_draw_arrays
;
292 nv40
->pipe
.draw_elements
= nv40_draw_elements
;
293 nv40
->pipe
.clear
= nv40_clear
;
295 nv40
->pipe
.flush
= nv40_flush
;
297 nv40_init_query_functions(nv40
);
298 nv40_init_surface_functions(nv40
);
299 nv40_init_state_functions(nv40
);
300 nv40_init_miptree_functions(nv40
);
302 nv40
->draw
= draw_create();
304 draw_set_rasterize_stage(nv40
->draw
, nv40_draw_render_stage(nv40
));