~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/v3d/v3d_screen.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2014-2017 Broadcom
3
 
 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
4
 
 *
5
 
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 
 * copy of this software and associated documentation files (the "Software"),
7
 
 * to deal in the Software without restriction, including without limitation
8
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 
 * and/or sell copies of the Software, and to permit persons to whom the
10
 
 * Software is furnished to do so, subject to the following conditions:
11
 
 *
12
 
 * The above copyright notice and this permission notice (including the next
13
 
 * paragraph) shall be included in all copies or substantial portions of the
14
 
 * Software.
15
 
 *
16
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
 
 * IN THE SOFTWARE.
23
 
 */
24
 
 
25
 
#include <sys/sysinfo.h>
26
 
 
27
 
#include "common/v3d_device_info.h"
28
 
#include "common/v3d_limits.h"
29
 
#include "util/os_misc.h"
30
 
#include "pipe/p_defines.h"
31
 
#include "pipe/p_screen.h"
32
 
#include "pipe/p_state.h"
33
 
 
34
 
#include "util/u_debug.h"
35
 
#include "util/u_memory.h"
36
 
#include "util/format/u_format.h"
37
 
#include "util/u_hash_table.h"
38
 
#include "util/u_screen.h"
39
 
#include "util/u_transfer_helper.h"
40
 
#include "util/ralloc.h"
41
 
#include "util/xmlconfig.h"
42
 
 
43
 
#include <xf86drm.h>
44
 
#include "v3d_screen.h"
45
 
#include "v3d_context.h"
46
 
#include "v3d_resource.h"
47
 
#include "compiler/v3d_compiler.h"
48
 
#include "drm-uapi/drm_fourcc.h"
49
 
 
50
 
static const char *
51
 
v3d_screen_get_name(struct pipe_screen *pscreen)
52
 
{
53
 
        struct v3d_screen *screen = v3d_screen(pscreen);
54
 
 
55
 
        if (!screen->name) {
56
 
                screen->name = ralloc_asprintf(screen,
57
 
                                               "V3D %d.%d",
58
 
                                               screen->devinfo.ver / 10,
59
 
                                               screen->devinfo.ver % 10);
60
 
        }
61
 
 
62
 
        return screen->name;
63
 
}
64
 
 
65
 
static const char *
66
 
v3d_screen_get_vendor(struct pipe_screen *pscreen)
67
 
{
68
 
        return "Broadcom";
69
 
}
70
 
 
71
 
static void
72
 
v3d_screen_destroy(struct pipe_screen *pscreen)
73
 
{
74
 
        struct v3d_screen *screen = v3d_screen(pscreen);
75
 
 
76
 
        _mesa_hash_table_destroy(screen->bo_handles, NULL);
77
 
        v3d_bufmgr_destroy(pscreen);
78
 
        slab_destroy_parent(&screen->transfer_pool);
79
 
        if (screen->ro)
80
 
                screen->ro->destroy(screen->ro);
81
 
 
82
 
        if (using_v3d_simulator)
83
 
                v3d_simulator_destroy(screen->sim_file);
84
 
 
85
 
        v3d_compiler_free(screen->compiler);
86
 
 
87
 
#ifdef ENABLE_SHADER_CACHE
88
 
        if (screen->disk_cache)
89
 
                disk_cache_destroy(screen->disk_cache);
90
 
#endif
91
 
 
92
 
        u_transfer_helper_destroy(pscreen->transfer_helper);
93
 
 
94
 
        close(screen->fd);
95
 
        ralloc_free(pscreen);
96
 
}
97
 
 
98
 
static bool
99
 
v3d_has_feature(struct v3d_screen *screen, enum drm_v3d_param feature)
100
 
{
101
 
        struct drm_v3d_get_param p = {
102
 
                .param = feature,
103
 
        };
104
 
        int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &p);
105
 
 
106
 
        if (ret != 0)
107
 
                return false;
108
 
 
109
 
        return p.value;
110
 
}
111
 
 
112
 
static int
113
 
v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
114
 
