r300g: fix reference counting when translating indices
[mesa.git] / src / gallium / drivers / nv50 / nv50_screen.c
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
33 static boolean
34 nv50_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
72 static int
73 nv50_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 case PIPE_CAP_SM3:
88 return 1;
89 case PIPE_CAP_ANISOTROPIC_FILTER:
90 return 1;
91 case PIPE_CAP_POINT_SPRITE:
92 return 1;
93 case PIPE_CAP_MAX_RENDER_TARGETS:
94 return 8;
95 case PIPE_CAP_OCCLUSION_QUERY:
96 return 1;
97 case PIPE_CAP_TIMER_QUERY:
98 return 0;
99 case PIPE_CAP_STREAM_OUTPUT:
100 return 0;
101 case PIPE_CAP_TEXTURE_SHADOW_MAP:
102 return 1;
103 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
104 return 13;
105 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
106 return 10;
107 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
108 return 13;
109 case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
110 case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
111 return 1;
112 case PIPE_CAP_TEXTURE_SWIZZLE:
113 return 1;
114 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
115 return 1;
116 case PIPE_CAP_INDEP_BLEND_ENABLE:
117 return 1;
118 case PIPE_CAP_INDEP_BLEND_FUNC:
119 return 0;
120 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
121 return 1;
122 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
123 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
124 return 1;
125 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
126 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
127 return 0;
128 case PIPE_CAP_DEPTH_CLAMP:
129 return 1;
130 case PIPE_CAP_SHADER_STENCIL_EXPORT:
131 return 0;
132 case PIPE_CAP_PRIMITIVE_RESTART:
133 return 0;
134 default:
135 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
136 return 0;
137 }
138 }
139
140 static int
141 nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
142 enum pipe_shader_cap param)
143 {
144 switch(shader) {
145 case PIPE_SHADER_FRAGMENT:
146 case PIPE_SHADER_VERTEX:
147 break;
148 case PIPE_SHADER_GEOMETRY:
149 default:
150 return 0;
151 }
152
153 switch(param) {
154 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
155 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
156 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
157 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: /* arbitrary limit */
158 return 16384;
159 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */
160 return 4;
161 case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */
162 if (shader == PIPE_SHADER_GEOMETRY)
163 return 128 / 4;
164 else
165 return 64 / 4;
166 case PIPE_SHADER_CAP_MAX_CONSTS:
167 return 65536 / 16;
168 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: /* 16 - 1, but not implemented */
169 return 1;
170 case PIPE_SHADER_CAP_MAX_ADDRS: /* no spilling atm */
171 return 1;
172 case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */
173 return 0;
174 case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */
175 return NV50_CAP_MAX_PROGRAM_TEMPS;
176 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
177 return 1;
178 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
179 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
180 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
181 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
182 return 1;
183 case PIPE_SHADER_CAP_SUBROUTINES:
184 return 0;
185 default:
186 return 0;
187 }
188 }
189
190 static float
191 nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param)
192 {
193 switch (param) {
194 case PIPE_CAP_MAX_LINE_WIDTH:
195 case PIPE_CAP_MAX_LINE_WIDTH_AA:
196 return 10.0;
197 case PIPE_CAP_MAX_POINT_WIDTH:
198 case PIPE_CAP_MAX_POINT_WIDTH_AA:
199 return 64.0;
200 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
201 return 16.0;
202 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
203 return 4.0;
204 default:
205 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
206 return 0.0;
207 }
208 }
209
210 static void
211 nv50_screen_destroy(struct pipe_screen *pscreen)
212 {
213 struct nv50_screen *screen = nv50_screen(pscreen);
214 unsigned i;
215
216 for (i = 0; i < 3; i++) {
217 if (screen->constbuf_parm[i])
218 nouveau_bo_ref(NULL, &screen->constbuf_parm[i]);
219 }
220
221 if (screen->constbuf_misc[0])
222 nouveau_bo_ref(NULL, &screen->constbuf_misc[0]);
223 if (screen->tic)
224 nouveau_bo_ref(NULL, &screen->tic);
225 if (screen->tsc)
226 nouveau_bo_ref(NULL, &screen->tsc);
227
228 nouveau_notifier_free(&screen->sync);
229 nouveau_grobj_free(&screen->tesla);
230 nouveau_grobj_free(&screen->eng2d);
231 nouveau_grobj_free(&screen->m2mf);
232 nouveau_resource_destroy(&screen->immd_heap);
233 nouveau_screen_fini(&screen->base);
234 FREE(screen);
235 }
236
237 #define BGN_RELOC(ch, bo, gr, m, n, fl) \
238 OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0)
239
240 void
241 nv50_screen_reloc_constbuf(struct nv50_screen *screen, unsigned cbi)
242 {
243 struct nouveau_bo *bo;
244 struct nouveau_channel *chan = screen->base.channel;
245 struct nouveau_grobj *tesla = screen->tesla;
246 unsigned size;
247 const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
248
249 switch (cbi) {
250 case NV50_CB_PMISC:
251 bo = screen->constbuf_misc[0];
252 size = 0x200;
253 break;
254 case NV50_CB_PVP:
255 case NV50_CB_PFP:
256 case NV50_CB_PGP:
257 bo = screen->constbuf_parm[cbi - NV50_CB_PVP];
258 size = 0;
259 break;
260 default:
261 return;
262 }
263
264 BGN_RELOC (chan, bo, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
265 OUT_RELOCh(chan, bo, 0, rl);
266 OUT_RELOCl(chan, bo, 0, rl);
267 OUT_RELOC (chan, bo, (cbi << 16) | size, rl, 0, 0);
268 }
269
270 void
271 nv50_screen_relocs(struct nv50_screen *screen)
272 {
273 struct nouveau_channel *chan = screen->base.channel;
274 struct nouveau_grobj *tesla = screen->tesla;
275 unsigned i;
276 const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
277
278 MARK_RING (chan, 28, 26);
279
280 /* cause grobj autobind */
281 BEGIN_RING(chan, tesla, 0x0100, 1);
282 OUT_RING (chan, 0);
283
284 BGN_RELOC (chan, screen->tic, tesla, NV50TCL_TIC_ADDRESS_HIGH, 2, rl);
285 OUT_RELOCh(chan, screen->tic, 0, rl);
286 OUT_RELOCl(chan, screen->tic, 0, rl);
287
288 BGN_RELOC (chan, screen->tsc, tesla, NV50TCL_TSC_ADDRESS_HIGH, 2, rl);
289 OUT_RELOCh(chan, screen->tsc, 0, rl);
290 OUT_RELOCl(chan, screen->tsc, 0, rl);
291
292 nv50_screen_reloc_constbuf(screen, NV50_CB_PMISC);
293
294 BGN_RELOC (chan, screen->constbuf_misc[0],
295 tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
296 OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
297 OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
298 OUT_RELOC (chan, screen->constbuf_misc[0],
299 (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0);
300
301 for (i = 0; i < 3; ++i)
302 nv50_screen_reloc_constbuf(screen, NV50_CB_PVP + i);
303
304 BGN_RELOC (chan, screen->stack_bo,
305 tesla, NV50TCL_STACK_ADDRESS_HIGH, 2, rl);
306 OUT_RELOCh(chan, screen->stack_bo, 0, rl);
307 OUT_RELOCl(chan, screen->stack_bo, 0, rl);
308
309 if (!screen->cur_ctx->req_lmem)
310 return;
311
312 BGN_RELOC (chan, screen->local_bo,
313 tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 2, rl);
314 OUT_RELOCh(chan, screen->local_bo, 0, rl);
315 OUT_RELOCl(chan, screen->local_bo, 0, rl);
316 }
317
318 #ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
319 # define NOUVEAU_GETPARAM_GRAPH_UNITS 13
320 #endif
321
322 extern int nouveau_device_get_param(struct nouveau_device *dev,
323 uint64_t param, uint64_t *value);
324
325 struct pipe_screen *
326 nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
327 {
328 struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
329 struct nouveau_channel *chan;
330 struct pipe_screen *pscreen;
331 uint64_t value;
332 unsigned chipset = dev->chipset;
333 unsigned tesla_class = 0;
334 unsigned stack_size, local_size, max_warps;
335 int ret, i;
336 const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
337
338 if (!screen)
339 return NULL;
340 pscreen = &screen->base.base;
341
342 ret = nouveau_screen_init(&screen->base, dev);
343 if (ret) {
344 nv50_screen_destroy(pscreen);
345 return NULL;
346 }
347 chan = screen->base.channel;
348
349 pscreen->winsys = ws;
350 pscreen->destroy = nv50_screen_destroy;
351 pscreen->get_param = nv50_screen_get_param;
352 pscreen->get_shader_param = nv50_screen_get_shader_param;
353 pscreen->get_paramf = nv50_screen_get_paramf;
354 pscreen->is_format_supported = nv50_screen_is_format_supported;
355 pscreen->context_create = nv50_create;
356
357 nv50_screen_init_resource_functions(pscreen);
358
359 /* DMA engine object */
360 ret = nouveau_grobj_alloc(chan, 0xbeef5039,
361 NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf);
362 if (ret) {
363 NOUVEAU_ERR("Error creating M2MF object: %d\n", ret);
364 nv50_screen_destroy(pscreen);
365 return NULL;
366 }
367
368 /* 2D object */
369 ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
370 if (ret) {
371 NOUVEAU_ERR("Error creating 2D object: %d\n", ret);
372 nv50_screen_destroy(pscreen);
373 return NULL;
374 }
375
376 /* 3D object */
377 switch (chipset & 0xf0) {
378 case 0x50:
379 tesla_class = NV50TCL;
380 break;
381 case 0x80:
382 case 0x90:
383 tesla_class = NV84TCL;
384 break;
385 case 0xa0:
386 switch (chipset) {
387 case 0xa0:
388 case 0xaa:
389 case 0xac:
390 tesla_class = NVA0TCL;
391 break;
392 default:
393 tesla_class = NVA8TCL;
394 break;
395 }
396 break;
397 default:
398 NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset);
399 nv50_screen_destroy(pscreen);
400 return NULL;
401 }
402
403 ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class,
404 &screen->tesla);
405 if (ret) {
406 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
407 nv50_screen_destroy(pscreen);
408 return NULL;
409 }
410
411 /* this is necessary for the new RING_3D / statebuffer code */
412 BIND_RING(chan, screen->tesla, 7);
413
414 /* Sync notifier */
415 ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
416 if (ret) {
417 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
418 nv50_screen_destroy(pscreen);
419 return NULL;
420 }
421
422 /* Static M2MF init */
423 BEGIN_RING(chan, screen->m2mf,
424 NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
425 OUT_RING (chan, screen->sync->handle);
426 OUT_RING (chan, chan->vram->handle);
427 OUT_RING (chan, chan->vram->handle);
428
429 /* Static 2D init */
430 BEGIN_RING(chan, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
431 OUT_RING (chan, screen->sync->handle);
432 OUT_RING (chan, chan->vram->handle);
433 OUT_RING (chan, chan->vram->handle);
434 OUT_RING (chan, chan->vram->handle);
435 BEGIN_RING(chan, screen->eng2d, NV50_2D_OPERATION, 1);
436 OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
437 BEGIN_RING(chan, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
438 OUT_RING (chan, 0);
439 BEGIN_RING(chan, screen->eng2d, 0x0888, 1);
440 OUT_RING (chan, 1);
441
442 /* Static tesla init */
443 BEGIN_RING(chan, screen->tesla, NV50TCL_COND_MODE, 1);
444 OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS);
445 BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
446 OUT_RING (chan, screen->sync->handle);
447 BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_ZETA, 11);
448 for (i = 0; i < 11; i++)
449 OUT_RING (chan, chan->vram->handle);
450 BEGIN_RING(chan, screen->tesla,
451 NV50TCL_DMA_COLOR(0), NV50TCL_DMA_COLOR__SIZE);
452 for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++)
453 OUT_RING (chan, chan->vram->handle);
454
455 BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1);
456 OUT_RING (chan, 1);
457
458 /* activate all 32 lanes (threads) in a warp */
459 BEGIN_RING(chan, screen->tesla, NV50TCL_REG_MODE, 1);
460 OUT_RING (chan, NV50TCL_REG_MODE_STRIPED);
461 BEGIN_RING(chan, screen->tesla, 0x1400, 1);
462 OUT_RING (chan, 0xf);
463
464 /* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */
465 for (i = 0; i < 3; ++i) {
466 BEGIN_RING(chan, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
467 OUT_RING (chan, 0x54);
468 }
469
470 /* origin is top left (set to 1 for bottom left) */
471 BEGIN_RING(chan, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
472 OUT_RING (chan, 0);
473 BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
474 OUT_RING (chan, 8);
475
476 BEGIN_RING(chan, screen->tesla, NV50TCL_CLEAR_FLAGS, 1);
477 OUT_RING (chan, NV50TCL_CLEAR_FLAGS_D3D);
478
479 /* constant buffers for immediates and VP/FP parameters */
480 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
481 &screen->constbuf_misc[0]);
482 if (ret) {
483 nv50_screen_destroy(pscreen);
484 return NULL;
485 }
486 BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
487 OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
488 OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
489 OUT_RING (chan, (NV50_CB_PMISC << 16) | 0x0200);
490 BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
491 OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
492 OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
493 OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200);
494
495 for (i = 0; i < 3; i++) {
496 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (4096 * 4) * 4,
497 &screen->constbuf_parm[i]);
498 if (ret) {
499 nv50_screen_destroy(pscreen);
500 return NULL;
501 }
502 BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
503 OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
504 OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
505 /* CB_DEF_SET_SIZE value of 0x0000 means 65536 */
506 OUT_RING (chan, ((NV50_CB_PVP + i) << 16) | 0x0000);
507 }
508
509 if (nouveau_resource_init(&screen->immd_heap, 0, 128)) {
510 NOUVEAU_ERR("Error initialising shader immediates heap.\n");
511 nv50_screen_destroy(pscreen);
512 return NULL;
513 }
514
515 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
516 &screen->tic);
517 if (ret) {
518 nv50_screen_destroy(pscreen);
519 return NULL;
520 }
521 BEGIN_RING(chan, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
522 OUT_RELOCh(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
523 OUT_RELOCl(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
524 OUT_RING (chan, 3 * 32 - 1);
525
526 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
527 &screen->tsc);
528 if (ret) {
529 nv50_screen_destroy(pscreen);
530 return NULL;
531 }
532 BEGIN_RING(chan, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
533 OUT_RELOCh(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
534 OUT_RELOCl(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
535 OUT_RING (chan, 0); /* ignored if TSC_LINKED (0x1234) == 1 */
536
537 /* map constant buffers:
538 * B = buffer ID (maybe more than 1 byte)
539 * N = CB index used in shader instruction
540 * P = program type (0 = VP, 2 = GP, 3 = FP)
541 * SET_PROGRAM_CB = 0x000BBNP1
542 */
543 BEGIN_RING_NI(chan, screen->tesla, NV50TCL_SET_PROGRAM_CB, 8);
544 /* bind immediate buffer */
545 OUT_RING (chan, 0x001 | (NV50_CB_PMISC << 12));
546 OUT_RING (chan, 0x021 | (NV50_CB_PMISC << 12));
547 OUT_RING (chan, 0x031 | (NV50_CB_PMISC << 12));
548 /* bind auxiliary constbuf to immediate data bo */
549 OUT_RING (chan, 0x201 | (NV50_CB_AUX << 12));
550 OUT_RING (chan, 0x221 | (NV50_CB_AUX << 12));
551 /* bind parameter buffers */
552 OUT_RING (chan, 0x101 | (NV50_CB_PVP << 12));
553 OUT_RING (chan, 0x121 | (NV50_CB_PGP << 12));
554 OUT_RING (chan, 0x131 | (NV50_CB_PFP << 12));
555
556 /* shader stack */
557 nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
558
559 max_warps = util_bitcount(value & 0xffff);
560 max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
561
562 stack_size = max_warps * 64 * 8;
563
564 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
565 stack_size, &screen->stack_bo);
566 if (ret) {
567 nv50_screen_destroy(pscreen);
568 return NULL;
569 }
570 BEGIN_RING(chan, screen->tesla, NV50TCL_STACK_ADDRESS_HIGH, 3);
571 OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
572 OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
573 OUT_RING (chan, 4);
574
575 local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32;
576
577 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
578 local_size, &screen->local_bo);
579 if (ret) {
580 nv50_screen_destroy(pscreen);
581 return NULL;
582 }
583
584 local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
585
586 BEGIN_RING(chan, screen->tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 3);
587 OUT_RELOCh(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
588 OUT_RELOCl(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
589 OUT_RING (chan, util_unsigned_logbase2(local_size / 8));
590
591 /* Vertex array limits - max them out */
592 for (i = 0; i < 16; i++) {
593 BEGIN_RING(chan, screen->tesla,
594 NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
595 OUT_RING (chan, 0x000000ff);
596 OUT_RING (chan, 0xffffffff);
597 }
598
599 BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
600 OUT_RINGf (chan, 0.0f);
601 OUT_RINGf (chan, 1.0f);
602
603 BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
604 OUT_RING (chan, 1);
605
606 /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
607 BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1);
608 OUT_RING (chan, 1);
609
610 BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
611 OUT_RING (chan, 1); /* default edgeflag to TRUE */
612
613 FIRE_RING (chan);
614
615 screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
616 if(!screen->force_push)
617 screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART;
618 return pscreen;
619 }
620