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