{
115
 
        struct v3d_screen *screen = v3d_screen(pscreen);
116
 
 
117
 
        switch (param) {
118
 
                /* Supported features (boolean caps). */
119
 
        case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
120
 
        case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
121
 
        case PIPE_CAP_NPOT_TEXTURES:
122
 
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
123
 
        case PIPE_CAP_TEXTURE_MULTISAMPLE:
124
 
        case PIPE_CAP_TEXTURE_SWIZZLE:
125
 
        case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
126
 
        case PIPE_CAP_START_INSTANCE:
127
 
        case PIPE_CAP_VS_INSTANCEID:
128
 
        case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
129
 
        case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
130
 
        case PIPE_CAP_VERTEX_SHADER_SATURATE:
131
 
        case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
132
 
        case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
133
 
        case PIPE_CAP_PRIMITIVE_RESTART:
134
 
        case PIPE_CAP_OCCLUSION_QUERY:
135
 
        case PIPE_CAP_POINT_SPRITE:
136
 
        case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
137
 
        case PIPE_CAP_DRAW_INDIRECT:
138
 
        case PIPE_CAP_MULTI_DRAW_INDIRECT:
139
 
        case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
140
 
        case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
141
 
        case PIPE_CAP_SHADER_CAN_READ_OUTPUTS:
142
 
        case PIPE_CAP_SHADER_PACK_HALF_FLOAT:
143
 
        case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
144
 
        case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
145
 
        case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
146
 
        case PIPE_CAP_TGSI_TEXCOORD:
147
 
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
148
 
        case PIPE_CAP_SAMPLER_VIEW_TARGET:
149
 
        case PIPE_CAP_ANISOTROPIC_FILTER:
150
 
                return 1;
151
 
 
152
 
        case PIPE_CAP_TEXTURE_QUERY_LOD:
153
 
                return screen->devinfo.ver >= 42;
154
 
                break;
155
 
 
156
 
        case PIPE_CAP_PACKED_UNIFORMS:
157
 
                /* We can't enable this flag, because it results in load_ubo
158
 
                 * intrinsics across a 16b boundary, but v3d's TMU general
159
 
                 * memory accesses wrap on 16b boundaries.
160
 
                 */
161
 
                return 0;
162
 
 
163
 
        case PIPE_CAP_NIR_IMAGES_AS_DEREF:
164
 
                return 0;
165
 
 
166
 
        case PIPE_CAP_TEXTURE_TRANSFER_MODES:
167
 
                /* XXX perf: we don't want to emit these extra blits for
168
 
                 * glReadPixels(), since we still have to do an uncached read
169
 
                 * from the GPU of the result after waiting for the TFU blit
170
 
                 * to happen.  However, disabling this introduces instability
171
 
                 * in
172
 
                 * dEQP-GLES31.functional.image_load_store.early_fragment_tests.*
173
 
                 * and corruption in chromium's rendering.
174
 
                 */
175
 
                return PIPE_TEXTURE_TRANSFER_BLIT;
176
 
 
177
 
        case PIPE_CAP_COMPUTE:
178
 
                return screen->has_csd && screen->devinfo.ver >= 41;
179
 
 
180
 
        case PIPE_CAP_GENERATE_MIPMAP:
181
 
                return v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_TFU);
182
 
 
183
 
        case PIPE_CAP_INDEP_BLEND_ENABLE:
184
 
                return screen->devinfo.ver >= 40;
185
 
 
186
 
        case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
187
 
                return V3D_NON_COHERENT_ATOM_SIZE;
188
 
 
189
 
        case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
190
 
                if (screen->devinfo.ver < 40)
191
 
                        return 0;
192
 
                return 4;
193
 
 
194
 
        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
195
 
                if (screen->has_cache_flush)
196
 
                        return 4;
197
 
                else
198
 
                        return 0; /* Disables shader storage */
199
 
 
200
 
        case PIPE_CAP_GLSL_FEATURE_LEVEL:
201
 
                return 330;
202
 
 
203
 
        case PIPE_CAP_ESSL_FEATURE_LEVEL:
204
 
                return 310;
205
 
 
206
 
        case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
207
 
                return 140;
208
 
 
209
 
        case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
210
 
                return 1;
211
 
        case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT:
212
 
                return 0;
213
 
        case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER:
214
 
                if (screen->devinfo.ver >= 40)
215
 
                        return 0;
216
 
                else
217
 
                        return 1;
218
 
        case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
219
 
                if (screen->devinfo.ver >= 40)
220
 
                        return 1;
221
 
                else
222
 
                        return 0;
223
 
 
224
 
        case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
225
 
        case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
226
 
        case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
227
 
                return 1;
228
 
 
229
 
        case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
230
 
                return 4;
231
 
 
232
 
        case PIPE_CAP_MAX_VARYINGS:
233
 
                return V3D_MAX_FS_INPUTS / 4;
234
 
 
235
 
                /* Texturing. */
236
 
        case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
237
 
                if (screen->devinfo.ver < 40)
238
 
                        return 2048;
239
 
                else if (screen->nonmsaa_texture_size_limit)
240
 
                        return 7680;
241
 
                else
242
 
                        return 4096;
243
 
        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
244
 
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
245
 
                if (screen->devinfo.ver < 40)
246
 
                        return 12;
247
 
                else
248
 
                        return V3D_MAX_MIP_LEVELS;
249
 
        case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
250
 
                return 2048;
251
 
 
252
 
                /* Render targets. */
253
 
        case PIPE_CAP_MAX_RENDER_TARGETS:
254
 
                return 4;
255
 
 
256
 
        case PIPE_CAP_VENDOR_ID:
257
 
                return 0x14E4;
258
 
        case PIPE_CAP_ACCELERATED:
259
 
                return 1;
260
 
        case PIPE_CAP_VIDEO_MEMORY: {
261
 
                uint64_t system_memory;
262
 
 
263
 
                if (!os_get_total_physical_memory(&system_memory))
264
 
                        return 0;
265
 
 
266
 
                return (int)(system_memory >> 20);
267
 
        }
268
 
        case PIPE_CAP_UMA:
269
 
                return 1;
270
 
 
271
 
        case PIPE_CAP_ALPHA_TEST:
272
 
        case PIPE_CAP_FLATSHADE:
273
 
        case PIPE_CAP_TWO_SIDED_COLOR:
274
 
        case PIPE_CAP_VERTEX_COLOR_CLAMPED:
275
 
        case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
276
 
        case PIPE_CAP_GL_CLAMP:
277
 
                return 0;
278
 
 
279
 
        /* Geometry shaders */
280
 
        case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
281
 
                /* Minimum required by GLES 3.2 */
282
 
                return 1024;
283
 
        case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
284
 
                /* MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS / 4 */
285
 
                return 256;
286
 
        case PIPE_CAP_MAX_GS_INVOCATIONS:
287
 
                return 32;
288
 
 
289
 
        case PIPE_CAP_SUPPORTED_PRIM_MODES:
290
 
        case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
291
 
                return screen->prim_types;
292
 
 
293
 
        case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
294
 
                return true;
295
 
 
296
 
        case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
297
 
                return 256;
298
 
 
299
 
        case PIPE_CAP_IMAGE_STORE_FORMATTED:
300
 
                return false;
301
 
 
302
 
        default:
303
 
                return u_pipe_screen_get_param_defaults(pscreen, param);
304
 
        }
