• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors:
24  *    Rob Clark <robclark@freedesktop.org>
25  */
26 
27 #include "pipe/p_defines.h"
28 #include "pipe/p_screen.h"
29 #include "pipe/p_state.h"
30 
31 #include "util/format/u_format.h"
32 #include "util/format/u_format_s3tc.h"
33 #include "util/u_debug.h"
34 #include "util/u_inlines.h"
35 #include "util/u_memory.h"
36 #include "util/u_screen.h"
37 #include "util/u_string.h"
38 #include "util/xmlconfig.h"
39 
40 #include "util/os_time.h"
41 
42 #include <errno.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include "drm-uapi/drm_fourcc.h"
46 #include <sys/sysinfo.h>
47 
48 #include "freedreno_fence.h"
49 #include "freedreno_perfetto.h"
50 #include "freedreno_query.h"
51 #include "freedreno_resource.h"
52 #include "freedreno_screen.h"
53 #include "freedreno_util.h"
54 
55 #include "a2xx/fd2_screen.h"
56 #include "a3xx/fd3_screen.h"
57 #include "a4xx/fd4_screen.h"
58 #include "a5xx/fd5_screen.h"
59 #include "a6xx/fd6_screen.h"
60 
61 /* for fd_get_driver/device_uuid() */
62 #include "common/freedreno_uuid.h"
63 
64 #include "a2xx/ir2.h"
65 #include "ir3/ir3_gallium.h"
66 #include "ir3/ir3_nir.h"
67 
68 /* clang-format off */
69 static const struct debug_named_value fd_debug_options[] = {
70    {"msgs",      FD_DBG_MSGS,     "Print debug messages"},
71    {"disasm",    FD_DBG_DISASM,   "Dump TGSI and adreno shader disassembly (a2xx only, see IR3_SHADER_DEBUG)"},
72    {"dclear",    FD_DBG_DCLEAR,   "Mark all state dirty after clear"},
73    {"ddraw",     FD_DBG_DDRAW,    "Mark all state dirty after draw"},
74    {"noscis",    FD_DBG_NOSCIS,   "Disable scissor optimization"},
75    {"direct",    FD_DBG_DIRECT,   "Force inline (SS_DIRECT) state loads"},
76    {"gmem",      FD_DBG_GMEM,     "Use gmem rendering when it is permitted"},
77    {"perf",      FD_DBG_PERF,     "Enable performance warnings"},
78    {"nobin",     FD_DBG_NOBIN,    "Disable hw binning"},
79    {"sysmem",    FD_DBG_SYSMEM,   "Use sysmem only rendering (no tiling)"},
80    {"serialc",   FD_DBG_SERIALC,"Disable asynchronous shader compile"},
81    {"shaderdb",  FD_DBG_SHADERDB, "Enable shaderdb output"},
82    {"flush",     FD_DBG_FLUSH,    "Force flush after every draw"},
83    {"deqp",      FD_DBG_DEQP,     "Enable dEQP hacks"},
84    {"inorder",   FD_DBG_INORDER,  "Disable reordering for draws/blits"},
85    {"bstat",     FD_DBG_BSTAT,    "Print batch stats at context destroy"},
86    {"nogrow",    FD_DBG_NOGROW,   "Disable \"growable\" cmdstream buffers, even if kernel supports it"},
87    {"lrz",       FD_DBG_LRZ,      "Enable experimental LRZ support (a5xx)"},
88    {"noindirect",FD_DBG_NOINDR,   "Disable hw indirect draws (emulate on CPU)"},
89    {"noblit",    FD_DBG_NOBLIT,   "Disable blitter (fallback to generic blit path)"},
90    {"hiprio",    FD_DBG_HIPRIO,   "Force high-priority context"},
91    {"ttile",     FD_DBG_TTILE,    "Enable texture tiling (a2xx/a3xx/a5xx)"},
92    {"perfcntrs", FD_DBG_PERFC,    "Expose performance counters"},
93    {"noubwc",    FD_DBG_NOUBWC,   "Disable UBWC for all internal buffers"},
94    {"nolrz",     FD_DBG_NOLRZ,    "Disable LRZ (a6xx)"},
95    {"notile",    FD_DBG_NOTILE,   "Disable tiling for all internal buffers"},
96    {"layout",    FD_DBG_LAYOUT,   "Dump resource layouts"},
97    {"nofp16",    FD_DBG_NOFP16,   "Disable mediump precision lowering"},
98    {"nohw",      FD_DBG_NOHW,     "Disable submitting commands to the HW"},
99    {"nosbin",    FD_DBG_NOSBIN,   "Execute GMEM bins in raster order instead of 'S' pattern"},
100    DEBUG_NAMED_VALUE_END
101 };
102 /* clang-format on */
103 
104 DEBUG_GET_ONCE_FLAGS_OPTION(fd_mesa_debug, "FD_MESA_DEBUG", fd_debug_options, 0)
105 
106 int fd_mesa_debug = 0;
107 bool fd_binning_enabled = true;
108 
109 static const char *
fd_screen_get_name(struct pipe_screen * pscreen)110 fd_screen_get_name(struct pipe_screen *pscreen)
111 {
112    return fd_dev_name(fd_screen(pscreen)->dev_id);
113 }
114 
115 static const char *
fd_screen_get_vendor(struct pipe_screen * pscreen)116 fd_screen_get_vendor(struct pipe_screen *pscreen)
117 {
118    return "freedreno";
119 }
120 
121 static const char *
fd_screen_get_device_vendor(struct pipe_screen * pscreen)122 fd_screen_get_device_vendor(struct pipe_screen *pscreen)
123 {
124    return "Qualcomm";
125 }
126 
127 static uint64_t
fd_screen_get_timestamp(struct pipe_screen * pscreen)128 fd_screen_get_timestamp(struct pipe_screen *pscreen)
129 {
130    struct fd_screen *screen = fd_screen(pscreen);
131 
132    if (screen->has_timestamp) {
133       uint64_t n;
134       fd_pipe_get_param(screen->pipe, FD_TIMESTAMP, &n);
135       assert(screen->max_freq > 0);
136       return n * 1000000000 / screen->max_freq;
137    } else {
138       int64_t cpu_time = os_time_get() * 1000;
139       return cpu_time + screen->cpu_gpu_time_delta;
140    }
141 }
142 
143 static void
fd_screen_destroy(struct pipe_screen * pscreen)144 fd_screen_destroy(struct pipe_screen *pscreen)
145 {
146    struct fd_screen *screen = fd_screen(pscreen);
147 
148    if (screen->tess_bo)
149       fd_bo_del(screen->tess_bo);
150 
151    if (screen->pipe)
152       fd_pipe_del(screen->pipe);
153 
154    if (screen->dev) {
155       fd_device_purge(screen->dev);
156       fd_device_del(screen->dev);
157    }
158 
159    if (screen->ro)
160       screen->ro->destroy(screen->ro);
161 
162    fd_bc_fini(&screen->batch_cache);
163    fd_gmem_screen_fini(pscreen);
164 
165    slab_destroy_parent(&screen->transfer_pool);
166 
167    simple_mtx_destroy(&screen->lock);
168 
169    util_idalloc_mt_fini(&screen->buffer_ids);
170 
171    u_transfer_helper_destroy(pscreen->transfer_helper);
172 
173    if (screen->compiler)
174       ir3_screen_fini(pscreen);
175 
176    free(screen->perfcntr_queries);
177    free(screen);
178 }
179 
180 /*
181 TODO either move caps to a2xx/a3xx specific code, or maybe have some
182 tables for things that differ if the delta is not too much..
183  */
184 static int
fd_screen_get_param(struct pipe_screen * pscreen,enum pipe_cap param)185 fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
186 {
187    struct fd_screen *screen = fd_screen(pscreen);
188 
189    /* this is probably not totally correct.. but it's a start: */
190    switch (param) {
191    /* Supported features (boolean caps). */
192    case PIPE_CAP_NPOT_TEXTURES:
193    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
194    case PIPE_CAP_ANISOTROPIC_FILTER:
195    case PIPE_CAP_POINT_SPRITE:
196    case PIPE_CAP_BLEND_EQUATION_SEPARATE:
197    case PIPE_CAP_TEXTURE_SWIZZLE:
198    case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
199    case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
200    case PIPE_CAP_SEAMLESS_CUBE_MAP:
201    case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
202    case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
203    case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
204    case PIPE_CAP_STRING_MARKER:
205    case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
206    case PIPE_CAP_TEXTURE_BARRIER:
207    case PIPE_CAP_INVALIDATE_BUFFER:
208    case PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND:
209    case PIPE_CAP_GLSL_TESS_LEVELS_AS_INPUTS:
210    case PIPE_CAP_NIR_COMPACT_ARRAYS:
211       return 1;
212 
213    case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
214       return is_a6xx(screen);
215 
216    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
217    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
218    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
219       return is_a2xx(screen);
220 
221    case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER:
222       return is_a2xx(screen);
223    case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
224       return !is_a2xx(screen);
225 
226    case PIPE_CAP_PACKED_UNIFORMS:
227       return !is_a2xx(screen);
228 
229    case PIPE_CAP_ROBUST_BUFFER_ACCESS_BEHAVIOR:
230    case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
231       return screen->has_robustness;
232 
233    case PIPE_CAP_VERTEXID_NOBASE:
234       return is_a3xx(screen) || is_a4xx(screen);
235 
236    case PIPE_CAP_COMPUTE:
237       return has_compute(screen);
238 
239    case PIPE_CAP_TEXTURE_TRANSFER_MODES:
240    case PIPE_CAP_PCI_GROUP:
241    case PIPE_CAP_PCI_BUS:
242    case PIPE_CAP_PCI_DEVICE:
243    case PIPE_CAP_PCI_FUNCTION:
244       return 0;
245 
246    case PIPE_CAP_SUPPORTED_PRIM_MODES:
247    case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART:
248       return screen->primtypes_mask;
249 
250    case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
251    case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
252    case PIPE_CAP_PRIMITIVE_RESTART:
253    case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
254    case PIPE_CAP_VS_INSTANCEID:
255    case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
256    case PIPE_CAP_INDEP_BLEND_ENABLE:
257    case PIPE_CAP_INDEP_BLEND_FUNC:
258    case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
259    case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
260    case PIPE_CAP_CONDITIONAL_RENDER:
261    case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
262    case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
263    case PIPE_CAP_CLIP_HALFZ:
264       return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) ||
265              is_a6xx(screen);
266 
267    case PIPE_CAP_FAKE_SW_MSAA:
268       return !fd_screen_get_param(pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE);
269 
270    case PIPE_CAP_TEXTURE_MULTISAMPLE:
271    case PIPE_CAP_IMAGE_STORE_FORMATTED:
272       return is_a5xx(screen) || is_a6xx(screen);
273 
274    case PIPE_CAP_SURFACE_SAMPLE_COUNT:
275       return is_a6xx(screen);
276 
277    case PIPE_CAP_DEPTH_CLIP_DISABLE:
278       return is_a3xx(screen) || is_a4xx(screen) || is_a6xx(screen);
279 
280    case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
281       return is_a6xx(screen);
282 
283    case PIPE_CAP_POLYGON_OFFSET_CLAMP:
284       return is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen);
285 
286    case PIPE_CAP_PREFER_IMM_ARRAYS_AS_CONSTBUF:
287       return 0;
288 
289    case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
290       if (is_a3xx(screen))
291          return 16;
292       if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
293          return 64;
294       return 0;
295    case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
296       /* We could possibly emulate more by pretending 2d/rect textures and
297        * splitting high bits of index into 2nd dimension..
298        */
299       if (is_a3xx(screen))
300          return 8192;
301 
302       /* Note that the Vulkan blob on a540 and 640 report a
303        * maxTexelBufferElements of just 65536 (the GLES3.2 and Vulkan
304        * minimum).
305        */
306       if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
307          return 1 << 27;
308       return 0;
309 
310    case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
311    case PIPE_CAP_CUBE_MAP_ARRAY:
312    case PIPE_CAP_SAMPLER_VIEW_TARGET:
313    case PIPE_CAP_TEXTURE_QUERY_LOD:
314       return is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen);
315 
316    case PIPE_CAP_START_INSTANCE:
317       /* Note that a5xx can do this, it just can't (at least with
318        * current firmware) do draw_indirect with base_instance.
319        * Since draw_indirect is needed sooner (gles31 and gl40 vs
320        * gl42), hide base_instance on a5xx.  :-/
321        */
322       return is_a4xx(screen);
323 
324    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
325       return 64;
326 
327    case PIPE_CAP_GLSL_FEATURE_LEVEL:
328    case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
329       if (is_a6xx(screen))
330          return 330;
331       else if (is_ir3(screen))
332          return 140;
333       else
334          return 120;
335 
336    case PIPE_CAP_ESSL_FEATURE_LEVEL:
337       if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
338          return 320;
339       if (is_ir3(screen))
340          return 300;
341       return 120;
342 
343    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
344       if (is_a6xx(screen))
345          return 64;
346       if (is_a5xx(screen))
347          return 4;
348       if (is_a4xx(screen))
349          return 4;
350       return 0;
351 
352    case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
353       if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
354          return 4;
355       return 0;
356 
357    /* TODO if we need this, do it in nir/ir3 backend to avoid breaking
358     * precompile: */
359    case PIPE_CAP_FORCE_PERSAMPLE_INTERP:
360       return 0;
361 
362    case PIPE_CAP_FBFETCH:
363       if (fd_device_version(screen->dev) >= FD_VERSION_GMEM_BASE &&
364           is_a6xx(screen))
365          return 1;
366       return 0;
367    case PIPE_CAP_SAMPLE_SHADING:
368       if (is_a6xx(screen))
369          return 1;
370       return 0;
371 
372    case PIPE_CAP_CONTEXT_PRIORITY_MASK:
373       return screen->priority_mask;
374 
375    case PIPE_CAP_DRAW_INDIRECT:
376       if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
377          return 1;
378       return 0;
379 
380    case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
381       if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen))
382          return 1;
383       return 0;
384 
385    case PIPE_CAP_LOAD_CONSTBUF:
386       /* name is confusing, but this turns on std430 packing */
387       if (is_ir3(screen))
388          return 1;
389       return 0;
390 
391    case PIPE_CAP_NIR_IMAGES_AS_DEREF:
392       return 0;
393 
394    case PIPE_CAP_MAX_VIEWPORTS:
395       return 1;
396 
397    case PIPE_CAP_MAX_VARYINGS:
398       return is_a6xx(screen) ? 31 : 16;
399 
400    case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
401       /* We don't really have a limit on this, it all goes into the main
402        * memory buffer. Needs to be at least 120 / 4 (minimum requirement
403        * for GL_MAX_TESS_PATCH_COMPONENTS).
404        */
405       return 128;
406 
407    case PIPE_CAP_MAX_TEXTURE_UPLOAD_MEMORY_BUDGET:
408       return 64 * 1024 * 1024;
409 
410    case PIPE_CAP_SHAREABLE_SHADERS:
411       if (is_ir3(screen))
412          return 1;
413       return 0;
414 
415    /* Geometry shaders.. */
416    case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
417       return 512;
418    case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
419       return 2048;
420    case PIPE_CAP_MAX_GS_INVOCATIONS:
421       return 32;
422 
423    /* Only a2xx has the half-border clamp mode in HW, just have mesa/st lower
424     * it for later HW.
425     */
426    case PIPE_CAP_GL_CLAMP:
427       return is_a2xx(screen);
428 
429    case PIPE_CAP_CLIP_PLANES:
430       /* Gens that support GS, have GS lowered into a quasi-VS which confuses
431        * the frontend clip-plane lowering.  So we handle this in the backend
432        *
433        */
434       if (pscreen->get_shader_param(pscreen, PIPE_SHADER_GEOMETRY,
435                                     PIPE_SHADER_CAP_MAX_INSTRUCTIONS))
436          return 1;
437 
438       /* On a3xx, there is HW support for GL user clip planes that
439        * occasionally has to fall back to shader key-based lowering to clip
440        * distances in the VS, and we don't support clip distances so that is
441        * always shader-based lowering in the FS.
442        *
443        * On a4xx, there is no HW support for clip planes, so they are
444        * always lowered to clip distances.  We also lack SW support for the
445        * HW's clip distances in HW, so we do shader-based lowering in the FS
446        * in the driver backend.
447        *
448        * On a5xx-a6xx, we have the HW clip distances hooked up, so we just let
449        * mesa/st lower desktop GL's clip planes to clip distances in the last
450        * vertex shader stage.
451        *
452        * NOTE: but see comment above about geometry shaders
453        */
454       return !is_a5xx(screen);
455 
456    /* Stream output. */
457    case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
458       if (is_ir3(screen))
459          return PIPE_MAX_SO_BUFFERS;
460       return 0;
461    case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
462    case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
463    case PIPE_CAP_FS_POSITION_IS_SYSVAL:
464    case PIPE_CAP_TGSI_TEXCOORD:
465       if (is_ir3(screen))
466          return 1;
467       return 0;
468    case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
469       return 1;
470    case PIPE_CAP_FS_POINT_IS_SYSVAL:
471       return is_a2xx(screen);
472    case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
473    case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
474       if (is_ir3(screen))
475          return 16 * 4; /* should only be shader out limit? */
476       return 0;
477 
478    /* Texturing. */
479    case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
480       if (is_a6xx(screen) || is_a5xx(screen) || is_a4xx(screen))
481          return 16384;
482       else
483          return 8192;
484    case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
485       if (is_a6xx(screen) || is_a5xx(screen) || is_a4xx(screen))
486          return 15;
487       else
488          return 14;
489 
490    case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
491       if (is_a3xx(screen))
492          return 11;
493       return 12;
494 
495    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
496       return (is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) ||
497               is_a6xx(screen))
498                 ? 256
499                 : 0;
500 
501    /* Render targets. */
502    case PIPE_CAP_MAX_RENDER_TARGETS:
503       return screen->max_rts;
504    case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
505       return (is_a3xx(screen) || is_a6xx(screen)) ? 1 : 0;
506 
507    /* Queries. */
508    case PIPE_CAP_OCCLUSION_QUERY:
509       return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) ||
510              is_a6xx(screen);
511    case PIPE_CAP_QUERY_TIMESTAMP:
512    case PIPE_CAP_QUERY_TIME_ELAPSED:
513       /* only a4xx, requires new enough kernel so we know max_freq: */
514       return (screen->max_freq > 0) &&
515              (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen));
516 
517    case PIPE_CAP_VENDOR_ID:
518       return 0x5143;
519    case PIPE_CAP_DEVICE_ID:
520       return 0xFFFFFFFF;
521    case PIPE_CAP_ACCELERATED:
522       return 1;
523 
524    case PIPE_CAP_VIDEO_MEMORY: {
525       uint64_t system_memory;
526 
527       if (!os_get_total_physical_memory(&system_memory))
528          return 0;
529 
530       return (int)(system_memory >> 20);
531    }
532 
533    case PIPE_CAP_UMA:
534       return 1;
535    case PIPE_CAP_MEMOBJ:
536       return fd_device_version(screen->dev) >= FD_VERSION_MEMORY_FD;
537    case PIPE_CAP_NATIVE_FENCE_FD:
538       return fd_device_version(screen->dev) >= FD_VERSION_FENCE_FD;
539    case PIPE_CAP_FENCE_SIGNAL:
540       return screen->has_syncobj;
541    case PIPE_CAP_CULL_DISTANCE:
542       return is_a6xx(screen);
543    case PIPE_CAP_SHADER_STENCIL_EXPORT:
544       return is_a6xx(screen);
545    case PIPE_CAP_TWO_SIDED_COLOR:
546       return 0;
547    default:
548       return u_pipe_screen_get_param_defaults(pscreen, param);
549    }
550 }
551 
552 static float
fd_screen_get_paramf(struct pipe_screen * pscreen,enum pipe_capf param)553 fd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
554 {
555    switch (param) {
556    case PIPE_CAPF_MIN_LINE_WIDTH:
557    case PIPE_CAPF_MIN_LINE_WIDTH_AA:
558    case PIPE_CAPF_MIN_POINT_SIZE:
559    case PIPE_CAPF_MIN_POINT_SIZE_AA:
560       return 1;
561    case PIPE_CAPF_POINT_SIZE_GRANULARITY:
562    case PIPE_CAPF_LINE_WIDTH_GRANULARITY:
563       return 0.1f;
564    case PIPE_CAPF_MAX_LINE_WIDTH:
565    case PIPE_CAPF_MAX_LINE_WIDTH_AA:
566       /* NOTE: actual value is 127.0f, but this is working around a deqp
567        * bug.. dEQP-GLES3.functional.rasterization.primitives.lines_wide
568        * uses too small of a render target size, and gets confused when
569        * the lines start going offscreen.
570        *
571        * See: https://code.google.com/p/android/issues/detail?id=206513
572        */
573       if (FD_DBG(DEQP))
574          return 48.0f;
575       return 127.0f;
576    case PIPE_CAPF_MAX_POINT_SIZE:
577    case PIPE_CAPF_MAX_POINT_SIZE_AA:
578       return 4092.0f;
579    case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
580       return 16.0f;
581    case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
582       return 15.0f;
583    case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
584    case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
585    case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
586       return 0.0f;
587    }
588    mesa_loge("unknown paramf %d", param);
589    return 0;
590 }
591 
592 static int
fd_screen_get_shader_param(struct pipe_screen * pscreen,enum pipe_shader_type shader,enum pipe_shader_cap param)593 fd_screen_get_shader_param(struct pipe_screen *pscreen,
594                            enum pipe_shader_type shader,
595                            enum pipe_shader_cap param)
596 {
597    struct fd_screen *screen = fd_screen(pscreen);
598 
599    switch (shader) {
600    case PIPE_SHADER_FRAGMENT:
601    case PIPE_SHADER_VERTEX:
602       break;
603    case PIPE_SHADER_TESS_CTRL:
604    case PIPE_SHADER_TESS_EVAL:
605    case PIPE_SHADER_GEOMETRY:
606       if (is_a6xx(screen))
607          break;
608       return 0;
609    case PIPE_SHADER_COMPUTE:
610       if (has_compute(screen))
611          break;
612       return 0;
613    default:
614       mesa_loge("unknown shader type %d", shader);
615       return 0;
616    }
617 
618    /* this is probably not totally correct.. but it's a start: */
619    switch (param) {
620    case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
621    case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
622    case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
623    case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
624       return 16384;
625    case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
626       return 8; /* XXX */
627    case PIPE_SHADER_CAP_MAX_INPUTS:
628       if (shader == PIPE_SHADER_GEOMETRY && is_a6xx(screen))
629          return 16;
630       return is_a6xx(screen) ? 32 : 16;
631    case PIPE_SHADER_CAP_MAX_OUTPUTS:
632       return is_a6xx(screen) ? 32 : 16;
633    case PIPE_SHADER_CAP_MAX_TEMPS:
634       return 64; /* Max native temporaries. */
635    case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
636       /* NOTE: seems to be limit for a3xx is actually 512 but
637        * split between VS and FS.  Use lower limit of 256 to
638        * avoid getting into impossible situations:
639        */
640       return ((is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen) ||
641                is_a6xx(screen))
642                  ? 4096
643                  : 64) *
644              sizeof(float[4]);
645    case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
646       return is_ir3(screen) ? 16 : 1;
647    case PIPE_SHADER_CAP_CONT_SUPPORTED:
648       return 1;
649    case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
650    case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
651    case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
652    case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
653       /* a2xx compiler doesn't handle indirect: */
654       return is_ir3(screen) ? 1 : 0;
655    case PIPE_SHADER_CAP_SUBROUTINES:
656    case PIPE_SHADER_CAP_DROUND_SUPPORTED:
657    case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED:
658    case PIPE_SHADER_CAP_LDEXP_SUPPORTED:
659    case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
660    case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
661    case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
662       return 0;
663    case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
664       return 1;
665    case PIPE_SHADER_CAP_INTEGERS:
666       return is_ir3(screen) ? 1 : 0;
667    case PIPE_SHADER_CAP_INT64_ATOMICS:
668    case PIPE_SHADER_CAP_FP16_DERIVATIVES:
669    case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
670    case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
671       return 0;
672    case PIPE_SHADER_CAP_INT16:
673    case PIPE_SHADER_CAP_FP16:
674       return (
675          (is_a5xx(screen) || is_a6xx(screen)) &&
676          (shader == PIPE_SHADER_COMPUTE || shader == PIPE_SHADER_FRAGMENT) &&
677          !FD_DBG(NOFP16));
678    case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
679    case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
680       return 16;
681    case PIPE_SHADER_CAP_PREFERRED_IR:
682       return PIPE_SHADER_IR_NIR;
683    case PIPE_SHADER_CAP_SUPPORTED_IRS:
684       return (1 << PIPE_SHADER_IR_NIR) |
685              COND(has_compute(screen) && (shader == PIPE_SHADER_COMPUTE),
686                   (1 << PIPE_SHADER_IR_NIR_SERIALIZED)) |
687              (1 << PIPE_SHADER_IR_TGSI);
688    case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
689    case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
690       if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) {
691          /* a5xx (and a4xx for that matter) has one state-block
692           * for compute-shader SSBO's and another that is shared
693           * by VS/HS/DS/GS/FS..  so to simplify things for now
694           * just advertise SSBOs for FS and CS.  We could possibly
695           * do what blob does, and partition the space for
696           * VS/HS/DS/GS/FS.  The blob advertises:
697           *
698           *   GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: 4
699           *   GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: 4
700           *   GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: 4
701           *   GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: 4
702           *   GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: 4
703           *   GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: 24
704           *   GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: 24
705           *
706           * I think that way we could avoid having to patch shaders
707           * for actual SSBO indexes by using a static partitioning.
708           *
709           * Note same state block is used for images and buffers,
710           * but images also need texture state for read access
711           * (isam/isam.3d)
712           */
713          switch (shader) {
714          case PIPE_SHADER_FRAGMENT:
715          case PIPE_SHADER_COMPUTE:
716             return 24;
717          default:
718             return 0;
719          }
720       }
721       return 0;
722    }
723    mesa_loge("unknown shader param %d", param);
724    return 0;
725 }
726 
727 /* TODO depending on how much the limits differ for a3xx/a4xx, maybe move this
728  * into per-generation backend?
729  */
730 static int
fd_get_compute_param(struct pipe_screen * pscreen,enum pipe_shader_ir ir_type,enum pipe_compute_cap param,void * ret)731 fd_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
732                      enum pipe_compute_cap param, void *ret)
733 {
734    struct fd_screen *screen = fd_screen(pscreen);
735    const char *const ir = "ir3";
736 
737    if (!has_compute(screen))
738       return 0;
739 
740    struct ir3_compiler *compiler = screen->compiler;
741 
742 #define RET(x)                                                                 \
743    do {                                                                        \
744       if (ret)                                                                 \
745          memcpy(ret, x, sizeof(x));                                            \
746       return sizeof(x);                                                        \
747    } while (0)
748 
749    switch (param) {
750    case PIPE_COMPUTE_CAP_ADDRESS_BITS:
751       if (screen->gen >= 5)
752          RET((uint32_t[]){64});
753       RET((uint32_t[]){32});
754 
755    case PIPE_COMPUTE_CAP_IR_TARGET:
756       if (ret)
757          sprintf(ret, "%s", ir);
758       return strlen(ir) * sizeof(char);
759 
760    case PIPE_COMPUTE_CAP_GRID_DIMENSION:
761       RET((uint64_t[]){3});
762 
763    case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
764       RET(((uint64_t[]){65535, 65535, 65535}));
765 
766    case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
767       RET(((uint64_t[]){1024, 1024, 64}));
768 
769    case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
770       RET((uint64_t[]){1024});
771 
772    case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
773       RET((uint64_t[]){screen->ram_size});
774 
775    case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
776       RET((uint64_t[]){32768});
777 
778    case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
779    case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
780       RET((uint64_t[]){4096});
781 
782    case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
783       RET((uint64_t[]){screen->ram_size});
784 
785    case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
786       RET((uint32_t[]){screen->max_freq / 1000000});
787 
788    case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
789       RET((uint32_t[]){9999}); // TODO
790 
791    case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
792       RET((uint32_t[]){1});
793 
794    case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:
795       RET((uint32_t[]){32}); // TODO
796 
797    case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
798       RET((uint64_t[]){ compiler->max_variable_workgroup_size });
799    }
800 
801    return 0;
802 }
803 
804 static const void *
fd_get_compiler_options(struct pipe_screen * pscreen,enum pipe_shader_ir ir,unsigned shader)805 fd_get_compiler_options(struct pipe_screen *pscreen, enum pipe_shader_ir ir,
806                         unsigned shader)
807 {
808    struct fd_screen *screen = fd_screen(pscreen);
809 
810    if (is_ir3(screen))
811       return ir3_get_compiler_options(screen->compiler);
812 
813    return ir2_get_compiler_options();
814 }
815 
816 static struct disk_cache *
fd_get_disk_shader_cache(struct pipe_screen * pscreen)817 fd_get_disk_shader_cache(struct pipe_screen *pscreen)
818 {
819    struct fd_screen *screen = fd_screen(pscreen);
820 
821    if (is_ir3(screen)) {
822       struct ir3_compiler *compiler = screen->compiler;
823       return compiler->disk_cache;
824    }
825 
826    return NULL;
827 }
828 
829 bool
fd_screen_bo_get_handle(struct pipe_screen * pscreen,struct fd_bo * bo,struct renderonly_scanout * scanout,unsigned stride,struct winsys_handle * whandle)830 fd_screen_bo_get_handle(struct pipe_screen *pscreen, struct fd_bo *bo,
831                         struct renderonly_scanout *scanout, unsigned stride,
832                         struct winsys_handle *whandle)
833 {
834    struct fd_screen *screen = fd_screen(pscreen);
835 
836    whandle->stride = stride;
837 
838    if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
839       return fd_bo_get_name(bo, &whandle->handle) == 0;
840    } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
841       if (screen->ro) {
842          return renderonly_get_handle(scanout, whandle);
843       } else {
844          whandle->handle = fd_bo_handle(bo);
845          return true;
846       }
847    } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
848       whandle->handle = fd_bo_dmabuf(bo);
849       return true;
850    } else {
851       return false;
852    }
853 }
854 
855 static void
fd_screen_query_dmabuf_modifiers(struct pipe_screen * pscreen,enum pipe_format format,int max,uint64_t * modifiers,unsigned int * external_only,int * count)856 fd_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
857                                  enum pipe_format format, int max,
858                                  uint64_t *modifiers,
859                                  unsigned int *external_only, int *count)
860 {
861    struct fd_screen *screen = fd_screen(pscreen);
862    int i, num = 0;
863 
864    max = MIN2(max, screen->num_supported_modifiers);
865 
866    if (!max) {
867       max = screen->num_supported_modifiers;
868       external_only = NULL;
869       modifiers = NULL;
870    }
871 
872    for (i = 0; i < max; i++) {
873       if (modifiers)
874          modifiers[num] = screen->supported_modifiers[i];
875 
876       if (external_only)
877          external_only[num] = 0;
878 
879       num++;
880    }
881 
882    *count = num;
883 }
884 
885 static bool
fd_screen_is_dmabuf_modifier_supported(struct pipe_screen * pscreen,uint64_t modifier,enum pipe_format format,bool * external_only)886 fd_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
887                                        uint64_t modifier,
888                                        enum pipe_format format,
889                                        bool *external_only)
890 {
891    struct fd_screen *screen = fd_screen(pscreen);
892    int i;
893 
894    for (i = 0; i < screen->num_supported_modifiers; i++) {
895       if (modifier == screen->supported_modifiers[i]) {
896          if (external_only)
897             *external_only = false;
898 
899          return true;
900       }
901    }
902 
903    return false;
904 }
905 
906 struct fd_bo *
fd_screen_bo_from_handle(struct pipe_screen * pscreen,struct winsys_handle * whandle)907 fd_screen_bo_from_handle(struct pipe_screen *pscreen,
908                          struct winsys_handle *whandle)
909 {
910    struct fd_screen *screen = fd_screen(pscreen);
911    struct fd_bo *bo;
912 
913    if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {
914       bo = fd_bo_from_name(screen->dev, whandle->handle);
915    } else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {
916       bo = fd_bo_from_handle(screen->dev, whandle->handle, 0);
917    } else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {
918       bo = fd_bo_from_dmabuf(screen->dev, whandle->handle);
919    } else {
920       DBG("Attempt to import unsupported handle type %d", whandle->type);
921       return NULL;
922    }
923 
924    if (!bo) {
925       DBG("ref name 0x%08x failed", whandle->handle);
926       return NULL;
927    }
928 
929    return bo;
930 }
931 
932 static void
_fd_fence_ref(struct pipe_screen * pscreen,struct pipe_fence_handle ** ptr,struct pipe_fence_handle * pfence)933 _fd_fence_ref(struct pipe_screen *pscreen, struct pipe_fence_handle **ptr,
934               struct pipe_fence_handle *pfence)
935 {
936    fd_fence_ref(ptr, pfence);
937 }
938 
939 static void
fd_screen_get_device_uuid(struct pipe_screen * pscreen,char * uuid)940 fd_screen_get_device_uuid(struct pipe_screen *pscreen, char *uuid)
941 {
942    struct fd_screen *screen = fd_screen(pscreen);
943 
944    fd_get_device_uuid(uuid, screen->dev_id);
945 }
946 
947 static void
fd_screen_get_driver_uuid(struct pipe_screen * pscreen,char * uuid)948 fd_screen_get_driver_uuid(struct pipe_screen *pscreen, char *uuid)
949 {
950    fd_get_driver_uuid(uuid);
951 }
952 
953 struct pipe_screen *
fd_screen_create(struct fd_device * dev,struct renderonly * ro,const struct pipe_screen_config * config)954 fd_screen_create(struct fd_device *dev, struct renderonly *ro,
955                  const struct pipe_screen_config *config)
956 {
957    struct fd_screen *screen = CALLOC_STRUCT(fd_screen);
958    struct pipe_screen *pscreen;
959    uint64_t val;
960 
961    fd_mesa_debug = debug_get_option_fd_mesa_debug();
962 
963    if (FD_DBG(NOBIN))
964       fd_binning_enabled = false;
965 
966    if (!screen)
967       return NULL;
968 
969 #ifdef HAVE_PERFETTO
970    fd_perfetto_init();
971 #endif
972 
973    pscreen = &screen->base;
974 
975    screen->dev = dev;
976    screen->ro = ro;
977    screen->refcnt = 1;
978 
979    // maybe this should be in context?
980    screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
981    if (!screen->pipe) {
982       DBG("could not create 3d pipe");
983       goto fail;
984    }
985 
986    if (fd_pipe_get_param(screen->pipe, FD_GMEM_SIZE, &val)) {
987       DBG("could not get GMEM size");
988       goto fail;
989    }
990    screen->gmemsize_bytes = env_var_as_unsigned("FD_MESA_GMEM", val);
991 
992    if (fd_device_version(dev) >= FD_VERSION_GMEM_BASE) {
993       fd_pipe_get_param(screen->pipe, FD_GMEM_BASE, &screen->gmem_base);
994    }
995 
996    if (fd_pipe_get_param(screen->pipe, FD_MAX_FREQ, &val)) {
997       DBG("could not get gpu freq");
998       /* this limits what performance related queries are
999        * supported but is not fatal
1000        */
1001       screen->max_freq = 0;
1002    } else {
1003       screen->max_freq = val;
1004       if (fd_pipe_get_param(screen->pipe, FD_TIMESTAMP, &val) == 0)
1005          screen->has_timestamp = true;
1006    }
1007 
1008    screen->dev_id = fd_pipe_dev_id(screen->pipe);
1009 
1010    if (fd_pipe_get_param(screen->pipe, FD_GPU_ID, &val)) {
1011       DBG("could not get gpu-id");
1012       goto fail;
1013    }
1014    screen->gpu_id = val;
1015 
1016    if (fd_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) {
1017       DBG("could not get chip-id");
1018       /* older kernels may not have this property: */
1019       unsigned core = screen->gpu_id / 100;
1020       unsigned major = (screen->gpu_id % 100) / 10;
1021       unsigned minor = screen->gpu_id % 10;
1022       unsigned patch = 0; /* assume the worst */
1023       val = (patch & 0xff) | ((minor & 0xff) << 8) | ((major & 0xff) << 16) |
1024             ((core & 0xff) << 24);
1025    }
1026    screen->chip_id = val;
1027    screen->gen = fd_dev_gen(screen->dev_id);
1028 
1029    if (fd_pipe_get_param(screen->pipe, FD_NR_RINGS, &val)) {
1030       DBG("could not get # of rings");
1031       screen->priority_mask = 0;
1032    } else {
1033       /* # of rings equates to number of unique priority values: */
1034       screen->priority_mask = (1 << val) - 1;
1035    }
1036 
1037    if (fd_device_version(dev) >= FD_VERSION_ROBUSTNESS)
1038       screen->has_robustness = true;
1039 
1040    screen->has_syncobj = fd_has_syncobj(screen->dev);
1041 
1042    /* parse driconf configuration now for device specific overrides: */
1043    driParseConfigFiles(config->options, config->options_info, 0, "msm",
1044                        NULL, fd_dev_name(screen->dev_id), NULL, 0, NULL, 0);
1045 
1046    struct sysinfo si;
1047    sysinfo(&si);
1048    screen->ram_size = si.totalram;
1049 
1050    DBG("Pipe Info:");
1051    DBG(" GPU-id:          %s", fd_dev_name(screen->dev_id));
1052    DBG(" Chip-id:         0x%016"PRIx64, screen->chip_id);
1053    DBG(" GMEM size:       0x%08x", screen->gmemsize_bytes);
1054 
1055    const struct fd_dev_info *info = fd_dev_info(screen->dev_id);
1056    if (!info) {
1057       mesa_loge("unsupported GPU: a%03d", screen->gpu_id);
1058       goto fail;
1059    }
1060 
1061    screen->info = info;
1062 
1063    /* explicitly checking for GPU revisions that are known to work.  This
1064     * may be overly conservative for a3xx, where spoofing the gpu_id with
1065     * the blob driver seems to generate identical cmdstream dumps.  But
1066     * on a2xx, there seem to be small differences between the GPU revs
1067     * so it is probably better to actually test first on real hardware
1068     * before enabling:
1069     *
1070     * If you have a different adreno version, feel free to add it to one
1071     * of the cases below and see what happens.  And if it works, please
1072     * send a patch ;-)
1073     */
1074    switch (screen->gen) {
1075    case 2:
1076       fd2_screen_init(pscreen);
1077       break;
1078    case 3:
1079       fd3_screen_init(pscreen);
1080       break;
1081    case 4:
1082       fd4_screen_init(pscreen);
1083       break;
1084    case 5:
1085       fd5_screen_init(pscreen);
1086       break;
1087    case 6:
1088       fd6_screen_init(pscreen);
1089       break;
1090    default:
1091       mesa_loge("unsupported GPU generation: a%uxx", screen->gen);
1092       goto fail;
1093    }
1094 
1095    /* fdN_screen_init() should set this: */
1096    assert(screen->primtypes);
1097    screen->primtypes_mask = 0;
1098    for (unsigned i = 0; i <= PIPE_PRIM_MAX; i++)
1099       if (screen->primtypes[i])
1100          screen->primtypes_mask |= (1 << i);
1101 
1102    if (FD_DBG(PERFC)) {
1103       screen->perfcntr_groups =
1104          fd_perfcntrs(screen->dev_id, &screen->num_perfcntr_groups);
1105    }
1106 
1107    /* NOTE: don't enable if we have too old of a kernel to support
1108     * growable cmdstream buffers, since memory requirement for cmdstream
1109     * buffers would be too much otherwise.
1110     */
1111    if (fd_device_version(dev) >= FD_VERSION_UNLIMITED_CMDS)
1112       screen->reorder = !FD_DBG(INORDER);
1113 
1114    fd_bc_init(&screen->batch_cache);
1115 
1116    list_inithead(&screen->context_list);
1117 
1118    util_idalloc_mt_init_tc(&screen->buffer_ids);
1119 
1120    (void)simple_mtx_init(&screen->lock, mtx_plain);
1121 
1122    pscreen->destroy = fd_screen_destroy;
1123    pscreen->get_param = fd_screen_get_param;
1124    pscreen->get_paramf = fd_screen_get_paramf;
1125    pscreen->get_shader_param = fd_screen_get_shader_param;
1126    pscreen->get_compute_param = fd_get_compute_param;
1127    pscreen->get_compiler_options = fd_get_compiler_options;
1128    pscreen->get_disk_shader_cache = fd_get_disk_shader_cache;
1129 
1130    fd_resource_screen_init(pscreen);
1131    fd_query_screen_init(pscreen);
1132    fd_gmem_screen_init(pscreen);
1133 
1134    pscreen->get_name = fd_screen_get_name;
1135    pscreen->get_vendor = fd_screen_get_vendor;
1136    pscreen->get_device_vendor = fd_screen_get_device_vendor;
1137 
1138    pscreen->get_timestamp = fd_screen_get_timestamp;
1139 
1140    pscreen->fence_reference = _fd_fence_ref;
1141    pscreen->fence_finish = fd_fence_finish;
1142    pscreen->fence_get_fd = fd_fence_get_fd;
1143 
1144    pscreen->query_dmabuf_modifiers = fd_screen_query_dmabuf_modifiers;
1145    pscreen->is_dmabuf_modifier_supported =
1146       fd_screen_is_dmabuf_modifier_supported;
1147 
1148    pscreen->get_device_uuid = fd_screen_get_device_uuid;
1149    pscreen->get_driver_uuid = fd_screen_get_driver_uuid;
1150 
1151    slab_create_parent(&screen->transfer_pool, sizeof(struct fd_transfer), 16);
1152 
1153    return pscreen;
1154 
1155 fail:
1156    fd_screen_destroy(pscreen);
1157    return NULL;
1158 }
1159