pan_screen.c 27.7 KB
Newer Older
1
2
3
4
5
/*
 * Copyright (C) 2008 VMware, Inc.
 * Copyright (C) 2014 Broadcom
 * Copyright (C) 2018 Alyssa Rosenzweig
 * Copyright (C) 2019 Collabora, Ltd.
6
 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
7
8
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
9
10
11
12
13
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
14
 *
15
16
17
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
18
 *
19
20
21
22
23
24
25
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
26
 *
27
 */
28

29
#include "util/u_debug.h"
30
#include "util/u_memory.h"
31
32
#include "util/format/u_format.h"
#include "util/format/u_format_s3tc.h"
33
#include "util/u_video.h"
34
#include "util/u_screen.h"
35
#include "util/os_time.h"
36
#include "util/u_process.h"
37
38
39
40
41
42
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "draw/draw_context.h"

#include <fcntl.h>

43
#include "drm-uapi/drm_fourcc.h"
44
#include "drm-uapi/panfrost_drm.h"
45

46
#include "pan_bo.h"
47
48
49
#include "pan_screen.h"
#include "pan_resource.h"
#include "pan_public.h"
50
#include "pan_util.h"
51
#include "decode.h"
52
53

#include "pan_context.h"
54
#include "midgard/midgard_compile.h"
55
#include "bifrost/bifrost_compile.h"
56
#include "panfrost-quirks.h"
57

58
static const struct debug_named_value debug_options[] = {
59
60
61
        {"msgs",      PAN_DBG_MSGS,	"Print debug messages"},
        {"trace",     PAN_DBG_TRACE,    "Trace the command stream"},
        {"deqp",      PAN_DBG_DEQP,     "Hacks for dEQP"},
62
        {"afbc",      PAN_DBG_AFBC,     "Enable AFBC buffer sharing"},
63
        {"sync",      PAN_DBG_SYNC,     "Wait for each job's completion and check for any GPU fault"},
64
        {"precompile", PAN_DBG_PRECOMPILE, "Precompile shaders for shader-db"},
65
        {"fp16",     PAN_DBG_FP16,     "Enable 16-bit support"},
66
        {"nofp16",     PAN_DBG_NOFP16,     "Disable 16-bit support"},
67
        {"gl3",       PAN_DBG_GL3,      "Enable experimental GL 3.x implementation, up to 3.3"},
68
        {"noafbc",    PAN_DBG_NO_AFBC,  "Disable AFBC support"},
69
        DEBUG_NAMED_VALUE_END
70
71
};

72
73
74
static const char *
panfrost_get_name(struct pipe_screen *screen)
{
75
        return panfrost_model_name(pan_device(screen)->gpu_id);
76
77
78
79
80
}

static const char *
panfrost_get_vendor(struct pipe_screen *screen)
{
81
        return "Panfrost";
82
83
84
85
86
87
88
89
90
91
92
}

static const char *
panfrost_get_device_vendor(struct pipe_screen *screen)
{
        return "Arm";
}