305
 
}
306
 
 
307
 
static float
308
 
v3d_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
309
 
{
310
 
        switch (param) {
311
 
        case PIPE_CAPF_MIN_LINE_WIDTH:
312
 
        case PIPE_CAPF_MIN_LINE_WIDTH_AA:
313
 
        case PIPE_CAPF_MIN_POINT_SIZE:
314
 
        case PIPE_CAPF_MIN_POINT_SIZE_AA:
315
 
           return 1;
316
 
 
317
 
        case PIPE_CAPF_POINT_SIZE_GRANULARITY:
318
 
        case PIPE_CAPF_LINE_WIDTH_GRANULARITY:
319
 
           return 0.1;
320
 
 
321
 
        case PIPE_CAPF_MAX_LINE_WIDTH:
322
 
        case PIPE_CAPF_MAX_LINE_WIDTH_AA:
323
 
                return V3D_MAX_LINE_WIDTH;
324
 
 
325
 
        case PIPE_CAPF_MAX_POINT_SIZE:
326
 
        case PIPE_CAPF_MAX_POINT_SIZE_AA:
327
 
                return V3D_MAX_POINT_SIZE;
328
 
 
329
 
        case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
330
 
                return 16.0f;
331
 
        case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
332
 
                return 16.0f;
333
 
 
334
 
        case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
335
 
        case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
336
 
        case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
337
 
                return 0.0f;
338
 
        default:
339
 
                fprintf(stderr, "unknown paramf %d\n", param);
340
 
                return 0;
341
 
        }
342
 
}
343
 
 
344
 
static int
345
 
v3d_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
346
 
                           enum pipe_shader_cap param)
347
 
