2 * Copyright 2008 Ben Skeggs
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
23 #include "util/u_format_s3tc.h"
24 #include "pipe/p_screen.h"
26 #include "nv50_context.h"
27 #include "nv50_screen.h"
28 #include "nv50_resource.h"
29 #include "nv50_program.h"
31 #include "nouveau/nouveau_stateobj.h"
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
)
43 if (!util_format_s3tc_enabled
) {
45 case PIPE_FORMAT_DXT1_RGB
:
46 case PIPE_FORMAT_DXT1_RGBA
:
47 case PIPE_FORMAT_DXT3_RGBA
:
48 case PIPE_FORMAT_DXT5_RGBA
:
56 case PIPE_FORMAT_Z16_UNORM
:
57 if ((nouveau_screen(pscreen
)->device
->chipset
& 0xf0) != 0xa0)
64 /* transfers & shared are always supported */
65 usage
&= ~(PIPE_BIND_TRANSFER_READ
|
66 PIPE_BIND_TRANSFER_WRITE
|
69 return (nv50_format_table
[format
].usage
& usage
) == usage
;
73 nv50_screen_get_param(struct pipe_screen
*pscreen
, enum pipe_cap param
)
76 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS
:
78 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS
:
80 case PIPE_CAP_MAX_COMBINED_SAMPLERS
:
82 case PIPE_CAP_NPOT_TEXTURES
:
84 case PIPE_CAP_TWO_SIDED_STENCIL
:
89 case PIPE_CAP_ANISOTROPIC_FILTER
:
91 case PIPE_CAP_POINT_SPRITE
:
93 case PIPE_CAP_MAX_RENDER_TARGETS
:
95 case PIPE_CAP_OCCLUSION_QUERY
:
97 case PIPE_CAP_TIMER_QUERY
:
99 case PIPE_CAP_STREAM_OUTPUT
:
101 case PIPE_CAP_TEXTURE_SHADOW_MAP
:
103 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS
:
105 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS
:
107 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS
:
109 case PIPE_CAP_TEXTURE_MIRROR_CLAMP
:
110 case PIPE_CAP_TEXTURE_MIRROR_REPEAT
:
112 case PIPE_CAP_TEXTURE_SWIZZLE
:
114 case PIPE_CAP_BLEND_EQUATION_SEPARATE
:
116 case PIPE_CAP_INDEP_BLEND_ENABLE
:
118 case PIPE_CAP_INDEP_BLEND_FUNC
:
120 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE
:
122 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT
:
123 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER
:
125 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT
:
126 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER
:
128 case PIPE_CAP_DEPTH_CLAMP
:
130 case PIPE_CAP_SHADER_STENCIL_EXPORT
:
132 case PIPE_CAP_PRIMITIVE_RESTART
:
135 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param
);
141 nv50_screen_get_shader_param(struct pipe_screen
*pscreen
, unsigned shader
,
142 enum pipe_shader_cap param
)
145 case PIPE_SHADER_FRAGMENT
:
146 case PIPE_SHADER_VERTEX
:
148 case PIPE_SHADER_GEOMETRY
:
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 */
159 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH
: /* need stack bo */
161 case PIPE_SHADER_CAP_MAX_INPUTS
: /* 128 / 4 with GP */
162 if (shader
== PIPE_SHADER_GEOMETRY
)
166 case PIPE_SHADER_CAP_MAX_CONSTS
:
168 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS
: /* 16 - 1, but not implemented */
170 case PIPE_SHADER_CAP_MAX_ADDRS
: /* no spilling atm */
172 case PIPE_SHADER_CAP_MAX_PREDS
: /* not yet handled */
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
:
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
:
183 case PIPE_SHADER_CAP_SUBROUTINES
:
191 nv50_screen_get_paramf(struct pipe_screen
*pscreen
, enum pipe_cap param
)
194 case PIPE_CAP_MAX_LINE_WIDTH
:
195 case PIPE_CAP_MAX_LINE_WIDTH_AA
:
197 case PIPE_CAP_MAX_POINT_WIDTH
:
198 case PIPE_CAP_MAX_POINT_WIDTH_AA
:
200 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY
:
202 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS
:
205 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param
);
211 nv50_screen_destroy(struct pipe_screen
*pscreen
)
213 struct nv50_screen
*screen
= nv50_screen(pscreen
);
216 for (i
= 0; i
< 3; i
++) {
217 if (screen
->constbuf_parm
[i
])
218 nouveau_bo_ref(NULL
, &screen
->constbuf_parm
[i
]);
221 if (screen
->constbuf_misc
[0])
222 nouveau_bo_ref(NULL
, &screen
->constbuf_misc
[0]);
224 nouveau_bo_ref(NULL
, &screen
->tic
);
226 nouveau_bo_ref(NULL
, &screen
->tsc
);
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
);
237 #define BGN_RELOC(ch, bo, gr, m, n, fl) \
238 OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0)
241 nv50_screen_reloc_constbuf(struct nv50_screen
*screen
, unsigned cbi
)
243 struct nouveau_bo
*bo
;
244 struct nouveau_channel
*chan
= screen
->base
.channel
;
245 struct nouveau_grobj
*tesla
= screen
->tesla
;
247 const unsigned rl
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
| NOUVEAU_BO_DUMMY
;
251 bo
= screen
->constbuf_misc
[0];
257 bo
= screen
->constbuf_parm
[cbi
- NV50_CB_PVP
];
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);
271 nv50_screen_relocs(struct nv50_screen
*screen
)
273 struct nouveau_channel
*chan
= screen
->base
.channel
;
274 struct nouveau_grobj
*tesla
= screen
->tesla
;
276 const unsigned rl
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
| NOUVEAU_BO_DUMMY
;
278 MARK_RING (chan
, 28, 26);
280 /* cause grobj autobind */
281 BEGIN_RING(chan
, tesla
, 0x0100, 1);
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
);
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
);
292 nv50_screen_reloc_constbuf(screen
, NV50_CB_PMISC
);
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);
301 for (i
= 0; i
< 3; ++i
)
302 nv50_screen_reloc_constbuf(screen
, NV50_CB_PVP
+ i
);
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
);
309 if (!screen
->cur_ctx
->req_lmem
)
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
);
318 #ifndef NOUVEAU_GETPARAM_GRAPH_UNITS
319 # define NOUVEAU_GETPARAM_GRAPH_UNITS 13
322 extern int nouveau_device_get_param(struct nouveau_device
*dev
,
323 uint64_t param
, uint64_t *value
);
326 nv50_screen_create(struct pipe_winsys
*ws
, struct nouveau_device
*dev
)
328 struct nv50_screen
*screen
= CALLOC_STRUCT(nv50_screen
);
329 struct nouveau_channel
*chan
;
330 struct pipe_screen
*pscreen
;
332 unsigned chipset
= dev
->chipset
;
333 unsigned tesla_class
= 0;
334 unsigned stack_size
, local_size
, max_warps
;
336 const unsigned rl
= NOUVEAU_BO_VRAM
| NOUVEAU_BO_RD
;
340 pscreen
= &screen
->base
.base
;
342 ret
= nouveau_screen_init(&screen
->base
, dev
);
344 nv50_screen_destroy(pscreen
);
347 chan
= screen
->base
.channel
;
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
;
357 nv50_screen_init_resource_functions(pscreen
);
359 /* DMA engine object */
360 ret
= nouveau_grobj_alloc(chan
, 0xbeef5039,
361 NV50_MEMORY_TO_MEMORY_FORMAT
, &screen
->m2mf
);
363 NOUVEAU_ERR("Error creating M2MF object: %d\n", ret
);
364 nv50_screen_destroy(pscreen
);
369 ret
= nouveau_grobj_alloc(chan
, 0xbeef502d, NV50_2D
, &screen
->eng2d
);
371 NOUVEAU_ERR("Error creating 2D object: %d\n", ret
);
372 nv50_screen_destroy(pscreen
);
377 switch (chipset
& 0xf0) {
379 tesla_class
= NV50TCL
;
383 tesla_class
= NV84TCL
;
390 tesla_class
= NVA0TCL
;
393 tesla_class
= NVA8TCL
;
398 NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset
);
399 nv50_screen_destroy(pscreen
);
403 ret
= nouveau_grobj_alloc(chan
, 0xbeef5097, tesla_class
,
406 NOUVEAU_ERR("Error creating 3D object: %d\n", ret
);
407 nv50_screen_destroy(pscreen
);
411 /* this is necessary for the new RING_3D / statebuffer code */
412 BIND_RING(chan
, screen
->tesla
, 7);
415 ret
= nouveau_notifier_alloc(chan
, 0xbeef0301, 1, &screen
->sync
);
417 NOUVEAU_ERR("Error creating notifier object: %d\n", ret
);
418 nv50_screen_destroy(pscreen
);
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
);
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);
439 BEGIN_RING(chan
, screen
->eng2d
, 0x0888, 1);
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
);
455 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_RT_CONTROL
, 1);
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);
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);
470 /* origin is top left (set to 1 for bottom left) */
471 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_Y_ORIGIN_BOTTOM
, 1);
473 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_VP_REG_ALLOC_RESULT
, 1);
476 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_CLEAR_FLAGS
, 1);
477 OUT_RING (chan
, NV50TCL_CLEAR_FLAGS_D3D
);
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]);
483 nv50_screen_destroy(pscreen
);
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);
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
]);
499 nv50_screen_destroy(pscreen
);
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);
509 if (nouveau_resource_init(&screen
->immd_heap
, 0, 128)) {
510 NOUVEAU_ERR("Error initialising shader immediates heap.\n");
511 nv50_screen_destroy(pscreen
);
515 ret
= nouveau_bo_new(dev
, NOUVEAU_BO_VRAM
, 0, 3 * 32 * (8 * 4),
518 nv50_screen_destroy(pscreen
);
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);
526 ret
= nouveau_bo_new(dev
, NOUVEAU_BO_VRAM
, 0, 3 * 32 * (8 * 4),
529 nv50_screen_destroy(pscreen
);
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 */
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
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));
557 nouveau_device_get_param(dev
, NOUVEAU_GETPARAM_GRAPH_UNITS
, &value
);
559 max_warps
= util_bitcount(value
& 0xffff);
560 max_warps
*= util_bitcount((value
>> 24) & 0xf) * 32;
562 stack_size
= max_warps
* 64 * 8;
564 ret
= nouveau_bo_new(dev
, NOUVEAU_BO_VRAM
, 1 << 16,
565 stack_size
, &screen
->stack_bo
);
567 nv50_screen_destroy(pscreen
);
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
);
575 local_size
= (NV50_CAP_MAX_PROGRAM_TEMPS
* 16) * max_warps
* 32;
577 ret
= nouveau_bo_new(dev
, NOUVEAU_BO_VRAM
, 1 << 16,
578 local_size
, &screen
->local_bo
);
580 nv50_screen_destroy(pscreen
);
584 local_size
= NV50_CAP_MAX_PROGRAM_TEMPS
* 16;
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));
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);
599 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
600 OUT_RINGf (chan
, 0.0f
);
601 OUT_RINGf (chan
, 1.0f
);
603 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_VIEWPORT_TRANSFORM_EN
, 1);
606 /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
607 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_LINKED_TSC
, 1);
610 BEGIN_RING(chan
, screen
->tesla
, NV50TCL_EDGEFLAG_ENABLE
, 1);
611 OUT_RING (chan
, 1); /* default edgeflag to TRUE */
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
;