static int
panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
{
93
        /* We expose in-dev stuff for dEQP that we don't want apps to use yet */
94
        struct panfrost_device *dev = pan_device(screen);
95
        bool is_deqp = dev->debug & PAN_DBG_DEQP;
96

97
        /* Our GL 3.x implementation is WIP */
98
        bool is_gl3 = dev->debug & PAN_DBG_GL3;
99
100
        is_gl3 |= is_deqp;

101
102
103
104
105
        /* Don't expose MRT related CAPs on GPUs that don't implement them */
        bool has_mrt = !(dev->quirks & MIDGARD_SFBD);

        /* Bifrost is WIP. No MRT support yet. */
        bool is_bifrost = (dev->quirks & IS_BIFROST);
106
        has_mrt &= !is_bifrost || is_deqp;
107

108
109
110
        switch (param) {
        case PIPE_CAP_NPOT_TEXTURES:
        case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
111
112
        case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
        case PIPE_CAP_VERTEX_SHADER_SATURATE:
113
        case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
114
        case PIPE_CAP_POINT_SPRITE:
115
        case PIPE_CAP_DEPTH_CLIP_DISABLE:
116
        case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
117
118
        case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
        case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
119
120
121
                return 1;

        case PIPE_CAP_MAX_RENDER_TARGETS:
122
123
        case PIPE_CAP_FBFETCH:
        case PIPE_CAP_FBFETCH_COHERENT:
Icecream95's avatar
Icecream95 committed
124
                return has_mrt ? 8 : 1;
125

126
        case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
127
                return 1;
128

129
130
131
132
        case PIPE_CAP_SAMPLE_SHADING:
                /* WIP */
                return is_gl3 ? 1 : 0;

133
134
135
136
        case PIPE_CAP_OCCLUSION_QUERY:
        case PIPE_CAP_PRIMITIVE_RESTART:
        case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
                return true;
137

138
139
140
        case PIPE_CAP_ANISOTROPIC_FILTER:
                return !!(dev->quirks & HAS_ANISOTROPIC);

141
142
143
        /* ES3 features unsupported on Bifrost */
        case PIPE_CAP_TGSI_INSTANCEID:
        case PIPE_CAP_TEXTURE_MULTISAMPLE:
144
        case PIPE_CAP_SURFACE_SAMPLE_COUNT:
145
                return !is_bifrost || is_deqp;
146

147
        case PIPE_CAP_SAMPLER_VIEW_TARGET:
148
        case PIPE_CAP_TEXTURE_SWIZZLE:
149
150
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
151
        case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
152
153
154
155
156
157
158
159
160
161
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
        case PIPE_CAP_INDEP_BLEND_ENABLE:
        case PIPE_CAP_INDEP_BLEND_FUNC:
        case PIPE_CAP_GENERATE_MIPMAP:
        case PIPE_CAP_ACCELERATED:
        case PIPE_CAP_UMA:
        case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
        case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
        case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
        case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
162
        case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED:
163
                return 1;
164
165

        case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
166
                return (is_bifrost && !is_deqp) ? 0 : 4;
167
168
        case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
        case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
169
                return (is_bifrost && !is_deqp) ? 0 : 64;
170
        case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
171
        case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
172
                return (is_bifrost && !is_deqp) ? 0 : 1;
173
174

        case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
175
                return (is_bifrost && !is_deqp) ? 0 : 256;
176
177
178

        case PIPE_CAP_GLSL_FEATURE_LEVEL:
        case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
179
                return is_gl3 ? 330 : (is_bifrost && !is_deqp) ? 120 : 140;
180
        case PIPE_CAP_ESSL_FEATURE_LEVEL:
181
                return (is_bifrost && !is_deqp) ? 120 : 300;
182
183

        case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
184
                return 16;
185

186
        /* For faking GLES 3.1 for dEQP-GLES31 */
187
        case PIPE_CAP_IMAGE_LOAD_FORMATTED:
188
        case PIPE_CAP_CUBE_MAP_ARRAY:
189
190
        case PIPE_CAP_COMPUTE:
                return is_deqp;
191
192
        case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
                return is_deqp ? 65536 : 0;
193

194
        case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
195
196
197
198
        case PIPE_CAP_QUERY_TIMESTAMP:
        case PIPE_CAP_CONDITIONAL_RENDER:
                return is_gl3;

199
200
201
202
        /* TODO: Where does this req come from in practice? */
        case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
                return 1;

203
204
        case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
                return 4096;
205
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
206
                return (is_bifrost && !is_deqp) ? 0 : 13;
207
208
209
210
        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
                return 13;

        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
211
212
213
214
                /* Hardware is natively upper left */
                return 0;

        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
215
216
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
217
        case PIPE_CAP_TGSI_TEXCOORD:
218
219
                return 1;

220
        /* We would prefer varyings on Midgard, but proper sysvals on Bifrost */
221
222
        case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
        case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
223
        case PIPE_CAP_TGSI_FS_POINT_IS_SYSVAL:
224
                return is_bifrost;
225

226
227
        case PIPE_CAP_SEAMLESS_CUBE_MAP:
        case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
228
                return !is_bifrost || is_deqp;
229
230
231
232
233
234
235
236
237
238

        case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
                return 0xffff;

        case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
                return 0;

        case PIPE_CAP_ENDIANNESS:
                return PIPE_ENDIAN_NATIVE;

239
240
241
        case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
                return is_deqp ? 4 : 0;

242
        case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
243
                return -8;
244
245

        case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
246
                return 7;
247
248
249
250
251
252
253
254
255
256

        case PIPE_CAP_VIDEO_MEMORY: {
                uint64_t system_memory;

                if (!os_get_total_physical_memory(&system_memory))
                        return 0;

                return (int)(system_memory >> 20);
        }

257
        case PIPE_CAP_SHADER_STENCIL_EXPORT:
258
                return !is_bifrost || is_deqp;
259

260
261
262
        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
                return 4;

263
264
265
        case PIPE_CAP_MAX_VARYINGS:
                return 16;

266
        case PIPE_CAP_ALPHA_TEST:
267
268
269
        case PIPE_CAP_FLATSHADE:
        case PIPE_CAP_TWO_SIDED_COLOR:
        case PIPE_CAP_CLIP_PLANES:
270
271
                return 0;

272
273
274
275
276
277
278
        case PIPE_CAP_PACKED_STREAM_OUTPUT:
                return 0;

        case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
        case PIPE_CAP_PSIZ_CLAMPED:
                return 1;

279
        default:
280
                return u_pipe_screen_get_param_defaults(screen, param);
281
282
283
284
285
286
287
288
        }
}