{
348
 
        struct v3d_screen *screen = v3d_screen(pscreen);
349
 
 
350
 
        switch (shader) {
351
 
        case PIPE_SHADER_VERTEX:
352
 
        case PIPE_SHADER_FRAGMENT:
353
 
                break;
354
 
        case PIPE_SHADER_COMPUTE:
355
 
                if (!screen->has_csd)
356
 
                        return 0;
357
 
                break;
358
 
        case PIPE_SHADER_GEOMETRY:
359
 
                if (screen->devinfo.ver < 41)
360
 
                        return 0;
361
 
                break;
362
 
        default:
363
 
                return 0;
364
 
        }
365
 
 
366
 
        /* this is probably not totally correct.. but it's a start: */
367
 
        switch (param) {
368
 
        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
369
 
        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
370
 
        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
371
 
        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
372
 
                return 16384;
373
 
 
374
 
        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
375
 
                return UINT_MAX;
376
 
 
377
 
        case PIPE_SHADER_CAP_MAX_INPUTS:
378
 
                switch (shader) {
379
 
                case PIPE_SHADER_VERTEX:
380
 
                        return V3D_MAX_VS_INPUTS / 4;
381
 
                case PIPE_SHADER_GEOMETRY:
382
 
                        return V3D_MAX_GS_INPUTS / 4;
383
 
                case PIPE_SHADER_FRAGMENT:
384
 
                        return V3D_MAX_FS_INPUTS / 4;
385
 
                default:
386
 
                        return 0;
387
 
                };
388
 
        case PIPE_SHADER_CAP_MAX_OUTPUTS:
389
 
                if (shader == PIPE_SHADER_FRAGMENT)
390
 
                        return 4;
391
 
                else
392
 
                        return V3D_MAX_FS_INPUTS / 4;
393
 
        case PIPE_SHADER_CAP_MAX_TEMPS:
394
 
                return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
395
 
        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
396
 
                /* Note: Limited by the offset size in
397
 
                 * v3d_unit_data_create().
398
 
                 */
399
 
                return 16 * 1024 * sizeof(float);
400
 
        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
401
 
                return 16;
402
 
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
403
 
                return 0;
404
 
        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
405
 
                /* We don't currently support this in the backend, but that is
406
 
                 * okay because our NIR compiler sets the option
407
 
                 * lower_all_io_to_temps, which will eliminate indirect
408
 
                 * indexing on all input/output variables by translating it to
409
 
                 * indirect indexing on temporary variables instead, which we
410
 
                 * will then lower to scratch. We prefer this over setting this
411
 
                 * to 0, which would cause if-ladder injection to eliminate
412
 
                 * indirect indexing on inputs.
413
 
                 */
414
 
                return 1;
415
 
        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
416
 
                return 1;
417
 
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
418
 
                return 1;
419
 
        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
420
 
                return 1;
421
 
        case PIPE_SHADER_CAP_SUBROUTINES:
422
 
                return 0;
423
 
        case PIPE_SHADER_CAP_INTEGERS:
424
 
                return 1;
425
 
        case PIPE_SHADER_CAP_FP16:
426
 
        case PIPE_SHADER_CAP_FP16_DERIVATIVES:
427
 
        case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
428
 
        case PIPE_SHADER_CAP_INT16:
429
 
        case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
430
 
        case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
431
 
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
432
 
        case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
433
 
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
434
 
        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
435
 
        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
436
 
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
437
 
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
438
 
                return 0;
439
 
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
440
 
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
441
 
                return V3D_OPENGL_MAX_TEXTURE_SAMPLERS;
442
 
 
443
 
        case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
444
 
                if (screen->has_cache_flush) {
445
 
                        if (shader == PIPE_SHADER_VERTEX ||
446
 
                            shader == PIPE_SHADER_GEOMETRY) {
447
 
                                return 0;
448
 
                        }
449
 
                        return PIPE_MAX_SHADER_BUFFERS;
450
 
                 } else {
451
 
                        return 0;
452
 
                 }
453
 
 
454
 
        case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
455
 
                if (screen->has_cache_flush) {
456
 
                        if (screen->devinfo.ver < 41)
457
 
                                return 0;
458
 
                        else
459
 
                                return PIPE_MAX_SHADER_IMAGES;
460
 
                } else {
461
 
                        return 0;
462
 
                }
463
 
 
464
 
        case PIPE_SHADER_CAP_PREFERRED_IR:
465
 
                return PIPE_SHADER_IR_NIR;
466
 
        case PIPE_SHADER_CAP_SUPPORTED_IRS:
467
 
                return 1 << PIPE_SHADER_IR_NIR;
468
 
        case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
469
 
                /* We use NIR's loop unrolling */
470
 
                return 0;
471
 
        case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
472
 
        case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
473
 
                return 0;
474
 
        default:
475
 
                fprintf(stderr, "unknown shader param %d\n", param);
476
 
                return 0;
477
 
        }
478
 
        return 0;
479
 
}
480
 
 
481
 
static int
482
 
v3d_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
483
 
                      enum pipe_compute_cap param, void *ret)
484
 
{
485
 
        struct v3d_screen *screen = v3d_screen(pscreen);
486
 
 
487
 
        if (!screen->has_csd)
488
 
                return 0;
489
 
 
490
 
#define RET(x) do {                                     \
491
 
                if (ret)                                \
492
 
                        memcpy(ret, x, sizeof(x));      \
493
 
                return sizeof(x);                       \
494
 
        } while (0)
