Merge remote branch 'upstream/gallium-0.2' into nouveau-gallium-0.2
[mesa.git] / src / gallium / drivers / nv30 / nv30_screen.c
1 #include "pipe/p_screen.h"
2
3 #include "nv30_context.h"
4 #include "nv30_screen.h"
5
6 #define NV30TCL_CHIPSET_3X_MASK 0x00000003
7 #define NV34TCL_CHIPSET_3X_MASK 0x00000010
8 #define NV35TCL_CHIPSET_3X_MASK 0x000001e0
9
10 static const char *
11 nv30_screen_get_name(struct pipe_screen *pscreen)
12 {
13 struct nv30_screen *screen = nv30_screen(pscreen);
14 struct nouveau_device *dev = screen->nvws->channel->device;
15 static char buffer[128];
16
17 snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
18 return buffer;
19 }
20
21 static const char *
22 nv30_screen_get_vendor(struct pipe_screen *pscreen)
23 {
24 return "nouveau";
25 }
26
27 static int
28 nv30_screen_get_param(struct pipe_screen *pscreen, int param)
29 {
30 switch (param) {
31 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
32 return 16;
33 case PIPE_CAP_NPOT_TEXTURES:
34 return 0;
35 case PIPE_CAP_TWO_SIDED_STENCIL:
36 return 1;
37 case PIPE_CAP_GLSL:
38 return 0;
39 case PIPE_CAP_S3TC:
40 return 0;
41 case PIPE_CAP_ANISOTROPIC_FILTER:
42 return 1;
43 case PIPE_CAP_POINT_SPRITE:
44 return 1;
45 case PIPE_CAP_MAX_RENDER_TARGETS:
46 return 2;
47 case PIPE_CAP_OCCLUSION_QUERY:
48 return 1;
49 case PIPE_CAP_TEXTURE_SHADOW_MAP:
50 return 1;
51 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
52 return 13;
53 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
54 return 10;
55 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
56 return 13;
57 case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
58 return 0;
59 case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
60 return 1;
61 case NOUVEAU_CAP_HW_VTXBUF:
62 case NOUVEAU_CAP_HW_IDXBUF:
63 return 1;
64 default:
65 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
66 return 0;
67 }
68 }
69
70 static float
71 nv30_screen_get_paramf(struct pipe_screen *pscreen, int param)
72 {
73 switch (param) {
74 case PIPE_CAP_MAX_LINE_WIDTH:
75 case PIPE_CAP_MAX_LINE_WIDTH_AA:
76 return 10.0;
77 case PIPE_CAP_MAX_POINT_WIDTH:
78 case PIPE_CAP_MAX_POINT_WIDTH_AA:
79 return 64.0;
80 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
81 return 8.0;
82 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
83 return 4.0;
84 default:
85 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
86 return 0.0;
87 }
88 }
89
90 static boolean
91 nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
92 enum pipe_format format,
93 enum pipe_texture_target target,
94 unsigned tex_usage, unsigned geom_flags)
95 {
96 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
97 switch (format) {
98 case PIPE_FORMAT_A8R8G8B8_UNORM:
99 case PIPE_FORMAT_R5G6B5_UNORM:
100 case PIPE_FORMAT_Z24S8_UNORM:
101 case PIPE_FORMAT_Z16_UNORM:
102 return TRUE;
103 default:
104 break;
105 }
106 } else {
107 switch (format) {
108 case PIPE_FORMAT_A8R8G8B8_UNORM:
109 case PIPE_FORMAT_A1R5G5B5_UNORM:
110 case PIPE_FORMAT_A4R4G4B4_UNORM:
111 case PIPE_FORMAT_R5G6B5_UNORM:
112 case PIPE_FORMAT_L8_UNORM:
113 case PIPE_FORMAT_A8_UNORM:
114 case PIPE_FORMAT_I8_UNORM:
115 case PIPE_FORMAT_A8L8_UNORM:
116 case PIPE_FORMAT_Z16_UNORM:
117 case PIPE_FORMAT_Z24S8_UNORM:
118 return TRUE;
119 default:
120 break;
121 }
122 }
123
124 return FALSE;
125 }
126
127 static void *
128 nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
129 unsigned flags )
130 {
131 struct pipe_winsys *ws = screen->winsys;
132 void *map;
133
134 map = ws->buffer_map(ws, surface->buffer, flags);
135 if (!map)
136 return NULL;
137
138 return map + surface->offset;
139 }
140
141 static void
142 nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
143 {
144 struct pipe_winsys *ws = screen->winsys;
145
146 ws->buffer_unmap(ws, surface->buffer);
147 }
148
149 static void
150 nv30_screen_destroy(struct pipe_screen *pscreen)
151 {
152 struct nv30_screen *screen = nv30_screen(pscreen);
153 struct nouveau_winsys *nvws = screen->nvws;
154
155 nvws->res_free(&screen->vp_exec_heap);
156 nvws->res_free(&screen->vp_data_heap);
157 nvws->res_free(&screen->query_heap);
158 nvws->notifier_free(&screen->query);
159 nvws->notifier_free(&screen->sync);
160 nvws->grobj_free(&screen->rankine);
161
162 FREE(pscreen);
163 }
164
165 struct pipe_screen *
166 nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
167 {
168 struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen);
169 struct nouveau_stateobj *so;
170 unsigned rankine_class = 0;
171 unsigned chipset = nvws->channel->device->chipset;
172 int ret, i;
173
174 if (!screen)
175 return NULL;
176 screen->nvws = nvws;
177
178 /* 3D object */
179 switch (chipset & 0xf0) {
180 case 0x30:
181 if (NV30TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
182 rankine_class = 0x0397;
183 else
184 if (NV34TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
185 rankine_class = 0x0697;
186 else
187 if (NV35TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
188 rankine_class = 0x0497;
189 break;
190 default:
191 break;
192 }
193
194 if (!rankine_class) {
195 NOUVEAU_ERR("Unknown nv3x chipset: nv%02x\n", chipset);
196 return NULL;
197 }
198
199 ret = nvws->grobj_alloc(nvws, rankine_class, &screen->rankine);
200 if (ret) {
201 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
202 return FALSE;
203 }
204
205 /* Notifier for sync purposes */
206 ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
207 if (ret) {
208 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
209 nv30_screen_destroy(&screen->pipe);
210 return NULL;
211 }
212
213 /* Query objects */
214 ret = nvws->notifier_alloc(nvws, 32, &screen->query);
215 if (ret) {
216 NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
217 nv30_screen_destroy(&screen->pipe);
218 return NULL;
219 }
220
221 ret = nvws->res_init(&screen->query_heap, 0, 32);
222 if (ret) {
223 NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
224 nv30_screen_destroy(&screen->pipe);
225 return NULL;
226 }
227
228 /* Vtxprog resources */
229 if (nvws->res_init(&screen->vp_exec_heap, 0, 256) ||
230 nvws->res_init(&screen->vp_data_heap, 0, 256)) {
231 nv30_screen_destroy(&screen->pipe);
232 return NULL;
233 }
234
235 /* Static rankine initialisation */
236 so = so_new(128, 0);
237 so_method(so, screen->rankine, NV34TCL_DMA_NOTIFY, 1);
238 so_data (so, screen->sync->handle);
239 so_method(so, screen->rankine, NV34TCL_DMA_TEXTURE0, 2);
240 so_data (so, nvws->channel->vram->handle);
241 so_data (so, nvws->channel->gart->handle);
242 so_method(so, screen->rankine, NV34TCL_DMA_COLOR1, 1);
243 so_data (so, nvws->channel->vram->handle);
244 so_method(so, screen->rankine, NV34TCL_DMA_COLOR0, 2);
245 so_data (so, nvws->channel->vram->handle);
246 so_data (so, nvws->channel->vram->handle);
247 so_method(so, screen->rankine, NV34TCL_DMA_VTXBUF0, 2);
248 so_data (so, nvws->channel->vram->handle);
249 so_data (so, nvws->channel->gart->handle);
250 /* so_method(so, screen->rankine, NV34TCL_DMA_FENCE, 2);
251 so_data (so, 0);
252 so_data (so, screen->query->handle);*/
253 so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY7, 1);
254 so_data (so, nvws->channel->vram->handle);
255 so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY8, 1);
256 so_data (so, nvws->channel->vram->handle);
257
258 for (i=1; i<8; i++) {
259 so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1);
260 so_data (so, 0);
261 so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_VERT(i), 1);
262 so_data (so, 0);
263 }
264
265 so_method(so, screen->rankine, 0x220, 1);
266 so_data (so, 1);
267
268 so_method(so, screen->rankine, 0x03b0, 1);
269 so_data (so, 0x00100000);
270 so_method(so, screen->rankine, 0x1454, 1);
271 so_data (so, 0);
272 so_method(so, screen->rankine, 0x1d80, 1);
273 so_data (so, 3);
274 so_method(so, screen->rankine, 0x1450, 1);
275 so_data (so, 0x00030004);
276
277 /* NEW */
278 so_method(so, screen->rankine, 0x1e98, 1);
279 so_data (so, 0);
280 so_method(so, screen->rankine, 0x17e0, 3);
281 so_data (so, fui(0.0));
282 so_data (so, fui(0.0));
283 so_data (so, fui(1.0));
284 so_method(so, screen->rankine, 0x1f80, 16);
285 for (i=0; i<16; i++) {
286 so_data (so, (i==8) ? 0x0000ffff : 0);
287 }
288
289 so_method(so, screen->rankine, 0x120, 3);
290 so_data (so, 0);
291 so_data (so, 1);
292 so_data (so, 2);
293
294 so_method(so, screen->rankine, 0x1d88, 1);
295 so_data (so, 0x00001200);
296
297 so_method(so, screen->rankine, NV34TCL_RC_ENABLE, 1);
298 so_data (so, 0);
299
300 so_method(so, screen->rankine, NV34TCL_DEPTH_RANGE_NEAR, 2);
301 so_data (so, fui(0.0));
302 so_data (so, fui(1.0));
303
304 so_method(so, screen->rankine, NV34TCL_MULTISAMPLE_CONTROL, 1);
305 so_data (so, 0xffff0000);
306
307 /* enables use of vp rather than fixed-function somehow */
308 so_method(so, screen->rankine, 0x1e94, 1);
309 so_data (so, 0x13);
310
311 so_emit(nvws, so);
312 so_ref(NULL, &so);
313 nvws->push_flush(nvws, 0, NULL);
314
315 screen->pipe.winsys = ws;
316 screen->pipe.destroy = nv30_screen_destroy;
317
318 screen->pipe.get_name = nv30_screen_get_name;
319 screen->pipe.get_vendor = nv30_screen_get_vendor;
320 screen->pipe.get_param = nv30_screen_get_param;
321 screen->pipe.get_paramf = nv30_screen_get_paramf;
322
323 screen->pipe.is_format_supported = nv30_screen_surface_format_supported;
324
325 screen->pipe.surface_map = nv30_surface_map;
326 screen->pipe.surface_unmap = nv30_surface_unmap;
327
328 nv30_screen_init_miptree_functions(&screen->pipe);
329
330 return &screen->pipe;
331 }
332