xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/v3d/v3d_screen.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2014-2017 Broadcom
3  * Copyright (C) 2012 Rob Clark <[email protected]>
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 const char *
v3d_screen_get_name(struct pipe_screen * pscreen)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.%d.%d",
58                                                screen->devinfo.ver / 10,
59                                                screen->devinfo.ver % 10,
60                                                screen->devinfo.rev,
61                                                screen->devinfo.compat_rev);
62         }
63 
64         return screen->name;
65 }
66 
67 static const char *
v3d_screen_get_vendor(struct pipe_screen * pscreen)68 v3d_screen_get_vendor(struct pipe_screen *pscreen)
69 {
70         return "Broadcom";
71 }
72 
73 static void
v3d_screen_destroy(struct pipe_screen * pscreen)74 v3d_screen_destroy(struct pipe_screen *pscreen)
75 {
76         struct v3d_screen *screen = v3d_screen(pscreen);
77 
78         ralloc_free(screen->perfcnt_names);
79         screen->perfcnt_names = NULL;
80 
81         _mesa_hash_table_destroy(screen->bo_handles, NULL);
82         v3d_bufmgr_destroy(pscreen);
83         slab_destroy_parent(&screen->transfer_pool);
84         if (screen->ro)
85                 screen->ro->destroy(screen->ro);
86 
87 #if USE_V3D_SIMULATOR
88         v3d_simulator_destroy(screen->sim_file);
89 #endif
90 
91         v3d_compiler_free(screen->compiler);
92 
93 #ifdef ENABLE_SHADER_CACHE
94         if (screen->disk_cache)
95                 disk_cache_destroy(screen->disk_cache);
96 #endif
97 
98         u_transfer_helper_destroy(pscreen->transfer_helper);
99 
100         close(screen->fd);
101         ralloc_free(pscreen);
102 }
103 
104 static bool
v3d_has_feature(struct v3d_screen * screen,enum drm_v3d_param feature)105 v3d_has_feature(struct v3d_screen *screen, enum drm_v3d_param feature)
106 {
107         struct drm_v3d_get_param p = {
108                 .param = feature,
109         };
110         int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_GET_PARAM, &p);
111 
112         if (ret != 0)
113                 return false;
114 
115         return p.value;
116 }
117 
118 static int
v3d_screen_get_param(struct pipe_screen * pscreen,enum pipe_cap param)119 v3d_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
120 {
121         struct v3d_screen *screen = v3d_screen(pscreen);
122 
123         switch (param) {
124                 /* Supported features (boolean caps). */
125         case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
126         case PIPE_CAP_NPOT_TEXTURES:
127         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
128         case PIPE_CAP_TEXTURE_MULTISAMPLE:
129         case PIPE_CAP_TEXTURE_SWIZZLE:
130         case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
131         case PIPE_CAP_START_INSTANCE:
132         case PIPE_CAP_VS_INSTANCEID:
133         case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
134         case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
135         case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
136         case PIPE_CAP_EMULATE_NONFIXED_PRIMITIVE_RESTART:
137         case PIPE_CAP_PRIMITIVE_RESTART:
138         case PIPE_CAP_OCCLUSION_QUERY:
139         case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
140         case PIPE_CAP_DRAW_INDIRECT:
141         case PIPE_CAP_MULTI_DRAW_INDIRECT:
142         case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
143         case PIPE_CAP_SIGNED_VERTEX_BUFFER_OFFSET:
144         case PIPE_CAP_SHADER_PACK_HALF_FLOAT:
145         case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
146         case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
147         case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
148         case PIPE_CAP_TGSI_TEXCOORD:
149         case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
150         case PIPE_CAP_SAMPLER_VIEW_TARGET:
151         case PIPE_CAP_ANISOTROPIC_FILTER:
152         case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
153         case PIPE_CAP_INDEP_BLEND_FUNC:
154         case PIPE_CAP_CONDITIONAL_RENDER:
155         case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
156         case PIPE_CAP_CUBE_MAP_ARRAY:
157         case PIPE_CAP_TEXTURE_BARRIER:
158         case PIPE_CAP_POLYGON_OFFSET_CLAMP:
159         case PIPE_CAP_TEXTURE_QUERY_LOD:
160                 return 1;
161 
162         case PIPE_CAP_TEXTURE_SAMPLER_INDEPENDENT:
163                 return 0;
164 
165         case PIPE_CAP_PACKED_UNIFORMS:
166                 /* We can't enable this flag, because it results in load_ubo
167                  * intrinsics across a 16b boundary, but v3d's TMU general
168                  * memory accesses wrap on 16b boundaries.
169                  */
170                 return 0;
171 
172         case PIPE_CAP_NIR_IMAGES_AS_DEREF:
173                 return 0;
174 
175         case PIPE_CAP_TEXTURE_TRANSFER_MODES:
176                 /* XXX perf: we don't want to emit these extra blits for
177                  * glReadPixels(), since we still have to do an uncached read
178                  * from the GPU of the result after waiting for the TFU blit
179                  * to happen.  However, disabling this introduces instability
180                  * in
181                  * dEQP-GLES31.functional.image_load_store.early_fragment_tests.*
182                  * and corruption in chromium's rendering.
183                  */
184                 return PIPE_TEXTURE_TRANSFER_BLIT;
185 
186         case PIPE_CAP_COMPUTE:
187                 return screen->has_csd;
188 
189         case PIPE_CAP_GENERATE_MIPMAP:
190                 return v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_TFU);
191 
192         case PIPE_CAP_INDEP_BLEND_ENABLE:
193                 return 1;
194 
195         case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
196                 return V3D_NON_COHERENT_ATOM_SIZE;
197 
198         case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
199                 return 4;
200 
201         case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
202                 if (screen->has_cache_flush)
203                         return 4;
204                 else
205                         return 0; /* Disables shader storage */
206 
207         case PIPE_CAP_GLSL_FEATURE_LEVEL:
208                 return 330;
209 
210         case PIPE_CAP_ESSL_FEATURE_LEVEL:
211                 return 310;
212 
213 	case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
214 		return 140;
215 
216         case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
217                 return 1;
218         case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT:
219                 return 0;
220         case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER:
221                 return 0;
222         case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
223                 return 1;
224 
225         case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
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->nonmsaa_texture_size_limit)
238                         return 7680;
239                 else
240                         return V3D_MAX_IMAGE_DIMENSION;
241         case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
242         case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
243                 return V3D_MAX_MIP_LEVELS;
244         case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
245                 return V3D_MAX_ARRAY_LAYERS;
246 
247         case PIPE_CAP_MAX_RENDER_TARGETS:
248                 return V3D_MAX_RENDER_TARGETS(screen->devinfo.ver);
249 
250         case PIPE_CAP_VENDOR_ID:
251                 return 0x14E4;
252         case PIPE_CAP_ACCELERATED:
253                 return 1;
254         case PIPE_CAP_VIDEO_MEMORY: {
255                 uint64_t system_memory;
256 
257                 if (!os_get_total_physical_memory(&system_memory))
258                         return 0;
259 
260                 return (int)(system_memory >> 20);
261         }
262         case PIPE_CAP_UMA:
263                 return 1;
264 
265         case PIPE_CAP_ALPHA_TEST:
266         case PIPE_CAP_FLATSHADE:
267         case PIPE_CAP_TWO_SIDED_COLOR:
268         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
269         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
270         case PIPE_CAP_GL_CLAMP:
271                 return 0;
272 
273         /* Geometry shaders */
274         case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
275                 /* Minimum required by GLES 3.2 */
276                 return 1024;
277         case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
278                 /* MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS / 4 */
279                 return 256;
280         case PIPE_CAP_MAX_GS_INVOCATIONS:
281                 return 32;
282 
283         case PIPE_CAP_SUPPORTED_PRIM_MODES:
284         case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
285                 return screen->prim_types;
286 
287         case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
288                 return true;
289 
290         case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
291                 return V3D_TMU_TEXEL_ALIGN;
292 
293         case PIPE_CAP_IMAGE_STORE_FORMATTED:
294                 return false;
295 
296         case PIPE_CAP_NATIVE_FENCE_FD:
297                 return true;
298 
299         case PIPE_CAP_DEPTH_CLIP_DISABLE:
300                 return screen->devinfo.ver >= 71;
301 
302         default:
303                 return u_pipe_screen_get_param_defaults(pscreen, param);
304         }
305 }
306 
307 static float
v3d_screen_get_paramf(struct pipe_screen * pscreen,enum pipe_capf param)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
v3d_screen_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)345 v3d_screen_get_shader_param(struct pipe_screen *pscreen, enum pipe_shader_type 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         case PIPE_SHADER_GEOMETRY:
354                 break;
355         case PIPE_SHADER_COMPUTE:
356                 if (!screen->has_csd)
357                         return 0;
358                 break;
359         default:
360                 return 0;
361         }
362 
363         /* this is probably not totally correct.. but it's a start: */
364         switch (param) {
365         case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
366         case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
367         case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
368         case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
369                 return 16384;
370 
371         case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
372                 return UINT_MAX;
373 
374         case PIPE_SHADER_CAP_MAX_INPUTS:
375                 switch (shader) {
376                 case PIPE_SHADER_VERTEX:
377                         return V3D_MAX_VS_INPUTS / 4;
378                 case PIPE_SHADER_GEOMETRY:
379                         return V3D_MAX_GS_INPUTS / 4;
380                 case PIPE_SHADER_FRAGMENT:
381                         return V3D_MAX_FS_INPUTS / 4;
382                 default:
383                         return 0;
384                 };
385         case PIPE_SHADER_CAP_MAX_OUTPUTS:
386                 if (shader == PIPE_SHADER_FRAGMENT)
387                         return 4;
388                 else
389                         return V3D_MAX_FS_INPUTS / 4;
390         case PIPE_SHADER_CAP_MAX_TEMPS:
391                 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
392         case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
393                 /* Note: Limited by the offset size in
394                  * v3d_unit_data_create().
395                  */
396                 return 16 * 1024 * sizeof(float);
397         case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
398                 return 16;
399         case PIPE_SHADER_CAP_CONT_SUPPORTED:
400                 return 0;
401         case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
402                 /* We don't currently support this in the backend, but that is
403                  * okay because our NIR compiler sets the option
404                  * lower_all_io_to_temps, which will eliminate indirect
405                  * indexing on all input/output variables by translating it to
406                  * indirect indexing on temporary variables instead, which we
407                  * will then lower to scratch. We prefer this over setting this
408                  * to 0, which would cause if-ladder injection to eliminate
409                  * indirect indexing on inputs.
410                  */
411                 return 1;
412         case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
413                 return 1;
414         case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
415                 return 1;
416         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
417                 return 1;
418         case PIPE_SHADER_CAP_SUBROUTINES:
419                 return 0;
420         case PIPE_SHADER_CAP_INTEGERS:
421                 return 1;
422         case PIPE_SHADER_CAP_FP16:
423         case PIPE_SHADER_CAP_FP16_DERIVATIVES:
424         case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
425         case PIPE_SHADER_CAP_INT16:
426         case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
427         case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
428         case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
429         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
430         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
431                 return 0;
432         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
433         case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
434                 return V3D_MAX_TEXTURE_SAMPLERS;
435 
436         case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
437                 if (screen->has_cache_flush) {
438                         if (shader == PIPE_SHADER_VERTEX ||
439                             shader == PIPE_SHADER_GEOMETRY) {
440                                 return 0;
441                         }
442                         return PIPE_MAX_SHADER_BUFFERS;
443                  } else {
444                         return 0;
445                  }
446 
447         case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
448                 return screen->has_cache_flush ? PIPE_MAX_SHADER_IMAGES : 0;
449 
450         case PIPE_SHADER_CAP_SUPPORTED_IRS:
451                 return 1 << PIPE_SHADER_IR_NIR;
452         default:
453                 fprintf(stderr, "unknown shader param %d\n", param);
454                 return 0;
455         }
456         return 0;
457 }
458 
459 static int
v3d_get_compute_param(struct pipe_screen * pscreen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * ret)460 v3d_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
461                       enum pipe_compute_cap param, void *ret)
462 {
463         struct v3d_screen *screen = v3d_screen(pscreen);
464 
465         if (!screen->has_csd)
466                 return 0;
467 
468 #define RET(x) do {                                     \
469                 if (ret)                                \
470                         memcpy(ret, x, sizeof(x));      \
471                 return sizeof(x);                       \
472         } while (0)
473 
474         switch (param) {
475         case PIPE_COMPUTE_CAP_ADDRESS_BITS:
476                 RET((uint32_t []) { 32 });
477                 break;
478 
479         case PIPE_COMPUTE_CAP_IR_TARGET:
480                 sprintf(ret, "v3d");
481                 return strlen(ret);
482 
483         case PIPE_COMPUTE_CAP_GRID_DIMENSION:
484                 RET((uint64_t []) { 3 });
485 
486         case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
487                 /* GL_MAX_COMPUTE_SHADER_WORK_GROUP_COUNT: The CSD has a
488                  * 16-bit field for the number of workgroups in each
489                  * dimension.
490                  */
491                 RET(((uint64_t []) { 65535, 65535, 65535 }));
492 
493         case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
494                 /* GL_MAX_COMPUTE_WORK_GROUP_SIZE */
495                 RET(((uint64_t []) { 256, 256, 256 }));
496 
497         case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
498         case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
499                 /* GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: This is
500                  * limited by WG_SIZE in the CSD.
501                  */
502                 RET((uint64_t []) { 256 });
503 
504         case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
505                 /* GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */
506                 RET((uint64_t []) { 32768 });
507 
508         case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
509         case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
510                 RET((uint64_t []) { 4096 });
511 
512         case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: {
513                 struct sysinfo si;
514                 sysinfo(&si);
515                 RET((uint64_t []) { si.totalram });
516         }
517 
518         case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: {
519                 struct sysinfo si;
520                 sysinfo(&si);
521                 RET((uint64_t []) { MIN2(V3D_MAX_BUFFER_RANGE, si.totalram) });
522         }
523 
524         case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
525                 /* OpenCL only */
526                 RET((uint32_t []) { 0 });
527 
528         case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
529                 RET((uint32_t []) { 1 });
530 
531         case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
532                 RET((uint32_t []) { 1 });
533 
534         case PIPE_COMPUTE_CAP_SUBGROUP_SIZES:
535                 RET((uint32_t []) { 16 });
536 
537         case PIPE_COMPUTE_CAP_MAX_SUBGROUPS:
538                 RET((uint32_t []) { 0 });
539 
540         }
541 
542         return 0;
543 }
544 
545 static bool
v3d_screen_is_format_supported(struct pipe_screen * pscreen,enum pipe_format format,enum pipe_texture_target target,unsigned sample_count,unsigned storage_sample_count,unsigned usage)546 v3d_screen_is_format_supported(struct pipe_screen *pscreen,
547                                enum pipe_format format,
548                                enum pipe_texture_target target,
549                                unsigned sample_count,
550                                unsigned storage_sample_count,
551                                unsigned usage)
552 {
553         struct v3d_screen *screen = v3d_screen(pscreen);
554 
555         if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
556                 return false;
557 
558         if (sample_count > 1 && sample_count != V3D_MAX_SAMPLES)
559                 return false;
560 
561         if (target >= PIPE_MAX_TEXTURE_TYPES) {
562                 return false;
563         }
564 
565         if (usage & PIPE_BIND_VERTEX_BUFFER) {
566                 switch (format) {
567                 case PIPE_FORMAT_R32G32B32A32_FLOAT:
568                 case PIPE_FORMAT_R32G32B32_FLOAT:
569                 case PIPE_FORMAT_R32G32_FLOAT:
570                 case PIPE_FORMAT_R32_FLOAT:
571                 case PIPE_FORMAT_R32G32B32A32_SNORM:
572                 case PIPE_FORMAT_R32G32B32_SNORM:
573                 case PIPE_FORMAT_R32G32_SNORM:
574                 case PIPE_FORMAT_R32_SNORM:
575                 case PIPE_FORMAT_R32G32B32A32_SSCALED:
576                 case PIPE_FORMAT_R32G32B32_SSCALED:
577                 case PIPE_FORMAT_R32G32_SSCALED:
578                 case PIPE_FORMAT_R32_SSCALED:
579                 case PIPE_FORMAT_R16G16B16A16_UNORM:
580                 case PIPE_FORMAT_R16G16B16A16_FLOAT:
581                 case PIPE_FORMAT_R16G16B16_UNORM:
582                 case PIPE_FORMAT_R16G16_UNORM:
583                 case PIPE_FORMAT_R16_UNORM:
584                 case PIPE_FORMAT_R16_FLOAT:
585                 case PIPE_FORMAT_R16G16B16A16_SNORM:
586                 case PIPE_FORMAT_R16G16B16_SNORM:
587                 case PIPE_FORMAT_R16G16_SNORM:
588                 case PIPE_FORMAT_R16G16_FLOAT:
589                 case PIPE_FORMAT_R16_SNORM:
590                 case PIPE_FORMAT_R16G16B16A16_USCALED:
591                 case PIPE_FORMAT_R16G16B16_USCALED:
592                 case PIPE_FORMAT_R16G16_USCALED:
593                 case PIPE_FORMAT_R16_USCALED:
594                 case PIPE_FORMAT_R16G16B16A16_SSCALED:
595                 case PIPE_FORMAT_R16G16B16_SSCALED:
596                 case PIPE_FORMAT_R16G16_SSCALED:
597                 case PIPE_FORMAT_R16_SSCALED:
598                 case PIPE_FORMAT_B8G8R8A8_UNORM:
599                 case PIPE_FORMAT_R8G8B8A8_UNORM:
600                 case PIPE_FORMAT_R8G8B8_UNORM:
601                 case PIPE_FORMAT_R8G8_UNORM:
602                 case PIPE_FORMAT_R8_UNORM:
603                 case PIPE_FORMAT_R8G8B8A8_SNORM:
604                 case PIPE_FORMAT_R8G8B8_SNORM:
605                 case PIPE_FORMAT_R8G8_SNORM:
606                 case PIPE_FORMAT_R8_SNORM:
607                 case PIPE_FORMAT_R8G8B8A8_USCALED:
608                 case PIPE_FORMAT_R8G8B8_USCALED:
609                 case PIPE_FORMAT_R8G8_USCALED:
610                 case PIPE_FORMAT_R8_USCALED:
611                 case PIPE_FORMAT_R8G8B8A8_SSCALED:
612                 case PIPE_FORMAT_R8G8B8_SSCALED:
613                 case PIPE_FORMAT_R8G8_SSCALED:
614                 case PIPE_FORMAT_R8_SSCALED:
615                 case PIPE_FORMAT_R10G10B10A2_UNORM:
616                 case PIPE_FORMAT_B10G10R10A2_UNORM:
617                 case PIPE_FORMAT_R10G10B10A2_SNORM:
618                 case PIPE_FORMAT_B10G10R10A2_SNORM:
619                 case PIPE_FORMAT_R10G10B10A2_USCALED:
620                 case PIPE_FORMAT_B10G10R10A2_USCALED:
621                 case PIPE_FORMAT_R10G10B10A2_SSCALED:
622                 case PIPE_FORMAT_B10G10R10A2_SSCALED:
623                         break;
624                 default:
625                         return false;
626                 }
627         }
628 
629         /* FORMAT_NONE gets allowed for ARB_framebuffer_no_attachments's probe
630          * of FRAMEBUFFER_MAX_SAMPLES
631          */
632         if ((usage & PIPE_BIND_RENDER_TARGET) &&
633             format != PIPE_FORMAT_NONE &&
634             !v3d_rt_format_supported(&screen->devinfo, format)) {
635                 return false;
636         }
637 
638         /* We do not support EXT_float_blend (blending with 32F formats)*/
639         if ((usage & PIPE_BIND_BLENDABLE) &&
640             (format == PIPE_FORMAT_R32G32B32A32_FLOAT ||
641              format == PIPE_FORMAT_R32G32_FLOAT ||
642              format == PIPE_FORMAT_R32_FLOAT)) {
643                 return false;
644         }
645 
646         if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
647             !v3d_tex_format_supported(&screen->devinfo, format)) {
648                 return false;
649         }
650 
651         if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
652             !(format == PIPE_FORMAT_S8_UINT_Z24_UNORM ||
653               format == PIPE_FORMAT_X8Z24_UNORM ||
654               format == PIPE_FORMAT_Z16_UNORM ||
655               format == PIPE_FORMAT_Z32_FLOAT ||
656               format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)) {
657                 return false;
658         }
659 
660         if ((usage & PIPE_BIND_INDEX_BUFFER) &&
661             !(format == PIPE_FORMAT_R8_UINT ||
662               format == PIPE_FORMAT_R16_UINT ||
663               format == PIPE_FORMAT_R32_UINT)) {
664                 return false;
665         }
666 
667         if (usage & PIPE_BIND_SHADER_IMAGE) {
668                 switch (format) {
669                 /* FIXME: maybe we can implement a swizzle-on-writes to add
670                  * support for BGRA-alike formats.
671                  */
672                 case PIPE_FORMAT_A4B4G4R4_UNORM:
673                 case PIPE_FORMAT_A1B5G5R5_UNORM:
674                 case PIPE_FORMAT_B5G6R5_UNORM:
675                 case PIPE_FORMAT_B8G8R8A8_UNORM:
676                 case PIPE_FORMAT_X8Z24_UNORM:
677                 case PIPE_FORMAT_Z16_UNORM:
678                         return false;
679                 default:
680                         return true;
681                 }
682         }
683 
684         return true;
685 }
686 
687 static const void *
v3d_screen_get_compiler_options(struct pipe_screen * pscreen,enum pipe_shader_ir ir,enum pipe_shader_type shader)688 v3d_screen_get_compiler_options(struct pipe_screen *pscreen,
689                                 enum pipe_shader_ir ir,
690                                 enum pipe_shader_type shader)
691 {
692         struct v3d_screen *screen = v3d_screen(pscreen);
693         const struct v3d_device_info *devinfo = &screen->devinfo;
694 
695         static bool initialized = false;
696         static nir_shader_compiler_options options = {
697                 .compact_arrays = true,
698                 .lower_uadd_sat = true,
699                 .lower_usub_sat = true,
700                 .lower_iadd_sat = true,
701                 .lower_all_io_to_temps = true,
702                 .lower_extract_byte = true,
703                 .lower_extract_word = true,
704                 .lower_insert_byte = true,
705                 .lower_insert_word = true,
706                 .lower_bitfield_insert = true,
707                 .lower_bitfield_extract = true,
708                 .lower_bitfield_reverse = true,
709                 .lower_bit_count = true,
710                 .lower_cs_local_id_to_index = true,
711                 .lower_ffract = true,
712                 .lower_fmod = true,
713                 .lower_pack_unorm_2x16 = true,
714                 .lower_pack_snorm_2x16 = true,
715                 .lower_pack_unorm_4x8 = true,
716                 .lower_pack_snorm_4x8 = true,
717                 .lower_unpack_unorm_4x8 = true,
718                 .lower_unpack_snorm_4x8 = true,
719                 .lower_pack_half_2x16 = true,
720                 .lower_unpack_half_2x16 = true,
721                 .lower_pack_32_2x16 = true,
722                 .lower_pack_32_2x16_split = true,
723                 .lower_unpack_32_2x16_split = true,
724                 .lower_fdiv = true,
725                 .lower_find_lsb = true,
726                 .lower_ffma16 = true,
727                 .lower_ffma32 = true,
728                 .lower_ffma64 = true,
729                 .lower_flrp32 = true,
730                 .lower_fpow = true,
731                 .lower_fsqrt = true,
732                 .lower_ifind_msb = true,
733                 .lower_isign = true,
734                 .lower_ldexp = true,
735                 .lower_hadd = true,
736                 .lower_fisnormal = true,
737                 .lower_mul_high = true,
738                 .lower_wpos_pntc = true,
739                 .lower_to_scalar = true,
740                 .lower_int64_options =
741                         nir_lower_bcsel64 |
742                         nir_lower_conv64 |
743                         nir_lower_iadd64 |
744                         nir_lower_icmp64 |
745                         nir_lower_imul_2x32_64 |
746                         nir_lower_imul64 |
747                         nir_lower_ineg64 |
748                         nir_lower_logic64 |
749                         nir_lower_shift64 |
750                         nir_lower_ufind_msb64,
751                 .lower_fquantize2f16 = true,
752                 .lower_ufind_msb = true,
753                 .has_fsub = true,
754                 .has_isub = true,
755                 .has_uclz = true,
756                 .divergence_analysis_options =
757                        nir_divergence_multiple_workgroup_per_compute_subgroup,
758                 /* This will enable loop unrolling in the state tracker so we won't
759                  * be able to selectively disable it in backend if it leads to
760                  * lower thread counts or TMU spills. Choose a conservative maximum to
761                  * limit register pressure impact.
762                  */
763                 .max_unroll_iterations = 16,
764                 .force_indirect_unrolling_sampler = true,
765                 .has_ddx_intrinsics = true,
766                 .scalarize_ddx = true,
767         };
768 
769         if (!initialized) {
770                 options.lower_fsat = devinfo->ver < 71;
771                 initialized = true;
772         }
773 
774         return &options;
775 }
776 
777 static const uint64_t v3d_available_modifiers[] = {
778    DRM_FORMAT_MOD_BROADCOM_UIF,
779    DRM_FORMAT_MOD_LINEAR,
780    DRM_FORMAT_MOD_BROADCOM_SAND128,
781 };
782 
783 static void
v3d_screen_query_dmabuf_modifiers(struct pipe_screen * pscreen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)784 v3d_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
785                                   enum pipe_format format, int max,
786                                   uint64_t *modifiers,
787                                   unsigned int *external_only,
788                                   int *count)
789 {
790         int i;
791         int num_modifiers = ARRAY_SIZE(v3d_available_modifiers);
792 
793         switch (format) {
794         case PIPE_FORMAT_P030:
795                 /* Expose SAND128, but not LINEAR or UIF */
796                 *count = 1;
797                 if (modifiers && max > 0) {
798                         modifiers[0] = DRM_FORMAT_MOD_BROADCOM_SAND128;
799                         if (external_only)
800                                 external_only[0] = true;
801                 }
802                 return;
803 
804         case PIPE_FORMAT_NV12:
805                 /* Expose UIF, LINEAR and SAND128 */
806                 break;
807 
808         case PIPE_FORMAT_R8_UNORM:
809         case PIPE_FORMAT_R8G8_UNORM:
810         case PIPE_FORMAT_R16_UNORM:
811         case PIPE_FORMAT_R16G16_UNORM:
812                 /* Expose UIF, LINEAR and SAND128 */
813 		if (!modifiers) break;
814                 *count = MIN2(max, num_modifiers);
815                 for (i = 0; i < *count; i++) {
816                         modifiers[i] = v3d_available_modifiers[i];
817                         if (external_only)
818                                 external_only[i] = modifiers[i] == DRM_FORMAT_MOD_BROADCOM_SAND128;
819                 }
820                 return;
821 
822         default:
823                 /* Expose UIF and LINEAR, but not SAND128 */
824                 num_modifiers--;
825         }
826 
827         if (!modifiers) {
828                 *count = num_modifiers;
829                 return;
830         }
831 
832         *count = MIN2(max, num_modifiers);
833         for (i = 0; i < *count; i++) {
834                 modifiers[i] = v3d_available_modifiers[i];
835                 if (external_only)
836                         external_only[i] = util_format_is_yuv(format);
837         }
838 }
839 
840 static bool
v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format,bool * external_only)841 v3d_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
842                                         uint64_t modifier,
843                                         enum pipe_format format,
844                                         bool *external_only)
845 {
846         int i;
847         if (fourcc_mod_broadcom_mod(modifier) == DRM_FORMAT_MOD_BROADCOM_SAND128) {
848                 switch(format) {
849                 case PIPE_FORMAT_NV12:
850                 case PIPE_FORMAT_P030:
851                 case PIPE_FORMAT_R8_UNORM:
852                 case PIPE_FORMAT_R8G8_UNORM:
853                 case PIPE_FORMAT_R16_UNORM:
854                 case PIPE_FORMAT_R16G16_UNORM:
855                         if (external_only)
856                                 *external_only = true;
857                         return true;
858                 default:
859                         return false;
860                 }
861         } else if (format == PIPE_FORMAT_P030) {
862                 /* For PIPE_FORMAT_P030 we don't expose LINEAR or UIF. */
863                 return false;
864         }
865 
866         /* We don't want to generally allow DRM_FORMAT_MOD_BROADCOM_SAND128
867          * modifier, that is the last v3d_available_modifiers. We only accept
868          * it in the case of having a PIPE_FORMAT_NV12 or PIPE_FORMAT_P030.
869          */
870         assert(v3d_available_modifiers[ARRAY_SIZE(v3d_available_modifiers) - 1] ==
871                DRM_FORMAT_MOD_BROADCOM_SAND128);
872         for (i = 0; i < ARRAY_SIZE(v3d_available_modifiers) - 1; i++) {
873                 if (v3d_available_modifiers[i] == modifier) {
874                         if (external_only)
875                                 *external_only = util_format_is_yuv(format);
876 
877                         return true;
878                 }
879         }
880 
881         return false;
882 }
883 
884 static enum pipe_format
v3d_screen_get_compatible_tlb_format(struct pipe_screen * screen,enum pipe_format format)885 v3d_screen_get_compatible_tlb_format(struct pipe_screen *screen,
886                                      enum pipe_format format)
887 {
888         switch (format) {
889         case PIPE_FORMAT_R16G16_UNORM:
890                 return PIPE_FORMAT_R16G16_UINT;
891         default:
892                 return format;
893         }
894 }
895 
896 static struct disk_cache *
v3d_screen_get_disk_shader_cache(struct pipe_screen * pscreen)897 v3d_screen_get_disk_shader_cache(struct pipe_screen *pscreen)
898 {
899         struct v3d_screen *screen = v3d_screen(pscreen);
900 
901         return screen->disk_cache;
902 }
903 
904 static int
v3d_screen_get_fd(struct pipe_screen * pscreen)905 v3d_screen_get_fd(struct pipe_screen *pscreen)
906 {
907         struct v3d_screen *screen = v3d_screen(pscreen);
908 
909         return screen->fd;
910 }
911 
912 struct pipe_screen *
v3d_screen_create(int fd,const struct pipe_screen_config * config,struct renderonly * ro)913 v3d_screen_create(int fd, const struct pipe_screen_config *config,
914                   struct renderonly *ro)
915 {
916         struct v3d_screen *screen = rzalloc(NULL, struct v3d_screen);
917         struct pipe_screen *pscreen;
918 
919         pscreen = &screen->base;
920 
921         pscreen->destroy = v3d_screen_destroy;
922         pscreen->get_screen_fd = v3d_screen_get_fd;
923         pscreen->get_param = v3d_screen_get_param;
924         pscreen->get_paramf = v3d_screen_get_paramf;
925         pscreen->get_shader_param = v3d_screen_get_shader_param;
926         pscreen->get_compute_param = v3d_get_compute_param;
927         pscreen->context_create = v3d_context_create;
928         pscreen->is_format_supported = v3d_screen_is_format_supported;
929         pscreen->get_canonical_format = v3d_screen_get_compatible_tlb_format;
930 
931         screen->fd = fd;
932         screen->ro = ro;
933 
934         list_inithead(&screen->bo_cache.time_list);
935         (void)mtx_init(&screen->bo_handles_mutex, mtx_plain);
936         screen->bo_handles = util_hash_table_create_ptr_keys();
937 
938 #if USE_V3D_SIMULATOR
939         screen->sim_file = v3d_simulator_init(screen->fd);
940 #endif
941 
942         if (!v3d_get_device_info(screen->fd, &screen->devinfo, &v3d_ioctl))
943                 goto fail;
944 
945         screen->perfcnt_names = rzalloc_array(screen, char*, screen->devinfo.max_perfcnt);
946         if (!screen->perfcnt_names) {
947                 fprintf(stderr, "Error allocating performance counters names");
948                 goto fail;
949         }
950 
951         driParseConfigFiles(config->options, config->options_info, 0, "v3d",
952                             NULL, NULL, NULL, 0, NULL, 0);
953 
954         /* We have to driCheckOption for the simulator mode to not assertion
955          * fail on not having our XML config.
956          */
957         const char *nonmsaa_name = "v3d_nonmsaa_texture_size_limit";
958         screen->nonmsaa_texture_size_limit =
959                 driCheckOption(config->options, nonmsaa_name, DRI_BOOL) &&
960                 driQueryOptionb(config->options, nonmsaa_name);
961 
962         slab_create_parent(&screen->transfer_pool, sizeof(struct v3d_transfer), 16);
963 
964         screen->has_csd = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CSD);
965         screen->has_cache_flush =
966                 v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH);
967         screen->has_perfmon = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_PERFMON);
968 
969         v3d_fence_screen_init(screen);
970 
971         v3d_process_debug_variable();
972 
973         v3d_resource_screen_init(pscreen);
974 
975         screen->compiler = v3d_compiler_init(&screen->devinfo, 0);
976 
977 #ifdef ENABLE_SHADER_CACHE
978         v3d_disk_cache_init(screen);
979 #endif
980 
981         pscreen->get_name = v3d_screen_get_name;
982         pscreen->get_vendor = v3d_screen_get_vendor;
983         pscreen->get_device_vendor = v3d_screen_get_vendor;
984         pscreen->get_compiler_options = v3d_screen_get_compiler_options;
985         pscreen->get_disk_shader_cache = v3d_screen_get_disk_shader_cache;
986         pscreen->query_dmabuf_modifiers = v3d_screen_query_dmabuf_modifiers;
987         pscreen->is_dmabuf_modifier_supported =
988                 v3d_screen_is_dmabuf_modifier_supported;
989 
990         if (screen->has_perfmon) {
991                 pscreen->get_driver_query_group_info = v3d_get_driver_query_group_info;
992                 pscreen->get_driver_query_info = v3d_get_driver_query_info;
993         }
994 
995         /* Generate the bitmask of supported draw primitives. */
996         screen->prim_types = BITFIELD_BIT(MESA_PRIM_POINTS) |
997                              BITFIELD_BIT(MESA_PRIM_LINES) |
998                              BITFIELD_BIT(MESA_PRIM_LINE_LOOP) |
999                              BITFIELD_BIT(MESA_PRIM_LINE_STRIP) |
1000                              BITFIELD_BIT(MESA_PRIM_TRIANGLES) |
1001                              BITFIELD_BIT(MESA_PRIM_TRIANGLE_STRIP) |
1002                              BITFIELD_BIT(MESA_PRIM_TRIANGLE_FAN) |
1003                              BITFIELD_BIT(MESA_PRIM_LINES_ADJACENCY) |
1004                              BITFIELD_BIT(MESA_PRIM_LINE_STRIP_ADJACENCY) |
1005                              BITFIELD_BIT(MESA_PRIM_TRIANGLES_ADJACENCY) |
1006                              BITFIELD_BIT(MESA_PRIM_TRIANGLE_STRIP_ADJACENCY);
1007 
1008         return pscreen;
1009 
1010 fail:
1011         close(fd);
1012         ralloc_free(pscreen);
1013         return NULL;
1014 }
1015