495
 
 
496
 
        switch (param) {
497
 
        case PIPE_COMPUTE_CAP_ADDRESS_BITS:
498
 
                RET((uint32_t []) { 32 });
499
 
                break;
500
 
 
501
 
        case PIPE_COMPUTE_CAP_IR_TARGET:
502
 
                sprintf(ret, "v3d");
503
 
                return strlen(ret);
504
 
 
505
 
        case PIPE_COMPUTE_CAP_GRID_DIMENSION:
506
 
                RET((uint64_t []) { 3 });
507
 
 
508
 
        case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
509
 
                /* GL_MAX_COMPUTE_SHADER_WORK_GROUP_COUNT: The CSD has a
510
 
                 * 16-bit field for the number of workgroups in each
511
 
                 * dimension.
512
 
                 */
513
 
                RET(((uint64_t []) { 65535, 65535, 65535 }));
514
 
 
515
 
        case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
516
 
                /* GL_MAX_COMPUTE_WORK_GROUP_SIZE */
517
 
                RET(((uint64_t []) { 256, 256, 256 }));
518
 
 
519
 
        case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
520
 
        case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
521
 
                /* GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: This is
522
 
                 * limited by WG_SIZE in the CSD.
523
 
                 */
524
 
                RET((uint64_t []) { 256 });
525
 
 
526
 
        case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
527
 
                RET((uint64_t []) { 1024 * 1024 * 1024 });
528
 
 
529
 
        case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
530
 
                /* GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */
531
 
                RET((uint64_t []) { 32768 });
532
 
 
533
 
        case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
534
 
        case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
535
 
                RET((uint64_t []) { 4096 });
536
 
 
537
 
        case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: {
538
 
                struct sysinfo si;
539
 
                sysinfo(&si);
540
 
                RET((uint64_t []) { si.totalram });
541
 
        }
542
 
 
543
 
        case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
544
 
                /* OpenCL only */
545
 
                RET((uint32_t []) { 0 });
546
 
 
547
 
        case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
548
 
                RET((uint32_t []) { 1 });
549
 
 
550
 
        case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
551
 
                RET((uint32_t []) { 1 });
552
 
 
553
 
        case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:
554
 
                RET((uint32_t []) { 16 });
555
 
 
556
 
        }
557
 
 
558
 
        return 0;
559
 
}
560
 
 
561
 
static bool
562
 
v3d_screen_is_format_supported(struct pipe_screen *pscreen,
563
 
                               enum pipe_format format,
564
 
                               enum pipe_texture_target target,
565
 
                               unsigned sample_count,
566
 
                               unsigned storage_sample_count,
567
 
                               unsigned usage)
568
 
{
569
 
        struct v3d_screen *screen = v3d_screen(pscreen);
570
 
 
571
 
        if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
572
 
                return false;
573
 
 
574
 
        if (sample_count > 1 && sample_count != V3D_MAX_SAMPLES)
575
 
                return false;
576
 
 
577
 
        if (target >= PIPE_MAX_TEXTURE_TYPES) {
578
 
                return false;
579
 
        }
580
 
 
581
 
        if (usage & PIPE_BIND_VERTEX_BUFFER) {
582
 
                switch (format) {
583
 
                case PIPE_FORMAT_R32G32B32A32_FLOAT:
584
 
                case PIPE_FORMAT_R32G32B32_FLOAT:
585
 
                case PIPE_FORMAT_R32G32_FLOAT:
586
 
                case PIPE_FORMAT_R32_FLOAT:
587
 
                case PIPE_FORMAT_R32G32B32A32_SNORM:
588
 
                case PIPE_FORMAT_R32G32B32_SNORM:
589
 
                case PIPE_FORMAT_R32G32_SNORM:
590
 
                case PIPE_FORMAT_R32_SNORM:
591
 
                case PIPE_FORMAT_R32G32B32A32_SSCALED:
592
 
                case PIPE_FORMAT_R32G32B32_SSCALED:
593
 
                case PIPE_FORMAT_R32G32_SSCALED:
594
 
                case PIPE_FORMAT_R32_SSCALED:
595
 
                case PIPE_FORMAT_R16G16B16A16_UNORM:
596
 
                case PIPE_FORMAT_R16G16B16_UNORM:
597
 
                case PIPE_FORMAT_R16G16_UNORM:
598
 
                case PIPE_FORMAT_R16_UNORM:
599
 
                case PIPE_FORMAT_R16G16B16A16_SNORM:
600
 
                case PIPE_FORMAT_R16G16B16_SNORM:
601
 
                case PIPE_FORMAT_R16G16_SNORM:
602
 
                case PIPE_FORMAT_R16_SNORM:
603
 
                case PIPE_FORMAT_R16G16B16A16_USCALED:
604
 
                case PIPE_FORMAT_R16G16B16_USCALED:
605
 
                case PIPE_FORMAT_R16G16_USCALED:
606
 
                case PIPE_FORMAT_R16_USCALED:
607
 
                case PIPE_FORMAT_R16G16B16A16_SSCALED:
608
 
                case PIPE_FORMAT_R16G16B16_SSCALED:
609
 
                case PIPE_FORMAT_R16G16_SSCALED:
610
 
                case PIPE_FORMAT_R16_SSCALED:
611
 
                case PIPE_FORMAT_B8G8R8A8_UNORM:
612
 
                case PIPE_FORMAT_R8G8B8A8_UNORM:
613
 
                case PIPE_FORMAT_R8G8B8_UNORM:
614
 
                case PIPE_FORMAT_R8G8_UNORM:
615
 
                case PIPE_FORMAT_R8_UNORM:
616
 
                case PIPE_FORMAT_R8G8B8A8_SNORM:
617
 
                case PIPE_FORMAT_R8G8B8_SNORM:
618
 
                case PIPE_FORMAT_R8G8_SNORM:
619
 
                case PIPE_FORMAT_R8_SNORM:
620
 
                case PIPE_FORMAT_R8G8B8A8_USCALED:
621
 
                case PIPE_FORMAT_R8G8B8_USCALED:
622
 
                case PIPE_FORMAT_R8G8_USCALED:
623
 
                case PIPE_FORMAT_R8_USCALED:
624
 
                case PIPE_FORMAT_R8G8B8A8_SSCALED:
625
 
                case PIPE_FORMAT_R8G8B8_SSCALED:
626
 
                case PIPE_FORMAT_R8G8_SSCALED:
627
 
                case PIPE_FORMAT_R8_SSCALED:
628
 
                case PIPE_FORMAT_R10G10B10A2_UNORM:
629
 
                case PIPE_FORMAT_B10G10R10A2_UNORM:
630
 
                case PIPE_FORMAT_R10G10B10A2_SNORM:
631
 
                case PIPE_FORMAT_B10G10R10A2_SNORM:
632
 
                case PIPE_FORMAT_R10G10B10A2_USCALED:
633
 
                case PIPE_FORMAT_B10G10R10A2_USCALED:
634
 
                case PIPE_FORMAT_R10G10B10A2_SSCALED:
635
 
                case PIPE_FORMAT_B10G10R10A2_SSCALED:
636
 
                        break;
637
 
                default:
638
 
                        return false;
639
 
                }
640
 
        }
641
 
 
642
 
        /* FORMAT_NONE gets allowed for ARB_framebuffer_no_attachments's probe
643
 
         * of FRAMEBUFFER_MAX_SAMPLES
644
 
         */
645
 
        if ((usage & PIPE_BIND_RENDER_TARGET) &&
646
 
            format != PIPE_FORMAT_NONE &&
647
 
            !v3d_rt_format_supported(&screen->devinfo, format)) {
648
 
                return false;
649
 
        }
650
 
 
651
 
        if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
652
 
            !v3d_tex_format_supported(&screen->devinfo, format)) {
653
 
                return false;
654
 
        }