static int
panfrost_get_shader_param(struct pipe_screen *screen,
                          enum pipe_shader_type shader,
                          enum pipe_shader_cap param)
{
289
        struct panfrost_device *dev = pan_device(screen);
290
        bool is_deqp = dev->debug & PAN_DBG_DEQP;
291
        bool is_fp16 = dev->debug & PAN_DBG_FP16;
292
        bool is_nofp16 = dev->debug & PAN_DBG_NOFP16;
293
        bool is_bifrost = dev->quirks & IS_BIFROST;
294

295
        if (shader != PIPE_SHADER_VERTEX &&
296
297
            shader != PIPE_SHADER_FRAGMENT &&
            !(shader == PIPE_SHADER_COMPUTE && is_deqp))
298
                return 0;
299

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
        /* this is probably not totally correct.. but it's a start: */
        switch (param) {
        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
                return 16384;

        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
                return 1024;

        case PIPE_SHADER_CAP_MAX_INPUTS:
                return 16;

        case PIPE_SHADER_CAP_MAX_OUTPUTS:
Icecream95's avatar
Icecream95 committed
315
                return shader == PIPE_SHADER_FRAGMENT ? 8 : 16;
316
317
318
319
320
321
322
323

        case PIPE_SHADER_CAP_MAX_TEMPS:
                return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */

        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
                return 16 * 1024 * sizeof(float);

        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
324
                return PAN_MAX_CONST_BUFFERS;
325
326
327
328
329

        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
                return 0;

        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
330
                return (is_bifrost && !is_deqp) ? 0 : 1;
331
332
        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
                return 0;
333

334
335
336
337
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
                return 0;

        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
338
                return 1;
339
340
341
342
343
344
345
346
347
348
349

        case PIPE_SHADER_CAP_SUBROUTINES:
                return 0;

        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
                return 0;

        case PIPE_SHADER_CAP_INTEGERS:
                return 1;

        case PIPE_SHADER_CAP_FP16:
350
        case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
351
                return (!is_nofp16 && !is_bifrost) || is_fp16;
352

353
354
        case PIPE_SHADER_CAP_FP16_DERIVATIVES:
        case PIPE_SHADER_CAP_INT16:
355
        case PIPE_SHADER_CAP_INT64_ATOMICS:
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
        case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
                return 0;

        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
                return 16; /* XXX: How many? */

        case PIPE_SHADER_CAP_PREFERRED_IR:
                return PIPE_SHADER_IR_NIR;

        case PIPE_SHADER_CAP_SUPPORTED_IRS:
371
                return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_NIR_SERIALIZED);
372
373
374
375
376
377

