• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014 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 "util/os_misc.h"
26 #include "pipe/p_defines.h"
27 #include "pipe/p_screen.h"
28 #include "pipe/p_state.h"
29 
30 #include "util/u_cpu_detect.h"
31 #include "util/u_debug.h"
32 #include "util/u_memory.h"
33 #include "util/format/u_format.h"
34 #include "util/u_hash_table.h"
35 #include "util/u_screen.h"
36 #include "util/u_transfer_helper.h"
37 #include "util/ralloc.h"
38 
39 #include <xf86drm.h>
40 #include "drm-uapi/drm_fourcc.h"
41 #include "drm-uapi/vc4_drm.h"
42 #include "vc4_screen.h"
43 #include "vc4_context.h"
44 #include "vc4_resource.h"
45 
46 static const struct debug_named_value debug_options[] = {
47         { "cl",       VC4_DEBUG_CL,
48           "Dump command list during creation" },
49         { "surf",       VC4_DEBUG_SURFACE,
50           "Dump surface layouts" },
51         { "qpu",      VC4_DEBUG_QPU,
52           "Dump generated QPU instructions" },
53         { "qir",      VC4_DEBUG_QIR,
54           "Dump QPU IR during program compile" },
55         { "nir",      VC4_DEBUG_NIR,
56           "Dump NIR during program compile" },
57         { "tgsi",     VC4_DEBUG_TGSI,
58           "Dump TGSI during program compile" },
59         { "shaderdb", VC4_DEBUG_SHADERDB,
60           "Dump program compile information for shader-db analysis" },
61         { "perf",     VC4_DEBUG_PERF,
62           "Print during performance-related events" },
63         { "norast",   VC4_DEBUG_NORAST,
64           "Skip actual hardware execution of commands" },
65         { "always_flush", VC4_DEBUG_ALWAYS_FLUSH,
66           "Flush after each draw call" },
67         { "always_sync", VC4_DEBUG_ALWAYS_SYNC,
68           "Wait for finish after each flush" },
69 #ifdef USE_VC4_SIMULATOR
70         { "dump", VC4_DEBUG_DUMP,
71           "Write a GPU command stream trace file" },
72 #endif
73         { NULL }
74 };
75 
76 DEBUG_GET_ONCE_FLAGS_OPTION(vc4_debug, "VC4_DEBUG", debug_options, 0)
77 uint32_t vc4_debug;
78 
79 static const char *
vc4_screen_get_name(struct pipe_screen * pscreen)80 vc4_screen_get_name(struct pipe_screen *pscreen)
81 {
82         struct vc4_screen *screen = vc4_screen(pscreen);
83 
84         if (!screen->name) {
85                 screen->name = ralloc_asprintf(screen,
86                                                "VC4 V3D %d.%d",
87                                                screen->v3d_ver / 10,
88                                                screen->v3d_ver % 10);
89         }
90 
91         return screen->name;
92 }
93 
94 static const char *
vc4_screen_get_vendor(struct pipe_screen * pscreen)95 vc4_screen_get_vendor(struct pipe_screen *pscreen)
96 {
97         return "Broadcom";
98 }
99 
100 static void
vc4_screen_destroy(struct pipe_screen * pscreen)101 vc4_screen_destroy(struct pipe_screen *pscreen)
102 {
103         struct vc4_screen *screen = vc4_screen(pscreen);
104 
105         _mesa_hash_table_destroy(screen->bo_handles, NULL);
106         vc4_bufmgr_destroy(pscreen);
107         slab_destroy_parent(&screen->transfer_pool);
108         free(screen->ro);
109 
110 #ifdef USE_VC4_SIMULATOR
111         vc4_simulator_destroy(screen);
112 #endif
113 
114         u_transfer_helper_destroy(pscreen->transfer_helper);
115 
116         close(screen->fd);
117         ralloc_free(pscreen);
118 }
119 
120 static bool
vc4_has_feature(struct vc4_screen * screen,uint32_t feature)121 vc4_has_feature(struct vc4_screen *screen, uint32_t feature)
122 {
123         struct drm_vc4_get_param p = {
124                 .param = feature,
125         };
126         int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);
127 
128         if (ret != 0)
129                 return false;
130 
131         return p.value;
132 }
133 
134 static int
vc4_screen_get_param(struct pipe_screen * pscreen,enum pipe_cap param)135 vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
136 {
137         struct vc4_screen *screen = vc4_screen(pscreen);
138 
139         switch (param) {
140                 /* Supported features (boolean caps). */
141         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
142         case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
143         case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
144         case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
145         case PIPE_CAP_NPOT_TEXTURES:
146         case PIPE_CAP_SHAREABLE_SHADERS:
147         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
148         case PIPE_CAP_TEXTURE_MULTISAMPLE:
149         case PIPE_CAP_TEXTURE_SWIZZLE:
150         case PIPE_CAP_TEXTURE_BARRIER:
151         case PIPE_CAP_TGSI_TEXCOORD:
152                 return 1;
153 
154         case PIPE_CAP_NATIVE_FENCE_FD:
155                 return screen->has_syncobj;
156 
157         case PIPE_CAP_TILE_RASTER_ORDER:
158                 return vc4_has_feature(screen,
159                                        DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER);
160 
161                 /* lying for GL 2.0 */
162         case PIPE_CAP_OCCLUSION_QUERY:
163         case PIPE_CAP_POINT_SPRITE:
164                 return 1;
165 
166         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
167         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
168         case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
169                 return 1;
170 
171         case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
172         case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
173                 return 1;
174 
175                 /* Texturing. */
176         case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
177                 return 2048;
178         case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
179                 return VC4_MAX_MIP_LEVELS;
180         case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
181                 /* Note: Not supported in hardware, just faking it. */
182                 return 5;
183 
184         case PIPE_CAP_MAX_VARYINGS:
185                 return 8;
186 
187         case PIPE_CAP_VENDOR_ID:
188                 return 0x14E4;
189         case PIPE_CAP_ACCELERATED:
190                 return 1;
191         case PIPE_CAP_VIDEO_MEMORY: {
192                 uint64_t system_memory;
193 
194                 if (!os_get_total_physical_memory(&system_memory))
195                         return 0;
196 
197                 return (int)(system_memory >> 20);
198         }
199         case PIPE_CAP_UMA:
200                 return 1;
201 
202         case PIPE_CAP_ALPHA_TEST:
203                 return 0;
204 
205         default:
206                 return u_pipe_screen_get_param_defaults(pscreen, param);
207         }
208 }
209 
210 static float
vc4_screen_get_paramf(struct pipe_screen * pscreen,enum pipe_capf param)211 vc4_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
212 {
213         switch (param) {
214         case PIPE_CAPF_MAX_LINE_WIDTH:
215         case PIPE_CAPF_MAX_LINE_WIDTH_AA:
216                 return 32;
217 
218         case PIPE_CAPF_MAX_POINT_WIDTH:
219         case PIPE_CAPF_MAX_POINT_WIDTH_AA:
220                 return 512.0f;
221 
222         case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
223                 return 0.0f;
224         case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
225                 return 0.0f;
226 
227         case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
228         case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
229         case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
230                 return 0.0f;
231         default:
232                 fprintf(stderr, "unknown paramf %d\n", param);
233                 return 0;
234         }
235 }
236 
237 static int
vc4_screen_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)238 vc4_screen_get_shader_param(struct pipe_screen *pscreen,
239                             enum pipe_shader_type shader,
240                             enum pipe_shader_cap param)
241 {
242         if (shader != PIPE_SHADER_VERTEX &&
243             shader != PIPE_SHADER_FRAGMENT) {
244                 return 0;
245         }
246 
247         /* this is probably not totally correct.. but it's a start: */
248         switch (param) {
249         case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
250         case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
251         case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
252         case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
253                 return 16384;
254 
255         case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
256                 return vc4_screen(pscreen)->has_control_flow;
257 
258         case PIPE_SHADER_CAP_MAX_INPUTS:
259                 return 8;
260         case PIPE_SHADER_CAP_MAX_OUTPUTS:
261                 return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;
262         case PIPE_SHADER_CAP_MAX_TEMPS:
263                 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
264         case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
265                 return 16 * 1024 * sizeof(float);
266         case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
267                 return 1;
268         case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
269                 return 0;
270         case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
271         case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
272         case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
273                 return 0;
274         case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
275                 return 1;
276         case PIPE_SHADER_CAP_SUBROUTINES:
277                 return 0;
278         case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
279                 return 0;
280         case PIPE_SHADER_CAP_INTEGERS:
281                 return 1;
282         case PIPE_SHADER_CAP_INT64_ATOMICS:
283         case PIPE_SHADER_CAP_FP16:
284         case PIPE_SHADER_CAP_FP16_DERIVATIVES:
285         case PIPE_SHADER_CAP_INT16:
286         case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
287         case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
288         case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
289         case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
290         case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
291         case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
292                 return 0;
293         case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
294         case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
295                 return VC4_MAX_TEXTURE_SAMPLERS;
296         case PIPE_SHADER_CAP_PREFERRED_IR:
297                 return PIPE_SHADER_IR_NIR;
298         case PIPE_SHADER_CAP_SUPPORTED_IRS:
299                 return 0;
300         case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
301                 return 32;
302         case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
303         case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
304         case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
305         case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
306         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
307         case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
308                 return 0;
309         default:
310                 fprintf(stderr, "unknown shader param %d\n", param);
311                 return 0;
312         }
313         return 0;
314 }
315 
316 static bool
vc4_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)317 vc4_screen_is_format_supported(struct pipe_screen *pscreen,
318                                enum pipe_format format,
319                                enum pipe_texture_target target,
320                                unsigned sample_count,
321                                unsigned storage_sample_count,
322                                unsigned usage)
323 {
324         struct vc4_screen *screen = vc4_screen(pscreen);
325 
326         if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
327                 return false;
328 
329         if (sample_count > 1 && sample_count != VC4_MAX_SAMPLES)
330                 return false;
331 
332         if (target >= PIPE_MAX_TEXTURE_TYPES) {
333                 return false;
334         }
335 
336         if (usage & PIPE_BIND_VERTEX_BUFFER) {
337                 switch (format) {
338                 case PIPE_FORMAT_R32G32B32A32_FLOAT:
339                 case PIPE_FORMAT_R32G32B32_FLOAT:
340                 case PIPE_FORMAT_R32G32_FLOAT:
341                 case PIPE_FORMAT_R32_FLOAT:
342                 case PIPE_FORMAT_R32G32B32A32_SNORM:
343                 case PIPE_FORMAT_R32G32B32_SNORM:
344                 case PIPE_FORMAT_R32G32_SNORM:
345                 case PIPE_FORMAT_R32_SNORM:
346                 case PIPE_FORMAT_R32G32B32A32_SSCALED:
347                 case PIPE_FORMAT_R32G32B32_SSCALED:
348                 case PIPE_FORMAT_R32G32_SSCALED:
349                 case PIPE_FORMAT_R32_SSCALED:
350                 case PIPE_FORMAT_R16G16B16A16_UNORM:
351                 case PIPE_FORMAT_R16G16B16_UNORM:
352                 case PIPE_FORMAT_R16G16_UNORM:
353                 case PIPE_FORMAT_R16_UNORM:
354                 case PIPE_FORMAT_R16G16B16A16_SNORM:
355                 case PIPE_FORMAT_R16G16B16_SNORM:
356                 case PIPE_FORMAT_R16G16_SNORM:
357                 case PIPE_FORMAT_R16_SNORM:
358                 case PIPE_FORMAT_R16G16B16A16_USCALED:
359                 case PIPE_FORMAT_R16G16B16_USCALED:
360                 case PIPE_FORMAT_R16G16_USCALED:
361                 case PIPE_FORMAT_R16_USCALED:
362                 case PIPE_FORMAT_R16G16B16A16_SSCALED:
363                 case PIPE_FORMAT_R16G16B16_SSCALED:
364                 case PIPE_FORMAT_R16G16_SSCALED:
365                 case PIPE_FORMAT_R16_SSCALED:
366                 case PIPE_FORMAT_R8G8B8A8_UNORM:
367                 case PIPE_FORMAT_R8G8B8_UNORM:
368                 case PIPE_FORMAT_R8G8_UNORM:
369                 case PIPE_FORMAT_R8_UNORM:
370                 case PIPE_FORMAT_R8G8B8A8_SNORM:
371                 case PIPE_FORMAT_R8G8B8_SNORM:
372                 case PIPE_FORMAT_R8G8_SNORM:
373                 case PIPE_FORMAT_R8_SNORM:
374                 case PIPE_FORMAT_R8G8B8A8_USCALED:
375                 case PIPE_FORMAT_R8G8B8_USCALED:
376                 case PIPE_FORMAT_R8G8_USCALED:
377                 case PIPE_FORMAT_R8_USCALED:
378                 case PIPE_FORMAT_R8G8B8A8_SSCALED:
379                 case PIPE_FORMAT_R8G8B8_SSCALED:
380                 case PIPE_FORMAT_R8G8_SSCALED:
381                 case PIPE_FORMAT_R8_SSCALED:
382                         break;
383                 default:
384                         return false;
385                 }
386         }
387 
388         if ((usage & PIPE_BIND_RENDER_TARGET) &&
389             !vc4_rt_format_supported(format)) {
390                 return false;
391         }
392 
393         if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
394             (!vc4_tex_format_supported(format) ||
395              (format == PIPE_FORMAT_ETC1_RGB8 && !screen->has_etc1))) {
396                 return false;
397         }
398 
399         if ((usage & PIPE_BIND_DEPTH_STENCIL) &&
400             format != PIPE_FORMAT_S8_UINT_Z24_UNORM &&
401             format != PIPE_FORMAT_X8Z24_UNORM) {
402                 return false;
403         }
404 
405         if ((usage & PIPE_BIND_INDEX_BUFFER) &&
406             format != PIPE_FORMAT_I8_UINT &&
407             format != PIPE_FORMAT_I16_UINT) {
408                 return false;
409         }
410 
411         return true;
412 }
413 
414 static void
vc4_screen_query_dmabuf_modifiers(struct pipe_screen * pscreen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)415 vc4_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
416                                   enum pipe_format format, int max,
417                                   uint64_t *modifiers,
418                                   unsigned int *external_only,
419                                   int *count)
420 {
421         int m, i;
422         bool tex_will_lower;
423         uint64_t available_modifiers[] = {
424                 DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED,
425                 DRM_FORMAT_MOD_LINEAR,
426         };
427         struct vc4_screen *screen = vc4_screen(pscreen);
428         int num_modifiers = screen->has_tiling_ioctl ? 2 : 1;
429 
430         if (!modifiers) {
431                 *count = num_modifiers;
432                 return;
433         }
434 
435         *count = MIN2(max, num_modifiers);
436         m = screen->has_tiling_ioctl ? 0 : 1;
437         tex_will_lower = !vc4_tex_format_supported(format);
438         /* We support both modifiers (tiled and linear) for all sampler
439          * formats, but if we don't have the DRM_VC4_GET_TILING ioctl
440          * we shouldn't advertise the tiled formats.
441          */
442         for (i = 0; i < *count; i++) {
443                 modifiers[i] = available_modifiers[m++];
444                 if (external_only)
445                         external_only[i] = tex_will_lower;
446        }
447 }
448 
449 static bool
vc4_get_chip_info(struct vc4_screen * screen)450 vc4_get_chip_info(struct vc4_screen *screen)
451 {
452         struct drm_vc4_get_param ident0 = {
453                 .param = DRM_VC4_PARAM_V3D_IDENT0,
454         };
455         struct drm_vc4_get_param ident1 = {
456                 .param = DRM_VC4_PARAM_V3D_IDENT1,
457         };
458         int ret;
459 
460         ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident0);
461         if (ret != 0) {
462                 if (errno == EINVAL) {
463                         /* Backwards compatibility with 2835 kernels which
464                          * only do V3D 2.1.
465                          */
466                         screen->v3d_ver = 21;
467                         return true;
468                 } else {
469                         fprintf(stderr, "Couldn't get V3D IDENT0: %s\n",
470                                 strerror(errno));
471                         return false;
472                 }
473         }
474         ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &ident1);
475         if (ret != 0) {
476                 fprintf(stderr, "Couldn't get V3D IDENT1: %s\n",
477                         strerror(errno));
478                 return false;
479         }
480 
481         uint32_t major = (ident0.value >> 24) & 0xff;
482         uint32_t minor = (ident1.value >> 0) & 0xf;
483         screen->v3d_ver = major * 10 + minor;
484 
485         if (screen->v3d_ver != 21 && screen->v3d_ver != 26) {
486                 fprintf(stderr,
487                         "V3D %d.%d not supported by this version of Mesa.\n",
488                         screen->v3d_ver / 10,
489                         screen->v3d_ver % 10);
490                 return false;
491         }
492 
493         return true;
494 }
495 
496 struct pipe_screen *
vc4_screen_create(int fd,struct renderonly * ro)497 vc4_screen_create(int fd, struct renderonly *ro)
498 {
499         struct vc4_screen *screen = rzalloc(NULL, struct vc4_screen);
500         uint64_t syncobj_cap = 0;
501         struct pipe_screen *pscreen;
502         int err;
503 
504         pscreen = &screen->base;
505 
506         pscreen->destroy = vc4_screen_destroy;
507         pscreen->get_param = vc4_screen_get_param;
508         pscreen->get_paramf = vc4_screen_get_paramf;
509         pscreen->get_shader_param = vc4_screen_get_shader_param;
510         pscreen->context_create = vc4_context_create;
511         pscreen->is_format_supported = vc4_screen_is_format_supported;
512 
513         screen->fd = fd;
514         if (ro) {
515                 screen->ro = renderonly_dup(ro);
516                 if (!screen->ro) {
517                         fprintf(stderr, "Failed to dup renderonly object\n");
518                         ralloc_free(screen);
519                         return NULL;
520                 }
521         }
522 
523         list_inithead(&screen->bo_cache.time_list);
524         (void) mtx_init(&screen->bo_handles_mutex, mtx_plain);
525         screen->bo_handles = util_hash_table_create_ptr_keys();
526 
527         screen->has_control_flow =
528                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_BRANCHES);
529         screen->has_etc1 =
530                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_ETC1);
531         screen->has_threaded_fs =
532                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_THREADED_FS);
533         screen->has_madvise =
534                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_MADVISE);
535         screen->has_perfmon_ioctl =
536                 vc4_has_feature(screen, DRM_VC4_PARAM_SUPPORTS_PERFMON);
537 
538         err = drmGetCap(fd, DRM_CAP_SYNCOBJ, &syncobj_cap);
539         if (err == 0 && syncobj_cap)
540                 screen->has_syncobj = true;
541 
542         if (!vc4_get_chip_info(screen))
543                 goto fail;
544 
545         util_cpu_detect();
546 
547         slab_create_parent(&screen->transfer_pool, sizeof(struct vc4_transfer), 16);
548 
549         vc4_fence_screen_init(screen);
550 
551         vc4_debug = debug_get_option_vc4_debug();
552         if (vc4_debug & VC4_DEBUG_SHADERDB)
553                 vc4_debug |= VC4_DEBUG_NORAST;
554 
555 #ifdef USE_VC4_SIMULATOR
556         vc4_simulator_init(screen);
557 #endif
558 
559         vc4_resource_screen_init(pscreen);
560 
561         pscreen->get_name = vc4_screen_get_name;
562         pscreen->get_vendor = vc4_screen_get_vendor;
563         pscreen->get_device_vendor = vc4_screen_get_vendor;
564         pscreen->get_compiler_options = vc4_screen_get_compiler_options;
565         pscreen->query_dmabuf_modifiers = vc4_screen_query_dmabuf_modifiers;
566 
567         if (screen->has_perfmon_ioctl) {
568                 pscreen->get_driver_query_group_info = vc4_get_driver_query_group_info;
569                 pscreen->get_driver_query_info = vc4_get_driver_query_info;
570         }
571 
572         return pscreen;
573 
574 fail:
575         close(fd);
576         ralloc_free(pscreen);
577         return NULL;
578 }
579