655
 
 
656
 
        if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
657
 
            !(format == PIPE_FORMAT_S8_UINT_Z24_UNORM ||
658
 
              format == PIPE_FORMAT_X8Z24_UNORM ||
659
 
              format == PIPE_FORMAT_Z16_UNORM ||
660
 
              format == PIPE_FORMAT_Z32_FLOAT ||
661
 
              format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)) {
662
 
                return false;
663
 
        }
664
 
 
665
 
        if ((usage & PIPE_BIND_INDEX_BUFFER) &&
666
 
            !(format == PIPE_FORMAT_R8_UINT ||
667
 
              format == PIPE_FORMAT_R16_UINT ||
668
 
              format == PIPE_FORMAT_R32_UINT)) {
669
 
                return false;
670
 
        }
671
 
 
672
 
        if (usage & PIPE_BIND_SHADER_IMAGE) {
673
 
                switch (format) {
674
 
                /* FIXME: maybe we can implement a swizzle-on-writes to add
675
 
                 * support for BGRA-alike formats.
676
 
                 */
677
 
                case PIPE_FORMAT_A4B4G4R4_UNORM:
678
 
                case PIPE_FORMAT_A1B5G5R5_UNORM:
679
 
                case PIPE_FORMAT_B5G6R5_UNORM:
680
 
                case PIPE_FORMAT_B8G8R8A8_UNORM:
681
 
                case PIPE_FORMAT_X8Z24_UNORM:
682
 
                case PIPE_FORMAT_Z16_UNORM:
683
 
                        return false;
684
 
                default:
685
 
                        return true;
686
 
                }
687
 
        }
688
 
 
689
 
        return true;
690
 
}
691
 
 
692
 