        case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
                return 32;

        case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
        case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
378
                return is_deqp ? 8 : 0;
379
380
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
381
                return 0;
382
383
384

        case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
        case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
385
386
387
                return 0;

        default:
388
                /* Other params are unknown */
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
                return 0;
        }

        return 0;
}

static float
panfrost_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
{
        switch (param) {
        case PIPE_CAPF_MAX_LINE_WIDTH:

        /* fall-through */
        case PIPE_CAPF_MAX_LINE_WIDTH_AA:
                return 255.0; /* arbitrary */

        case PIPE_CAPF_MAX_POINT_WIDTH:

        /* fall-through */
        case PIPE_CAPF_MAX_POINT_WIDTH_AA:
Alyssa Rosenzweig's avatar
Alyssa Rosenzweig committed
409
                return 1024.0;
410
411
412
413
414
415
416

        case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
                return 16.0;

        case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
                return 16.0; /* arbitrary */

417
418
419
420
421
        case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
        case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
        case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
                return 0.0f;

422
423
424
425
426
427
428
429
430
431
432
        default:
                debug_printf("Unexpected PIPE_CAPF %d query\n", param);
                return 0.0;
        }
}

/**
 * Query format support for creating a texture, drawing surface, etc.
 * \param format  the format to test
 * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
 */
433
static bool
434
435
436
437
438
439
440
panfrost_is_format_supported( struct pipe_screen *screen,
                              enum pipe_format format,
                              enum pipe_texture_target target,
                              unsigned sample_count,
                              unsigned storage_sample_count,
                              unsigned bind)
{
441
        struct panfrost_device *dev = pan_device(screen);
442
        bool is_bifrost = (dev->quirks & IS_BIFROST);
443
        bool is_deqp = dev->debug & PAN_DBG_DEQP;
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
        const struct util_format_description *format_desc;

        assert(target == PIPE_BUFFER ||
               target == PIPE_TEXTURE_1D ||
               target == PIPE_TEXTURE_1D_ARRAY ||
               target == PIPE_TEXTURE_2D ||
               target == PIPE_TEXTURE_2D_ARRAY ||
               target == PIPE_TEXTURE_RECT ||
               target == PIPE_TEXTURE_3D ||
               target == PIPE_TEXTURE_CUBE ||
               target == PIPE_TEXTURE_CUBE_ARRAY);

        format_desc = util_format_description(format);

        if (!format_desc)
459
                return false;
460

461
        /* MSAA 4x supported, but no more. Technically some revisions of the
462
463
         * hardware can go up to 16x but we don't support higher modes yet.
         * MSAA 2x is notably not supported and gets rounded up to MSAA 4x. */
464

465
        if (!(sample_count == 0 || sample_count == 1 || sample_count == 4))
466
467
468
                return false;

        if (MAX2(sample_count, 1) != MAX2(storage_sample_count, 1))
469
                return false;
470

471
        /* Don't advertise multisampling on Bifrost yet */
472
        if ((is_bifrost && !is_deqp) && sample_count > 1)
473
474
                return false;

475
476
477
478
        /* Z16 causes dEQP failures on t720 */
        if (format == PIPE_FORMAT_Z16_UNORM && dev->quirks & MIDGARD_SFBD)
                return false;

479
480
        /* Don't confuse poorly written apps (workaround dEQP bug) that expect
         * more alpha than they ask for */
481

482
        bool scanout = bind & (PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET);
483
484
485
        bool renderable = bind & PIPE_BIND_RENDER_TARGET;

        if (scanout && renderable && !util_format_is_rgba8_variant(format_desc))
486
                return false;
487

488
        /* Check we support the format with the given bind */
489

490
491
492
        unsigned relevant_bind = bind &
                ( PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET
                | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_SAMPLER_VIEW);
493

494
495
        struct panfrost_format fmt = dev->formats[format];
        enum mali_format indexed = MALI_EXTRACT_INDEX(fmt.hw);
496
497
498

        /* Also check that compressed texture formats are supported on this
         * particular chip. They may not be depending on system integration
Icecream95's avatar
Icecream95 committed
499
500
501
         * differences. RGTC can be emulated so is always supported. */

        bool is_rgtc = format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
502
        bool supported = panfrost_supports_compressed_format(dev, indexed);
503

Icecream95's avatar
Icecream95 committed
504
        if (!is_rgtc && !supported)
505
506
                return false;

507
        return indexed && ((relevant_bind & ~fmt.bind) == 0);
508
509
}

