Path: blob/21.2-virgl/src/gallium/drivers/panfrost/pan_screen.c
4570 views
/*1* Copyright (C) 2008 VMware, Inc.2* Copyright (C) 2014 Broadcom3* Copyright (C) 2018 Alyssa Rosenzweig4* Copyright (C) 2019 Collabora, Ltd.5* Copyright (C) 2012 Rob Clark <[email protected]>6*7* Permission is hereby granted, free of charge, to any person obtaining a8* copy of this software and associated documentation files (the "Software"),9* to deal in the Software without restriction, including without limitation10* the rights to use, copy, modify, merge, publish, distribute, sublicense,11* and/or sell copies of the Software, and to permit persons to whom the12* Software is furnished to do so, subject to the following conditions:13*14* The above copyright notice and this permission notice (including the next15* paragraph) shall be included in all copies or substantial portions of the16* Software.17*18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR19* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,20* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL21* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER22* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,23* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE24* SOFTWARE.25*26*/2728#include "util/u_debug.h"29#include "util/u_memory.h"30#include "util/format/u_format.h"31#include "util/format/u_format_s3tc.h"32#include "util/u_video.h"33#include "util/u_screen.h"34#include "util/os_time.h"35#include "util/u_process.h"36#include "pipe/p_defines.h"37#include "pipe/p_screen.h"38#include "draw/draw_context.h"3940#include <fcntl.h>4142#include "drm-uapi/drm_fourcc.h"43#include "drm-uapi/panfrost_drm.h"4445#include "pan_bo.h"46#include "pan_shader.h"47#include "pan_screen.h"48#include "pan_resource.h"49#include "pan_public.h"50#include "pan_util.h"51#include "pan_indirect_dispatch.h"52#include "pan_indirect_draw.h"53#include "decode.h"5455#include "pan_context.h"56#include "panfrost-quirks.h"5758static const struct debug_named_value panfrost_debug_options[] = {59{"trace", PAN_DBG_TRACE, "Trace the command stream"},60{"deqp", PAN_DBG_DEQP, "Hacks for dEQP"},61{"dirty", PAN_DBG_DIRTY, "Always re-emit all state"},62{"sync", PAN_DBG_SYNC, "Wait for each job's completion and abort on GPU faults"},63{"precompile", PAN_DBG_PRECOMPILE, "Precompile shaders for shader-db"},64{"nofp16", PAN_DBG_NOFP16, "Disable 16-bit support"},65{"gl3", PAN_DBG_GL3, "Enable experimental GL 3.x implementation, up to 3.3"},66{"noafbc", PAN_DBG_NO_AFBC, "Disable AFBC support"},67{"nocrc", PAN_DBG_NO_CRC, "Disable transaction elimination"},68{"msaa16", PAN_DBG_MSAA16, "Enable MSAA 8x and 16x support"},69{"noindirect", PAN_DBG_NOINDIRECT, "Emulate indirect draws on the CPU"},70DEBUG_NAMED_VALUE_END71};7273static const char *74panfrost_get_name(struct pipe_screen *screen)75{76return panfrost_model_name(pan_device(screen)->gpu_id);77}7879static const char *80panfrost_get_vendor(struct pipe_screen *screen)81{82return "Panfrost";83}8485static const char *86panfrost_get_device_vendor(struct pipe_screen *screen)87{88return "Arm";89}9091static int92panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)93{94struct panfrost_device *dev = pan_device(screen);9596/* Our GL 3.x implementation is WIP */97bool is_gl3 = dev->debug & (PAN_DBG_GL3 | PAN_DBG_DEQP);9899/* Don't expose MRT related CAPs on GPUs that don't implement them */100bool has_mrt = !(dev->quirks & MIDGARD_SFBD);101102/* Only kernel drivers >= 1.1 can allocate HEAP BOs */103bool has_heap = dev->kernel_version->version_major > 1 ||104dev->kernel_version->version_minor >= 1;105106/* Bifrost is WIP */107switch (param) {108case PIPE_CAP_NPOT_TEXTURES:109case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:110case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:111case PIPE_CAP_VERTEX_SHADER_SATURATE:112case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:113case PIPE_CAP_POINT_SPRITE:114case PIPE_CAP_DEPTH_CLIP_DISABLE:115case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:116case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:117case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:118case PIPE_CAP_FRONTEND_NOOP:119case PIPE_CAP_SAMPLE_SHADING:120case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:121case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:122return 1;123124case PIPE_CAP_MAX_RENDER_TARGETS:125case PIPE_CAP_FBFETCH:126case PIPE_CAP_FBFETCH_COHERENT:127return has_mrt ? 8 : 1;128129case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:130return 1;131132case PIPE_CAP_OCCLUSION_QUERY:133case PIPE_CAP_PRIMITIVE_RESTART:134case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:135return true;136137case PIPE_CAP_ANISOTROPIC_FILTER:138return !!(dev->quirks & HAS_ANISOTROPIC);139140/* Compile side is done for Bifrost, Midgard TODO. Needs some kernel141* work to turn on, since CYCLE_COUNT_START needs to be issued. In142* kbase, userspace requests this via BASE_JD_REQ_PERMON. There is not143* yet way to request this with mainline TODO */144case PIPE_CAP_TGSI_CLOCK:145return 0;146147case PIPE_CAP_TGSI_INSTANCEID:148case PIPE_CAP_TEXTURE_MULTISAMPLE:149case PIPE_CAP_SURFACE_SAMPLE_COUNT:150return true;151152case PIPE_CAP_SAMPLER_VIEW_TARGET:153case PIPE_CAP_TEXTURE_SWIZZLE:154case PIPE_CAP_TEXTURE_MIRROR_CLAMP:155case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:156case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:157case PIPE_CAP_BLEND_EQUATION_SEPARATE:158case PIPE_CAP_INDEP_BLEND_ENABLE:159case PIPE_CAP_INDEP_BLEND_FUNC:160case PIPE_CAP_GENERATE_MIPMAP:161case PIPE_CAP_ACCELERATED:162case PIPE_CAP_UMA:163case PIPE_CAP_TEXTURE_FLOAT_LINEAR:164case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:165case PIPE_CAP_TGSI_ARRAY_COMPONENTS:166case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED:167case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:168case PIPE_CAP_TEXTURE_BUFFER_SAMPLER:169case PIPE_CAP_PACKED_UNIFORMS:170case PIPE_CAP_IMAGE_LOAD_FORMATTED:171case PIPE_CAP_CUBE_MAP_ARRAY:172case PIPE_CAP_COMPUTE:173return 1;174175/* We need this for OES_copy_image, but currently there are some awful176* interactions with AFBC that need to be worked out. */177case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:178return 0;179180case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:181return PIPE_MAX_SO_BUFFERS;182183case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:184case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:185return PIPE_MAX_SO_OUTPUTS;186187case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:188case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:189return 1;190191case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:192return 256;193194case PIPE_CAP_GLSL_FEATURE_LEVEL:195case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:196return is_gl3 ? 330 : 140;197case PIPE_CAP_ESSL_FEATURE_LEVEL:198return pan_is_bifrost(dev) ? 320 : 310;199200case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:201return 16;202203case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:204return 65536;205206/* Must be at least 64 for correct behaviour */207case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:208return 64;209210case PIPE_CAP_QUERY_TIMESTAMP:211return is_gl3;212213/* TODO: Where does this req come from in practice? */214case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:215return 1;216217case PIPE_CAP_MAX_TEXTURE_2D_SIZE:218return 4096;219case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:220return 13;221case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:222return 13;223224case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:225/* Hardware is natively upper left */226return 0;227228case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:229case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:230case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:231case PIPE_CAP_TGSI_TEXCOORD:232return 1;233234/* We would prefer varyings on Midgard, but proper sysvals on Bifrost */235case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:236case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:237case PIPE_CAP_TGSI_FS_POINT_IS_SYSVAL:238return pan_is_bifrost(dev);239240case PIPE_CAP_SEAMLESS_CUBE_MAP:241case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:242return true;243244case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:245return 0xffff;246247case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:248return 0;249250case PIPE_CAP_ENDIANNESS:251return PIPE_ENDIAN_NATIVE;252253case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:254return 4;255256case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:257return -8;258259case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:260return 7;261262case PIPE_CAP_VIDEO_MEMORY: {263uint64_t system_memory;264265if (!os_get_total_physical_memory(&system_memory))266return 0;267268return (int)(system_memory >> 20);269}270271case PIPE_CAP_SHADER_STENCIL_EXPORT:272case PIPE_CAP_CONDITIONAL_RENDER:273case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:274return true;275276case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:277return 4;278279case PIPE_CAP_MAX_VARYINGS:280return PIPE_MAX_ATTRIBS;281282/* Removed in v6 (Bifrost) */283case PIPE_CAP_ALPHA_TEST:284return dev->arch <= 5;285286case PIPE_CAP_FLATSHADE:287case PIPE_CAP_TWO_SIDED_COLOR:288case PIPE_CAP_CLIP_PLANES:289return 0;290291case PIPE_CAP_PACKED_STREAM_OUTPUT:292return 0;293294case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:295case PIPE_CAP_PSIZ_CLAMPED:296return 1;297298case PIPE_CAP_NIR_IMAGES_AS_DEREF:299return 0;300301case PIPE_CAP_DRAW_INDIRECT:302return has_heap;303304case PIPE_CAP_START_INSTANCE:305case PIPE_CAP_DRAW_PARAMETERS:306return pan_is_bifrost(dev);307308default:309return u_pipe_screen_get_param_defaults(screen, param);310}311}312313static int314panfrost_get_shader_param(struct pipe_screen *screen,315enum pipe_shader_type shader,316enum pipe_shader_cap param)317{318struct panfrost_device *dev = pan_device(screen);319bool is_nofp16 = dev->debug & PAN_DBG_NOFP16;320bool is_deqp = dev->debug & PAN_DBG_DEQP;321322switch (shader) {323case PIPE_SHADER_VERTEX:324case PIPE_SHADER_FRAGMENT:325case PIPE_SHADER_COMPUTE:326break;327default:328return 0;329}330331switch (param) {332case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:333case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:334case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:335case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:336return 16384; /* arbitrary */337338case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:339return 1024; /* arbitrary */340341case PIPE_SHADER_CAP_MAX_INPUTS:342/* Used as ABI on Midgard */343return 16;344345case PIPE_SHADER_CAP_MAX_OUTPUTS:346return shader == PIPE_SHADER_FRAGMENT ? 8 : PIPE_MAX_ATTRIBS;347348case PIPE_SHADER_CAP_MAX_TEMPS:349return 256; /* arbitrary */350351case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:352return 16 * 1024 * sizeof(float);353354case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:355STATIC_ASSERT(PAN_MAX_CONST_BUFFERS < 0x100);356return PAN_MAX_CONST_BUFFERS;357358case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:359return 0;360361case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:362return 1;363case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:364return 0;365366case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:367return pan_is_bifrost(dev);368369case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:370return 1;371372case PIPE_SHADER_CAP_SUBROUTINES:373return 0;374375case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:376return 0;377378case PIPE_SHADER_CAP_INTEGERS:379return 1;380381/* The Bifrost compiler supports full 16-bit. Midgard could but int16382* support is untested, so restrict INT16 to Bifrost. Midgard383* architecturally cannot support fp16 derivatives. */384385case PIPE_SHADER_CAP_FP16:386case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:387return !is_nofp16;388case PIPE_SHADER_CAP_FP16_DERIVATIVES:389case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:390return pan_is_bifrost(dev) && !is_nofp16;391case PIPE_SHADER_CAP_INT16:392/* XXX: Advertise this CAP when a proper fix to lower_precision393* lands. GLSL IR validation failure in glmark2 -bterrain */394return pan_is_bifrost(dev) && !is_nofp16 && is_deqp;395396case PIPE_SHADER_CAP_INT64_ATOMICS:397case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:398case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:399case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:400case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:401case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:402return 0;403404case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:405STATIC_ASSERT(PIPE_MAX_SAMPLERS < 0x10000);406return PIPE_MAX_SAMPLERS;407408case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:409STATIC_ASSERT(PIPE_MAX_SHADER_SAMPLER_VIEWS < 0x10000);410return PIPE_MAX_SHADER_SAMPLER_VIEWS;411412case PIPE_SHADER_CAP_PREFERRED_IR:413return PIPE_SHADER_IR_NIR;414415case PIPE_SHADER_CAP_SUPPORTED_IRS:416return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_NIR_SERIALIZED);417418case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:419return 16;420421case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:422return PIPE_MAX_SHADER_IMAGES;423424case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:425case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:426case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:427case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:428case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:429return 0;430431default:432return 0;433}434435return 0;436}437438static float439panfrost_get_paramf(struct pipe_screen *screen, enum pipe_capf param)440{441switch (param) {442case PIPE_CAPF_MAX_LINE_WIDTH:443444FALLTHROUGH;445case PIPE_CAPF_MAX_LINE_WIDTH_AA:446return 255.0; /* arbitrary */447448case PIPE_CAPF_MAX_POINT_WIDTH:449450FALLTHROUGH;451case PIPE_CAPF_MAX_POINT_WIDTH_AA:452return 1024.0;453454case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:455return 16.0;456457case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:458return 16.0; /* arbitrary */459460case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:461case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:462case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:463return 0.0f;464465default:466debug_printf("Unexpected PIPE_CAPF %d query\n", param);467return 0.0;468}469}470471/**472* Query format support for creating a texture, drawing surface, etc.473* \param format the format to test474* \param type one of PIPE_TEXTURE, PIPE_SURFACE475*/476static bool477panfrost_is_format_supported( struct pipe_screen *screen,478enum pipe_format format,479enum pipe_texture_target target,480unsigned sample_count,481unsigned storage_sample_count,482unsigned bind)483{484struct panfrost_device *dev = pan_device(screen);485const struct util_format_description *format_desc;486487assert(target == PIPE_BUFFER ||488target == PIPE_TEXTURE_1D ||489target == PIPE_TEXTURE_1D_ARRAY ||490target == PIPE_TEXTURE_2D ||491target == PIPE_TEXTURE_2D_ARRAY ||492target == PIPE_TEXTURE_RECT ||493target == PIPE_TEXTURE_3D ||494target == PIPE_TEXTURE_CUBE ||495target == PIPE_TEXTURE_CUBE_ARRAY);496497format_desc = util_format_description(format);498499if (!format_desc)500return false;501502/* MSAA 2x gets rounded up to 4x. MSAA 8x/16x only supported on v5+.503* TODO: debug MSAA 8x/16x */504505switch (sample_count) {506case 0:507case 1:508case 4:509break;510case 8:511case 16:512if (dev->debug & PAN_DBG_MSAA16)513break;514else515return false;516default:517return false;518}519520if (MAX2(sample_count, 1) != MAX2(storage_sample_count, 1))521return false;522523/* Z16 causes dEQP failures on t720 */524if (format == PIPE_FORMAT_Z16_UNORM && dev->quirks & MIDGARD_SFBD)525return false;526527/* Check we support the format with the given bind */528529unsigned relevant_bind = bind &530( PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET531| PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_SAMPLER_VIEW);532533struct panfrost_format fmt = dev->formats[format];534535/* Also check that compressed texture formats are supported on this536* particular chip. They may not be depending on system integration537* differences. RGTC can be emulated so is always supported. */538539bool is_rgtc = format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC;540bool supported = panfrost_supports_compressed_format(dev,541MALI_EXTRACT_INDEX(fmt.hw));542543if (!is_rgtc && !supported)544return false;545546return MALI_EXTRACT_INDEX(fmt.hw) && ((relevant_bind & ~fmt.bind) == 0);547}548549/* We always support linear and tiled operations, both external and internal.550* We support AFBC for a subset of formats, and colourspace transform for a551* subset of those. */552553static void554panfrost_walk_dmabuf_modifiers(struct pipe_screen *screen,555enum pipe_format format, int max, uint64_t *modifiers, unsigned556int *external_only, int *out_count, uint64_t test_modifier)557{558/* Query AFBC status */559struct panfrost_device *dev = pan_device(screen);560bool afbc = panfrost_format_supports_afbc(dev, format);561bool ytr = panfrost_afbc_can_ytr(format);562563/* Don't advertise AFBC before T760 */564afbc &= !(dev->quirks & MIDGARD_NO_AFBC);565566unsigned count = 0;567568for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) {569if (drm_is_afbc(pan_best_modifiers[i]) && !afbc)570continue;571572if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr)573continue;574575if (test_modifier != DRM_FORMAT_MOD_INVALID &&576test_modifier != pan_best_modifiers[i])577continue;578579count++;580581if (max > (int) count) {582modifiers[count] = pan_best_modifiers[i];583584if (external_only)585external_only[count] = false;586}587}588589*out_count = count;590}591592static void593panfrost_query_dmabuf_modifiers(struct pipe_screen *screen,594enum pipe_format format, int max, uint64_t *modifiers, unsigned595int *external_only, int *out_count)596{597panfrost_walk_dmabuf_modifiers(screen, format, max, modifiers,598external_only, out_count, DRM_FORMAT_MOD_INVALID);599}600601static bool602panfrost_is_dmabuf_modifier_supported(struct pipe_screen *screen,603uint64_t modifier, enum pipe_format format,604bool *external_only)605{606uint64_t unused;607unsigned int uint_extern_only = 0;608int count;609610panfrost_walk_dmabuf_modifiers(screen, format, 1, &unused,611&uint_extern_only, &count, modifier);612613if (external_only)614*external_only = uint_extern_only ? true : false;615616return count > 0;617}618619static int620panfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,621enum pipe_compute_cap param, void *ret)622{623struct panfrost_device *dev = pan_device(pscreen);624const char * const ir = "panfrost";625626#define RET(x) do { \627if (ret) \628memcpy(ret, x, sizeof(x)); \629return sizeof(x); \630} while (0)631632switch (param) {633case PIPE_COMPUTE_CAP_ADDRESS_BITS:634RET((uint32_t []){ 64 });635636case PIPE_COMPUTE_CAP_IR_TARGET:637if (ret)638sprintf(ret, "%s", ir);639return strlen(ir) * sizeof(char);640641case PIPE_COMPUTE_CAP_GRID_DIMENSION:642RET((uint64_t []) { 3 });643644case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:645RET(((uint64_t []) { 65535, 65535, 65535 }));646647case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:648/* Unpredictable behaviour at larger sizes. Mali-G52 advertises649* 384x384x384. The smaller size is advertised by Mali-T628,650* use min until we have a need to key by arch */651RET(((uint64_t []) { 256, 256, 256 }));652653case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:654RET((uint64_t []) { 256 });655656case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:657RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ });658659case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:660RET((uint64_t []) { 32768 });661662case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:663case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:664RET((uint64_t []) { 4096 });665666case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:667RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ });668669case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:670RET((uint32_t []) { 800 /* MHz -- TODO */ });671672case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:673RET((uint32_t []) { 9999 }); // TODO674675case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:676RET((uint32_t []) { 1 });677678case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:679RET((uint32_t []) { dev->arch >= 7 ? 8 : 4 });680681case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:682RET((uint64_t []) { 1024 }); // TODO683}684685return 0;686}687688static void689panfrost_destroy_screen(struct pipe_screen *pscreen)690{691struct panfrost_device *dev = pan_device(pscreen);692struct panfrost_screen *screen = pan_screen(pscreen);693694pan_indirect_dispatch_cleanup(dev);695panfrost_cleanup_indirect_draw_shaders(dev);696panfrost_pool_cleanup(&screen->indirect_draw.bin_pool);697panfrost_pool_cleanup(&screen->blitter.bin_pool);698panfrost_pool_cleanup(&screen->blitter.desc_pool);699pan_blend_shaders_cleanup(dev);700701screen->vtbl.screen_destroy(pscreen);702703if (dev->ro)704dev->ro->destroy(dev->ro);705panfrost_close_device(dev);706ralloc_free(pscreen);707}708709static uint64_t710panfrost_get_timestamp(struct pipe_screen *_screen)711{712return os_time_get_nano();713}714715static void716panfrost_fence_reference(struct pipe_screen *pscreen,717struct pipe_fence_handle **ptr,718struct pipe_fence_handle *fence)719{720struct panfrost_device *dev = pan_device(pscreen);721struct pipe_fence_handle *old = *ptr;722723if (pipe_reference(&old->reference, &fence->reference)) {724drmSyncobjDestroy(dev->fd, old->syncobj);725free(old);726}727728*ptr = fence;729}730731static bool732panfrost_fence_finish(struct pipe_screen *pscreen,733struct pipe_context *ctx,734struct pipe_fence_handle *fence,735uint64_t timeout)736{737struct panfrost_device *dev = pan_device(pscreen);738int ret;739740if (fence->signaled)741return true;742743uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);744if (abs_timeout == OS_TIMEOUT_INFINITE)745abs_timeout = INT64_MAX;746747ret = drmSyncobjWait(dev->fd, &fence->syncobj,7481,749abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL,750NULL);751752fence->signaled = (ret >= 0);753return fence->signaled;754}755756struct pipe_fence_handle *757panfrost_fence_create(struct panfrost_context *ctx)758{759struct pipe_fence_handle *f = calloc(1, sizeof(*f));760if (!f)761return NULL;762763struct panfrost_device *dev = pan_device(ctx->base.screen);764int fd = -1, ret;765766/* Snapshot the last rendering out fence. We'd rather have another767* syncobj instead of a sync file, but this is all we get.768* (HandleToFD/FDToHandle just gives you another syncobj ID for the769* same syncobj).770*/771ret = drmSyncobjExportSyncFile(dev->fd, ctx->syncobj, &fd);772if (ret || fd == -1) {773fprintf(stderr, "export failed\n");774goto err_free_fence;775}776777ret = drmSyncobjCreate(dev->fd, 0, &f->syncobj);778if (ret) {779fprintf(stderr, "create syncobj failed\n");780goto err_close_fd;781}782783ret = drmSyncobjImportSyncFile(dev->fd, f->syncobj, fd);784if (ret) {785fprintf(stderr, "create syncobj failed\n");786goto err_destroy_syncobj;787}788789assert(f->syncobj != ctx->syncobj);790close(fd);791pipe_reference_init(&f->reference, 1);792793return f;794795err_destroy_syncobj:796drmSyncobjDestroy(dev->fd, f->syncobj);797err_close_fd:798close(fd);799err_free_fence:800free(f);801return NULL;802}803804static const void *805panfrost_screen_get_compiler_options(struct pipe_screen *pscreen,806enum pipe_shader_ir ir,807enum pipe_shader_type shader)808{809return pan_shader_get_compiler_options(pan_device(pscreen));810}811812struct pipe_screen *813panfrost_create_screen(int fd, struct renderonly *ro)814{815/* Create the screen */816struct panfrost_screen *screen = rzalloc(NULL, struct panfrost_screen);817818if (!screen)819return NULL;820821struct panfrost_device *dev = pan_device(&screen->base);822823/* Debug must be set first for pandecode to work correctly */824dev->debug = debug_get_flags_option("PAN_MESA_DEBUG", panfrost_debug_options, 0);825panfrost_open_device(screen, fd, dev);826827if (dev->debug & PAN_DBG_NO_AFBC)828dev->quirks |= MIDGARD_NO_AFBC;829830/* XXX: AFBC is currently broken on Bifrost in a few different ways831*832* - Preload is broken if the effective tile size is not 16x16833* - Some systems lack AFBC but we need kernel changes to know that834*/835if (dev->arch == 7)836dev->quirks |= MIDGARD_NO_AFBC;837838/* XXX: Indirect draws on Midgard need debugging, emulate for now */839if (dev->arch < 6)840dev->debug |= PAN_DBG_NOINDIRECT;841842dev->ro = ro;843844/* Check if we're loading against a supported GPU model. */845846switch (dev->gpu_id) {847case 0x720: /* T720 */848case 0x750: /* T760 */849case 0x820: /* T820 */850case 0x860: /* T860 */851case 0x6221: /* G72 */852case 0x7093: /* G31 */853case 0x7212: /* G52 */854case 0x7402: /* G52r1 */855break;856default:857/* Fail to load against untested models */858debug_printf("panfrost: Unsupported model %X", dev->gpu_id);859panfrost_destroy_screen(&(screen->base));860return NULL;861}862863screen->base.destroy = panfrost_destroy_screen;864865screen->base.get_name = panfrost_get_name;866screen->base.get_vendor = panfrost_get_vendor;867screen->base.get_device_vendor = panfrost_get_device_vendor;868screen->base.get_param = panfrost_get_param;869screen->base.get_shader_param = panfrost_get_shader_param;870screen->base.get_compute_param = panfrost_get_compute_param;871screen->base.get_paramf = panfrost_get_paramf;872screen->base.get_timestamp = panfrost_get_timestamp;873screen->base.is_format_supported = panfrost_is_format_supported;874screen->base.query_dmabuf_modifiers = panfrost_query_dmabuf_modifiers;875screen->base.is_dmabuf_modifier_supported =876panfrost_is_dmabuf_modifier_supported;877screen->base.context_create = panfrost_create_context;878screen->base.get_compiler_options = panfrost_screen_get_compiler_options;879screen->base.fence_reference = panfrost_fence_reference;880screen->base.fence_finish = panfrost_fence_finish;881screen->base.set_damage_region = panfrost_resource_set_damage_region;882883panfrost_resource_screen_init(&screen->base);884pan_blend_shaders_init(dev);885panfrost_pool_init(&screen->indirect_draw.bin_pool, NULL, dev,886PAN_BO_EXECUTE, 65536, "Indirect draw shaders",887false, true);888panfrost_init_indirect_draw_shaders(dev, &screen->indirect_draw.bin_pool.base);889pan_indirect_dispatch_init(dev);890panfrost_pool_init(&screen->blitter.bin_pool, NULL, dev, PAN_BO_EXECUTE,8914096, "Blitter shaders", false, true);892panfrost_pool_init(&screen->blitter.desc_pool, NULL, dev, 0, 65536,893"Blitter RSDs", false, true);894panfrost_cmdstream_screen_init(screen);895896return &screen->base;897}898899900