static const nir_shader_compiler_options v3d_nir_options = {
693
 
        .lower_uadd_sat = true,
694
 
        .lower_iadd_sat = true,
695
 
        .lower_all_io_to_temps = true,
696
 
        .lower_extract_byte = true,
697
 
        .lower_extract_word = true,
698
 
        .lower_insert_byte = true,
699
 
        .lower_insert_word = true,
700
 
        .lower_bitfield_insert_to_shifts = true,
701
 
        .lower_bitfield_extract_to_shifts = true,
702
 
        .lower_bitfield_reverse = true,
703
 
        .lower_bit_count = true,
704
 
        .lower_cs_local_id_to_index = true,
705
 
        .lower_ffract = true,
706
 
        .lower_fmod = true,
707
 
        .lower_pack_unorm_2x16 = true,
708
 
        .lower_pack_snorm_2x16 = true,
709
 
        .lower_pack_unorm_4x8 = true,
710
 
        .lower_pack_snorm_4x8 = true,
711
 
        .lower_unpack_unorm_4x8 = true,
712
 
        .lower_unpack_snorm_4x8 = true,
713
 
        .lower_pack_half_2x16 = true,
714
 
        .lower_unpack_half_2x16 = true,
715
 
        .lower_pack_32_2x16 = true,
716
 
        .lower_pack_32_2x16_split = true,
717
 
        .lower_unpack_32_2x16_split = true,
718
 
        .lower_fdiv = true,
719
 
        .lower_find_lsb = true,
720
 
        .lower_ffma16 = true,
721
 
        .lower_ffma32 = true,
722
 
        .lower_ffma64 = true,
723
 
        .lower_flrp32 = true,
724
 
        .lower_fpow = true,
725
 
        .lower_fsat = true,
726
 
        .lower_fsqrt = true,
727
 
        .lower_ifind_msb = true,
728
 
        .lower_isign = true,
729
 
        .lower_ldexp = true,
730
 
        .lower_mul_high = true,
731
 
        .lower_wpos_pntc = true,
732
 
        .lower_rotate = true,
733
 
        .lower_to_scalar = true,
734
 
        .has_fsub = true,
735
 
        .has_isub = true,
736
 
        .divergence_analysis_options =
737
 
                nir_divergence_multiple_workgroup_per_compute_subgroup,
738
 
        /* This will enable loop unrolling in the state tracker so we won't
739
 
         * be able to selectively disable it in backend if it leads to
740
 
         * lower thread counts or TMU spills. Choose a conservative maximum to
741
 
         * limit register pressure impact.
742
 
         */
743
 
        .max_unroll_iterations = 16,
744
 
};
745
 
 
746
 
static const void *
747
 
v3d_screen_get_compiler_options(struct pipe_screen *pscreen,
748
 
                                enum pipe_shader_ir ir, unsigned shader)
749
 
{
750
 
        return &v3d_nir_options;
751
 
}
752
 
 
753
 
static const uint64_t v3d_available_modifiers[] = {
754
 
   DRM_FORMAT_MOD_BROADCOM_UIF,
755
 
   DRM_FORMAT_MOD_LINEAR,
756
 
   DRM_FORMAT_MOD_BROADCOM_SAND128,
757
 
};
758
 
 
759
 
static void
760
 
v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
761
 
                                  enum pipe_format format, int max,
762
 
                                  uint64_t *modifiers,
763
 
                                  unsigned int *external_only,
764
 
                                  int *count)
765
 
{
766
 
        int i;
767
 
        int num_modifiers = ARRAY_SIZE(v3d_available_modifiers);
768
 
 
769
 
        /* Expose DRM_FORMAT_MOD_BROADCOM_SAND128 only for PIPE_FORMAT_NV12 */
770
 
        if (format != PIPE_FORMAT_NV12)
771
 
                num_modifiers--;
772
 
 
773
 
        if (!modifiers) {
774
 
                *count = num_modifiers;
775
 
                return;
776
 
        }
777
 
 
778
 
        *count = MIN2(max, num_modifiers);
779
 
        for (i = 0; i < *count; i++) {
780
 
                modifiers[i] = v3d_available_modifiers[i];
781
 
                if (external_only)
782
 
                        external_only[i] = util_format_is_yuv(format);
783
 
        }
784
 
}
785
 
 
786
 
static bool
787
 
v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
788
 
                                        uint64_t modifier,
789
 
                                        enum pipe_format format,
790
 
                                        bool *external_only)
791
 
{
792
 
        int i;
793
 
        bool is_sand_col128 = (format == PIPE_FORMAT_NV12) &&
794
 
                (fourcc_mod_broadcom_mod(modifier) == DRM_FORMAT_MOD_BROADCOM_SAND128);
795
 
 
796
 
        if (is_sand_col128) {
797
 
                if (external_only)
798
 
                        *external_only = true;
799
 
                return true;
800
 
        }
801
 
 
802
 
        /* We don't want to generally allow DRM_FORMAT_MOD_BROADCOM_SAND128
803
 
         * modifier, that is the last v3d_available_modifiers. We only accept
804
 
         * it in the case of having a PIPE_FORMAT_NV12.
805
 
         */
806
 
        assert(v3d_available_modifiers[ARRAY_SIZE(v3d_available_modifiers) - 1] ==
807
 
               DRM_FORMAT_MOD_BROADCOM_SAND128);
808
 
        for (i = 0; i < ARRAY_SIZE(v3d_available_modifiers) - 1; i++) {
809
 
                if (v3d_available_modifiers[i] == modifier) {
810
 
                        if (external_only)
811
 
                                *external_only = util_format_is_yuv(format);
812
 
 
813
 
                        return true;
814
 
                }
815
 
        }
816
 
 
817
 
        return false;
818
 
}
819
 
 
820
 
struct pipe_screen *
821
 
v3d_screen_create(int fd, const struct pipe_screen_config *config,
822
 
                  struct renderonly *ro)
