17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 2008 VMware, Inc. 37ec681f3Smrg * Copyright (C) 2014 Broadcom 47ec681f3Smrg * Copyright (C) 2018 Alyssa Rosenzweig 57ec681f3Smrg * Copyright (C) 2019 Collabora, Ltd. 67ec681f3Smrg * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 79f464c52Smaya * 89f464c52Smaya * Permission is hereby granted, free of charge, to any person obtaining a 97ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 107ec681f3Smrg * to deal in the Software without restriction, including without limitation 117ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 127ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 137ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 149f464c52Smaya * 157ec681f3Smrg * The above copyright notice and this permission notice (including the next 167ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 177ec681f3Smrg * Software. 189f464c52Smaya * 197ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 207ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 217ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 227ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 237ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 247ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 257ec681f3Smrg * SOFTWARE. 269f464c52Smaya * 277ec681f3Smrg */ 289f464c52Smaya 299f464c52Smaya#include "util/u_debug.h" 309f464c52Smaya#include "util/u_memory.h" 317ec681f3Smrg#include "util/format/u_format.h" 327ec681f3Smrg#include "util/format/u_format_s3tc.h" 339f464c52Smaya#include "util/u_video.h" 349f464c52Smaya#include "util/u_screen.h" 359f464c52Smaya#include "util/os_time.h" 367ec681f3Smrg#include "util/u_process.h" 379f464c52Smaya#include "pipe/p_defines.h" 389f464c52Smaya#include "pipe/p_screen.h" 399f464c52Smaya#include "draw/draw_context.h" 409f464c52Smaya 419f464c52Smaya#include <fcntl.h> 429f464c52Smaya 439f464c52Smaya#include "drm-uapi/drm_fourcc.h" 447ec681f3Smrg#include "drm-uapi/panfrost_drm.h" 459f464c52Smaya 467ec681f3Smrg#include "pan_bo.h" 477ec681f3Smrg#include "pan_shader.h" 489f464c52Smaya#include "pan_screen.h" 499f464c52Smaya#include "pan_resource.h" 509f464c52Smaya#include "pan_public.h" 519f464c52Smaya#include "pan_util.h" 527ec681f3Smrg#include "decode.h" 539f464c52Smaya 549f464c52Smaya#include "pan_context.h" 557ec681f3Smrg#include "panfrost-quirks.h" 567ec681f3Smrg 577ec681f3Smrgstatic const struct debug_named_value panfrost_debug_options[] = { 587ec681f3Smrg {"perf", PAN_DBG_PERF, "Enable performance warnings"}, 597ec681f3Smrg {"trace", PAN_DBG_TRACE, "Trace the command stream"}, 607ec681f3Smrg {"deqp", PAN_DBG_DEQP, "Hacks for dEQP"}, 617ec681f3Smrg {"dirty", PAN_DBG_DIRTY, "Always re-emit all state"}, 627ec681f3Smrg {"sync", PAN_DBG_SYNC, "Wait for each job's completion and abort on GPU faults"}, 637ec681f3Smrg {"precompile", PAN_DBG_PRECOMPILE, "Precompile shaders for shader-db"}, 647ec681f3Smrg {"nofp16", PAN_DBG_NOFP16, "Disable 16-bit support"}, 657ec681f3Smrg {"gl3", PAN_DBG_GL3, "Enable experimental GL 3.x implementation, up to 3.3"}, 667ec681f3Smrg {"noafbc", PAN_DBG_NO_AFBC, "Disable AFBC support"}, 677ec681f3Smrg {"nocrc", PAN_DBG_NO_CRC, "Disable transaction elimination"}, 687ec681f3Smrg {"msaa16", PAN_DBG_MSAA16, "Enable MSAA 8x and 16x support"}, 697ec681f3Smrg {"indirect", PAN_DBG_INDIRECT, "Use experimental compute kernel for indirect draws"}, 707ec681f3Smrg {"linear", PAN_DBG_LINEAR, "Force linear textures"}, 717ec681f3Smrg {"nocache", PAN_DBG_NO_CACHE, "Disable BO cache"}, 727ec681f3Smrg DEBUG_NAMED_VALUE_END 739f464c52Smaya}; 749f464c52Smaya 759f464c52Smayastatic const char * 769f464c52Smayapanfrost_get_name(struct pipe_screen *screen) 779f464c52Smaya{ 787ec681f3Smrg return panfrost_model_name(pan_device(screen)->gpu_id); 799f464c52Smaya} 809f464c52Smaya 819f464c52Smayastatic const char * 829f464c52Smayapanfrost_get_vendor(struct pipe_screen *screen) 839f464c52Smaya{ 847ec681f3Smrg return "Panfrost"; 859f464c52Smaya} 869f464c52Smaya 879f464c52Smayastatic const char * 889f464c52Smayapanfrost_get_device_vendor(struct pipe_screen *screen) 899f464c52Smaya{ 909f464c52Smaya return "Arm"; 919f464c52Smaya} 929f464c52Smaya 939f464c52Smayastatic int 949f464c52Smayapanfrost_get_param(struct pipe_screen *screen, enum pipe_cap param) 959f464c52Smaya{ 967ec681f3Smrg struct panfrost_device *dev = pan_device(screen); 977ec681f3Smrg 987ec681f3Smrg /* Our GL 3.x implementation is WIP */ 997ec681f3Smrg bool is_gl3 = dev->debug & (PAN_DBG_GL3 | PAN_DBG_DEQP); 1007ec681f3Smrg 1017ec681f3Smrg /* Don't expose MRT related CAPs on GPUs that don't implement them */ 1027ec681f3Smrg bool has_mrt = !(dev->quirks & MIDGARD_SFBD); 1037ec681f3Smrg 1047ec681f3Smrg /* Only kernel drivers >= 1.1 can allocate HEAP BOs */ 1057ec681f3Smrg bool has_heap = dev->kernel_version->version_major > 1 || 1067ec681f3Smrg dev->kernel_version->version_minor >= 1; 1077ec681f3Smrg 1087ec681f3Smrg /* Bifrost is WIP */ 1099f464c52Smaya switch (param) { 1109f464c52Smaya case PIPE_CAP_NPOT_TEXTURES: 1119f464c52Smaya case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 1127ec681f3Smrg case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 1137ec681f3Smrg case PIPE_CAP_VERTEX_SHADER_SATURATE: 1147ec681f3Smrg case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 1159f464c52Smaya case PIPE_CAP_POINT_SPRITE: 1167ec681f3Smrg case PIPE_CAP_DEPTH_CLIP_DISABLE: 1177ec681f3Smrg case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE: 1187ec681f3Smrg case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 1197ec681f3Smrg case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 1207ec681f3Smrg case PIPE_CAP_FRONTEND_NOOP: 1217ec681f3Smrg case PIPE_CAP_SAMPLE_SHADING: 1227ec681f3Smrg case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 1237ec681f3Smrg case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 1249f464c52Smaya return 1; 1259f464c52Smaya 1269f464c52Smaya case PIPE_CAP_MAX_RENDER_TARGETS: 1277ec681f3Smrg case PIPE_CAP_FBFETCH: 1287ec681f3Smrg case PIPE_CAP_FBFETCH_COHERENT: 1297ec681f3Smrg return has_mrt ? 8 : 1; 1307ec681f3Smrg 1319f464c52Smaya case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 1329f464c52Smaya return 1; 1339f464c52Smaya 1349f464c52Smaya case PIPE_CAP_OCCLUSION_QUERY: 1357ec681f3Smrg case PIPE_CAP_PRIMITIVE_RESTART: 1367ec681f3Smrg case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: 1377ec681f3Smrg return true; 1387ec681f3Smrg 1397ec681f3Smrg case PIPE_CAP_ANISOTROPIC_FILTER: 1407ec681f3Smrg return !!(dev->quirks & HAS_ANISOTROPIC); 1417ec681f3Smrg 1427ec681f3Smrg /* Compile side is done for Bifrost, Midgard TODO. Needs some kernel 1437ec681f3Smrg * work to turn on, since CYCLE_COUNT_START needs to be issued. In 1447ec681f3Smrg * kbase, userspace requests this via BASE_JD_REQ_PERMON. There is not 1457ec681f3Smrg * yet way to request this with mainline TODO */ 1467ec681f3Smrg case PIPE_CAP_TGSI_CLOCK: 1477ec681f3Smrg return 0; 1489f464c52Smaya 1499f464c52Smaya case PIPE_CAP_TGSI_INSTANCEID: 1507ec681f3Smrg case PIPE_CAP_TEXTURE_MULTISAMPLE: 1517ec681f3Smrg case PIPE_CAP_SURFACE_SAMPLE_COUNT: 1527ec681f3Smrg return true; 1539f464c52Smaya 1547ec681f3Smrg case PIPE_CAP_SAMPLER_VIEW_TARGET: 1557ec681f3Smrg case PIPE_CAP_TEXTURE_SWIZZLE: 1567ec681f3Smrg case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 1577ec681f3Smrg case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: 1587ec681f3Smrg case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 1599f464c52Smaya case PIPE_CAP_BLEND_EQUATION_SEPARATE: 1609f464c52Smaya case PIPE_CAP_INDEP_BLEND_ENABLE: 1619f464c52Smaya case PIPE_CAP_INDEP_BLEND_FUNC: 1627ec681f3Smrg case PIPE_CAP_GENERATE_MIPMAP: 1637ec681f3Smrg case PIPE_CAP_ACCELERATED: 1647ec681f3Smrg case PIPE_CAP_UMA: 1657ec681f3Smrg case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 1667ec681f3Smrg case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 1677ec681f3Smrg case PIPE_CAP_TGSI_ARRAY_COMPONENTS: 1687ec681f3Smrg case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED: 1697ec681f3Smrg case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 1707ec681f3Smrg case PIPE_CAP_TEXTURE_BUFFER_SAMPLER: 1717ec681f3Smrg case PIPE_CAP_PACKED_UNIFORMS: 1727ec681f3Smrg case PIPE_CAP_IMAGE_LOAD_FORMATTED: 1737ec681f3Smrg case PIPE_CAP_CUBE_MAP_ARRAY: 1747ec681f3Smrg case PIPE_CAP_COMPUTE: 1759f464c52Smaya return 1; 1769f464c52Smaya 1777ec681f3Smrg /* We need this for OES_copy_image, but currently there are some awful 1787ec681f3Smrg * interactions with AFBC that need to be worked out. */ 1797ec681f3Smrg case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 1807ec681f3Smrg return 0; 1819f464c52Smaya 1827ec681f3Smrg case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 1837ec681f3Smrg return PIPE_MAX_SO_BUFFERS; 1849f464c52Smaya 1859f464c52Smaya case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 1869f464c52Smaya case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 1877ec681f3Smrg return PIPE_MAX_SO_OUTPUTS; 1889f464c52Smaya 1897ec681f3Smrg case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 1907ec681f3Smrg case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 1919f464c52Smaya return 1; 1929f464c52Smaya 1939f464c52Smaya case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 1947ec681f3Smrg return 256; 1959f464c52Smaya 1969f464c52Smaya case PIPE_CAP_GLSL_FEATURE_LEVEL: 1977ec681f3Smrg case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 1987ec681f3Smrg return is_gl3 ? 330 : 140; 1997ec681f3Smrg case PIPE_CAP_ESSL_FEATURE_LEVEL: 2007ec681f3Smrg return pan_is_bifrost(dev) ? 320 : 310; 2019f464c52Smaya 2029f464c52Smaya case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 2039f464c52Smaya return 16; 2049f464c52Smaya 2057ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE: 2067ec681f3Smrg return 65536; 2077ec681f3Smrg 2087ec681f3Smrg /* Must be at least 64 for correct behaviour */ 2097ec681f3Smrg case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 2107ec681f3Smrg return 64; 2119f464c52Smaya 2129f464c52Smaya case PIPE_CAP_QUERY_TIMESTAMP: 2137ec681f3Smrg return is_gl3; 2149f464c52Smaya 2157ec681f3Smrg /* TODO: Where does this req come from in practice? */ 2167ec681f3Smrg case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 2179f464c52Smaya return 1; 2189f464c52Smaya 2197ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 2207ec681f3Smrg return 1 << (MAX_MIP_LEVELS - 1); 2219f464c52Smaya 2227ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 2237ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 2247ec681f3Smrg return MAX_MIP_LEVELS; 2257ec681f3Smrg 2267ec681f3Smrg case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 2277ec681f3Smrg case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 2287ec681f3Smrg /* Hardware is upper left. Pixel center at (0.5, 0.5) */ 2299f464c52Smaya return 0; 2309f464c52Smaya 2317ec681f3Smrg case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 2327ec681f3Smrg case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 2337ec681f3Smrg case PIPE_CAP_TGSI_TEXCOORD: 2347ec681f3Smrg return 1; 2357ec681f3Smrg 2367ec681f3Smrg /* We would prefer varyings on Midgard, but proper sysvals on Bifrost */ 2377ec681f3Smrg case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL: 2387ec681f3Smrg case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL: 2397ec681f3Smrg case PIPE_CAP_TGSI_FS_POINT_IS_SYSVAL: 2407ec681f3Smrg return pan_is_bifrost(dev); 2417ec681f3Smrg 2427ec681f3Smrg case PIPE_CAP_SEAMLESS_CUBE_MAP: 2437ec681f3Smrg case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 2447ec681f3Smrg return true; 2457ec681f3Smrg 2467ec681f3Smrg case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET: 2477ec681f3Smrg return 0xffff; 2487ec681f3Smrg 2499f464c52Smaya case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: 2509f464c52Smaya return 0; 2519f464c52Smaya 2529f464c52Smaya case PIPE_CAP_ENDIANNESS: 2539f464c52Smaya return PIPE_ENDIAN_NATIVE; 2549f464c52Smaya 2559f464c52Smaya case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 2569f464c52Smaya return 4; 2579f464c52Smaya 2589f464c52Smaya case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 2597ec681f3Smrg return -8; 2609f464c52Smaya 2619f464c52Smaya case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 2627ec681f3Smrg return 7; 2639f464c52Smaya 2649f464c52Smaya case PIPE_CAP_VIDEO_MEMORY: { 2659f464c52Smaya uint64_t system_memory; 2669f464c52Smaya 2679f464c52Smaya if (!os_get_total_physical_memory(&system_memory)) 2689f464c52Smaya return 0; 2699f464c52Smaya 2709f464c52Smaya return (int)(system_memory >> 20); 2719f464c52Smaya } 2729f464c52Smaya 2737ec681f3Smrg case PIPE_CAP_SHADER_STENCIL_EXPORT: 2747ec681f3Smrg case PIPE_CAP_CONDITIONAL_RENDER: 2759f464c52Smaya case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 2767ec681f3Smrg return true; 2779f464c52Smaya 2789f464c52Smaya case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 2799f464c52Smaya return 4; 2809f464c52Smaya 2819f464c52Smaya case PIPE_CAP_MAX_VARYINGS: 2827ec681f3Smrg /* Return the GLSL maximum. The internal maximum 2837ec681f3Smrg * PAN_MAX_VARYINGS accommodates internal varyings. */ 2847ec681f3Smrg return MAX_VARYING; 2857ec681f3Smrg 2867ec681f3Smrg /* Removed in v6 (Bifrost) */ 2877ec681f3Smrg case PIPE_CAP_ALPHA_TEST: 2887ec681f3Smrg return dev->arch <= 5; 2897ec681f3Smrg 2907ec681f3Smrg case PIPE_CAP_FLATSHADE: 2917ec681f3Smrg case PIPE_CAP_TWO_SIDED_COLOR: 2927ec681f3Smrg case PIPE_CAP_CLIP_PLANES: 2937ec681f3Smrg return 0; 2947ec681f3Smrg 2957ec681f3Smrg case PIPE_CAP_PACKED_STREAM_OUTPUT: 2967ec681f3Smrg return 0; 2977ec681f3Smrg 2987ec681f3Smrg case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED: 2997ec681f3Smrg case PIPE_CAP_PSIZ_CLAMPED: 3007ec681f3Smrg return 1; 3017ec681f3Smrg 3027ec681f3Smrg case PIPE_CAP_NIR_IMAGES_AS_DEREF: 3037ec681f3Smrg return 0; 3047ec681f3Smrg 3057ec681f3Smrg case PIPE_CAP_DRAW_INDIRECT: 3067ec681f3Smrg return has_heap; 3077ec681f3Smrg 3087ec681f3Smrg case PIPE_CAP_START_INSTANCE: 3097ec681f3Smrg case PIPE_CAP_DRAW_PARAMETERS: 3107ec681f3Smrg return pan_is_bifrost(dev); 3117ec681f3Smrg 3127ec681f3Smrg case PIPE_CAP_SUPPORTED_PRIM_MODES: 3137ec681f3Smrg case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: { 3147ec681f3Smrg /* Mali supports GLES and QUADS. Midgard supports more */ 3157ec681f3Smrg uint32_t modes = BITFIELD_MASK(PIPE_PRIM_QUADS + 1); 3167ec681f3Smrg 3177ec681f3Smrg if (dev->arch <= 5) { 3187ec681f3Smrg modes |= BITFIELD_BIT(PIPE_PRIM_QUAD_STRIP); 3197ec681f3Smrg modes |= BITFIELD_BIT(PIPE_PRIM_POLYGON); 3207ec681f3Smrg } 3217ec681f3Smrg 3227ec681f3Smrg return modes; 3237ec681f3Smrg } 3249f464c52Smaya 3259f464c52Smaya default: 3269f464c52Smaya return u_pipe_screen_get_param_defaults(screen, param); 3279f464c52Smaya } 3289f464c52Smaya} 3299f464c52Smaya 3309f464c52Smayastatic int 3319f464c52Smayapanfrost_get_shader_param(struct pipe_screen *screen, 3329f464c52Smaya enum pipe_shader_type shader, 3339f464c52Smaya enum pipe_shader_cap param) 3349f464c52Smaya{ 3357ec681f3Smrg struct panfrost_device *dev = pan_device(screen); 3367ec681f3Smrg bool is_nofp16 = dev->debug & PAN_DBG_NOFP16; 3377ec681f3Smrg bool is_deqp = dev->debug & PAN_DBG_DEQP; 3387ec681f3Smrg 3397ec681f3Smrg switch (shader) { 3407ec681f3Smrg case PIPE_SHADER_VERTEX: 3417ec681f3Smrg case PIPE_SHADER_FRAGMENT: 3427ec681f3Smrg case PIPE_SHADER_COMPUTE: 3437ec681f3Smrg break; 3447ec681f3Smrg default: 3459f464c52Smaya return 0; 3469f464c52Smaya } 3479f464c52Smaya 3489f464c52Smaya switch (param) { 3499f464c52Smaya case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 3509f464c52Smaya case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 3519f464c52Smaya case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 3529f464c52Smaya case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 3537ec681f3Smrg return 16384; /* arbitrary */ 3549f464c52Smaya 3559f464c52Smaya case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 3567ec681f3Smrg return 1024; /* arbitrary */ 3579f464c52Smaya 3589f464c52Smaya case PIPE_SHADER_CAP_MAX_INPUTS: 3597ec681f3Smrg /* Used as ABI on Midgard */ 3609f464c52Smaya return 16; 3619f464c52Smaya 3629f464c52Smaya case PIPE_SHADER_CAP_MAX_OUTPUTS: 3637ec681f3Smrg return shader == PIPE_SHADER_FRAGMENT ? 8 : PIPE_MAX_ATTRIBS; 3649f464c52Smaya 3659f464c52Smaya case PIPE_SHADER_CAP_MAX_TEMPS: 3667ec681f3Smrg return 256; /* arbitrary */ 3679f464c52Smaya 3689f464c52Smaya case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: 3699f464c52Smaya return 16 * 1024 * sizeof(float); 3709f464c52Smaya 3719f464c52Smaya case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 3727ec681f3Smrg STATIC_ASSERT(PAN_MAX_CONST_BUFFERS < 0x100); 3737ec681f3Smrg return PAN_MAX_CONST_BUFFERS; 3749f464c52Smaya 3759f464c52Smaya case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 3769f464c52Smaya return 0; 3779f464c52Smaya 3789f464c52Smaya case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 3799f464c52Smaya return 1; 3809f464c52Smaya case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 3819f464c52Smaya return 0; 3829f464c52Smaya 3839f464c52Smaya case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 3847ec681f3Smrg return pan_is_bifrost(dev); 3859f464c52Smaya 3869f464c52Smaya case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 3879f464c52Smaya return 1; 3889f464c52Smaya 3899f464c52Smaya case PIPE_SHADER_CAP_SUBROUTINES: 3909f464c52Smaya return 0; 3919f464c52Smaya 3929f464c52Smaya case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 3939f464c52Smaya return 0; 3949f464c52Smaya 3959f464c52Smaya case PIPE_SHADER_CAP_INTEGERS: 3969f464c52Smaya return 1; 3979f464c52Smaya 3987ec681f3Smrg /* The Bifrost compiler supports full 16-bit. Midgard could but int16 3997ec681f3Smrg * support is untested, so restrict INT16 to Bifrost. Midgard 4007ec681f3Smrg * architecturally cannot support fp16 derivatives. */ 4017ec681f3Smrg 4029f464c52Smaya case PIPE_SHADER_CAP_FP16: 4037ec681f3Smrg case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: 4047ec681f3Smrg return !is_nofp16; 4057ec681f3Smrg case PIPE_SHADER_CAP_FP16_DERIVATIVES: 4067ec681f3Smrg case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: 4077ec681f3Smrg return pan_is_bifrost(dev) && !is_nofp16; 4087ec681f3Smrg case PIPE_SHADER_CAP_INT16: 4097ec681f3Smrg /* XXX: Advertise this CAP when a proper fix to lower_precision 4107ec681f3Smrg * lands. GLSL IR validation failure in glmark2 -bterrain */ 4117ec681f3Smrg return pan_is_bifrost(dev) && !is_nofp16 && is_deqp; 4127ec681f3Smrg 4137ec681f3Smrg case PIPE_SHADER_CAP_INT64_ATOMICS: 4149f464c52Smaya case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: 4159f464c52Smaya case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: 4169f464c52Smaya case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED: 4179f464c52Smaya case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: 4189f464c52Smaya case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 4199f464c52Smaya return 0; 4209f464c52Smaya 4219f464c52Smaya case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 4227ec681f3Smrg STATIC_ASSERT(PIPE_MAX_SAMPLERS < 0x10000); 4237ec681f3Smrg return PIPE_MAX_SAMPLERS; 4247ec681f3Smrg 4259f464c52Smaya case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 4267ec681f3Smrg STATIC_ASSERT(PIPE_MAX_SHADER_SAMPLER_VIEWS < 0x10000); 4277ec681f3Smrg return PIPE_MAX_SHADER_SAMPLER_VIEWS; 4289f464c52Smaya 4299f464c52Smaya case PIPE_SHADER_CAP_PREFERRED_IR: 4309f464c52Smaya return PIPE_SHADER_IR_NIR; 4319f464c52Smaya 4329f464c52Smaya case PIPE_SHADER_CAP_SUPPORTED_IRS: 4337ec681f3Smrg return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_NIR_SERIALIZED); 4349f464c52Smaya 4359f464c52Smaya case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 4367ec681f3Smrg return 16; 4377ec681f3Smrg 4389f464c52Smaya case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 4397ec681f3Smrg return PIPE_MAX_SHADER_IMAGES; 4407ec681f3Smrg 4417ec681f3Smrg case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: 4429f464c52Smaya case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 4439f464c52Smaya case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 4447ec681f3Smrg case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS: 4457ec681f3Smrg case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD: 4469f464c52Smaya return 0; 4479f464c52Smaya 4489f464c52Smaya default: 4499f464c52Smaya return 0; 4509f464c52Smaya } 4519f464c52Smaya 4529f464c52Smaya return 0; 4539f464c52Smaya} 4549f464c52Smaya 4559f464c52Smayastatic float 4569f464c52Smayapanfrost_get_paramf(struct pipe_screen *screen, enum pipe_capf param) 4579f464c52Smaya{ 4589f464c52Smaya switch (param) { 4599f464c52Smaya case PIPE_CAPF_MAX_LINE_WIDTH: 4609f464c52Smaya 4617ec681f3Smrg FALLTHROUGH; 4629f464c52Smaya case PIPE_CAPF_MAX_LINE_WIDTH_AA: 4639f464c52Smaya return 255.0; /* arbitrary */ 4649f464c52Smaya 4659f464c52Smaya case PIPE_CAPF_MAX_POINT_WIDTH: 4669f464c52Smaya 4677ec681f3Smrg FALLTHROUGH; 4689f464c52Smaya case PIPE_CAPF_MAX_POINT_WIDTH_AA: 4697ec681f3Smrg return 1024.0; 4709f464c52Smaya 4719f464c52Smaya case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 4729f464c52Smaya return 16.0; 4739f464c52Smaya 4749f464c52Smaya case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 4759f464c52Smaya return 16.0; /* arbitrary */ 4769f464c52Smaya 4777ec681f3Smrg case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 4787ec681f3Smrg case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 4797ec681f3Smrg case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 4807ec681f3Smrg return 0.0f; 4817ec681f3Smrg 4829f464c52Smaya default: 4839f464c52Smaya debug_printf("Unexpected PIPE_CAPF %d query\n", param); 4849f464c52Smaya return 0.0; 4859f464c52Smaya } 4869f464c52Smaya} 4879f464c52Smaya 4889f464c52Smaya/** 4899f464c52Smaya * Query format support for creating a texture, drawing surface, etc. 4909f464c52Smaya * \param format the format to test 4919f464c52Smaya * \param type one of PIPE_TEXTURE, PIPE_SURFACE 4929f464c52Smaya */ 4937ec681f3Smrgstatic bool 4949f464c52Smayapanfrost_is_format_supported( struct pipe_screen *screen, 4959f464c52Smaya enum pipe_format format, 4969f464c52Smaya enum pipe_texture_target target, 4979f464c52Smaya unsigned sample_count, 4989f464c52Smaya unsigned storage_sample_count, 4999f464c52Smaya unsigned bind) 5009f464c52Smaya{ 5017ec681f3Smrg struct panfrost_device *dev = pan_device(screen); 5029f464c52Smaya const struct util_format_description *format_desc; 5039f464c52Smaya 5049f464c52Smaya assert(target == PIPE_BUFFER || 5059f464c52Smaya target == PIPE_TEXTURE_1D || 5069f464c52Smaya target == PIPE_TEXTURE_1D_ARRAY || 5079f464c52Smaya target == PIPE_TEXTURE_2D || 5089f464c52Smaya target == PIPE_TEXTURE_2D_ARRAY || 5099f464c52Smaya target == PIPE_TEXTURE_RECT || 5109f464c52Smaya target == PIPE_TEXTURE_3D || 5119f464c52Smaya target == PIPE_TEXTURE_CUBE || 5129f464c52Smaya target == PIPE_TEXTURE_CUBE_ARRAY); 5139f464c52Smaya 5149f464c52Smaya format_desc = util_format_description(format); 5159f464c52Smaya 5169f464c52Smaya if (!format_desc) 5177ec681f3Smrg return false; 5187ec681f3Smrg 5197ec681f3Smrg /* MSAA 2x gets rounded up to 4x. MSAA 8x/16x only supported on v5+. 5207ec681f3Smrg * TODO: debug MSAA 8x/16x */ 5217ec681f3Smrg 5227ec681f3Smrg switch (sample_count) { 5237ec681f3Smrg case 0: 5247ec681f3Smrg case 1: 5257ec681f3Smrg case 4: 5267ec681f3Smrg break; 5277ec681f3Smrg case 8: 5287ec681f3Smrg case 16: 5297ec681f3Smrg if (dev->debug & PAN_DBG_MSAA16) 5307ec681f3Smrg break; 5317ec681f3Smrg else 5327ec681f3Smrg return false; 5337ec681f3Smrg default: 5347ec681f3Smrg return false; 5357ec681f3Smrg } 5369f464c52Smaya 5377ec681f3Smrg if (MAX2(sample_count, 1) != MAX2(storage_sample_count, 1)) 5387ec681f3Smrg return false; 5399f464c52Smaya 5407ec681f3Smrg /* Z16 causes dEQP failures on t720 */ 5417ec681f3Smrg if (format == PIPE_FORMAT_Z16_UNORM && dev->quirks & MIDGARD_SFBD) 5427ec681f3Smrg return false; 5439f464c52Smaya 5447ec681f3Smrg /* Check we support the format with the given bind */ 5459f464c52Smaya 5467ec681f3Smrg unsigned relevant_bind = bind & 5477ec681f3Smrg ( PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET 5487ec681f3Smrg | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_SAMPLER_VIEW); 5499f464c52Smaya 5507ec681f3Smrg struct panfrost_format fmt = dev->formats[format]; 5519f464c52Smaya 5527ec681f3Smrg /* Also check that compressed texture formats are supported on this 5537ec681f3Smrg * particular chip. They may not be depending on system integration 5547ec681f3Smrg * differences. RGTC can be emulated so is always supported. */ 5559f464c52Smaya 5567ec681f3Smrg bool is_rgtc = format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC; 5577ec681f3Smrg bool supported = panfrost_supports_compressed_format(dev, 5587ec681f3Smrg MALI_EXTRACT_INDEX(fmt.hw)); 5599f464c52Smaya 5607ec681f3Smrg if (!is_rgtc && !supported) 5617ec681f3Smrg return false; 5629f464c52Smaya 5637ec681f3Smrg return MALI_EXTRACT_INDEX(fmt.hw) && ((relevant_bind & ~fmt.bind) == 0); 5647ec681f3Smrg} 5657ec681f3Smrg 5667ec681f3Smrg/* We always support linear and tiled operations, both external and internal. 5677ec681f3Smrg * We support AFBC for a subset of formats, and colourspace transform for a 5687ec681f3Smrg * subset of those. */ 5697ec681f3Smrg 5707ec681f3Smrgstatic void 5717ec681f3Smrgpanfrost_walk_dmabuf_modifiers(struct pipe_screen *screen, 5727ec681f3Smrg enum pipe_format format, int max, uint64_t *modifiers, unsigned 5737ec681f3Smrg int *external_only, int *out_count, uint64_t test_modifier) 5747ec681f3Smrg{ 5757ec681f3Smrg /* Query AFBC status */ 5767ec681f3Smrg struct panfrost_device *dev = pan_device(screen); 5777ec681f3Smrg bool afbc = dev->has_afbc && panfrost_format_supports_afbc(dev, format); 5787ec681f3Smrg bool ytr = panfrost_afbc_can_ytr(format); 5799f464c52Smaya 5807ec681f3Smrg unsigned count = 0; 5817ec681f3Smrg 5827ec681f3Smrg for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) { 5837ec681f3Smrg if (drm_is_afbc(pan_best_modifiers[i]) && !afbc) 5847ec681f3Smrg continue; 5857ec681f3Smrg 5867ec681f3Smrg if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr) 5877ec681f3Smrg continue; 5887ec681f3Smrg 5897ec681f3Smrg if (test_modifier != DRM_FORMAT_MOD_INVALID && 5907ec681f3Smrg test_modifier != pan_best_modifiers[i]) 5917ec681f3Smrg continue; 5927ec681f3Smrg 5937ec681f3Smrg count++; 5947ec681f3Smrg 5957ec681f3Smrg if (max > (int) count) { 5967ec681f3Smrg modifiers[count] = pan_best_modifiers[i]; 5977ec681f3Smrg 5987ec681f3Smrg if (external_only) 5997ec681f3Smrg external_only[count] = false; 6009f464c52Smaya } 6019f464c52Smaya } 6029f464c52Smaya 6037ec681f3Smrg *out_count = count; 6049f464c52Smaya} 6059f464c52Smaya 6069f464c52Smayastatic void 6077ec681f3Smrgpanfrost_query_dmabuf_modifiers(struct pipe_screen *screen, 6087ec681f3Smrg enum pipe_format format, int max, uint64_t *modifiers, unsigned 6097ec681f3Smrg int *external_only, int *out_count) 6109f464c52Smaya{ 6117ec681f3Smrg panfrost_walk_dmabuf_modifiers(screen, format, max, modifiers, 6127ec681f3Smrg external_only, out_count, DRM_FORMAT_MOD_INVALID); 6137ec681f3Smrg} 6147ec681f3Smrg 6157ec681f3Smrgstatic bool 6167ec681f3Smrgpanfrost_is_dmabuf_modifier_supported(struct pipe_screen *screen, 6177ec681f3Smrg uint64_t modifier, enum pipe_format format, 6187ec681f3Smrg bool *external_only) 6197ec681f3Smrg{ 6207ec681f3Smrg uint64_t unused; 6217ec681f3Smrg unsigned int uint_extern_only = 0; 6227ec681f3Smrg int count; 6237ec681f3Smrg 6247ec681f3Smrg panfrost_walk_dmabuf_modifiers(screen, format, 1, &unused, 6257ec681f3Smrg &uint_extern_only, &count, modifier); 6267ec681f3Smrg 6277ec681f3Smrg if (external_only) 6287ec681f3Smrg *external_only = uint_extern_only ? true : false; 6297ec681f3Smrg 6307ec681f3Smrg return count > 0; 6317ec681f3Smrg} 6327ec681f3Smrg 6337ec681f3Smrgstatic int 6347ec681f3Smrgpanfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, 6357ec681f3Smrg enum pipe_compute_cap param, void *ret) 6367ec681f3Smrg{ 6377ec681f3Smrg struct panfrost_device *dev = pan_device(pscreen); 6387ec681f3Smrg const char * const ir = "panfrost"; 6397ec681f3Smrg 6407ec681f3Smrg#define RET(x) do { \ 6417ec681f3Smrg if (ret) \ 6427ec681f3Smrg memcpy(ret, x, sizeof(x)); \ 6437ec681f3Smrg return sizeof(x); \ 6447ec681f3Smrg} while (0) 6457ec681f3Smrg 6467ec681f3Smrg switch (param) { 6477ec681f3Smrg case PIPE_COMPUTE_CAP_ADDRESS_BITS: 6487ec681f3Smrg RET((uint32_t []){ 64 }); 6497ec681f3Smrg 6507ec681f3Smrg case PIPE_COMPUTE_CAP_IR_TARGET: 6517ec681f3Smrg if (ret) 6527ec681f3Smrg sprintf(ret, "%s", ir); 6537ec681f3Smrg return strlen(ir) * sizeof(char); 6547ec681f3Smrg 6557ec681f3Smrg case PIPE_COMPUTE_CAP_GRID_DIMENSION: 6567ec681f3Smrg RET((uint64_t []) { 3 }); 6577ec681f3Smrg 6587ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: 6597ec681f3Smrg RET(((uint64_t []) { 65535, 65535, 65535 })); 6607ec681f3Smrg 6617ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: 6627ec681f3Smrg /* Unpredictable behaviour at larger sizes. Mali-G52 advertises 6637ec681f3Smrg * 384x384x384. The smaller size is advertised by Mali-T628, 6647ec681f3Smrg * use min until we have a need to key by arch */ 6657ec681f3Smrg RET(((uint64_t []) { 256, 256, 256 })); 6667ec681f3Smrg 6677ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 6687ec681f3Smrg RET((uint64_t []) { 256 }); 6697ec681f3Smrg 6707ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: 6717ec681f3Smrg RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ }); 6727ec681f3Smrg 6737ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 6747ec681f3Smrg RET((uint64_t []) { 32768 }); 6757ec681f3Smrg 6767ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: 6777ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: 6787ec681f3Smrg RET((uint64_t []) { 4096 }); 6797ec681f3Smrg 6807ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: 6817ec681f3Smrg RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ }); 6827ec681f3Smrg 6837ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY: 6847ec681f3Smrg RET((uint32_t []) { 800 /* MHz -- TODO */ }); 6857ec681f3Smrg 6867ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: 6877ec681f3Smrg RET((uint32_t []) { 9999 }); // TODO 6887ec681f3Smrg 6897ec681f3Smrg case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: 6907ec681f3Smrg RET((uint32_t []) { 1 }); 6917ec681f3Smrg 6927ec681f3Smrg case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: 6937ec681f3Smrg RET((uint32_t []) { dev->arch >= 7 ? 8 : 4 }); 6947ec681f3Smrg 6957ec681f3Smrg case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 6967ec681f3Smrg RET((uint64_t []) { 1024 }); // TODO 6977ec681f3Smrg } 6987ec681f3Smrg 6997ec681f3Smrg return 0; 7009f464c52Smaya} 7019f464c52Smaya 7029f464c52Smayastatic void 7037ec681f3Smrgpanfrost_destroy_screen(struct pipe_screen *pscreen) 7049f464c52Smaya{ 7057ec681f3Smrg struct panfrost_device *dev = pan_device(pscreen); 7067ec681f3Smrg struct panfrost_screen *screen = pan_screen(pscreen); 7077ec681f3Smrg 7087ec681f3Smrg panfrost_resource_screen_destroy(pscreen); 7097ec681f3Smrg panfrost_pool_cleanup(&screen->indirect_draw.bin_pool); 7107ec681f3Smrg panfrost_pool_cleanup(&screen->blitter.bin_pool); 7117ec681f3Smrg panfrost_pool_cleanup(&screen->blitter.desc_pool); 7127ec681f3Smrg pan_blend_shaders_cleanup(dev); 7137ec681f3Smrg 7147ec681f3Smrg if (screen->vtbl.screen_destroy) 7157ec681f3Smrg screen->vtbl.screen_destroy(pscreen); 7167ec681f3Smrg 7177ec681f3Smrg if (dev->ro) 7187ec681f3Smrg dev->ro->destroy(dev->ro); 7197ec681f3Smrg panfrost_close_device(dev); 7207ec681f3Smrg ralloc_free(pscreen); 7219f464c52Smaya} 7229f464c52Smaya 7239f464c52Smayastatic uint64_t 7249f464c52Smayapanfrost_get_timestamp(struct pipe_screen *_screen) 7259f464c52Smaya{ 7269f464c52Smaya return os_time_get_nano(); 7279f464c52Smaya} 7289f464c52Smaya 7299f464c52Smayastatic void 7309f464c52Smayapanfrost_fence_reference(struct pipe_screen *pscreen, 7319f464c52Smaya struct pipe_fence_handle **ptr, 7329f464c52Smaya struct pipe_fence_handle *fence) 7339f464c52Smaya{ 7347ec681f3Smrg struct panfrost_device *dev = pan_device(pscreen); 7357ec681f3Smrg struct pipe_fence_handle *old = *ptr; 7367ec681f3Smrg 7377ec681f3Smrg if (pipe_reference(&old->reference, &fence->reference)) { 7387ec681f3Smrg drmSyncobjDestroy(dev->fd, old->syncobj); 7397ec681f3Smrg free(old); 7407ec681f3Smrg } 7417ec681f3Smrg 7427ec681f3Smrg *ptr = fence; 7439f464c52Smaya} 7449f464c52Smaya 7457ec681f3Smrgstatic bool 7469f464c52Smayapanfrost_fence_finish(struct pipe_screen *pscreen, 7479f464c52Smaya struct pipe_context *ctx, 7489f464c52Smaya struct pipe_fence_handle *fence, 7499f464c52Smaya uint64_t timeout) 7509f464c52Smaya{ 7517ec681f3Smrg struct panfrost_device *dev = pan_device(pscreen); 7527ec681f3Smrg int ret; 7537ec681f3Smrg 7547ec681f3Smrg if (fence->signaled) 7557ec681f3Smrg return true; 7567ec681f3Smrg 7577ec681f3Smrg uint64_t abs_timeout = os_time_get_absolute_timeout(timeout); 7587ec681f3Smrg if (abs_timeout == OS_TIMEOUT_INFINITE) 7597ec681f3Smrg abs_timeout = INT64_MAX; 7607ec681f3Smrg 7617ec681f3Smrg ret = drmSyncobjWait(dev->fd, &fence->syncobj, 7627ec681f3Smrg 1, 7637ec681f3Smrg abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL, 7647ec681f3Smrg NULL); 7657ec681f3Smrg 7667ec681f3Smrg fence->signaled = (ret >= 0); 7677ec681f3Smrg return fence->signaled; 7687ec681f3Smrg} 7697ec681f3Smrg 7707ec681f3Smrgstruct pipe_fence_handle * 7717ec681f3Smrgpanfrost_fence_create(struct panfrost_context *ctx) 7727ec681f3Smrg{ 7737ec681f3Smrg struct pipe_fence_handle *f = calloc(1, sizeof(*f)); 7747ec681f3Smrg if (!f) 7757ec681f3Smrg return NULL; 7767ec681f3Smrg 7777ec681f3Smrg struct panfrost_device *dev = pan_device(ctx->base.screen); 7787ec681f3Smrg int fd = -1, ret; 7797ec681f3Smrg 7807ec681f3Smrg /* Snapshot the last rendering out fence. We'd rather have another 7817ec681f3Smrg * syncobj instead of a sync file, but this is all we get. 7827ec681f3Smrg * (HandleToFD/FDToHandle just gives you another syncobj ID for the 7837ec681f3Smrg * same syncobj). 7847ec681f3Smrg */ 7857ec681f3Smrg ret = drmSyncobjExportSyncFile(dev->fd, ctx->syncobj, &fd); 7867ec681f3Smrg if (ret || fd == -1) { 7877ec681f3Smrg fprintf(stderr, "export failed\n"); 7887ec681f3Smrg goto err_free_fence; 7897ec681f3Smrg } 7907ec681f3Smrg 7917ec681f3Smrg ret = drmSyncobjCreate(dev->fd, 0, &f->syncobj); 7927ec681f3Smrg if (ret) { 7937ec681f3Smrg fprintf(stderr, "create syncobj failed\n"); 7947ec681f3Smrg goto err_close_fd; 7957ec681f3Smrg } 7967ec681f3Smrg 7977ec681f3Smrg ret = drmSyncobjImportSyncFile(dev->fd, f->syncobj, fd); 7987ec681f3Smrg if (ret) { 7997ec681f3Smrg fprintf(stderr, "create syncobj failed\n"); 8007ec681f3Smrg goto err_destroy_syncobj; 8017ec681f3Smrg } 8027ec681f3Smrg 8037ec681f3Smrg assert(f->syncobj != ctx->syncobj); 8047ec681f3Smrg close(fd); 8057ec681f3Smrg pipe_reference_init(&f->reference, 1); 8067ec681f3Smrg 8077ec681f3Smrg return f; 8087ec681f3Smrg 8097ec681f3Smrgerr_destroy_syncobj: 8107ec681f3Smrg drmSyncobjDestroy(dev->fd, f->syncobj); 8117ec681f3Smrgerr_close_fd: 8127ec681f3Smrg close(fd); 8137ec681f3Smrgerr_free_fence: 8147ec681f3Smrg free(f); 8157ec681f3Smrg return NULL; 8169f464c52Smaya} 8179f464c52Smaya 8189f464c52Smayastatic const void * 8199f464c52Smayapanfrost_screen_get_compiler_options(struct pipe_screen *pscreen, 8209f464c52Smaya enum pipe_shader_ir ir, 8219f464c52Smaya enum pipe_shader_type shader) 8229f464c52Smaya{ 8237ec681f3Smrg return pan_screen(pscreen)->vtbl.get_compiler_options(); 8249f464c52Smaya} 8259f464c52Smaya 8269f464c52Smayastruct pipe_screen * 8279f464c52Smayapanfrost_create_screen(int fd, struct renderonly *ro) 8289f464c52Smaya{ 8297ec681f3Smrg /* Create the screen */ 8307ec681f3Smrg struct panfrost_screen *screen = rzalloc(NULL, struct panfrost_screen); 8319f464c52Smaya 8329f464c52Smaya if (!screen) 8339f464c52Smaya return NULL; 8349f464c52Smaya 8357ec681f3Smrg struct panfrost_device *dev = pan_device(&screen->base); 8369f464c52Smaya 8377ec681f3Smrg /* Debug must be set first for pandecode to work correctly */ 8387ec681f3Smrg dev->debug = debug_get_flags_option("PAN_MESA_DEBUG", panfrost_debug_options, 0); 8397ec681f3Smrg panfrost_open_device(screen, fd, dev); 8409f464c52Smaya 8417ec681f3Smrg if (dev->debug & PAN_DBG_NO_AFBC) 8427ec681f3Smrg dev->has_afbc = false; 8439f464c52Smaya 8447ec681f3Smrg /* Check if we're loading against a supported GPU model. */ 8459f464c52Smaya 8467ec681f3Smrg switch (dev->gpu_id) { 8477ec681f3Smrg case 0x720: /* T720 */ 8487ec681f3Smrg case 0x750: /* T760 */ 8497ec681f3Smrg case 0x820: /* T820 */ 8507ec681f3Smrg case 0x860: /* T860 */ 8517ec681f3Smrg case 0x6221: /* G72 */ 8527ec681f3Smrg case 0x7093: /* G31 */ 8537ec681f3Smrg case 0x7212: /* G52 */ 8547ec681f3Smrg case 0x7402: /* G52r1 */ 8557ec681f3Smrg break; 8567ec681f3Smrg default: 8577ec681f3Smrg /* Fail to load against untested models */ 8587ec681f3Smrg debug_printf("panfrost: Unsupported model %X", dev->gpu_id); 8597ec681f3Smrg panfrost_destroy_screen(&(screen->base)); 8607ec681f3Smrg return NULL; 8619f464c52Smaya } 8629f464c52Smaya 8637ec681f3Smrg dev->ro = ro; 8647ec681f3Smrg 8659f464c52Smaya screen->base.destroy = panfrost_destroy_screen; 8669f464c52Smaya 8679f464c52Smaya screen->base.get_name = panfrost_get_name; 8689f464c52Smaya screen->base.get_vendor = panfrost_get_vendor; 8699f464c52Smaya screen->base.get_device_vendor = panfrost_get_device_vendor; 8709f464c52Smaya screen->base.get_param = panfrost_get_param; 8719f464c52Smaya screen->base.get_shader_param = panfrost_get_shader_param; 8727ec681f3Smrg screen->base.get_compute_param = panfrost_get_compute_param; 8739f464c52Smaya screen->base.get_paramf = panfrost_get_paramf; 8749f464c52Smaya screen->base.get_timestamp = panfrost_get_timestamp; 8759f464c52Smaya screen->base.is_format_supported = panfrost_is_format_supported; 8767ec681f3Smrg screen->base.query_dmabuf_modifiers = panfrost_query_dmabuf_modifiers; 8777ec681f3Smrg screen->base.is_dmabuf_modifier_supported = 8787ec681f3Smrg panfrost_is_dmabuf_modifier_supported; 8799f464c52Smaya screen->base.context_create = panfrost_create_context; 8809f464c52Smaya screen->base.get_compiler_options = panfrost_screen_get_compiler_options; 8819f464c52Smaya screen->base.fence_reference = panfrost_fence_reference; 8829f464c52Smaya screen->base.fence_finish = panfrost_fence_finish; 8837ec681f3Smrg screen->base.set_damage_region = panfrost_resource_set_damage_region; 8847ec681f3Smrg 8857ec681f3Smrg panfrost_resource_screen_init(&screen->base); 8867ec681f3Smrg pan_blend_shaders_init(dev); 8877ec681f3Smrg panfrost_pool_init(&screen->indirect_draw.bin_pool, NULL, dev, 8887ec681f3Smrg PAN_BO_EXECUTE, 65536, "Indirect draw shaders", 8897ec681f3Smrg false, true); 8907ec681f3Smrg panfrost_pool_init(&screen->blitter.bin_pool, NULL, dev, PAN_BO_EXECUTE, 8917ec681f3Smrg 4096, "Blitter shaders", false, true); 8927ec681f3Smrg panfrost_pool_init(&screen->blitter.desc_pool, NULL, dev, 0, 65536, 8937ec681f3Smrg "Blitter RSDs", false, true); 8947ec681f3Smrg if (dev->arch == 4) 8957ec681f3Smrg panfrost_cmdstream_screen_init_v4(screen); 8967ec681f3Smrg else if (dev->arch == 5) 8977ec681f3Smrg panfrost_cmdstream_screen_init_v5(screen); 8987ec681f3Smrg else if (dev->arch == 6) 8997ec681f3Smrg panfrost_cmdstream_screen_init_v6(screen); 9007ec681f3Smrg else if (dev->arch == 7) 9017ec681f3Smrg panfrost_cmdstream_screen_init_v7(screen); 9027ec681f3Smrg else 9037ec681f3Smrg unreachable("Unhandled architecture major"); 9049f464c52Smaya 9059f464c52Smaya return &screen->base; 9069f464c52Smaya} 907