510
511
512
513
514
/* We always support linear and tiled operations, both external and internal.
 * We support AFBC for a subset of formats, and colourspace transform for a
 * subset of those. */

static void
515
panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen,
516
                enum pipe_format format, int max, uint64_t *modifiers, unsigned
517
                int *external_only, int *out_count, uint64_t test_modifier)
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
{
        /* Query AFBC status */
        bool afbc = panfrost_format_supports_afbc(format);
        bool ytr = panfrost_afbc_can_ytr(format);

        /* Don't advertise AFBC before T760 */
        struct panfrost_device *dev = pan_device(screen);
        afbc &= !(dev->quirks & MIDGARD_NO_AFBC);

        /* XXX: AFBC scanout is broken on mainline RK3399 with older kernels */
        afbc &= (dev->debug & PAN_DBG_AFBC);

        unsigned count = 0;

        for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) {
                if (drm_is_afbc(pan_best_modifiers[i]) && !afbc)
                        continue;

                if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr)
                        continue;

539
540
541
542
                if (test_modifier != DRM_FORMAT_MOD_INVALID &&
                    test_modifier != pan_best_modifiers[i])
                        continue;

543
544
545
546
547
548
549
550
551
552
553
554
555
                count++;

                if (max > (int) count) {
                        modifiers[count] = pan_best_modifiers[i];

                        if (external_only)
                                external_only[count] = false;
                }
        }

        *out_count = count;
}

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
static void
panfrost_query_dmabuf_modifiers(struct pipe_screen *screen,
                enum pipe_format format, int max, uint64_t *modifiers, unsigned
                int *external_only, int *out_count)
{
        panfrost_walk_dmabuf_modifiers(screen, format, max, modifiers,
                external_only, out_count, DRM_FORMAT_MOD_INVALID);
}

static bool
panfrost_is_dmabuf_modifier_supported(struct pipe_screen *screen,
                uint64_t modifier, enum pipe_format format,
                bool *external_only)
{
        uint64_t unused;
        unsigned int uint_extern_only = 0;
        int count;

        panfrost_walk_dmabuf_modifiers(screen, format, 1, &unused,
                &uint_extern_only, &count, modifier);

        if (external_only)
           *external_only = uint_extern_only ? true : false;

        return count > 0;
}

583
584
585
586
static int
panfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
                enum pipe_compute_cap param, void *ret)
{
587
        struct panfrost_device *dev = pan_device(pscreen);
588
589
	const char * const ir = "panfrost";

590
	if (!(dev->debug & PAN_DBG_DEQP))
591
592
593
594
595
596
597
598
599
600
		return 0;

#define RET(x) do {                  \
   if (ret)                          \
      memcpy(ret, x, sizeof(x));     \
   return sizeof(x);                 \
} while (0)

	switch (param) {
	case PIPE_COMPUTE_CAP_ADDRESS_BITS:
601
		RET((uint32_t []){ 64 });
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650

	case PIPE_COMPUTE_CAP_IR_TARGET:
		if (ret)
			sprintf(ret, "%s", ir);
		return strlen(ir) * sizeof(char);

	case PIPE_COMPUTE_CAP_GRID_DIMENSION:
		RET((uint64_t []) { 3 });

	case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
		RET(((uint64_t []) { 65535, 65535, 65535 }));

	case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
		RET(((uint64_t []) { 1024, 1024, 64 }));

	case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
		RET((uint64_t []) { 1024 });

	case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
		RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ });

	case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
		RET((uint64_t []) { 32768 });

	case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
	case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
		RET((uint64_t []) { 4096 });

	case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
		RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ });

	case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
		RET((uint32_t []) { 800 /* MHz -- TODO */ });

	case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
		RET((uint32_t []) { 9999 });  // TODO

	case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
		RET((uint32_t []) { 1 }); // TODO

	case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:
		RET((uint32_t []) { 32 });  // TODO

	case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
		RET((uint64_t []) { 1024 }); // TODO
	}

	return 0;
}
651
652

