gallium drivers: report that user vertex buffers are supported
[mesa.git] / src / gallium / drivers / nvc0 / nvc0_screen.c
1 /*
2 * Copyright 2010 Christoph Bumiller
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.h"
24 #include "util/u_format_s3tc.h"
25 #include "pipe/p_screen.h"
26
27 #include "vl/vl_decoder.h"
28 #include "vl/vl_video_buffer.h"
29
30 #include "nvc0_context.h"
31 #include "nvc0_screen.h"
32
33 #include "nvc0_graph_macros.h"
34
35 static boolean
36 nvc0_screen_is_format_supported(struct pipe_screen *pscreen,
37 enum pipe_format format,
38 enum pipe_texture_target target,
39 unsigned sample_count,
40 unsigned bindings)
41 {
42 if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */
43 return FALSE;
44
45 if (!util_format_is_supported(format, bindings))
46 return FALSE;
47
48 switch (format) {
49 case PIPE_FORMAT_R8G8B8A8_UNORM:
50 case PIPE_FORMAT_R8G8B8X8_UNORM:
51 /* HACK: GL requires equal formats for MS resolve and window is BGRA */
52 if (bindings & PIPE_BIND_RENDER_TARGET)
53 return FALSE;
54 default:
55 break;
56 }
57
58 /* transfers & shared are always supported */
59 bindings &= ~(PIPE_BIND_TRANSFER_READ |
60 PIPE_BIND_TRANSFER_WRITE |
61 PIPE_BIND_SHARED);
62
63 return (nvc0_format_table[format].usage & bindings) == bindings;
64 }
65
66 static int
67 nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
68 {
69 const uint16_t class_3d = nouveau_screen(pscreen)->class_3d;
70
71 switch (param) {
72 case PIPE_CAP_MAX_COMBINED_SAMPLERS:
73 return 16 * PIPE_SHADER_TYPES; /* NOTE: should not count COMPUTE */
74 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
75 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
76 return 15;
77 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
78 return 12;
79 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
80 return 2048;
81 case PIPE_CAP_MIN_TEXEL_OFFSET:
82 return -8;
83 case PIPE_CAP_MAX_TEXEL_OFFSET:
84 return 7;
85 case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
86 case PIPE_CAP_TEXTURE_SWIZZLE:
87 case PIPE_CAP_TEXTURE_SHADOW_MAP:
88 case PIPE_CAP_NPOT_TEXTURES:
89 case PIPE_CAP_ANISOTROPIC_FILTER:
90 case PIPE_CAP_SEAMLESS_CUBE_MAP:
91 return 1;
92 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
93 return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
94 case PIPE_CAP_TWO_SIDED_STENCIL:
95 case PIPE_CAP_DEPTH_CLIP_DISABLE:
96 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
97 case PIPE_CAP_POINT_SPRITE:
98 return 1;
99 case PIPE_CAP_SM3:
100 return 1;
101 case PIPE_CAP_GLSL_FEATURE_LEVEL:
102 return 150;
103 case PIPE_CAP_MAX_RENDER_TARGETS:
104 return 8;
105 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
106 return 1;
107 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
108 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
109 case PIPE_CAP_VERTEX_COLOR_CLAMPED:
110 return 1;
111 case PIPE_CAP_TIMER_QUERY:
112 case PIPE_CAP_OCCLUSION_QUERY:
113 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
114 return 1;
115 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
116 return 4;
117 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
118 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
119 return 128;
120 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
121 case PIPE_CAP_INDEP_BLEND_ENABLE:
122 case PIPE_CAP_INDEP_BLEND_FUNC:
123 return 1;
124 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
125 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
126 return 1;
127 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
128 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
129 return 0;
130 case PIPE_CAP_SHADER_STENCIL_EXPORT:
131 return 0;
132 case PIPE_CAP_PRIMITIVE_RESTART:
133 case PIPE_CAP_TGSI_INSTANCEID:
134 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
135 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
136 case PIPE_CAP_CONDITIONAL_RENDER:
137 case PIPE_CAP_TEXTURE_BARRIER:
138 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
139 return 1;
140 case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
141 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
142 return 0; /* state trackers will know better */
143 case PIPE_CAP_USER_VERTEX_BUFFERS:
144 return 1;
145 default:
146 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
147 return 0;
148 }
149 }
150
151 static int
152 nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
153 enum pipe_shader_cap param)
154 {
155 switch (shader) {
156 case PIPE_SHADER_VERTEX:
157 /*
158 case PIPE_SHADER_TESSELLATION_CONTROL:
159 case PIPE_SHADER_TESSELLATION_EVALUATION:
160 */
161 case PIPE_SHADER_GEOMETRY:
162 case PIPE_SHADER_FRAGMENT:
163 break;
164 default:
165 return 0;
166 }
167
168 switch (param) {
169 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
170 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
171 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
172 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
173 return 16384;
174 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
175 return 16;
176 case PIPE_SHADER_CAP_MAX_INPUTS:
177 if (shader == PIPE_SHADER_VERTEX)
178 return 32;
179 if (shader == PIPE_SHADER_FRAGMENT)
180 return (0x200 + 0x20 + 0x80) / 16; /* generic + colors + TexCoords */
181 return (0x200 + 0x40 + 0x80) / 16; /* without 0x60 for per-patch inputs */
182 case PIPE_SHADER_CAP_MAX_CONSTS:
183 return 65536 / 16;
184 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
185 return 14;
186 case PIPE_SHADER_CAP_MAX_ADDRS:
187 return 1;
188 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
189 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
190 return shader != PIPE_SHADER_FRAGMENT;
191 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
192 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
193 return 1;
194 case PIPE_SHADER_CAP_MAX_PREDS:
195 return 0;
196 case PIPE_SHADER_CAP_MAX_TEMPS:
197 return NVC0_CAP_MAX_PROGRAM_TEMPS;
198 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
199 return 1;
200 case PIPE_SHADER_CAP_SUBROUTINES:
201 return 1; /* but inlining everything, we need function declarations */
202 case PIPE_SHADER_CAP_INTEGERS:
203 return 1;
204 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
205 return 16; /* would be 32 in linked (OpenGL-style) mode */
206 /*
207 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLER_VIEWS:
208 return 32;
209 */
210 default:
211 NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
212 return 0;
213 }
214 }
215
216 static float
217 nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
218 {
219 switch (param) {
220 case PIPE_CAPF_MAX_LINE_WIDTH:
221 case PIPE_CAPF_MAX_LINE_WIDTH_AA:
222 return 10.0f;
223 case PIPE_CAPF_MAX_POINT_WIDTH:
224 return 63.0f;
225 case PIPE_CAPF_MAX_POINT_WIDTH_AA:
226 return 63.375f;
227 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
228 return 16.0f;
229 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
230 return 15.0f;
231 default:
232 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
233 return 0.0f;
234 }
235 }
236
237 static void
238 nvc0_screen_destroy(struct pipe_screen *pscreen)
239 {
240 struct nvc0_screen *screen = nvc0_screen(pscreen);
241
242 if (screen->base.fence.current) {
243 nouveau_fence_wait(screen->base.fence.current);
244 nouveau_fence_ref(NULL, &screen->base.fence.current);
245 }
246 if (screen->base.pushbuf)
247 screen->base.pushbuf->user_priv = NULL;
248
249 if (screen->blitctx)
250 FREE(screen->blitctx);
251
252 nouveau_bo_ref(NULL, &screen->text);
253 nouveau_bo_ref(NULL, &screen->uniform_bo);
254 nouveau_bo_ref(NULL, &screen->tls);
255 nouveau_bo_ref(NULL, &screen->txc);
256 nouveau_bo_ref(NULL, &screen->fence.bo);
257 nouveau_bo_ref(NULL, &screen->poly_cache);
258
259 nouveau_heap_destroy(&screen->lib_code);
260 nouveau_heap_destroy(&screen->text_heap);
261
262 if (screen->tic.entries)
263 FREE(screen->tic.entries);
264
265 nouveau_mm_destroy(screen->mm_VRAM_fe0);
266
267 nouveau_object_del(&screen->eng3d);
268 nouveau_object_del(&screen->eng2d);
269 nouveau_object_del(&screen->m2mf);
270
271 nouveau_screen_fini(&screen->base);
272
273 FREE(screen);
274 }
275
276 static int
277 nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos,
278 unsigned size, const uint32_t *data)
279 {
280 struct nouveau_pushbuf *push = screen->base.pushbuf;
281
282 size /= 4;
283
284 BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2);
285 PUSH_DATA (push, (m - 0x3800) / 8);
286 PUSH_DATA (push, pos);
287 BEGIN_1IC0(push, SUBC_3D(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
288 PUSH_DATA (push, pos);
289 PUSH_DATAp(push, data, size);
290
291 return pos + size;
292 }
293
294 static void
295 nvc0_magic_3d_init(struct nouveau_pushbuf *push, uint16_t obj_class)
296 {
297 BEGIN_NVC0(push, SUBC_3D(0x10cc), 1);
298 PUSH_DATA (push, 0xff);
299 BEGIN_NVC0(push, SUBC_3D(0x10e0), 2);
300 PUSH_DATA (push, 0xff);
301 PUSH_DATA (push, 0xff);
302 BEGIN_NVC0(push, SUBC_3D(0x10ec), 2);
303 PUSH_DATA (push, 0xff);
304 PUSH_DATA (push, 0xff);
305 BEGIN_NVC0(push, SUBC_3D(0x074c), 1);
306 PUSH_DATA (push, 0x3f);
307
308 BEGIN_NVC0(push, SUBC_3D(0x16a8), 1);
309 PUSH_DATA (push, (3 << 16) | 3);
310 BEGIN_NVC0(push, SUBC_3D(0x1794), 1);
311 PUSH_DATA (push, (2 << 16) | 2);
312 BEGIN_NVC0(push, SUBC_3D(0x0de8), 1);
313 PUSH_DATA (push, 1);
314
315 BEGIN_NVC0(push, SUBC_3D(0x12ac), 1);
316 PUSH_DATA (push, 0);
317 BEGIN_NVC0(push, SUBC_3D(0x0218), 1);
318 PUSH_DATA (push, 0x10);
319 BEGIN_NVC0(push, SUBC_3D(0x10fc), 1);
320 PUSH_DATA (push, 0x10);
321 BEGIN_NVC0(push, SUBC_3D(0x1290), 1);
322 PUSH_DATA (push, 0x10);
323 BEGIN_NVC0(push, SUBC_3D(0x12d8), 2);
324 PUSH_DATA (push, 0x10);
325 PUSH_DATA (push, 0x10);
326 BEGIN_NVC0(push, SUBC_3D(0x1140), 1);
327 PUSH_DATA (push, 0x10);
328 BEGIN_NVC0(push, SUBC_3D(0x1610), 1);
329 PUSH_DATA (push, 0xe);
330
331 BEGIN_NVC0(push, SUBC_3D(0x164c), 1);
332 PUSH_DATA (push, 1 << 12);
333 BEGIN_NVC0(push, SUBC_3D(0x030c), 1);
334 PUSH_DATA (push, 0);
335 BEGIN_NVC0(push, SUBC_3D(0x0300), 1);
336 PUSH_DATA (push, 3);
337
338 BEGIN_NVC0(push, SUBC_3D(0x02d0), 1);
339 PUSH_DATA (push, 0x3fffff);
340 BEGIN_NVC0(push, SUBC_3D(0x0fdc), 1);
341 PUSH_DATA (push, 1);
342 BEGIN_NVC0(push, SUBC_3D(0x19c0), 1);
343 PUSH_DATA (push, 1);
344 BEGIN_NVC0(push, SUBC_3D(0x075c), 1);
345 PUSH_DATA (push, 3);
346
347 if (obj_class >= NVE4_3D_CLASS) {
348 BEGIN_NVC0(push, SUBC_3D(0x07fc), 1);
349 PUSH_DATA (push, 1);
350 }
351
352 /* TODO: find out what software methods 0x1528, 0x1280 and (on nve4) 0x02dc
353 * are supposed to do */
354 }
355
356 static void
357 nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
358 {
359 struct nvc0_screen *screen = nvc0_screen(pscreen);
360 struct nouveau_pushbuf *push = screen->base.pushbuf;
361
362 /* we need to do it after possible flush in MARK_RING */
363 *sequence = ++screen->base.fence.sequence;
364
365 BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4);
366 PUSH_DATAh(push, screen->fence.bo->offset);
367 PUSH_DATA (push, screen->fence.bo->offset);
368 PUSH_DATA (push, *sequence);
369 PUSH_DATA (push, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
370 (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT));
371 }
372
373 static u32
374 nvc0_screen_fence_update(struct pipe_screen *pscreen)
375 {
376 struct nvc0_screen *screen = nvc0_screen(pscreen);
377 return screen->fence.map[0];
378 }
379
380 #define FAIL_SCREEN_INIT(str, err) \
381 do { \
382 NOUVEAU_ERR(str, err); \
383 nvc0_screen_destroy(pscreen); \
384 return NULL; \
385 } while(0)
386
387 struct pipe_screen *
388 nvc0_screen_create(struct nouveau_device *dev)
389 {
390 struct nvc0_screen *screen;
391 struct pipe_screen *pscreen;
392 struct nouveau_object *chan;
393 struct nouveau_pushbuf *push;
394 uint32_t obj_class;
395 int ret;
396 unsigned i;
397 union nouveau_bo_config mm_config;
398
399 switch (dev->chipset & ~0xf) {
400 case 0xc0:
401 case 0xd0:
402 case 0xe0:
403 break;
404 default:
405 return NULL;
406 }
407
408 screen = CALLOC_STRUCT(nvc0_screen);
409 if (!screen)
410 return NULL;
411 pscreen = &screen->base.base;
412
413 screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER;
414
415 ret = nouveau_screen_init(&screen->base, dev);
416 if (ret) {
417 nvc0_screen_destroy(pscreen);
418 return NULL;
419 }
420 chan = screen->base.channel;
421 push = screen->base.pushbuf;
422 push->user_priv = screen;
423
424 pscreen->destroy = nvc0_screen_destroy;
425 pscreen->context_create = nvc0_create;
426 pscreen->is_format_supported = nvc0_screen_is_format_supported;
427 pscreen->get_param = nvc0_screen_get_param;
428 pscreen->get_shader_param = nvc0_screen_get_shader_param;
429 pscreen->get_paramf = nvc0_screen_get_paramf;
430
431 nvc0_screen_init_resource_functions(pscreen);
432
433 nouveau_screen_init_vdec(&screen->base);
434
435 ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, NULL,
436 &screen->fence.bo);
437 if (ret)
438 goto fail;
439 nouveau_bo_map(screen->fence.bo, 0, NULL);
440 screen->fence.map = screen->fence.bo->map;
441 screen->base.fence.emit = nvc0_screen_fence_emit;
442 screen->base.fence.update = nvc0_screen_fence_update;
443
444 switch (dev->chipset & 0xf0) {
445 case 0xe0:
446 obj_class = NVE4_P2MF_CLASS;
447 break;
448 default:
449 obj_class = NVC0_M2MF_CLASS;
450 break;
451 }
452 ret = nouveau_object_new(chan, 0xbeef323f, obj_class, NULL, 0,
453 &screen->m2mf);
454 if (ret)
455 FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
456
457 BEGIN_NVC0(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
458 PUSH_DATA (push, screen->m2mf->oclass);
459 if (screen->m2mf->oclass == NVE4_P2MF_CLASS) {
460 BEGIN_NVC0(push, SUBC_COPY(NV01_SUBCHAN_OBJECT), 1);
461 PUSH_DATA (push, 0xa0b5);
462 }
463
464 ret = nouveau_object_new(chan, 0xbeef902d, NVC0_2D_CLASS, NULL, 0,
465 &screen->eng2d);
466 if (ret)
467 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
468
469 BEGIN_NVC0(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
470 PUSH_DATA (push, screen->eng2d->oclass);
471 BEGIN_NVC0(push, NVC0_2D(OPERATION), 1);
472 PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY);
473 BEGIN_NVC0(push, NVC0_2D(CLIP_ENABLE), 1);
474 PUSH_DATA (push, 0);
475 BEGIN_NVC0(push, NVC0_2D(COLOR_KEY_ENABLE), 1);
476 PUSH_DATA (push, 0);
477 BEGIN_NVC0(push, SUBC_2D(0x0884), 1);
478 PUSH_DATA (push, 0x3f);
479 BEGIN_NVC0(push, SUBC_2D(0x0888), 1);
480 PUSH_DATA (push, 1);
481
482 BEGIN_NVC0(push, SUBC_2D(NVC0_GRAPH_NOTIFY_ADDRESS_HIGH), 2);
483 PUSH_DATAh(push, screen->fence.bo->offset + 16);
484 PUSH_DATA (push, screen->fence.bo->offset + 16);
485
486 switch (dev->chipset & 0xf0) {
487 case 0xe0:
488 obj_class = NVE4_3D_CLASS;
489 break;
490 case 0xd0:
491 case 0xc0:
492 default:
493 switch (dev->chipset) {
494 case 0xd9:
495 case 0xc8:
496 obj_class = NVC8_3D_CLASS;
497 break;
498 case 0xc1:
499 obj_class = NVC1_3D_CLASS;
500 break;
501 default:
502 obj_class = NVC0_3D_CLASS;
503 break;
504 }
505 break;
506 }
507 ret = nouveau_object_new(chan, 0xbeef003d, obj_class, NULL, 0,
508 &screen->eng3d);
509 if (ret)
510 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
511 screen->base.class_3d = obj_class;
512
513 BEGIN_NVC0(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
514 PUSH_DATA (push, screen->eng3d->oclass);
515
516 BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1);
517 PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS);
518
519 if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
520 /* kill shaders after about 1 second (at 100 MHz) */
521 BEGIN_NVC0(push, NVC0_3D(WATCHDOG_TIMER), 1);
522 PUSH_DATA (push, 0x17);
523 }
524
525 BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
526 PUSH_DATA (push, 1);
527
528 BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1);
529 PUSH_DATA (push, 0);
530 BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 1);
531 PUSH_DATA (push, 0);
532 BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 1);
533 PUSH_DATA (push, NVC0_3D_MULTISAMPLE_MODE_MS1);
534 BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_CTRL), 1);
535 PUSH_DATA (push, 0);
536 BEGIN_NVC0(push, NVC0_3D(LINE_WIDTH_SEPARATE), 1);
537 PUSH_DATA (push, 1);
538 BEGIN_NVC0(push, NVC0_3D(LINE_LAST_PIXEL), 1);
539 PUSH_DATA (push, 0);
540 BEGIN_NVC0(push, NVC0_3D(BLEND_SEPARATE_ALPHA), 1);
541 PUSH_DATA (push, 1);
542 BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE_COMMON), 1);
543 PUSH_DATA (push, 0);
544 if (screen->eng3d->oclass < NVE4_3D_CLASS) {
545 BEGIN_NVC0(push, NVC0_3D(TEX_MISC), 1);
546 PUSH_DATA (push, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
547 } else {
548 BEGIN_NVC0(push, NVE4_3D(TEX_CB_INDEX), 1);
549 PUSH_DATA (push, 15);
550 }
551 BEGIN_NVC0(push, NVC0_3D(CALL_LIMIT_LOG), 1);
552 PUSH_DATA (push, 8); /* 128 */
553 BEGIN_NVC0(push, NVC0_3D(ZCULL_STATCTRS_ENABLE), 1);
554 PUSH_DATA (push, 1);
555 if (screen->eng3d->oclass >= NVC1_3D_CLASS) {
556 BEGIN_NVC0(push, NVC0_3D(CACHE_SPLIT), 1);
557 PUSH_DATA (push, NVC0_3D_CACHE_SPLIT_48K_SHARED_16K_L1);
558 }
559
560 nvc0_magic_3d_init(push, screen->eng3d->oclass);
561
562 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
563 &screen->text);
564 if (ret)
565 goto fail;
566
567 /* XXX: getting a page fault at the end of the code buffer every few
568 * launches, don't use the last 256 bytes to work around them - prefetch ?
569 */
570 nouveau_heap_init(&screen->text_heap, 0, (1 << 20) - 0x100);
571
572 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, NULL,
573 &screen->uniform_bo);
574 if (ret)
575 goto fail;
576
577 for (i = 0; i < 5; ++i) {
578 /* TIC and TSC entries for each unit (nve4+ only) */
579 /* auxiliary constants (6 user clip planes, base instance id */
580 BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
581 PUSH_DATA (push, 512);
582 PUSH_DATAh(push, screen->uniform_bo->offset + (5 << 16) + (i << 9));
583 PUSH_DATA (push, screen->uniform_bo->offset + (5 << 16) + (i << 9));
584 BEGIN_NVC0(push, NVC0_3D(CB_BIND(i)), 1);
585 PUSH_DATA (push, (15 << 4) | 1);
586 if (screen->eng3d->oclass >= NVE4_3D_CLASS) {
587 unsigned j;
588 BEGIN_1IC0(push, NVC0_3D(CB_POS), 9);
589 PUSH_DATA (push, 0);
590 for (j = 0; j < 8; ++j)
591 PUSH_DATA(push, j);
592 } else {
593 BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(i)), 1);
594 PUSH_DATA (push, 0x54);
595 }
596 }
597 BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1);
598 PUSH_DATA (push, 0);
599
600 /* max MPs * max warps per MP (TODO: ask kernel) */
601 if (screen->eng3d->oclass >= NVE4_3D_CLASS)
602 screen->tls_size = 8 * 64;
603 else
604 screen->tls_size = 16 * 48;
605 screen->tls_size *= NVC0_CAP_MAX_PROGRAM_TEMPS * 16;
606 screen->tls_size = align(screen->tls_size, 1 << 17);
607
608 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17,
609 screen->tls_size, NULL, &screen->tls);
610 if (ret)
611 goto fail;
612
613 BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2);
614 PUSH_DATAh(push, screen->text->offset);
615 PUSH_DATA (push, screen->text->offset);
616 BEGIN_NVC0(push, NVC0_3D(TEMP_ADDRESS_HIGH), 4);
617 PUSH_DATAh(push, screen->tls->offset);
618 PUSH_DATA (push, screen->tls->offset);
619 PUSH_DATA (push, screen->tls_size >> 32);
620 PUSH_DATA (push, screen->tls_size);
621 BEGIN_NVC0(push, NVC0_3D(WARP_TEMP_ALLOC), 1);
622 PUSH_DATA (push, 0);
623 BEGIN_NVC0(push, NVC0_3D(LOCAL_BASE), 1);
624 PUSH_DATA (push, 0);
625
626 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
627 &screen->poly_cache);
628 if (ret)
629 goto fail;
630
631 BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
632 PUSH_DATAh(push, screen->poly_cache->offset);
633 PUSH_DATA (push, screen->poly_cache->offset);
634 PUSH_DATA (push, 3);
635
636 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, NULL,
637 &screen->txc);
638 if (ret)
639 goto fail;
640
641 BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3);
642 PUSH_DATAh(push, screen->txc->offset);
643 PUSH_DATA (push, screen->txc->offset);
644 PUSH_DATA (push, NVC0_TIC_MAX_ENTRIES - 1);
645
646 BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3);
647 PUSH_DATAh(push, screen->txc->offset + 65536);
648 PUSH_DATA (push, screen->txc->offset + 65536);
649 PUSH_DATA (push, NVC0_TSC_MAX_ENTRIES - 1);
650
651 BEGIN_NVC0(push, NVC0_3D(SCREEN_Y_CONTROL), 1);
652 PUSH_DATA (push, 0);
653 BEGIN_NVC0(push, NVC0_3D(WINDOW_OFFSET_X), 2);
654 PUSH_DATA (push, 0);
655 PUSH_DATA (push, 0);
656 BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
657 PUSH_DATA (push, 0x3f);
658
659 BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_MODE), 1);
660 PUSH_DATA (push, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
661 BEGIN_NVC0(push, NVC0_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
662 for (i = 0; i < 8 * 2; ++i)
663 PUSH_DATA(push, 0);
664 BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_EN), 1);
665 PUSH_DATA (push, 0);
666 BEGIN_NVC0(push, NVC0_3D(CLIPID_ENABLE), 1);
667 PUSH_DATA (push, 0);
668
669 /* neither scissors, viewport nor stencil mask should affect clears */
670 BEGIN_NVC0(push, NVC0_3D(CLEAR_FLAGS), 1);
671 PUSH_DATA (push, 0);
672
673 BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
674 PUSH_DATA (push, 1);
675 BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
676 PUSH_DATAf(push, 0.0f);
677 PUSH_DATAf(push, 1.0f);
678 BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1);
679 PUSH_DATA (push, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
680
681 /* We use scissors instead of exact view volume clipping,
682 * so they're always enabled.
683 */
684 BEGIN_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 3);
685 PUSH_DATA (push, 1);
686 PUSH_DATA (push, 8192 << 16);
687 PUSH_DATA (push, 8192 << 16);
688
689 #define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n);
690
691 i = 0;
692 MK_MACRO(NVC0_3D_MACRO_VERTEX_ARRAY_PER_INSTANCE, nvc0_9097_per_instance_bf);
693 MK_MACRO(NVC0_3D_MACRO_BLEND_ENABLES, nvc0_9097_blend_enables);
694 MK_MACRO(NVC0_3D_MACRO_VERTEX_ARRAY_SELECT, nvc0_9097_vertex_array_select);
695 MK_MACRO(NVC0_3D_MACRO_TEP_SELECT, nvc0_9097_tep_select);
696 MK_MACRO(NVC0_3D_MACRO_GP_SELECT, nvc0_9097_gp_select);
697 MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front);
698 MK_MACRO(NVC0_3D_MACRO_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back);
699
700 BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1);
701 PUSH_DATA (push, 1);
702 BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1);
703 PUSH_DATA (push, 1);
704 BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1);
705 PUSH_DATA (push, 0x40);
706 BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
707 PUSH_DATA (push, 0);
708 BEGIN_NVC0(push, NVC0_3D(MACRO_TEP_SELECT), 1);
709 PUSH_DATA (push, 0x30);
710 BEGIN_NVC0(push, NVC0_3D(PATCH_VERTICES), 1);
711 PUSH_DATA (push, 3);
712 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
713 PUSH_DATA (push, 0x20);
714 BEGIN_NVC0(push, NVC0_3D(SP_SELECT(0)), 1);
715 PUSH_DATA (push, 0x00);
716
717 BEGIN_NVC0(push, NVC0_3D(POINT_COORD_REPLACE), 1);
718 PUSH_DATA (push, 0);
719 BEGIN_NVC0(push, NVC0_3D(POINT_RASTER_RULES), 1);
720 PUSH_DATA (push, NVC0_3D_POINT_RASTER_RULES_OGL);
721
722 IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1);
723
724 BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
725 PUSH_DATA (push, 0xab);
726 PUSH_DATA (push, 0x00000000);
727
728 PUSH_KICK (push);
729
730 screen->tic.entries = CALLOC(4096, sizeof(void *));
731 screen->tsc.entries = screen->tic.entries + 2048;
732
733 mm_config.nvc0.tile_mode = 0;
734 mm_config.nvc0.memtype = 0xfe0;
735 screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
736
737 if (!nvc0_blitctx_create(screen))
738 goto fail;
739
740 nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
741
742 return pscreen;
743
744 fail:
745 nvc0_screen_destroy(pscreen);
746 return NULL;
747 }
748
749 int
750 nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry)
751 {
752 int i = screen->tic.next;
753
754 while (screen->tic.lock[i / 32] & (1 << (i % 32)))
755 i = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1);
756
757 screen->tic.next = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1);
758
759 if (screen->tic.entries[i])
760 nv50_tic_entry(screen->tic.entries[i])->id = -1;
761
762 screen->tic.entries[i] = entry;
763 return i;
764 }
765
766 int
767 nvc0_screen_tsc_alloc(struct nvc0_screen *screen, void *entry)
768 {
769 int i = screen->tsc.next;
770
771 while (screen->tsc.lock[i / 32] & (1 << (i % 32)))
772 i = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1);
773
774 screen->tsc.next = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1);
775
776 if (screen->tsc.entries[i])
777 nv50_tsc_entry(screen->tsc.entries[i])->id = -1;
778
779 screen->tsc.entries[i] = entry;
780 return i;
781 }