Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[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 static char buffer[128];
16
17 snprintf(buffer, sizeof(buffer), "NV%02X", screen->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 NOUVEAU_CAP_HW_VTXBUF:
58 case NOUVEAU_CAP_HW_IDXBUF:
59 return 0;
60 default:
61 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
62 return 0;
63 }
64 }
65
66 static float
67 nv30_screen_get_paramf(struct pipe_screen *pscreen, int param)
68 {
69 switch (param) {
70 case PIPE_CAP_MAX_LINE_WIDTH:
71 case PIPE_CAP_MAX_LINE_WIDTH_AA:
72 return 10.0;
73 case PIPE_CAP_MAX_POINT_WIDTH:
74 case PIPE_CAP_MAX_POINT_WIDTH_AA:
75 return 64.0;
76 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
77 return 16.0;
78 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
79 return 4.0;
80 case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
81 return 0.0;
82 default:
83 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
84 return 0.0;
85 }
86 }
87
88 static boolean
89 nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
90 enum pipe_format format, uint type)
91 {
92 switch (type) {
93 case PIPE_SURFACE:
94 switch (format) {
95 case PIPE_FORMAT_A8R8G8B8_UNORM:
96 case PIPE_FORMAT_R5G6B5_UNORM:
97 case PIPE_FORMAT_Z24S8_UNORM:
98 case PIPE_FORMAT_Z16_UNORM:
99 return TRUE;
100 default:
101 break;
102 }
103 break;
104 case PIPE_TEXTURE:
105 switch (format) {
106 case PIPE_FORMAT_A8R8G8B8_UNORM:
107 case PIPE_FORMAT_A1R5G5B5_UNORM:
108 case PIPE_FORMAT_A4R4G4B4_UNORM:
109 case PIPE_FORMAT_R5G6B5_UNORM:
110 case PIPE_FORMAT_U_L8:
111 case PIPE_FORMAT_U_A8:
112 case PIPE_FORMAT_U_I8:
113 case PIPE_FORMAT_U_A8_L8:
114 case PIPE_FORMAT_Z16_UNORM:
115 case PIPE_FORMAT_Z24S8_UNORM:
116 return TRUE;
117 default:
118 break;
119 }
120 break;
121 default:
122 assert(0);
123 };
124
125 return FALSE;
126 }
127
128 static void
129 nv30_screen_destroy(struct pipe_screen *pscreen)
130 {
131 struct nv30_screen *screen = nv30_screen(pscreen);
132 struct nouveau_winsys *nvws = screen->nvws;
133
134 nvws->res_free(&screen->vp_exec_heap);
135 nvws->res_free(&screen->vp_data_heap);
136 nvws->res_free(&screen->query_heap);
137 nvws->notifier_free(&screen->query);
138 nvws->notifier_free(&screen->sync);
139 nvws->grobj_free(&screen->rankine);
140
141 FREE(pscreen);
142 }
143
144 struct pipe_screen *
145 nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws,
146 unsigned chipset)
147 {
148 struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen);
149 struct nouveau_stateobj *so;
150 unsigned rankine_class = 0;
151 int ret, i;
152
153 if (!screen)
154 return NULL;
155 screen->chipset = chipset;
156 screen->nvws = nvws;
157
158 /* 3D object */
159 switch (chipset & 0xf0) {
160 case 0x30:
161 if (NV30TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
162 rankine_class = 0x0397;
163 else
164 if (NV34TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
165 rankine_class = 0x0697;
166 else
167 if (NV35TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
168 rankine_class = 0x0497;
169 break;
170 default:
171 break;
172 }
173
174 if (!rankine_class) {
175 NOUVEAU_ERR("Unknown nv3x chipset: nv%02x\n", chipset);
176 return NULL;
177 }
178
179 ret = nvws->grobj_alloc(nvws, rankine_class, &screen->rankine);
180 if (ret) {
181 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
182 return FALSE;
183 }
184
185 /* Notifier for sync purposes */
186 ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
187 if (ret) {
188 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
189 nv30_screen_destroy(&screen->pipe);
190 return NULL;
191 }
192
193 /* Query objects */
194 ret = nvws->notifier_alloc(nvws, 32, &screen->query);
195 if (ret) {
196 NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
197 nv30_screen_destroy(&screen->pipe);
198 return NULL;
199 }
200
201 ret = nvws->res_init(&screen->query_heap, 0, 32);
202 if (ret) {
203 NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
204 nv30_screen_destroy(&screen->pipe);
205 return NULL;
206 }
207
208 /* Vtxprog resources */
209 if (nvws->res_init(&screen->vp_exec_heap, 0, 256) ||
210 nvws->res_init(&screen->vp_data_heap, 0, 256)) {
211 nv30_screen_destroy(&screen->pipe);
212 return NULL;
213 }
214
215 /* Static rankine initialisation */
216 so = so_new(128, 0);
217 so_method(so, screen->rankine, NV34TCL_DMA_NOTIFY, 1);
218 so_data (so, screen->sync->handle);
219 so_method(so, screen->rankine, NV34TCL_DMA_TEXTURE0, 2);
220 so_data (so, nvws->channel->vram->handle);
221 so_data (so, nvws->channel->gart->handle);
222 so_method(so, screen->rankine, NV34TCL_DMA_COLOR1, 1);
223 so_data (so, nvws->channel->vram->handle);
224 so_method(so, screen->rankine, NV34TCL_DMA_COLOR0, 2);
225 so_data (so, nvws->channel->vram->handle);
226 so_data (so, nvws->channel->vram->handle);
227 so_method(so, screen->rankine, NV34TCL_DMA_VTXBUF0, 2);
228 so_data (so, nvws->channel->vram->handle);
229 so_data (so, nvws->channel->gart->handle);
230 /* so_method(so, screen->rankine, NV34TCL_DMA_FENCE, 2);
231 so_data (so, 0);
232 so_data (so, screen->query->handle);*/
233 so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY7, 1);
234 so_data (so, nvws->channel->vram->handle);
235 so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY8, 1);
236 so_data (so, nvws->channel->vram->handle);
237
238 for (i=1; i<8; i++) {
239 so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1);
240 so_data (so, 0);
241 so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_VERT(i), 1);
242 so_data (so, 0);
243 }
244
245 so_method(so, screen->rankine, 0x220, 1);
246 so_data (so, 1);
247
248 so_method(so, screen->rankine, 0x03b0, 1);
249 so_data (so, 0x00100000);
250 so_method(so, screen->rankine, 0x1454, 1);
251 so_data (so, 0);
252 so_method(so, screen->rankine, 0x1d80, 1);
253 so_data (so, 3);
254 so_method(so, screen->rankine, 0x1450, 1);
255 so_data (so, 0x00030004);
256
257 /* NEW */
258 so_method(so, screen->rankine, 0x1e98, 1);
259 so_data (so, 0);
260 so_method(so, screen->rankine, 0x17e0, 3);
261 so_data (so, fui(0.0));
262 so_data (so, fui(0.0));
263 so_data (so, fui(1.0));
264 so_method(so, screen->rankine, 0x1f80, 16);
265 for (i=0; i<16; i++) {
266 so_data (so, (i==8) ? 0x0000ffff : 0);
267 }
268
269 so_method(so, screen->rankine, 0x120, 3);
270 so_data (so, 0);
271 so_data (so, 1);
272 so_data (so, 2);
273
274 so_method(so, screen->rankine, 0x1d88, 1);
275 so_data (so, 0x00001200);
276
277 so_method(so, screen->rankine, NV34TCL_RC_ENABLE, 1);
278 so_data (so, 0);
279
280 so_method(so, screen->rankine, NV34TCL_DEPTH_RANGE_NEAR, 2);
281 so_data (so, fui(0.0));
282 so_data (so, fui(1.0));
283
284 so_method(so, screen->rankine, NV34TCL_MULTISAMPLE_CONTROL, 1);
285 so_data (so, 0xffff0000);
286
287 /* enables use of vp rather than fixed-function somehow */
288 so_method(so, screen->rankine, 0x1e94, 1);
289 so_data (so, 0x13);
290
291 so_emit(nvws, so);
292 so_ref(NULL, &so);
293 nvws->push_flush(nvws, 0, NULL);
294
295 screen->pipe.winsys = ws;
296 screen->pipe.destroy = nv30_screen_destroy;
297
298 screen->pipe.get_name = nv30_screen_get_name;
299 screen->pipe.get_vendor = nv30_screen_get_vendor;
300 screen->pipe.get_param = nv30_screen_get_param;
301 screen->pipe.get_paramf = nv30_screen_get_paramf;
302
303 screen->pipe.is_format_supported = nv30_screen_surface_format_supported;
304
305 nv30_screen_init_miptree_functions(&screen->pipe);
306
307 return &screen->pipe;
308 }
309