static void
653
panfrost_destroy_screen(struct pipe_screen *pscreen)
654
{
655
        panfrost_close_device(pan_device(pscreen));
656
        ralloc_free(pscreen);
657
658
659
660
661
662
663
664
665
}

static uint64_t
panfrost_get_timestamp(struct pipe_screen *_screen)
{
        return os_time_get_nano();
}

static void
666
panfrost_fence_reference(struct pipe_screen *pscreen,
667
668
669
                         struct pipe_fence_handle **ptr,
                         struct pipe_fence_handle *fence)
{
670
        struct panfrost_device *dev = pan_device(pscreen);
671
672
673
674
675
        struct panfrost_fence **p = (struct panfrost_fence **)ptr;
        struct panfrost_fence *f = (struct panfrost_fence *)fence;
        struct panfrost_fence *old = *p;

        if (pipe_reference(&(*p)->reference, &f->reference)) {
676
                drmSyncobjDestroy(dev->fd, old->syncobj);
677
678
679
                free(old);
        }
        *p = f;
680
681
}

682
static bool
683
panfrost_fence_finish(struct pipe_screen *pscreen,
684
685
686
687
                      struct pipe_context *ctx,
                      struct pipe_fence_handle *fence,
                      uint64_t timeout)
{
688
        struct panfrost_device *dev = pan_device(pscreen);
689
690
        struct panfrost_fence *f = (struct panfrost_fence *)fence;
        int ret;
691

692
        if (f->signaled)
693
694
                return true;

695
696
697
698
        uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);
        if (abs_timeout == OS_TIMEOUT_INFINITE)
                abs_timeout = INT64_MAX;

699
700
        ret = drmSyncobjWait(dev->fd, &f->syncobj,
                             1,
701
702
                             abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL,
                             NULL);
703

704
705
        f->signaled = (ret >= 0);
        return f->signaled;
706
707
708
}

struct panfrost_fence *
Boris Brezillon's avatar
Boris Brezillon committed
709
panfrost_fence_create(struct panfrost_context *ctx)
710
711
712
713
714
{
        struct panfrost_fence *f = calloc(1, sizeof(*f));
        if (!f)
                return NULL;

Boris Brezillon's avatar
Boris Brezillon committed
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
        struct panfrost_device *dev = pan_device(ctx->base.screen);
        int fd = -1, ret;

        /* Snapshot the last rendering out fence. We'd rather have another
         * syncobj instead of a sync file, but this is all we get.
         * (HandleToFD/FDToHandle just gives you another syncobj ID for the
         * same syncobj).
         */
        ret = drmSyncobjExportSyncFile(dev->fd, ctx->syncobj, &fd);
        if (ret || fd == -1) {
                fprintf(stderr, "export failed\n");
                goto err_free_fence;
        }

        ret = drmSyncobjCreate(dev->fd, 0, &f->syncobj);
        if (ret) {
                fprintf(stderr, "create syncobj failed\n");
                goto err_close_fd;
        }

        ret = drmSyncobjImportSyncFile(dev->fd, f->syncobj, fd);
        if (ret) {
                fprintf(stderr, "create syncobj failed\n");
                goto err_destroy_syncobj;
        }

        assert(f->syncobj != ctx->syncobj);
        close(fd);
743
744
745
        pipe_reference_init(&f->reference, 1);

        return f;
Boris Brezillon's avatar
Boris Brezillon committed
746
747
748
749
750
751
752
753

err_destroy_syncobj:
        drmSyncobjDestroy(dev->fd, f->syncobj);
err_close_fd:
        close(fd);
err_free_fence:
        free(f);
        return NULL;
754
755
756
757
758
759
760
}

