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