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