static const void *
panfrost_screen_get_compiler_options(struct pipe_screen *pscreen,
                                     enum pipe_shader_ir ir,
                                     enum pipe_shader_type shader)
{
761
762
763
764
        if (pan_device(pscreen)->quirks & IS_BIFROST)
                return &bifrost_nir_options;
        else
                return &midgard_nir_options;
765
766
767
}

struct pipe_screen *
768
panfrost_create_screen(int fd, struct renderonly *ro)
769
{
770
771
772
        /* Create the screen */
        struct panfrost_screen *screen = rzalloc(NULL, struct panfrost_screen);

773
774
775
        if (!screen)
                return NULL;

776
        struct panfrost_device *dev = pan_device(&screen->base);
777
        panfrost_open_device(screen, fd, dev);
778

779
780
        dev->debug = debug_get_flags_option("PAN_MESA_DEBUG", debug_options, 0);

781
782
783
        if (dev->debug & PAN_DBG_NO_AFBC)
                dev->quirks |= MIDGARD_NO_AFBC;

784
        if (ro) {
785
786
                dev->ro = renderonly_dup(ro);
                if (!dev->ro) {
787
788
789
                        if (dev->debug & PAN_DBG_MSGS)
                                fprintf(stderr, "Failed to dup renderonly object\n");

790
791
792
793
794
                        free(screen);
                        return NULL;
                }
        }

795
        /* Check if we're loading against a supported GPU model. */
796

797
        switch (dev->gpu_id) {
798
        case 0x720: /* T720 */
799
        case 0x750: /* T760 */
800
801
        case 0x820: /* T820 */
        case 0x860: /* T860 */
802
        case 0x6221: /* G72 */
803
804
        case 0x7093: /* G31 */
        case 0x7212: /* G52 */
805
                break;
806
807
        default:
                /* Fail to load against untested models */
808
                debug_printf("panfrost: Unsupported model %X", dev->gpu_id);
809
                panfrost_destroy_screen(&(screen->base));
810
                return NULL;
811
812
        }

813
814
        if (dev->debug & (PAN_DBG_TRACE | PAN_DBG_SYNC))
                pandecode_initialize(!(dev->debug & PAN_DBG_TRACE));
815

816
817
818
819
820
821
822
        screen->base.destroy = panfrost_destroy_screen;

        screen->base.get_name = panfrost_get_name;
        screen->base.get_vendor = panfrost_get_vendor;
        screen->base.get_device_vendor = panfrost_get_device_vendor;
        screen->base.get_param = panfrost_get_param;
        screen->base.get_shader_param = panfrost_get_shader_param;
823
        screen->base.get_compute_param = panfrost_get_compute_param;
824
825
826
        screen->base.get_paramf = panfrost_get_paramf;
        screen->base.get_timestamp = panfrost_get_timestamp;
        screen->base.is_format_supported = panfrost_is_format_supported;
827
        screen->base.query_dmabuf_modifiers = panfrost_query_dmabuf_modifiers;
828
829
        screen->base.is_dmabuf_modifier_supported =
               panfrost_is_dmabuf_modifier_supported;
830
        screen->base.context_create = panfrost_create_context;
831
832
833
        screen->base.get_compiler_options = panfrost_screen_get_compiler_options;
        screen->base.fence_reference = panfrost_fence_reference;
        screen->base.fence_finish = panfrost_fence_finish;
834
        screen->base.set_damage_region = panfrost_resource_set_damage_region;
835

836
        panfrost_resource_screen_init(&screen->base);
837
        panfrost_init_blit_shaders(dev);
838

839
        return &screen->base;
840
}