nv50_screen.c revision 4c1e7d931dd6e5676297bee23932cc6d66c93cac
1/*
2 * Copyright 2008 Ben Skeggs
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#include "util/u_format_s3tc.h"
24#include "pipe/p_screen.h"
25
26#include "nv50_context.h"
27#include "nv50_screen.h"
28#include "nv50_resource.h"
29#include "nv50_program.h"
30
31#include "nouveau/nouveau_stateobj.h"
32
33static boolean
34nv50_screen_is_format_supported(struct pipe_screen *pscreen,
35				enum pipe_format format,
36				enum pipe_texture_target target,
37				unsigned sample_count,
38				unsigned usage, unsigned geom_flags)
39{
40	if (sample_count > 1)
41		return FALSE;
42
43	if (!util_format_s3tc_enabled) {
44		switch (format) {
45		case PIPE_FORMAT_DXT1_RGB:
46		case PIPE_FORMAT_DXT1_RGBA:
47		case PIPE_FORMAT_DXT3_RGBA:
48		case PIPE_FORMAT_DXT5_RGBA:
49			return FALSE;
50		default:
51			break;
52		}
53	}
54
55	switch (format) {
56	case PIPE_FORMAT_Z16_UNORM:
57		if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0)
58			return FALSE;
59		break;
60	default:
61		break;
62	}
63
64	/* transfers & shared are always supported */
65	usage &= ~(PIPE_BIND_TRANSFER_READ |
66		   PIPE_BIND_TRANSFER_WRITE |
67		   PIPE_BIND_SHARED);
68
69	return (nv50_format_table[format].usage & usage) == usage;
70}
71
72static int
73nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
74{
75	switch (param) {
76	case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
77		return 32;
78	case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
79		return 32;
80	case PIPE_CAP_MAX_COMBINED_SAMPLERS:
81		return 64;
82	case PIPE_CAP_NPOT_TEXTURES:
83		return 1;
84	case PIPE_CAP_TWO_SIDED_STENCIL:
85		return 1;
86	case PIPE_CAP_GLSL:
87		return 1;
88	case PIPE_CAP_ANISOTROPIC_FILTER:
89		return 1;
90	case PIPE_CAP_POINT_SPRITE:
91		return 1;
92	case PIPE_CAP_MAX_RENDER_TARGETS:
93		return 8;
94	case PIPE_CAP_OCCLUSION_QUERY:
95		return 1;
96        case PIPE_CAP_TIMER_QUERY:
97		return 0;
98	case PIPE_CAP_TEXTURE_SHADOW_MAP:
99		return 1;
100	case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
101		return 13;
102	case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
103		return 10;
104	case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
105		return 13;
106	case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
107	case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
108		return 1;
109	case PIPE_CAP_TEXTURE_SWIZZLE:
110		return 1;
111	case PIPE_CAP_BLEND_EQUATION_SEPARATE:
112		return 1;
113	case PIPE_CAP_INDEP_BLEND_ENABLE:
114		return 1;
115	case PIPE_CAP_INDEP_BLEND_FUNC:
116		return 0;
117	case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
118		return 1;
119	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
120	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
121		return 1;
122	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
123	case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
124		return 0;
125	case PIPE_CAP_DEPTH_CLAMP:
126		return 1;
127	default:
128		NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
129		return 0;
130	}
131}
132
133static int
134nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
135			     enum pipe_shader_cap param)
136{
137	switch(shader) {
138	case PIPE_SHADER_FRAGMENT:
139	case PIPE_SHADER_VERTEX:
140	case PIPE_SHADER_GEOMETRY:
141		break;
142	default:
143		return 0;
144	}
145
146	switch(param) {
147	case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
148	case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
149	case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
150	case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: /* arbitrary limit */
151		return 16384;
152	case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */
153		return 4;
154	case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */
155		if (shader == PIPE_SHADER_GEOMETRY)
156			return 128 / 4;
157		else
158			return 64 / 4;
159	case PIPE_SHADER_CAP_MAX_CONSTS:
160		return 65536 / 16;
161	case PIPE_SHADER_CAP_MAX_ADDRS: /* no spilling atm */
162		return 1;
163	case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */
164		return 0;
165	case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */
166		return NV50_CAP_MAX_PROGRAM_TEMPS;
167	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
168		return 1;
169	default:
170		return 0;
171	}
172}
173
174static float
175nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param)
176{
177	switch (param) {
178	case PIPE_CAP_MAX_LINE_WIDTH:
179	case PIPE_CAP_MAX_LINE_WIDTH_AA:
180		return 10.0;
181	case PIPE_CAP_MAX_POINT_WIDTH:
182	case PIPE_CAP_MAX_POINT_WIDTH_AA:
183		return 64.0;
184	case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
185		return 16.0;
186	case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
187		return 4.0;
188	default:
189		NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
190		return 0.0;
191	}
192}
193
194static void
195nv50_screen_destroy(struct pipe_screen *pscreen)
196{
197	struct nv50_screen *screen = nv50_screen(pscreen);
198	unsigned i;
199
200	for (i = 0; i < 3; i++) {
201		if (screen->constbuf_parm[i])
202			nouveau_bo_ref(NULL, &screen->constbuf_parm[i]);
203	}
204
205	if (screen->constbuf_misc[0])
206		nouveau_bo_ref(NULL, &screen->constbuf_misc[0]);
207	if (screen->tic)
208		nouveau_bo_ref(NULL, &screen->tic);
209	if (screen->tsc)
210		nouveau_bo_ref(NULL, &screen->tsc);
211
212	nouveau_notifier_free(&screen->sync);
213	nouveau_grobj_free(&screen->tesla);
214	nouveau_grobj_free(&screen->eng2d);
215	nouveau_grobj_free(&screen->m2mf);
216	nouveau_resource_destroy(&screen->immd_heap);
217	nouveau_screen_fini(&screen->base);
218	FREE(screen);
219}
220
221#define BGN_RELOC(ch, bo, gr, m, n, fl) \
222   OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0)
223
224void
225nv50_screen_reloc_constbuf(struct nv50_screen *screen, unsigned cbi)
226{
227	struct nouveau_bo *bo;
228	struct nouveau_channel *chan = screen->base.channel;
229	struct nouveau_grobj *tesla = screen->tesla;
230	unsigned size;
231	const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
232
233	switch (cbi) {
234	case NV50_CB_PMISC:
235		bo = screen->constbuf_misc[0];
236		size = 0x200;
237		break;
238	case NV50_CB_PVP:
239	case NV50_CB_PFP:
240	case NV50_CB_PGP:
241		bo = screen->constbuf_parm[cbi - NV50_CB_PVP];
242		size = 0;
243		break;
244	default:
245		return;
246	}
247
248	BGN_RELOC (chan, bo, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
249	OUT_RELOCh(chan, bo, 0, rl);
250	OUT_RELOCl(chan, bo, 0, rl);
251	OUT_RELOC (chan, bo, (cbi << 16) | size, rl, 0, 0);
252}
253
254void
255nv50_screen_relocs(struct nv50_screen *screen)
256{
257	struct nouveau_channel *chan = screen->base.channel;
258	struct nouveau_grobj *tesla = screen->tesla;
259	unsigned i;
260	const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
261
262	MARK_RING (chan, 28, 26);
263
264	/* cause grobj autobind */
265	BEGIN_RING(chan, tesla, 0x0100, 1);
266	OUT_RING  (chan, 0);
267
268	BGN_RELOC (chan, screen->tic, tesla, NV50TCL_TIC_ADDRESS_HIGH, 2, rl);
269	OUT_RELOCh(chan, screen->tic, 0, rl);
270	OUT_RELOCl(chan, screen->tic, 0, rl);
271
272	BGN_RELOC (chan, screen->tsc, tesla, NV50TCL_TSC_ADDRESS_HIGH, 2, rl);
273	OUT_RELOCh(chan, screen->tsc, 0, rl);
274	OUT_RELOCl(chan, screen->tsc, 0, rl);
275
276	nv50_screen_reloc_constbuf(screen, NV50_CB_PMISC);
277
278	BGN_RELOC (chan, screen->constbuf_misc[0],
279		   tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
280	OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
281	OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
282	OUT_RELOC (chan, screen->constbuf_misc[0],
283		   (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0);
284
285	for (i = 0; i < 3; ++i)
286		nv50_screen_reloc_constbuf(screen, NV50_CB_PVP + i);
287
288	BGN_RELOC (chan, screen->stack_bo,
289		   tesla, NV50TCL_STACK_ADDRESS_HIGH, 2, rl);
290	OUT_RELOCh(chan, screen->stack_bo, 0, rl);
291	OUT_RELOCl(chan, screen->stack_bo, 0, rl);
292
293	if (!screen->cur_ctx->req_lmem)
294		return;
295
296	BGN_RELOC (chan, screen->local_bo,
297		   tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 2, rl);
298	OUT_RELOCh(chan, screen->local_bo, 0, rl);
299	OUT_RELOCl(chan, screen->local_bo, 0, rl);
300}
301
302#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
303# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
304#endif
305
306extern int nouveau_device_get_param(struct nouveau_device *dev,
307                                    uint64_t param, uint64_t *value);
308
309struct pipe_screen *
310nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
311{
312	struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
313	struct nouveau_channel *chan;
314	struct pipe_screen *pscreen;
315	uint64_t value;
316	unsigned chipset = dev->chipset;
317	unsigned tesla_class = 0;
318	unsigned stack_size, local_size, max_warps;
319	int ret, i;
320	const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
321
322	if (!screen)
323		return NULL;
324	pscreen = &screen->base.base;
325
326	ret = nouveau_screen_init(&screen->base, dev);
327	if (ret) {
328		nv50_screen_destroy(pscreen);
329		return NULL;
330	}
331	chan = screen->base.channel;
332
333	pscreen->winsys = ws;
334	pscreen->destroy = nv50_screen_destroy;
335	pscreen->get_param = nv50_screen_get_param;
336	pscreen->get_shader_param = nv50_screen_get_shader_param;
337	pscreen->get_paramf = nv50_screen_get_paramf;
338	pscreen->is_format_supported = nv50_screen_is_format_supported;
339	pscreen->context_create = nv50_create;
340
341	nv50_screen_init_resource_functions(pscreen);
342
343	/* DMA engine object */
344	ret = nouveau_grobj_alloc(chan, 0xbeef5039,
345		NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf);
346	if (ret) {
347		NOUVEAU_ERR("Error creating M2MF object: %d\n", ret);
348		nv50_screen_destroy(pscreen);
349		return NULL;
350	}
351
352	/* 2D object */
353	ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
354	if (ret) {
355		NOUVEAU_ERR("Error creating 2D object: %d\n", ret);
356		nv50_screen_destroy(pscreen);
357		return NULL;
358	}
359
360	/* 3D object */
361	switch (chipset & 0xf0) {
362	case 0x50:
363		tesla_class = NV50TCL;
364		break;
365	case 0x80:
366	case 0x90:
367		tesla_class = NV84TCL;
368		break;
369	case 0xa0:
370		switch (chipset) {
371		case 0xa0:
372		case 0xaa:
373		case 0xac:
374			tesla_class = NVA0TCL;
375			break;
376		default:
377			tesla_class = NVA8TCL;
378			break;
379		}
380		break;
381	default:
382		NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset);
383		nv50_screen_destroy(pscreen);
384		return NULL;
385	}
386
387	ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class,
388		&screen->tesla);
389	if (ret) {
390		NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
391		nv50_screen_destroy(pscreen);
392		return NULL;
393	}
394
395	/* this is necessary for the new RING_3D / statebuffer code */
396	BIND_RING(chan, screen->tesla, 7);
397
398	/* Sync notifier */
399	ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
400	if (ret) {
401		NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
402		nv50_screen_destroy(pscreen);
403		return NULL;
404	}
405
406	/* Static M2MF init */
407	BEGIN_RING(chan, screen->m2mf,
408		   NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
409	OUT_RING  (chan, screen->sync->handle);
410	OUT_RING  (chan, chan->vram->handle);
411	OUT_RING  (chan, chan->vram->handle);
412
413	/* Static 2D init */
414	BEGIN_RING(chan, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
415	OUT_RING  (chan, screen->sync->handle);
416	OUT_RING  (chan, chan->vram->handle);
417	OUT_RING  (chan, chan->vram->handle);
418	OUT_RING  (chan, chan->vram->handle);
419	BEGIN_RING(chan, screen->eng2d, NV50_2D_OPERATION, 1);
420	OUT_RING  (chan, NV50_2D_OPERATION_SRCCOPY);
421	BEGIN_RING(chan, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
422	OUT_RING  (chan, 0);
423	BEGIN_RING(chan, screen->eng2d, 0x0888, 1);
424	OUT_RING  (chan, 1);
425
426	/* Static tesla init */
427	BEGIN_RING(chan, screen->tesla, NV50TCL_COND_MODE, 1);
428	OUT_RING  (chan, NV50TCL_COND_MODE_ALWAYS);
429	BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
430	OUT_RING  (chan, screen->sync->handle);
431	BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_ZETA, 11);
432	for (i = 0; i < 11; i++)
433		OUT_RING  (chan, chan->vram->handle);
434	BEGIN_RING(chan, screen->tesla,
435		   NV50TCL_DMA_COLOR(0), NV50TCL_DMA_COLOR__SIZE);
436	for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++)
437		OUT_RING  (chan, chan->vram->handle);
438
439	BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1);
440	OUT_RING  (chan, 1);
441
442	/* activate all 32 lanes (threads) in a warp */
443	BEGIN_RING(chan, screen->tesla, NV50TCL_REG_MODE, 1);
444	OUT_RING  (chan, NV50TCL_REG_MODE_STRIPED);
445	BEGIN_RING(chan, screen->tesla, 0x1400, 1);
446	OUT_RING  (chan, 0xf);
447
448	/* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */
449	for (i = 0; i < 3; ++i) {
450		BEGIN_RING(chan, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
451		OUT_RING  (chan, 0x54);
452	}
453
454	/* origin is top left (set to 1 for bottom left) */
455	BEGIN_RING(chan, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
456	OUT_RING  (chan, 0);
457	BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
458	OUT_RING  (chan, 8);
459
460	/* constant buffers for immediates and VP/FP parameters */
461	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
462			     &screen->constbuf_misc[0]);
463	if (ret) {
464		nv50_screen_destroy(pscreen);
465		return NULL;
466	}
467	BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
468	OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
469	OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
470	OUT_RING  (chan, (NV50_CB_PMISC << 16) | 0x0200);
471	BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
472	OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
473	OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
474	OUT_RING  (chan, (NV50_CB_AUX << 16) | 0x0200);
475
476	for (i = 0; i < 3; i++) {
477		ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (4096 * 4) * 4,
478				     &screen->constbuf_parm[i]);
479		if (ret) {
480			nv50_screen_destroy(pscreen);
481			return NULL;
482		}
483		BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
484		OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
485		OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
486		/* CB_DEF_SET_SIZE value of 0x0000 means 65536 */
487		OUT_RING  (chan, ((NV50_CB_PVP + i) << 16) | 0x0000);
488	}
489
490	if (nouveau_resource_init(&screen->immd_heap, 0, 128)) {
491		NOUVEAU_ERR("Error initialising shader immediates heap.\n");
492		nv50_screen_destroy(pscreen);
493		return NULL;
494	}
495
496	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
497			     &screen->tic);
498	if (ret) {
499		nv50_screen_destroy(pscreen);
500		return NULL;
501	}
502	BEGIN_RING(chan, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
503	OUT_RELOCh(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
504	OUT_RELOCl(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
505	OUT_RING  (chan, 3 * 32 - 1);
506
507	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
508			     &screen->tsc);
509	if (ret) {
510		nv50_screen_destroy(pscreen);
511		return NULL;
512	}
513	BEGIN_RING(chan, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
514	OUT_RELOCh(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
515	OUT_RELOCl(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
516	OUT_RING  (chan, 0); /* ignored if TSC_LINKED (0x1234) == 1 */
517
518	/* map constant buffers:
519	 *  B = buffer ID (maybe more than 1 byte)
520	 *  N = CB index used in shader instruction
521	 *  P = program type (0 = VP, 2 = GP, 3 = FP)
522	 * SET_PROGRAM_CB = 0x000BBNP1
523	 */
524	BEGIN_RING_NI(chan, screen->tesla, NV50TCL_SET_PROGRAM_CB, 8);
525	/* bind immediate buffer */
526	OUT_RING  (chan, 0x001 | (NV50_CB_PMISC << 12));
527	OUT_RING  (chan, 0x021 | (NV50_CB_PMISC << 12));
528	OUT_RING  (chan, 0x031 | (NV50_CB_PMISC << 12));
529	/* bind auxiliary constbuf to immediate data bo */
530	OUT_RING  (chan, 0x201 | (NV50_CB_AUX << 12));
531	OUT_RING  (chan, 0x221 | (NV50_CB_AUX << 12));
532	/* bind parameter buffers */
533	OUT_RING  (chan, 0x101 | (NV50_CB_PVP << 12));
534	OUT_RING  (chan, 0x121 | (NV50_CB_PGP << 12));
535	OUT_RING  (chan, 0x131 | (NV50_CB_PFP << 12));
536
537	/* shader stack */
538	nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
539
540	max_warps  = util_bitcount(value & 0xffff);
541	max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
542
543	stack_size = max_warps * 64 * 8;
544
545	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
546			     stack_size, &screen->stack_bo);
547	if (ret) {
548		nv50_screen_destroy(pscreen);
549		return NULL;
550	}
551	BEGIN_RING(chan, screen->tesla, NV50TCL_STACK_ADDRESS_HIGH, 3);
552	OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
553	OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
554	OUT_RING  (chan, 4);
555
556	local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32;
557
558	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
559			     local_size, &screen->local_bo);
560	if (ret) {
561		nv50_screen_destroy(pscreen);
562		return NULL;
563	}
564
565	local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
566
567	BEGIN_RING(chan, screen->tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 3);
568	OUT_RELOCh(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
569	OUT_RELOCl(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
570	OUT_RING  (chan, util_unsigned_logbase2(local_size / 8));
571
572	/* Vertex array limits - max them out */
573	for (i = 0; i < 16; i++) {
574		BEGIN_RING(chan, screen->tesla,
575			   NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
576		OUT_RING  (chan, 0x000000ff);
577		OUT_RING  (chan, 0xffffffff);
578	}
579
580	BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
581	OUT_RINGf (chan, 0.0f);
582	OUT_RINGf (chan, 1.0f);
583
584	BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
585	OUT_RING  (chan, 1);
586
587	/* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
588	BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1);
589	OUT_RING  (chan, 1);
590
591	BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
592	OUT_RING  (chan, 1); /* default edgeflag to TRUE */
593
594	FIRE_RING (chan);
595
596	screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
597	if(!screen->force_push)
598		screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART;
599	return pscreen;
600}
601
602