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 */ 69static 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 104DEBUG_GET_ONCE_FLAGS_OPTION(fd_mesa_debug, "FD_MESA_DEBUG", fd_debug_options, 0) 105 106int fd_mesa_debug = 0; 107bool fd_binning_enabled = true; 108 109static const char * 110fd_screen_get_name(struct pipe_screen *pscreen) 111{ 112 return fd_dev_name(fd_screen(pscreen)->dev_id); 113} 114 115static const char * 116fd_screen_get_vendor(struct pipe_screen *pscreen) 117{ 118 return "freedreno"; 119} 120 121static const char * 122fd_screen_get_device_vendor(struct pipe_screen *pscreen) 123{ 124 return "Qualcomm"; 125} 126 127static uint64_t 128fd_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 143static void 144fd_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/* 181TODO either move caps to a2xx/a3xx specific code, or maybe have some 182tables for things that differ if the delta is not too much.. 183 */ 184static int 185fd_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 552static float 553fd_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 592static int 593fd_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 */ 730static int 731fd_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 804static const void * 805fd_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 816static struct disk_cache * 817fd_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 829bool 830fd_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 855static void 856fd_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 885static bool 886fd_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 906struct fd_bo * 907fd_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 932static void 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 939static void 940fd_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 947static void 948fd_screen_get_driver_uuid(struct pipe_screen *pscreen, char *uuid) 949{ 950 fd_get_driver_uuid(uuid); 951} 952 953struct pipe_screen * 954fd_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 1155fail: 1156 fd_screen_destroy(pscreen); 1157 return NULL; 1158} 1159