1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2008 VMware, Inc. 3bf215546Sopenharmony_ci * Copyright (C) 2014 Broadcom 4bf215546Sopenharmony_ci * Copyright (C) 2018 Alyssa Rosenzweig 5bf215546Sopenharmony_ci * Copyright (C) 2019 Collabora, Ltd. 6bf215546Sopenharmony_ci * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 16bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 17bf215546Sopenharmony_ci * Software. 18bf215546Sopenharmony_ci * 19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25bf215546Sopenharmony_ci * SOFTWARE. 26bf215546Sopenharmony_ci * 27bf215546Sopenharmony_ci */ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "util/u_debug.h" 30bf215546Sopenharmony_ci#include "util/u_memory.h" 31bf215546Sopenharmony_ci#include "util/format/u_format.h" 32bf215546Sopenharmony_ci#include "util/format/u_format_s3tc.h" 33bf215546Sopenharmony_ci#include "util/u_video.h" 34bf215546Sopenharmony_ci#include "util/u_screen.h" 35bf215546Sopenharmony_ci#include "util/os_time.h" 36bf215546Sopenharmony_ci#include "util/u_process.h" 37bf215546Sopenharmony_ci#include "pipe/p_defines.h" 38bf215546Sopenharmony_ci#include "pipe/p_screen.h" 39bf215546Sopenharmony_ci#include "draw/draw_context.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci#include <fcntl.h> 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 44bf215546Sopenharmony_ci#include "drm-uapi/panfrost_drm.h" 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#include "pan_bo.h" 47bf215546Sopenharmony_ci#include "pan_shader.h" 48bf215546Sopenharmony_ci#include "pan_screen.h" 49bf215546Sopenharmony_ci#include "pan_resource.h" 50bf215546Sopenharmony_ci#include "pan_public.h" 51bf215546Sopenharmony_ci#include "pan_util.h" 52bf215546Sopenharmony_ci#include "decode.h" 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci#include "pan_context.h" 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_cistatic const struct debug_named_value panfrost_debug_options[] = { 57bf215546Sopenharmony_ci {"perf", PAN_DBG_PERF, "Enable performance warnings"}, 58bf215546Sopenharmony_ci {"trace", PAN_DBG_TRACE, "Trace the command stream"}, 59bf215546Sopenharmony_ci {"deqp", PAN_DBG_DEQP, "Hacks for dEQP"}, 60bf215546Sopenharmony_ci {"dirty", PAN_DBG_DIRTY, "Always re-emit all state"}, 61bf215546Sopenharmony_ci {"sync", PAN_DBG_SYNC, "Wait for each job's completion and abort on GPU faults"}, 62bf215546Sopenharmony_ci {"precompile", PAN_DBG_PRECOMPILE, "Precompile shaders for shader-db"}, 63bf215546Sopenharmony_ci {"nofp16", PAN_DBG_NOFP16, "Disable 16-bit support"}, 64bf215546Sopenharmony_ci {"gl3", PAN_DBG_GL3, "Enable experimental GL 3.x implementation, up to 3.3"}, 65bf215546Sopenharmony_ci {"noafbc", PAN_DBG_NO_AFBC, "Disable AFBC support"}, 66bf215546Sopenharmony_ci {"nocrc", PAN_DBG_NO_CRC, "Disable transaction elimination"}, 67bf215546Sopenharmony_ci {"msaa16", PAN_DBG_MSAA16, "Enable MSAA 8x and 16x support"}, 68bf215546Sopenharmony_ci {"indirect", PAN_DBG_INDIRECT, "Use experimental compute kernel for indirect draws"}, 69bf215546Sopenharmony_ci {"linear", PAN_DBG_LINEAR, "Force linear textures"}, 70bf215546Sopenharmony_ci {"nocache", PAN_DBG_NO_CACHE, "Disable BO cache"}, 71bf215546Sopenharmony_ci {"dump", PAN_DBG_DUMP, "Dump all graphics memory"}, 72bf215546Sopenharmony_ci#ifdef PAN_DBG_OVERFLOW 73bf215546Sopenharmony_ci {"overflow", PAN_DBG_OVERFLOW, "Check for buffer overflows in pool uploads"}, 74bf215546Sopenharmony_ci#endif 75bf215546Sopenharmony_ci DEBUG_NAMED_VALUE_END 76bf215546Sopenharmony_ci}; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic const char * 79bf215546Sopenharmony_cipanfrost_get_name(struct pipe_screen *screen) 80bf215546Sopenharmony_ci{ 81bf215546Sopenharmony_ci return pan_device(screen)->model->name; 82bf215546Sopenharmony_ci} 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cistatic const char * 85bf215546Sopenharmony_cipanfrost_get_vendor(struct pipe_screen *screen) 86bf215546Sopenharmony_ci{ 87bf215546Sopenharmony_ci return "Panfrost"; 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_cistatic const char * 91bf215546Sopenharmony_cipanfrost_get_device_vendor(struct pipe_screen *screen) 92bf215546Sopenharmony_ci{ 93bf215546Sopenharmony_ci return "Arm"; 94bf215546Sopenharmony_ci} 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_cistatic int 97bf215546Sopenharmony_cipanfrost_get_param(struct pipe_screen *screen, enum pipe_cap param) 98bf215546Sopenharmony_ci{ 99bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(screen); 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci /* Our GL 3.x implementation is WIP */ 102bf215546Sopenharmony_ci bool is_gl3 = dev->debug & (PAN_DBG_GL3 | PAN_DBG_DEQP); 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci /* Native MRT is introduced with v5 */ 105bf215546Sopenharmony_ci bool has_mrt = (dev->arch >= 5); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci /* Only kernel drivers >= 1.1 can allocate HEAP BOs */ 108bf215546Sopenharmony_ci bool has_heap = dev->kernel_version->version_major > 1 || 109bf215546Sopenharmony_ci dev->kernel_version->version_minor >= 1; 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci switch (param) { 112bf215546Sopenharmony_ci case PIPE_CAP_NPOT_TEXTURES: 113bf215546Sopenharmony_ci case PIPE_CAP_MIXED_COLOR_DEPTH_BITS: 114bf215546Sopenharmony_ci case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 115bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 116bf215546Sopenharmony_ci case PIPE_CAP_POINT_SPRITE: 117bf215546Sopenharmony_ci case PIPE_CAP_DEPTH_CLIP_DISABLE: 118bf215546Sopenharmony_ci case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE: 119bf215546Sopenharmony_ci case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 120bf215546Sopenharmony_ci case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: 121bf215546Sopenharmony_ci case PIPE_CAP_FRONTEND_NOOP: 122bf215546Sopenharmony_ci case PIPE_CAP_SAMPLE_SHADING: 123bf215546Sopenharmony_ci case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 124bf215546Sopenharmony_ci case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT: 125bf215546Sopenharmony_ci case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 126bf215546Sopenharmony_ci case PIPE_CAP_SHADER_PACK_HALF_FLOAT: 127bf215546Sopenharmony_ci case PIPE_CAP_NATIVE_FENCE_FD: 128bf215546Sopenharmony_ci return 1; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci case PIPE_CAP_MAX_RENDER_TARGETS: 131bf215546Sopenharmony_ci case PIPE_CAP_FBFETCH: 132bf215546Sopenharmony_ci case PIPE_CAP_FBFETCH_COHERENT: 133bf215546Sopenharmony_ci return has_mrt ? 8 : 1; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 136bf215546Sopenharmony_ci return 1; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci case PIPE_CAP_OCCLUSION_QUERY: 139bf215546Sopenharmony_ci case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX: 140bf215546Sopenharmony_ci return true; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci case PIPE_CAP_ANISOTROPIC_FILTER: 143bf215546Sopenharmony_ci return dev->revision >= dev->model->min_rev_anisotropic; 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci /* Compile side is done for Bifrost, Midgard TODO. Needs some kernel 146bf215546Sopenharmony_ci * work to turn on, since CYCLE_COUNT_START needs to be issued. In 147bf215546Sopenharmony_ci * kbase, userspace requests this via BASE_JD_REQ_PERMON. There is not 148bf215546Sopenharmony_ci * yet way to request this with mainline TODO */ 149bf215546Sopenharmony_ci case PIPE_CAP_SHADER_CLOCK: 150bf215546Sopenharmony_ci return 0; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci case PIPE_CAP_VS_INSTANCEID: 153bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_MULTISAMPLE: 154bf215546Sopenharmony_ci case PIPE_CAP_SURFACE_SAMPLE_COUNT: 155bf215546Sopenharmony_ci return true; 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci case PIPE_CAP_SAMPLER_VIEW_TARGET: 158bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_SWIZZLE: 159bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE: 160bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 161bf215546Sopenharmony_ci case PIPE_CAP_BLEND_EQUATION_SEPARATE: 162bf215546Sopenharmony_ci case PIPE_CAP_INDEP_BLEND_ENABLE: 163bf215546Sopenharmony_ci case PIPE_CAP_INDEP_BLEND_FUNC: 164bf215546Sopenharmony_ci case PIPE_CAP_GENERATE_MIPMAP: 165bf215546Sopenharmony_ci case PIPE_CAP_ACCELERATED: 166bf215546Sopenharmony_ci case PIPE_CAP_UMA: 167bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_FLOAT_LINEAR: 168bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 169bf215546Sopenharmony_ci case PIPE_CAP_SHADER_ARRAY_COMPONENTS: 170bf215546Sopenharmony_ci case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED: 171bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: 172bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BUFFER_SAMPLER: 173bf215546Sopenharmony_ci case PIPE_CAP_PACKED_UNIFORMS: 174bf215546Sopenharmony_ci case PIPE_CAP_IMAGE_LOAD_FORMATTED: 175bf215546Sopenharmony_ci case PIPE_CAP_CUBE_MAP_ARRAY: 176bf215546Sopenharmony_ci case PIPE_CAP_COMPUTE: 177bf215546Sopenharmony_ci return 1; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci /* We need this for OES_copy_image, but currently there are some awful 180bf215546Sopenharmony_ci * interactions with AFBC that need to be worked out. */ 181bf215546Sopenharmony_ci case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS: 182bf215546Sopenharmony_ci return 0; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 185bf215546Sopenharmony_ci return PIPE_MAX_SO_BUFFERS; 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 188bf215546Sopenharmony_ci case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 189bf215546Sopenharmony_ci return PIPE_MAX_SO_OUTPUTS; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 192bf215546Sopenharmony_ci case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS: 193bf215546Sopenharmony_ci return 1; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 196bf215546Sopenharmony_ci return 256; 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci case PIPE_CAP_GLSL_FEATURE_LEVEL: 199bf215546Sopenharmony_ci case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: 200bf215546Sopenharmony_ci return is_gl3 ? 330 : 140; 201bf215546Sopenharmony_ci case PIPE_CAP_ESSL_FEATURE_LEVEL: 202bf215546Sopenharmony_ci return dev->arch >= 6 ? 320 : 310; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 205bf215546Sopenharmony_ci return 16; 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT: 208bf215546Sopenharmony_ci return 65536; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci /* Must be at least 64 for correct behaviour */ 211bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT: 212bf215546Sopenharmony_ci return 64; 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci case PIPE_CAP_QUERY_TIMESTAMP: 215bf215546Sopenharmony_ci return is_gl3; 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci /* TODO: Where does this req come from in practice? */ 218bf215546Sopenharmony_ci case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 219bf215546Sopenharmony_ci return 1; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 222bf215546Sopenharmony_ci return 1 << (MAX_MIP_LEVELS - 1); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 225bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 226bf215546Sopenharmony_ci return MAX_MIP_LEVELS; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT: 229bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: 230bf215546Sopenharmony_ci /* Hardware is upper left. Pixel center at (0.5, 0.5) */ 231bf215546Sopenharmony_ci return 0; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT: 234bf215546Sopenharmony_ci case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 235bf215546Sopenharmony_ci case PIPE_CAP_TGSI_TEXCOORD: 236bf215546Sopenharmony_ci return 1; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci /* We would prefer varyings on Midgard, but proper sysvals on Bifrost */ 239bf215546Sopenharmony_ci case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL: 240bf215546Sopenharmony_ci case PIPE_CAP_FS_POSITION_IS_SYSVAL: 241bf215546Sopenharmony_ci case PIPE_CAP_FS_POINT_IS_SYSVAL: 242bf215546Sopenharmony_ci return dev->arch >= 6; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci case PIPE_CAP_SEAMLESS_CUBE_MAP: 245bf215546Sopenharmony_ci case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 246bf215546Sopenharmony_ci return true; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET: 249bf215546Sopenharmony_ci return 0xffff; 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_TRANSFER_MODES: 252bf215546Sopenharmony_ci return 0; 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci case PIPE_CAP_ENDIANNESS: 255bf215546Sopenharmony_ci return PIPE_ENDIAN_NATIVE; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS: 258bf215546Sopenharmony_ci return 4; 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: 261bf215546Sopenharmony_ci return -8; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: 264bf215546Sopenharmony_ci return 7; 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci case PIPE_CAP_VIDEO_MEMORY: { 267bf215546Sopenharmony_ci uint64_t system_memory; 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci if (!os_get_total_physical_memory(&system_memory)) 270bf215546Sopenharmony_ci return 0; 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci return (int)(system_memory >> 20); 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci case PIPE_CAP_SHADER_STENCIL_EXPORT: 276bf215546Sopenharmony_ci case PIPE_CAP_CONDITIONAL_RENDER: 277bf215546Sopenharmony_ci case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: 278bf215546Sopenharmony_ci return true; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT: 281bf215546Sopenharmony_ci return 4; 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci case PIPE_CAP_MAX_VARYINGS: 284bf215546Sopenharmony_ci /* Return the GLSL maximum. The internal maximum 285bf215546Sopenharmony_ci * PAN_MAX_VARYINGS accommodates internal varyings. */ 286bf215546Sopenharmony_ci return MAX_VARYING; 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci /* Removed in v6 (Bifrost) */ 289bf215546Sopenharmony_ci case PIPE_CAP_GL_CLAMP: 290bf215546Sopenharmony_ci case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 291bf215546Sopenharmony_ci case PIPE_CAP_ALPHA_TEST: 292bf215546Sopenharmony_ci return dev->arch <= 5; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci /* Removed in v9 (Valhall). PRIMTIIVE_RESTART_FIXED_INDEX is of course 295bf215546Sopenharmony_ci * still supported as it is core GLES3.0 functionality 296bf215546Sopenharmony_ci */ 297bf215546Sopenharmony_ci case PIPE_CAP_PRIMITIVE_RESTART: 298bf215546Sopenharmony_ci return dev->arch <= 7; 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci case PIPE_CAP_FLATSHADE: 301bf215546Sopenharmony_ci case PIPE_CAP_TWO_SIDED_COLOR: 302bf215546Sopenharmony_ci case PIPE_CAP_CLIP_PLANES: 303bf215546Sopenharmony_ci return 0; 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci case PIPE_CAP_PACKED_STREAM_OUTPUT: 306bf215546Sopenharmony_ci return 0; 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED: 309bf215546Sopenharmony_ci case PIPE_CAP_PSIZ_CLAMPED: 310bf215546Sopenharmony_ci return 1; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci case PIPE_CAP_NIR_IMAGES_AS_DEREF: 313bf215546Sopenharmony_ci return 0; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci case PIPE_CAP_DRAW_INDIRECT: 316bf215546Sopenharmony_ci return has_heap; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci case PIPE_CAP_START_INSTANCE: 319bf215546Sopenharmony_ci case PIPE_CAP_DRAW_PARAMETERS: 320bf215546Sopenharmony_ci return pan_is_bifrost(dev); 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci case PIPE_CAP_SUPPORTED_PRIM_MODES: 323bf215546Sopenharmony_ci case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: { 324bf215546Sopenharmony_ci /* Mali supports GLES and QUADS. Midgard and v6 Bifrost 325bf215546Sopenharmony_ci * support more */ 326bf215546Sopenharmony_ci uint32_t modes = BITFIELD_MASK(PIPE_PRIM_QUADS + 1); 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci if (dev->arch <= 6) { 329bf215546Sopenharmony_ci modes |= BITFIELD_BIT(PIPE_PRIM_QUAD_STRIP); 330bf215546Sopenharmony_ci modes |= BITFIELD_BIT(PIPE_PRIM_POLYGON); 331bf215546Sopenharmony_ci } 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci if (dev->arch >= 9) { 334bf215546Sopenharmony_ci /* Although Valhall is supposed to support quads, they 335bf215546Sopenharmony_ci * don't seem to work correctly. Disable to fix 336bf215546Sopenharmony_ci * arb-provoking-vertex-render. 337bf215546Sopenharmony_ci */ 338bf215546Sopenharmony_ci modes &= ~BITFIELD_BIT(PIPE_PRIM_QUADS); 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci return modes; 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci case PIPE_CAP_IMAGE_STORE_FORMATTED: 345bf215546Sopenharmony_ci return 1; 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci default: 348bf215546Sopenharmony_ci return u_pipe_screen_get_param_defaults(screen, param); 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci} 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_cistatic int 353bf215546Sopenharmony_cipanfrost_get_shader_param(struct pipe_screen *screen, 354bf215546Sopenharmony_ci enum pipe_shader_type shader, 355bf215546Sopenharmony_ci enum pipe_shader_cap param) 356bf215546Sopenharmony_ci{ 357bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(screen); 358bf215546Sopenharmony_ci bool is_nofp16 = dev->debug & PAN_DBG_NOFP16; 359bf215546Sopenharmony_ci bool is_deqp = dev->debug & PAN_DBG_DEQP; 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci switch (shader) { 362bf215546Sopenharmony_ci case PIPE_SHADER_VERTEX: 363bf215546Sopenharmony_ci case PIPE_SHADER_FRAGMENT: 364bf215546Sopenharmony_ci case PIPE_SHADER_COMPUTE: 365bf215546Sopenharmony_ci break; 366bf215546Sopenharmony_ci default: 367bf215546Sopenharmony_ci return 0; 368bf215546Sopenharmony_ci } 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci /* We only allow observable side effects (memory writes) in compute and 371bf215546Sopenharmony_ci * fragment shaders. Side effects in the geometry pipeline cause 372bf215546Sopenharmony_ci * trouble with IDVS. 373bf215546Sopenharmony_ci * 374bf215546Sopenharmony_ci * This restriction doesn't apply to Midgard, which does not implement 375bf215546Sopenharmony_ci * IDVS and therefore executes vertex shaders exactly once. 376bf215546Sopenharmony_ci */ 377bf215546Sopenharmony_ci bool allow_side_effects = (shader != PIPE_SHADER_VERTEX) || 378bf215546Sopenharmony_ci (dev->arch <= 5); 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci switch (param) { 381bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 382bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 383bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 384bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 385bf215546Sopenharmony_ci return 16384; /* arbitrary */ 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 388bf215546Sopenharmony_ci return 1024; /* arbitrary */ 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_INPUTS: 391bf215546Sopenharmony_ci /* Used as ABI on Midgard */ 392bf215546Sopenharmony_ci return 16; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_OUTPUTS: 395bf215546Sopenharmony_ci return shader == PIPE_SHADER_FRAGMENT ? 8 : PIPE_MAX_ATTRIBS; 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEMPS: 398bf215546Sopenharmony_ci return 256; /* arbitrary */ 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE: 401bf215546Sopenharmony_ci return 16 * 1024 * sizeof(float); 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 404bf215546Sopenharmony_ci STATIC_ASSERT(PAN_MAX_CONST_BUFFERS < 0x100); 405bf215546Sopenharmony_ci return PAN_MAX_CONST_BUFFERS; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci case PIPE_SHADER_CAP_CONT_SUPPORTED: 408bf215546Sopenharmony_ci return 0; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 411bf215546Sopenharmony_ci return 1; 412bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 413bf215546Sopenharmony_ci return 0; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 416bf215546Sopenharmony_ci return dev->arch >= 6; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 419bf215546Sopenharmony_ci return 1; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci case PIPE_SHADER_CAP_SUBROUTINES: 422bf215546Sopenharmony_ci return 0; 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: 425bf215546Sopenharmony_ci return 0; 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INTEGERS: 428bf215546Sopenharmony_ci return 1; 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci /* The Bifrost compiler supports full 16-bit. Midgard could but int16 431bf215546Sopenharmony_ci * support is untested, so restrict INT16 to Bifrost. Midgard 432bf215546Sopenharmony_ci * architecturally cannot support fp16 derivatives. */ 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16: 435bf215546Sopenharmony_ci case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS: 436bf215546Sopenharmony_ci return !is_nofp16; 437bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16_DERIVATIVES: 438bf215546Sopenharmony_ci case PIPE_SHADER_CAP_FP16_CONST_BUFFERS: 439bf215546Sopenharmony_ci return dev->arch >= 6 && !is_nofp16; 440bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INT16: 441bf215546Sopenharmony_ci /* XXX: Advertise this CAP when a proper fix to lower_precision 442bf215546Sopenharmony_ci * lands. GLSL IR validation failure in glmark2 -bterrain */ 443bf215546Sopenharmony_ci return dev->arch >= 6 && !is_nofp16 && is_deqp; 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci case PIPE_SHADER_CAP_INT64_ATOMICS: 446bf215546Sopenharmony_ci case PIPE_SHADER_CAP_DROUND_SUPPORTED: 447bf215546Sopenharmony_ci case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED: 448bf215546Sopenharmony_ci case PIPE_SHADER_CAP_LDEXP_SUPPORTED: 449bf215546Sopenharmony_ci case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE: 450bf215546Sopenharmony_ci return 0; 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 453bf215546Sopenharmony_ci STATIC_ASSERT(PIPE_MAX_SAMPLERS < 0x10000); 454bf215546Sopenharmony_ci return PIPE_MAX_SAMPLERS; 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 457bf215546Sopenharmony_ci STATIC_ASSERT(PIPE_MAX_SHADER_SAMPLER_VIEWS < 0x10000); 458bf215546Sopenharmony_ci return PIPE_MAX_SHADER_SAMPLER_VIEWS; 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci case PIPE_SHADER_CAP_PREFERRED_IR: 461bf215546Sopenharmony_ci return PIPE_SHADER_IR_NIR; 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci case PIPE_SHADER_CAP_SUPPORTED_IRS: 464bf215546Sopenharmony_ci return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_NIR_SERIALIZED); 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS: 467bf215546Sopenharmony_ci return allow_side_effects ? 16 : 0; 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_SHADER_IMAGES: 470bf215546Sopenharmony_ci return allow_side_effects ? PIPE_MAX_SHADER_IMAGES : 0; 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS: 473bf215546Sopenharmony_ci case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS: 474bf215546Sopenharmony_ci return 0; 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci default: 477bf215546Sopenharmony_ci return 0; 478bf215546Sopenharmony_ci } 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci return 0; 481bf215546Sopenharmony_ci} 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_cistatic float 484bf215546Sopenharmony_cipanfrost_get_paramf(struct pipe_screen *screen, enum pipe_capf param) 485bf215546Sopenharmony_ci{ 486bf215546Sopenharmony_ci switch (param) { 487bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH: 488bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH_AA: 489bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE: 490bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE_AA: 491bf215546Sopenharmony_ci return 1; 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci case PIPE_CAPF_POINT_SIZE_GRANULARITY: 494bf215546Sopenharmony_ci case PIPE_CAPF_LINE_WIDTH_GRANULARITY: 495bf215546Sopenharmony_ci return 0.0625; 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH: 498bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH_AA: 499bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE: 500bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE_AA: 501bf215546Sopenharmony_ci return 4095.9375; 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 504bf215546Sopenharmony_ci return 16.0; 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 507bf215546Sopenharmony_ci return 16.0; /* arbitrary */ 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 510bf215546Sopenharmony_ci case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 511bf215546Sopenharmony_ci case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 512bf215546Sopenharmony_ci return 0.0f; 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci default: 515bf215546Sopenharmony_ci debug_printf("Unexpected PIPE_CAPF %d query\n", param); 516bf215546Sopenharmony_ci return 0.0; 517bf215546Sopenharmony_ci } 518bf215546Sopenharmony_ci} 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci/** 521bf215546Sopenharmony_ci * Query format support for creating a texture, drawing surface, etc. 522bf215546Sopenharmony_ci * \param format the format to test 523bf215546Sopenharmony_ci * \param type one of PIPE_TEXTURE, PIPE_SURFACE 524bf215546Sopenharmony_ci */ 525bf215546Sopenharmony_cistatic bool 526bf215546Sopenharmony_cipanfrost_is_format_supported( struct pipe_screen *screen, 527bf215546Sopenharmony_ci enum pipe_format format, 528bf215546Sopenharmony_ci enum pipe_texture_target target, 529bf215546Sopenharmony_ci unsigned sample_count, 530bf215546Sopenharmony_ci unsigned storage_sample_count, 531bf215546Sopenharmony_ci unsigned bind) 532bf215546Sopenharmony_ci{ 533bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(screen); 534bf215546Sopenharmony_ci const struct util_format_description *format_desc; 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci assert(target == PIPE_BUFFER || 537bf215546Sopenharmony_ci target == PIPE_TEXTURE_1D || 538bf215546Sopenharmony_ci target == PIPE_TEXTURE_1D_ARRAY || 539bf215546Sopenharmony_ci target == PIPE_TEXTURE_2D || 540bf215546Sopenharmony_ci target == PIPE_TEXTURE_2D_ARRAY || 541bf215546Sopenharmony_ci target == PIPE_TEXTURE_RECT || 542bf215546Sopenharmony_ci target == PIPE_TEXTURE_3D || 543bf215546Sopenharmony_ci target == PIPE_TEXTURE_CUBE || 544bf215546Sopenharmony_ci target == PIPE_TEXTURE_CUBE_ARRAY); 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci format_desc = util_format_description(format); 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci /* MSAA 2x gets rounded up to 4x. MSAA 8x/16x only supported on v5+. 549bf215546Sopenharmony_ci * TODO: debug MSAA 8x/16x */ 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci switch (sample_count) { 552bf215546Sopenharmony_ci case 0: 553bf215546Sopenharmony_ci case 1: 554bf215546Sopenharmony_ci case 4: 555bf215546Sopenharmony_ci break; 556bf215546Sopenharmony_ci case 8: 557bf215546Sopenharmony_ci case 16: 558bf215546Sopenharmony_ci if (dev->debug & PAN_DBG_MSAA16) 559bf215546Sopenharmony_ci break; 560bf215546Sopenharmony_ci else 561bf215546Sopenharmony_ci return false; 562bf215546Sopenharmony_ci default: 563bf215546Sopenharmony_ci return false; 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci if (MAX2(sample_count, 1) != MAX2(storage_sample_count, 1)) 567bf215546Sopenharmony_ci return false; 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci /* Z16 causes dEQP failures on t720 */ 570bf215546Sopenharmony_ci if (format == PIPE_FORMAT_Z16_UNORM && dev->arch <= 4) 571bf215546Sopenharmony_ci return false; 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci /* Check we support the format with the given bind */ 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_ci unsigned relevant_bind = bind & 576bf215546Sopenharmony_ci ( PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET 577bf215546Sopenharmony_ci | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_SAMPLER_VIEW); 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci struct panfrost_format fmt = dev->formats[format]; 580bf215546Sopenharmony_ci 581bf215546Sopenharmony_ci /* Also check that compressed texture formats are supported on this 582bf215546Sopenharmony_ci * particular chip. They may not be depending on system integration 583bf215546Sopenharmony_ci * differences. RGTC can be emulated so is always supported. */ 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci bool is_rgtc = format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC; 586bf215546Sopenharmony_ci bool supported = panfrost_supports_compressed_format(dev, 587bf215546Sopenharmony_ci MALI_EXTRACT_INDEX(fmt.hw)); 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci if (!is_rgtc && !supported) 590bf215546Sopenharmony_ci return false; 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci return MALI_EXTRACT_INDEX(fmt.hw) && ((relevant_bind & ~fmt.bind) == 0); 593bf215546Sopenharmony_ci} 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_ci/* We always support linear and tiled operations, both external and internal. 596bf215546Sopenharmony_ci * We support AFBC for a subset of formats, and colourspace transform for a 597bf215546Sopenharmony_ci * subset of those. */ 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_cistatic void 600bf215546Sopenharmony_cipanfrost_walk_dmabuf_modifiers(struct pipe_screen *screen, 601bf215546Sopenharmony_ci enum pipe_format format, int max, uint64_t *modifiers, unsigned 602bf215546Sopenharmony_ci int *external_only, int *out_count, uint64_t test_modifier) 603bf215546Sopenharmony_ci{ 604bf215546Sopenharmony_ci /* Query AFBC status */ 605bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(screen); 606bf215546Sopenharmony_ci bool afbc = dev->has_afbc && panfrost_format_supports_afbc(dev, format); 607bf215546Sopenharmony_ci bool ytr = panfrost_afbc_can_ytr(format); 608bf215546Sopenharmony_ci bool tiled_afbc = panfrost_afbc_can_tile(dev); 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci unsigned count = 0; 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) { 613bf215546Sopenharmony_ci if (drm_is_afbc(pan_best_modifiers[i]) && !afbc) 614bf215546Sopenharmony_ci continue; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr) 617bf215546Sopenharmony_ci continue; 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_TILED) && !tiled_afbc) 620bf215546Sopenharmony_ci continue; 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci if (test_modifier != DRM_FORMAT_MOD_INVALID && 623bf215546Sopenharmony_ci test_modifier != pan_best_modifiers[i]) 624bf215546Sopenharmony_ci continue; 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci count++; 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci if (max > (int) count) { 629bf215546Sopenharmony_ci modifiers[count] = pan_best_modifiers[i]; 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci if (external_only) 632bf215546Sopenharmony_ci external_only[count] = false; 633bf215546Sopenharmony_ci } 634bf215546Sopenharmony_ci } 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ci *out_count = count; 637bf215546Sopenharmony_ci} 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_cistatic void 640bf215546Sopenharmony_cipanfrost_query_dmabuf_modifiers(struct pipe_screen *screen, 641bf215546Sopenharmony_ci enum pipe_format format, int max, uint64_t *modifiers, unsigned 642bf215546Sopenharmony_ci int *external_only, int *out_count) 643bf215546Sopenharmony_ci{ 644bf215546Sopenharmony_ci panfrost_walk_dmabuf_modifiers(screen, format, max, modifiers, 645bf215546Sopenharmony_ci external_only, out_count, DRM_FORMAT_MOD_INVALID); 646bf215546Sopenharmony_ci} 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_cistatic bool 649bf215546Sopenharmony_cipanfrost_is_dmabuf_modifier_supported(struct pipe_screen *screen, 650bf215546Sopenharmony_ci uint64_t modifier, enum pipe_format format, 651bf215546Sopenharmony_ci bool *external_only) 652bf215546Sopenharmony_ci{ 653bf215546Sopenharmony_ci uint64_t unused; 654bf215546Sopenharmony_ci unsigned int uint_extern_only = 0; 655bf215546Sopenharmony_ci int count; 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci panfrost_walk_dmabuf_modifiers(screen, format, 1, &unused, 658bf215546Sopenharmony_ci &uint_extern_only, &count, modifier); 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_ci if (external_only) 661bf215546Sopenharmony_ci *external_only = uint_extern_only ? true : false; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci return count > 0; 664bf215546Sopenharmony_ci} 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_cistatic int 667bf215546Sopenharmony_cipanfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type, 668bf215546Sopenharmony_ci enum pipe_compute_cap param, void *ret) 669bf215546Sopenharmony_ci{ 670bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(pscreen); 671bf215546Sopenharmony_ci const char * const ir = "panfrost"; 672bf215546Sopenharmony_ci 673bf215546Sopenharmony_ci#define RET(x) do { \ 674bf215546Sopenharmony_ci if (ret) \ 675bf215546Sopenharmony_ci memcpy(ret, x, sizeof(x)); \ 676bf215546Sopenharmony_ci return sizeof(x); \ 677bf215546Sopenharmony_ci} while (0) 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci switch (param) { 680bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_ADDRESS_BITS: 681bf215546Sopenharmony_ci RET((uint32_t []){ 64 }); 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IR_TARGET: 684bf215546Sopenharmony_ci if (ret) 685bf215546Sopenharmony_ci sprintf(ret, "%s", ir); 686bf215546Sopenharmony_ci return strlen(ir) * sizeof(char); 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_GRID_DIMENSION: 689bf215546Sopenharmony_ci RET((uint64_t []) { 3 }); 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: 692bf215546Sopenharmony_ci RET(((uint64_t []) { 65535, 65535, 65535 })); 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: 695bf215546Sopenharmony_ci /* Unpredictable behaviour at larger sizes. Mali-G52 advertises 696bf215546Sopenharmony_ci * 384x384x384. 697bf215546Sopenharmony_ci * 698bf215546Sopenharmony_ci * On Midgard, we don't allow more than 128 threads in each 699bf215546Sopenharmony_ci * direction to match PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK. 700bf215546Sopenharmony_ci * That still exceeds the minimum-maximum. 701bf215546Sopenharmony_ci */ 702bf215546Sopenharmony_ci if (dev->arch >= 6) 703bf215546Sopenharmony_ci RET(((uint64_t []) { 256, 256, 256 })); 704bf215546Sopenharmony_ci else 705bf215546Sopenharmony_ci RET(((uint64_t []) { 128, 128, 128 })); 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 708bf215546Sopenharmony_ci /* On Bifrost and newer, all GPUs can support at least 256 threads 709bf215546Sopenharmony_ci * regardless of register usage, so we report 256. 710bf215546Sopenharmony_ci * 711bf215546Sopenharmony_ci * On Midgard, with maximum register usage, the maximum 712bf215546Sopenharmony_ci * thread count is only 64. We would like to report 64 here, but 713bf215546Sopenharmony_ci * the GLES3.1 spec minimum is 128, so we report 128 and limit 714bf215546Sopenharmony_ci * the register allocation of affected compute kernels. 715bf215546Sopenharmony_ci */ 716bf215546Sopenharmony_ci RET((uint64_t []) { dev->arch >= 6 ? 256 : 128 }); 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: 719bf215546Sopenharmony_ci RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ }); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 722bf215546Sopenharmony_ci RET((uint64_t []) { 32768 }); 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: 725bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: 726bf215546Sopenharmony_ci RET((uint64_t []) { 4096 }); 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: 729bf215546Sopenharmony_ci RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ }); 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY: 732bf215546Sopenharmony_ci RET((uint32_t []) { 800 /* MHz -- TODO */ }); 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: 735bf215546Sopenharmony_ci RET((uint32_t []) { dev->core_count }); 736bf215546Sopenharmony_ci 737bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: 738bf215546Sopenharmony_ci RET((uint32_t []) { 1 }); 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: 741bf215546Sopenharmony_ci RET((uint32_t []) { pan_subgroup_size(dev->arch) }); 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 744bf215546Sopenharmony_ci RET((uint64_t []) { 1024 }); // TODO 745bf215546Sopenharmony_ci } 746bf215546Sopenharmony_ci 747bf215546Sopenharmony_ci return 0; 748bf215546Sopenharmony_ci} 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_cistatic void 751bf215546Sopenharmony_cipanfrost_destroy_screen(struct pipe_screen *pscreen) 752bf215546Sopenharmony_ci{ 753bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(pscreen); 754bf215546Sopenharmony_ci struct panfrost_screen *screen = pan_screen(pscreen); 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci panfrost_resource_screen_destroy(pscreen); 757bf215546Sopenharmony_ci panfrost_pool_cleanup(&screen->indirect_draw.bin_pool); 758bf215546Sopenharmony_ci panfrost_pool_cleanup(&screen->blitter.bin_pool); 759bf215546Sopenharmony_ci panfrost_pool_cleanup(&screen->blitter.desc_pool); 760bf215546Sopenharmony_ci pan_blend_shaders_cleanup(dev); 761bf215546Sopenharmony_ci 762bf215546Sopenharmony_ci if (screen->vtbl.screen_destroy) 763bf215546Sopenharmony_ci screen->vtbl.screen_destroy(pscreen); 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci if (dev->ro) 766bf215546Sopenharmony_ci dev->ro->destroy(dev->ro); 767bf215546Sopenharmony_ci panfrost_close_device(dev); 768bf215546Sopenharmony_ci ralloc_free(pscreen); 769bf215546Sopenharmony_ci} 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_cistatic uint64_t 772bf215546Sopenharmony_cipanfrost_get_timestamp(struct pipe_screen *_screen) 773bf215546Sopenharmony_ci{ 774bf215546Sopenharmony_ci return os_time_get_nano(); 775bf215546Sopenharmony_ci} 776bf215546Sopenharmony_ci 777bf215546Sopenharmony_cistatic void 778bf215546Sopenharmony_cipanfrost_fence_reference(struct pipe_screen *pscreen, 779bf215546Sopenharmony_ci struct pipe_fence_handle **ptr, 780bf215546Sopenharmony_ci struct pipe_fence_handle *fence) 781bf215546Sopenharmony_ci{ 782bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(pscreen); 783bf215546Sopenharmony_ci struct pipe_fence_handle *old = *ptr; 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci if (pipe_reference(&old->reference, &fence->reference)) { 786bf215546Sopenharmony_ci drmSyncobjDestroy(dev->fd, old->syncobj); 787bf215546Sopenharmony_ci free(old); 788bf215546Sopenharmony_ci } 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci *ptr = fence; 791bf215546Sopenharmony_ci} 792bf215546Sopenharmony_ci 793bf215546Sopenharmony_cistatic int 794bf215546Sopenharmony_cipanfrost_fence_get_fd(struct pipe_screen *_screen, 795bf215546Sopenharmony_ci struct pipe_fence_handle *fence) 796bf215546Sopenharmony_ci{ 797bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(_screen); 798bf215546Sopenharmony_ci int fd = -1; 799bf215546Sopenharmony_ci drmSyncobjExportSyncFile(dev->fd, fence->syncobj, &fd); 800bf215546Sopenharmony_ci return fd; 801bf215546Sopenharmony_ci} 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_cistatic bool 804bf215546Sopenharmony_cipanfrost_fence_finish(struct pipe_screen *pscreen, 805bf215546Sopenharmony_ci struct pipe_context *ctx, 806bf215546Sopenharmony_ci struct pipe_fence_handle *fence, 807bf215546Sopenharmony_ci uint64_t timeout) 808bf215546Sopenharmony_ci{ 809bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(pscreen); 810bf215546Sopenharmony_ci int ret; 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_ci if (fence->signaled) 813bf215546Sopenharmony_ci return true; 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_ci uint64_t abs_timeout = os_time_get_absolute_timeout(timeout); 816bf215546Sopenharmony_ci if (abs_timeout == OS_TIMEOUT_INFINITE) 817bf215546Sopenharmony_ci abs_timeout = INT64_MAX; 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci ret = drmSyncobjWait(dev->fd, &fence->syncobj, 820bf215546Sopenharmony_ci 1, 821bf215546Sopenharmony_ci abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL, 822bf215546Sopenharmony_ci NULL); 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci fence->signaled = (ret >= 0); 825bf215546Sopenharmony_ci return fence->signaled; 826bf215546Sopenharmony_ci} 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_cistruct pipe_fence_handle * 829bf215546Sopenharmony_cipanfrost_fence_create(struct panfrost_context *ctx) 830bf215546Sopenharmony_ci{ 831bf215546Sopenharmony_ci struct pipe_fence_handle *f = calloc(1, sizeof(*f)); 832bf215546Sopenharmony_ci if (!f) 833bf215546Sopenharmony_ci return NULL; 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(ctx->base.screen); 836bf215546Sopenharmony_ci int fd = -1, ret; 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci /* Snapshot the last rendering out fence. We'd rather have another 839bf215546Sopenharmony_ci * syncobj instead of a sync file, but this is all we get. 840bf215546Sopenharmony_ci * (HandleToFD/FDToHandle just gives you another syncobj ID for the 841bf215546Sopenharmony_ci * same syncobj). 842bf215546Sopenharmony_ci */ 843bf215546Sopenharmony_ci ret = drmSyncobjExportSyncFile(dev->fd, ctx->syncobj, &fd); 844bf215546Sopenharmony_ci if (ret || fd == -1) { 845bf215546Sopenharmony_ci fprintf(stderr, "export failed\n"); 846bf215546Sopenharmony_ci goto err_free_fence; 847bf215546Sopenharmony_ci } 848bf215546Sopenharmony_ci 849bf215546Sopenharmony_ci ret = drmSyncobjCreate(dev->fd, 0, &f->syncobj); 850bf215546Sopenharmony_ci if (ret) { 851bf215546Sopenharmony_ci fprintf(stderr, "create syncobj failed\n"); 852bf215546Sopenharmony_ci goto err_close_fd; 853bf215546Sopenharmony_ci } 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci ret = drmSyncobjImportSyncFile(dev->fd, f->syncobj, fd); 856bf215546Sopenharmony_ci if (ret) { 857bf215546Sopenharmony_ci fprintf(stderr, "create syncobj failed\n"); 858bf215546Sopenharmony_ci goto err_destroy_syncobj; 859bf215546Sopenharmony_ci } 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci assert(f->syncobj != ctx->syncobj); 862bf215546Sopenharmony_ci close(fd); 863bf215546Sopenharmony_ci pipe_reference_init(&f->reference, 1); 864bf215546Sopenharmony_ci 865bf215546Sopenharmony_ci return f; 866bf215546Sopenharmony_ci 867bf215546Sopenharmony_cierr_destroy_syncobj: 868bf215546Sopenharmony_ci drmSyncobjDestroy(dev->fd, f->syncobj); 869bf215546Sopenharmony_cierr_close_fd: 870bf215546Sopenharmony_ci close(fd); 871bf215546Sopenharmony_cierr_free_fence: 872bf215546Sopenharmony_ci free(f); 873bf215546Sopenharmony_ci return NULL; 874bf215546Sopenharmony_ci} 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_cistatic const void * 877bf215546Sopenharmony_cipanfrost_screen_get_compiler_options(struct pipe_screen *pscreen, 878bf215546Sopenharmony_ci enum pipe_shader_ir ir, 879bf215546Sopenharmony_ci enum pipe_shader_type shader) 880bf215546Sopenharmony_ci{ 881bf215546Sopenharmony_ci return pan_screen(pscreen)->vtbl.get_compiler_options(); 882bf215546Sopenharmony_ci} 883bf215546Sopenharmony_ci 884bf215546Sopenharmony_cistruct pipe_screen * 885bf215546Sopenharmony_cipanfrost_create_screen(int fd, struct renderonly *ro) 886bf215546Sopenharmony_ci{ 887bf215546Sopenharmony_ci /* Create the screen */ 888bf215546Sopenharmony_ci struct panfrost_screen *screen = rzalloc(NULL, struct panfrost_screen); 889bf215546Sopenharmony_ci 890bf215546Sopenharmony_ci if (!screen) 891bf215546Sopenharmony_ci return NULL; 892bf215546Sopenharmony_ci 893bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(&screen->base); 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci /* Debug must be set first for pandecode to work correctly */ 896bf215546Sopenharmony_ci dev->debug = debug_get_flags_option("PAN_MESA_DEBUG", panfrost_debug_options, 0); 897bf215546Sopenharmony_ci panfrost_open_device(screen, fd, dev); 898bf215546Sopenharmony_ci 899bf215546Sopenharmony_ci if (dev->debug & PAN_DBG_NO_AFBC) 900bf215546Sopenharmony_ci dev->has_afbc = false; 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_ci /* Bail early on unsupported hardware */ 903bf215546Sopenharmony_ci if (dev->model == NULL) { 904bf215546Sopenharmony_ci debug_printf("panfrost: Unsupported model %X", dev->gpu_id); 905bf215546Sopenharmony_ci panfrost_destroy_screen(&(screen->base)); 906bf215546Sopenharmony_ci return NULL; 907bf215546Sopenharmony_ci } 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci dev->ro = ro; 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci screen->base.destroy = panfrost_destroy_screen; 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci screen->base.get_name = panfrost_get_name; 914bf215546Sopenharmony_ci screen->base.get_vendor = panfrost_get_vendor; 915bf215546Sopenharmony_ci screen->base.get_device_vendor = panfrost_get_device_vendor; 916bf215546Sopenharmony_ci screen->base.get_param = panfrost_get_param; 917bf215546Sopenharmony_ci screen->base.get_shader_param = panfrost_get_shader_param; 918bf215546Sopenharmony_ci screen->base.get_compute_param = panfrost_get_compute_param; 919bf215546Sopenharmony_ci screen->base.get_paramf = panfrost_get_paramf; 920bf215546Sopenharmony_ci screen->base.get_timestamp = panfrost_get_timestamp; 921bf215546Sopenharmony_ci screen->base.is_format_supported = panfrost_is_format_supported; 922bf215546Sopenharmony_ci screen->base.query_dmabuf_modifiers = panfrost_query_dmabuf_modifiers; 923bf215546Sopenharmony_ci screen->base.is_dmabuf_modifier_supported = 924bf215546Sopenharmony_ci panfrost_is_dmabuf_modifier_supported; 925bf215546Sopenharmony_ci screen->base.context_create = panfrost_create_context; 926bf215546Sopenharmony_ci screen->base.get_compiler_options = panfrost_screen_get_compiler_options; 927bf215546Sopenharmony_ci screen->base.fence_reference = panfrost_fence_reference; 928bf215546Sopenharmony_ci screen->base.fence_finish = panfrost_fence_finish; 929bf215546Sopenharmony_ci screen->base.fence_get_fd = panfrost_fence_get_fd; 930bf215546Sopenharmony_ci screen->base.set_damage_region = panfrost_resource_set_damage_region; 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci panfrost_resource_screen_init(&screen->base); 933bf215546Sopenharmony_ci pan_blend_shaders_init(dev); 934bf215546Sopenharmony_ci panfrost_pool_init(&screen->indirect_draw.bin_pool, NULL, dev, 935bf215546Sopenharmony_ci PAN_BO_EXECUTE, 65536, "Indirect draw shaders", 936bf215546Sopenharmony_ci false, true); 937bf215546Sopenharmony_ci panfrost_pool_init(&screen->blitter.bin_pool, NULL, dev, PAN_BO_EXECUTE, 938bf215546Sopenharmony_ci 4096, "Blitter shaders", false, true); 939bf215546Sopenharmony_ci panfrost_pool_init(&screen->blitter.desc_pool, NULL, dev, 0, 65536, 940bf215546Sopenharmony_ci "Blitter RSDs", false, true); 941bf215546Sopenharmony_ci if (dev->arch == 4) 942bf215546Sopenharmony_ci panfrost_cmdstream_screen_init_v4(screen); 943bf215546Sopenharmony_ci else if (dev->arch == 5) 944bf215546Sopenharmony_ci panfrost_cmdstream_screen_init_v5(screen); 945bf215546Sopenharmony_ci else if (dev->arch == 6) 946bf215546Sopenharmony_ci panfrost_cmdstream_screen_init_v6(screen); 947bf215546Sopenharmony_ci else if (dev->arch == 7) 948bf215546Sopenharmony_ci panfrost_cmdstream_screen_init_v7(screen); 949bf215546Sopenharmony_ci else if (dev->arch == 9) 950bf215546Sopenharmony_ci panfrost_cmdstream_screen_init_v9(screen); 951bf215546Sopenharmony_ci else 952bf215546Sopenharmony_ci unreachable("Unhandled architecture major"); 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_ci return &screen->base; 955bf215546Sopenharmony_ci} 956