823
 
{
824
 
        struct v3d_screen *screen = rzalloc(NULL, struct v3d_screen);
825
 
        struct pipe_screen *pscreen;
826
 
 
827
 
        pscreen = &screen->base;
828
 
 
829
 
        pscreen->destroy = v3d_screen_destroy;
830
 
        pscreen->get_param = v3d_screen_get_param;
831
 
        pscreen->get_paramf = v3d_screen_get_paramf;
832
 
        pscreen->get_shader_param = v3d_screen_get_shader_param;
833
 
        pscreen->get_compute_param = v3d_get_compute_param;
834
 
        pscreen->context_create = v3d_context_create;
835
 
        pscreen->is_format_supported = v3d_screen_is_format_supported;
836
 
 
837
 
        screen->fd = fd;
838
 
        screen->ro = ro;
839
 
 
840
 
        list_inithead(&screen->bo_cache.time_list);
841
 
        (void)mtx_init(&screen->bo_handles_mutex, mtx_plain);
842
 
        screen->bo_handles = util_hash_table_create_ptr_keys();
843
 
 
844
 
#if defined(USE_V3D_SIMULATOR)
845
 
        screen->sim_file = v3d_simulator_init(screen->fd);
846
 
#endif
847
 
 
848
 
        if (!v3d_get_device_info(screen->fd, &screen->devinfo, &v3d_ioctl))
849
 
                goto fail;
850
 
 
851
 
        driParseConfigFiles(config->options, config->options_info, 0, "v3d",
852
 
                            NULL, NULL, NULL, 0, NULL, 0);
853
 
 
854
 
        /* We have to driCheckOption for the simulator mode to not assertion
855
 
         * fail on not having our XML config.
856
 
         */
857
 
        const char *nonmsaa_name = "v3d_nonmsaa_texture_size_limit";
858
 
        screen->nonmsaa_texture_size_limit =
859
 
                driCheckOption(config->options, nonmsaa_name, DRI_BOOL) &&
860
 
                driQueryOptionb(config->options, nonmsaa_name);
861
 
 
862
 
        slab_create_parent(&screen->transfer_pool, sizeof(struct v3d_transfer), 16);
863
 
 
864
 
        screen->has_csd = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CSD);
865
 
        screen->has_cache_flush =
866
 
                v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH);
867
 
        screen->has_perfmon = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_PERFMON);
868
 
 
869
 
        v3d_fence_init(screen);
870
 
 
871
 
        v3d_process_debug_variable();
872
 
 
873
 
        v3d_resource_screen_init(pscreen);
874
 
 
875
 
        screen->compiler = v3d_compiler_init(&screen->devinfo, 0);
876
 
 
877
 
#ifdef ENABLE_SHADER_CACHE
878
 
        v3d_disk_cache_init(screen);
879
 
#endif
880
 
 
881
 
        pscreen->get_name = v3d_screen_get_name;
882
 
        pscreen->get_vendor = v3d_screen_get_vendor;
883
 
        pscreen->get_device_vendor = v3d_screen_get_vendor;
884
 
        pscreen->get_compiler_options = v3d_screen_get_compiler_options;
885
 
        pscreen->query_dmabuf_modifiers = v3d_screen_query_dmabuf_modifiers;
886
 
        pscreen->is_dmabuf_modifier_supported =
887
 
                v3d_screen_is_dmabuf_modifier_supported;
888
 
 
889
 
        if (screen->has_perfmon) {
890
 
                pscreen->get_driver_query_group_info = v3d_get_driver_query_group_info;
891
 
                pscreen->get_driver_query_info = v3d_get_driver_query_info;
892
 
        }
893
 
 
894
 
        /* Generate the bitmask of supported draw primitives. */
895
 
        screen->prim_types = BITFIELD_BIT(PIPE_PRIM_POINTS) |
896
 
                             BITFIELD_BIT(PIPE_PRIM_LINES) |
897
 
                             BITFIELD_BIT(PIPE_PRIM_LINE_LOOP) |
898
 
                             BITFIELD_BIT(PIPE_PRIM_LINE_STRIP) |
899
 
                             BITFIELD_BIT(PIPE_PRIM_TRIANGLES) |
900
 
                             BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP) |
901
 
                             BITFIELD_BIT(PIPE_PRIM_TRIANGLE_FAN) |
902
 
                             BITFIELD_BIT(PIPE_PRIM_LINES_ADJACENCY) |
903
 
                             BITFIELD_BIT(PIPE_PRIM_LINE_STRIP_ADJACENCY) |
904
 
                             BITFIELD_BIT(PIPE_PRIM_TRIANGLES_ADJACENCY) |
905
 
                             BITFIELD_BIT(PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
906
 
 
907
 
        return pscreen;
908
 
 
909
 
fail:
910
 
        close(fd);
911
 
        ralloc_free(pscreen);
912
 
        return NULL;
913
 
}