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