19f464c52Smaya/* 29f464c52Smaya * Copyright (c) 2017-2019 Lima Project 39f464c52Smaya * 49f464c52Smaya * Permission is hereby granted, free of charge, to any person obtaining a 59f464c52Smaya * copy of this software and associated documentation files (the "Software"), 69f464c52Smaya * to deal in the Software without restriction, including without limitation 79f464c52Smaya * the rights to use, copy, modify, merge, publish, distribute, sub license, 89f464c52Smaya * and/or sell copies of the Software, and to permit persons to whom the 99f464c52Smaya * Software is furnished to do so, subject to the following conditions: 109f464c52Smaya * 119f464c52Smaya * The above copyright notice and this permission notice (including the 129f464c52Smaya * next paragraph) shall be included in all copies or substantial portions 139f464c52Smaya * of the Software. 149f464c52Smaya * 159f464c52Smaya * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 169f464c52Smaya * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 179f464c52Smaya * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 189f464c52Smaya * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 199f464c52Smaya * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 209f464c52Smaya * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 219f464c52Smaya * DEALINGS IN THE SOFTWARE. 229f464c52Smaya * 239f464c52Smaya */ 249f464c52Smaya 259f464c52Smaya#include <string.h> 269f464c52Smaya 279f464c52Smaya#include "util/ralloc.h" 289f464c52Smaya#include "util/u_debug.h" 299f464c52Smaya#include "util/u_screen.h" 309f464c52Smaya#include "renderonly/renderonly.h" 319f464c52Smaya 329f464c52Smaya#include "drm-uapi/drm_fourcc.h" 339f464c52Smaya#include "drm-uapi/lima_drm.h" 349f464c52Smaya 359f464c52Smaya#include "lima_screen.h" 369f464c52Smaya#include "lima_context.h" 379f464c52Smaya#include "lima_resource.h" 389f464c52Smaya#include "lima_program.h" 399f464c52Smaya#include "lima_bo.h" 409f464c52Smaya#include "lima_fence.h" 417ec681f3Smrg#include "lima_format.h" 427ec681f3Smrg#include "lima_disk_cache.h" 439f464c52Smaya#include "ir/lima_ir.h" 449f464c52Smaya 459f464c52Smaya#include "xf86drm.h" 469f464c52Smaya 477ec681f3Smrgint lima_plb_max_blk = 0; 487ec681f3Smrgint lima_plb_pp_stream_cache_size = 0; 497ec681f3Smrg 509f464c52Smayastatic void 519f464c52Smayalima_screen_destroy(struct pipe_screen *pscreen) 529f464c52Smaya{ 539f464c52Smaya struct lima_screen *screen = lima_screen(pscreen); 549f464c52Smaya 559f464c52Smaya slab_destroy_parent(&screen->transfer_pool); 569f464c52Smaya 579f464c52Smaya if (screen->ro) 587ec681f3Smrg screen->ro->destroy(screen->ro); 599f464c52Smaya 609f464c52Smaya if (screen->pp_buffer) 617ec681f3Smrg lima_bo_unreference(screen->pp_buffer); 629f464c52Smaya 637ec681f3Smrg lima_bo_cache_fini(screen); 649f464c52Smaya lima_bo_table_fini(screen); 657ec681f3Smrg disk_cache_destroy(screen->disk_cache); 669f464c52Smaya ralloc_free(screen); 679f464c52Smaya} 689f464c52Smaya 699f464c52Smayastatic const char * 709f464c52Smayalima_screen_get_name(struct pipe_screen *pscreen) 719f464c52Smaya{ 729f464c52Smaya struct lima_screen *screen = lima_screen(pscreen); 739f464c52Smaya 749f464c52Smaya switch (screen->gpu_type) { 759f464c52Smaya case DRM_LIMA_PARAM_GPU_ID_MALI400: 769f464c52Smaya return "Mali400"; 779f464c52Smaya case DRM_LIMA_PARAM_GPU_ID_MALI450: 789f464c52Smaya return "Mali450"; 799f464c52Smaya } 809f464c52Smaya 819f464c52Smaya return NULL; 829f464c52Smaya} 839f464c52Smaya 849f464c52Smayastatic const char * 859f464c52Smayalima_screen_get_vendor(struct pipe_screen *pscreen) 869f464c52Smaya{ 879f464c52Smaya return "lima"; 889f464c52Smaya} 899f464c52Smaya 909f464c52Smayastatic const char * 919f464c52Smayalima_screen_get_device_vendor(struct pipe_screen *pscreen) 929f464c52Smaya{ 939f464c52Smaya return "ARM"; 949f464c52Smaya} 959f464c52Smaya 969f464c52Smayastatic int 979f464c52Smayalima_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 989f464c52Smaya{ 999f464c52Smaya switch (param) { 1009f464c52Smaya case PIPE_CAP_NPOT_TEXTURES: 1019f464c52Smaya case PIPE_CAP_BLEND_EQUATION_SEPARATE: 1029f464c52Smaya case PIPE_CAP_ACCELERATED: 1039f464c52Smaya case PIPE_CAP_UMA: 1047ec681f3Smrg case PIPE_CAP_CLIP_HALFZ: 1059f464c52Smaya case PIPE_CAP_NATIVE_FENCE_FD: 1067ec681f3Smrg case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD: 1077ec681f3Smrg case PIPE_CAP_TEXTURE_SWIZZLE: 1087ec681f3Smrg case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 1099f464c52Smaya return 1; 1109f464c52Smaya 1119f464c52Smaya /* Unimplemented, but for exporting OpenGL 2.0 */ 1129f464c52Smaya case PIPE_CAP_OCCLUSION_QUERY: 1139f464c52Smaya case PIPE_CAP_POINT_SPRITE: 1149f464c52Smaya return 1; 1159f464c52Smaya 1169f464c52Smaya /* not clear supported */ 1179f464c52Smaya case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 1189f464c52Smaya case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 1199f464c52Smaya case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 1209f464c52Smaya case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 1219f464c52Smaya return 1; 1229f464c52Smaya 1239f464c52Smaya case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL: 1247ec681f3Smrg case PIPE_CAP_TGSI_FS_POINT_IS_SYSVAL: 1257ec681f3Smrg case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL: 1269f464c52Smaya return 1; 1279f464c52Smaya 1287ec681f3Smrg case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR: 1297ec681f3Smrg return 1; 1307ec681f3Smrg 1317ec681f3Smrg case PIPE_CAP_MAX_TEXTURE_2D_SIZE: 1327ec681f3Smrg return 1 << (LIMA_MAX_MIP_LEVELS - 1); 1339f464c52Smaya case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 1349f464c52Smaya case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 1359f464c52Smaya return LIMA_MAX_MIP_LEVELS; 1369f464c52Smaya 1379f464c52Smaya case PIPE_CAP_VENDOR_ID: 1389f464c52Smaya return 0x13B5; 1399f464c52Smaya 1409f464c52Smaya case PIPE_CAP_VIDEO_MEMORY: 1419f464c52Smaya return 0; 1429f464c52Smaya 1439f464c52Smaya case PIPE_CAP_PCI_GROUP: 1449f464c52Smaya case PIPE_CAP_PCI_BUS: 1459f464c52Smaya case PIPE_CAP_PCI_DEVICE: 1469f464c52Smaya case PIPE_CAP_PCI_FUNCTION: 1479f464c52Smaya return 0; 1489f464c52Smaya 1499f464c52Smaya case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: 1507ec681f3Smrg case PIPE_CAP_SHAREABLE_SHADERS: 1517ec681f3Smrg return 0; 1527ec681f3Smrg 1537ec681f3Smrg case PIPE_CAP_ALPHA_TEST: 1547ec681f3Smrg return 1; 1557ec681f3Smrg 1567ec681f3Smrg case PIPE_CAP_FLATSHADE: 1577ec681f3Smrg case PIPE_CAP_TWO_SIDED_COLOR: 1587ec681f3Smrg case PIPE_CAP_CLIP_PLANES: 1599f464c52Smaya return 0; 1609f464c52Smaya 1617ec681f3Smrg case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES: 1627ec681f3Smrg return 1; 1637ec681f3Smrg 1649f464c52Smaya default: 1659f464c52Smaya return u_pipe_screen_get_param_defaults(pscreen, param); 1669f464c52Smaya } 1679f464c52Smaya} 1689f464c52Smaya 1699f464c52Smayastatic float 1709f464c52Smayalima_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 1719f464c52Smaya{ 1729f464c52Smaya switch (param) { 1739f464c52Smaya case PIPE_CAPF_MAX_LINE_WIDTH: 1749f464c52Smaya case PIPE_CAPF_MAX_LINE_WIDTH_AA: 1759f464c52Smaya case PIPE_CAPF_MAX_POINT_WIDTH: 1769f464c52Smaya case PIPE_CAPF_MAX_POINT_WIDTH_AA: 1777ec681f3Smrg return 100.0f; 1789f464c52Smaya case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 1799f464c52Smaya return 16.0f; 1809f464c52Smaya case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 1817ec681f3Smrg return 15.0f; 1829f464c52Smaya 1839f464c52Smaya default: 1849f464c52Smaya return 0.0f; 1859f464c52Smaya } 1869f464c52Smaya} 1879f464c52Smaya 1889f464c52Smayastatic int 1899f464c52Smayaget_vertex_shader_param(struct lima_screen *screen, 1909f464c52Smaya enum pipe_shader_cap param) 1919f464c52Smaya{ 1929f464c52Smaya switch (param) { 1939f464c52Smaya case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 1949f464c52Smaya case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 1959f464c52Smaya case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 1969f464c52Smaya case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 1979f464c52Smaya return 16384; /* need investigate */ 1989f464c52Smaya 1997ec681f3Smrg case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 2007ec681f3Smrg return 1024; 2017ec681f3Smrg 2029f464c52Smaya case PIPE_SHADER_CAP_MAX_INPUTS: 2039f464c52Smaya return 16; /* attributes */ 2049f464c52Smaya 2059f464c52Smaya case PIPE_SHADER_CAP_MAX_OUTPUTS: 2069f464c52Smaya return LIMA_MAX_VARYING_NUM; /* varying */ 2079f464c52Smaya 2087ec681f3Smrg /* Mali-400 GP provides space for 304 vec4 uniforms, globals and 2097ec681f3Smrg * temporary variables. */ 2109f464c52Smaya case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: 2117ec681f3Smrg return 304 * 4 * sizeof(float); 2127ec681f3Smrg 2139f464c52Smaya case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 2149f464c52Smaya return 1; 2159f464c52Smaya 2169f464c52Smaya case PIPE_SHADER_CAP_PREFERRED_IR: 2179f464c52Smaya return PIPE_SHADER_IR_NIR; 2189f464c52Smaya 2199f464c52Smaya case PIPE_SHADER_CAP_MAX_TEMPS: 2209f464c52Smaya return 256; /* need investigate */ 2219f464c52Smaya 2227ec681f3Smrg case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: 2237ec681f3Smrg return 32; 2247ec681f3Smrg 2259f464c52Smaya default: 2269f464c52Smaya return 0; 2279f464c52Smaya } 2289f464c52Smaya} 2299f464c52Smaya 2309f464c52Smayastatic int 2319f464c52Smayaget_fragment_shader_param(struct lima_screen *screen, 2329f464c52Smaya enum pipe_shader_cap param) 2339f464c52Smaya{ 2349f464c52Smaya switch (param) { 2359f464c52Smaya case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 2369f464c52Smaya case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 2379f464c52Smaya case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 2389f464c52Smaya case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 2399f464c52Smaya return 16384; /* need investigate */ 2409f464c52Smaya 2419f464c52Smaya case PIPE_SHADER_CAP_MAX_INPUTS: 2429f464c52Smaya return LIMA_MAX_VARYING_NUM - 1; /* varying, minus gl_Position */ 2439f464c52Smaya 2447ec681f3Smrg case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 2457ec681f3Smrg return 1024; 2467ec681f3Smrg 2477ec681f3Smrg /* The Mali-PP supports a uniform table up to size 32768 total. 2487ec681f3Smrg * However, indirect access to an uniform only supports indices up 2497ec681f3Smrg * to 8192 (a 2048 vec4 array). To prevent indices bigger than that, 2507ec681f3Smrg * limit max const buffer size to 8192 for now. */ 2519f464c52Smaya case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: 2527ec681f3Smrg return 2048 * 4 * sizeof(float); 2537ec681f3Smrg 2549f464c52Smaya case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 2559f464c52Smaya return 1; 2569f464c52Smaya 2577ec681f3Smrg case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: 2589f464c52Smaya case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 2599f464c52Smaya return 16; /* need investigate */ 2609f464c52Smaya 2619f464c52Smaya case PIPE_SHADER_CAP_PREFERRED_IR: 2629f464c52Smaya return PIPE_SHADER_IR_NIR; 2639f464c52Smaya 2649f464c52Smaya case PIPE_SHADER_CAP_MAX_TEMPS: 2659f464c52Smaya return 256; /* need investigate */ 2669f464c52Smaya 2677ec681f3Smrg case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 2687ec681f3Smrg case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 2697ec681f3Smrg return 1; 2707ec681f3Smrg 2717ec681f3Smrg case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 2727ec681f3Smrg case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 2737ec681f3Smrg return 0; 2747ec681f3Smrg 2757ec681f3Smrg case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT: 2767ec681f3Smrg return 32; 2777ec681f3Smrg 2789f464c52Smaya default: 2799f464c52Smaya return 0; 2809f464c52Smaya } 2819f464c52Smaya} 2829f464c52Smaya 2839f464c52Smayastatic int 2849f464c52Smayalima_screen_get_shader_param(struct pipe_screen *pscreen, 2859f464c52Smaya enum pipe_shader_type shader, 2869f464c52Smaya enum pipe_shader_cap param) 2879f464c52Smaya{ 2889f464c52Smaya struct lima_screen *screen = lima_screen(pscreen); 2899f464c52Smaya 2909f464c52Smaya switch (shader) { 2919f464c52Smaya case PIPE_SHADER_FRAGMENT: 2929f464c52Smaya return get_fragment_shader_param(screen, param); 2939f464c52Smaya case PIPE_SHADER_VERTEX: 2949f464c52Smaya return get_vertex_shader_param(screen, param); 2959f464c52Smaya 2969f464c52Smaya default: 2979f464c52Smaya return 0; 2989f464c52Smaya } 2999f464c52Smaya} 3009f464c52Smaya 3017ec681f3Smrgstatic bool 3029f464c52Smayalima_screen_is_format_supported(struct pipe_screen *pscreen, 3039f464c52Smaya enum pipe_format format, 3049f464c52Smaya enum pipe_texture_target target, 3059f464c52Smaya unsigned sample_count, 3069f464c52Smaya unsigned storage_sample_count, 3079f464c52Smaya unsigned usage) 3089f464c52Smaya{ 3099f464c52Smaya switch (target) { 3109f464c52Smaya case PIPE_BUFFER: 3119f464c52Smaya case PIPE_TEXTURE_1D: 3129f464c52Smaya case PIPE_TEXTURE_2D: 3137ec681f3Smrg case PIPE_TEXTURE_RECT: 3147ec681f3Smrg case PIPE_TEXTURE_CUBE: 3159f464c52Smaya break; 3169f464c52Smaya default: 3177ec681f3Smrg return false; 3189f464c52Smaya } 3199f464c52Smaya 3209f464c52Smaya if (MAX2(1, sample_count) != MAX2(1, storage_sample_count)) 3219f464c52Smaya return false; 3229f464c52Smaya 3239f464c52Smaya /* be able to support 16, now limit to 4 */ 3249f464c52Smaya if (sample_count > 1 && sample_count != 4) 3257ec681f3Smrg return false; 3269f464c52Smaya 3279f464c52Smaya if (usage & PIPE_BIND_RENDER_TARGET) { 3287ec681f3Smrg if (!lima_format_pixel_supported(format)) 3297ec681f3Smrg return false; 3307ec681f3Smrg 3317ec681f3Smrg /* multisample unsupported with half float target */ 3327ec681f3Smrg if (sample_count > 1 && util_format_is_float(format)) 3337ec681f3Smrg return false; 3349f464c52Smaya } 3359f464c52Smaya 3369f464c52Smaya if (usage & PIPE_BIND_DEPTH_STENCIL) { 3379f464c52Smaya switch (format) { 3389f464c52Smaya case PIPE_FORMAT_Z16_UNORM: 3399f464c52Smaya case PIPE_FORMAT_Z24_UNORM_S8_UINT: 3409f464c52Smaya case PIPE_FORMAT_Z24X8_UNORM: 3419f464c52Smaya break; 3429f464c52Smaya default: 3437ec681f3Smrg return false; 3449f464c52Smaya } 3459f464c52Smaya } 3469f464c52Smaya 3479f464c52Smaya if (usage & PIPE_BIND_VERTEX_BUFFER) { 3489f464c52Smaya switch (format) { 3497ec681f3Smrg case PIPE_FORMAT_R32_FLOAT: 3507ec681f3Smrg case PIPE_FORMAT_R32G32_FLOAT: 3519f464c52Smaya case PIPE_FORMAT_R32G32B32_FLOAT: 3527ec681f3Smrg case PIPE_FORMAT_R32G32B32A32_FLOAT: 3537ec681f3Smrg case PIPE_FORMAT_R32_FIXED: 3547ec681f3Smrg case PIPE_FORMAT_R32G32_FIXED: 3557ec681f3Smrg case PIPE_FORMAT_R32G32B32_FIXED: 3567ec681f3Smrg case PIPE_FORMAT_R32G32B32A32_FIXED: 3577ec681f3Smrg case PIPE_FORMAT_R16_FLOAT: 3587ec681f3Smrg case PIPE_FORMAT_R16G16_FLOAT: 3597ec681f3Smrg case PIPE_FORMAT_R16G16B16_FLOAT: 3607ec681f3Smrg case PIPE_FORMAT_R16G16B16A16_FLOAT: 3617ec681f3Smrg case PIPE_FORMAT_R32_UNORM: 3627ec681f3Smrg case PIPE_FORMAT_R32G32_UNORM: 3637ec681f3Smrg case PIPE_FORMAT_R32G32B32_UNORM: 3647ec681f3Smrg case PIPE_FORMAT_R32G32B32A32_UNORM: 3657ec681f3Smrg case PIPE_FORMAT_R32_SNORM: 3667ec681f3Smrg case PIPE_FORMAT_R32G32_SNORM: 3677ec681f3Smrg case PIPE_FORMAT_R32G32B32_SNORM: 3687ec681f3Smrg case PIPE_FORMAT_R32G32B32A32_SNORM: 3697ec681f3Smrg case PIPE_FORMAT_R32_USCALED: 3707ec681f3Smrg case PIPE_FORMAT_R32G32_USCALED: 3717ec681f3Smrg case PIPE_FORMAT_R32G32B32_USCALED: 3727ec681f3Smrg case PIPE_FORMAT_R32G32B32A32_USCALED: 3737ec681f3Smrg case PIPE_FORMAT_R32_SSCALED: 3747ec681f3Smrg case PIPE_FORMAT_R32G32_SSCALED: 3757ec681f3Smrg case PIPE_FORMAT_R32G32B32_SSCALED: 3767ec681f3Smrg case PIPE_FORMAT_R32G32B32A32_SSCALED: 3777ec681f3Smrg case PIPE_FORMAT_R16_UNORM: 3787ec681f3Smrg case PIPE_FORMAT_R16G16_UNORM: 3797ec681f3Smrg case PIPE_FORMAT_R16G16B16_UNORM: 3807ec681f3Smrg case PIPE_FORMAT_R16G16B16A16_UNORM: 3817ec681f3Smrg case PIPE_FORMAT_R16_SNORM: 3827ec681f3Smrg case PIPE_FORMAT_R16G16_SNORM: 3837ec681f3Smrg case PIPE_FORMAT_R16G16B16_SNORM: 3847ec681f3Smrg case PIPE_FORMAT_R16G16B16A16_SNORM: 3857ec681f3Smrg case PIPE_FORMAT_R16_USCALED: 3867ec681f3Smrg case PIPE_FORMAT_R16G16_USCALED: 3877ec681f3Smrg case PIPE_FORMAT_R16G16B16_USCALED: 3887ec681f3Smrg case PIPE_FORMAT_R16G16B16A16_USCALED: 3897ec681f3Smrg case PIPE_FORMAT_R16_SSCALED: 3907ec681f3Smrg case PIPE_FORMAT_R16G16_SSCALED: 3917ec681f3Smrg case PIPE_FORMAT_R16G16B16_SSCALED: 3927ec681f3Smrg case PIPE_FORMAT_R16G16B16A16_SSCALED: 3937ec681f3Smrg case PIPE_FORMAT_R8_UNORM: 3947ec681f3Smrg case PIPE_FORMAT_R8G8_UNORM: 3957ec681f3Smrg case PIPE_FORMAT_R8G8B8_UNORM: 3967ec681f3Smrg case PIPE_FORMAT_R8G8B8A8_UNORM: 3977ec681f3Smrg case PIPE_FORMAT_R8_SNORM: 3987ec681f3Smrg case PIPE_FORMAT_R8G8_SNORM: 3997ec681f3Smrg case PIPE_FORMAT_R8G8B8_SNORM: 4007ec681f3Smrg case PIPE_FORMAT_R8G8B8A8_SNORM: 4017ec681f3Smrg case PIPE_FORMAT_R8_USCALED: 4027ec681f3Smrg case PIPE_FORMAT_R8G8_USCALED: 4037ec681f3Smrg case PIPE_FORMAT_R8G8B8_USCALED: 4047ec681f3Smrg case PIPE_FORMAT_R8G8B8A8_USCALED: 4057ec681f3Smrg case PIPE_FORMAT_R8_SSCALED: 4067ec681f3Smrg case PIPE_FORMAT_R8G8_SSCALED: 4077ec681f3Smrg case PIPE_FORMAT_R8G8B8_SSCALED: 4087ec681f3Smrg case PIPE_FORMAT_R8G8B8A8_SSCALED: 4099f464c52Smaya break; 4109f464c52Smaya default: 4117ec681f3Smrg return false; 4129f464c52Smaya } 4139f464c52Smaya } 4149f464c52Smaya 4159f464c52Smaya if (usage & PIPE_BIND_INDEX_BUFFER) { 4169f464c52Smaya switch (format) { 4177ec681f3Smrg case PIPE_FORMAT_R8_UINT: 4187ec681f3Smrg case PIPE_FORMAT_R16_UINT: 4197ec681f3Smrg case PIPE_FORMAT_R32_UINT: 4209f464c52Smaya break; 4219f464c52Smaya default: 4227ec681f3Smrg return false; 4239f464c52Smaya } 4249f464c52Smaya } 4259f464c52Smaya 4267ec681f3Smrg if (usage & PIPE_BIND_SAMPLER_VIEW) 4277ec681f3Smrg return lima_format_texel_supported(format); 4289f464c52Smaya 4297ec681f3Smrg return true; 4309f464c52Smaya} 4319f464c52Smaya 4329f464c52Smayastatic const void * 4339f464c52Smayalima_screen_get_compiler_options(struct pipe_screen *pscreen, 4349f464c52Smaya enum pipe_shader_ir ir, 4359f464c52Smaya enum pipe_shader_type shader) 4369f464c52Smaya{ 4379f464c52Smaya return lima_program_get_compiler_options(shader); 4389f464c52Smaya} 4399f464c52Smaya 4407ec681f3Smrgstatic bool 4417ec681f3Smrglima_screen_set_plb_max_blk(struct lima_screen *screen) 4427ec681f3Smrg{ 4437ec681f3Smrg if (lima_plb_max_blk) { 4447ec681f3Smrg screen->plb_max_blk = lima_plb_max_blk; 4457ec681f3Smrg return true; 4467ec681f3Smrg } 4477ec681f3Smrg 4487ec681f3Smrg if (screen->gpu_type == DRM_LIMA_PARAM_GPU_ID_MALI450) 4497ec681f3Smrg screen->plb_max_blk = 4096; 4507ec681f3Smrg else 4517ec681f3Smrg screen->plb_max_blk = 512; 4527ec681f3Smrg 4537ec681f3Smrg drmDevicePtr devinfo; 4547ec681f3Smrg 4557ec681f3Smrg if (drmGetDevice2(screen->fd, 0, &devinfo)) 4567ec681f3Smrg return false; 4577ec681f3Smrg 4587ec681f3Smrg if (devinfo->bustype == DRM_BUS_PLATFORM && devinfo->deviceinfo.platform) { 4597ec681f3Smrg char **compatible = devinfo->deviceinfo.platform->compatible; 4607ec681f3Smrg 4617ec681f3Smrg if (compatible && *compatible) 4627ec681f3Smrg if (!strcmp("allwinner,sun50i-h5-mali", *compatible)) 4637ec681f3Smrg screen->plb_max_blk = 2048; 4647ec681f3Smrg } 4657ec681f3Smrg 4667ec681f3Smrg drmFreeDevice(&devinfo); 4677ec681f3Smrg 4687ec681f3Smrg return true; 4697ec681f3Smrg} 4707ec681f3Smrg 4719f464c52Smayastatic bool 4729f464c52Smayalima_screen_query_info(struct lima_screen *screen) 4739f464c52Smaya{ 4747ec681f3Smrg drmVersionPtr version = drmGetVersion(screen->fd); 4757ec681f3Smrg if (!version) 4767ec681f3Smrg return false; 4777ec681f3Smrg 4787ec681f3Smrg if (version->version_major > 1 || version->version_minor > 0) 4797ec681f3Smrg screen->has_growable_heap_buffer = true; 4807ec681f3Smrg 4817ec681f3Smrg drmFreeVersion(version); 4827ec681f3Smrg 4837ec681f3Smrg if (lima_debug & LIMA_DEBUG_NO_GROW_HEAP) 4847ec681f3Smrg screen->has_growable_heap_buffer = false; 4857ec681f3Smrg 4869f464c52Smaya struct drm_lima_get_param param; 4879f464c52Smaya 4889f464c52Smaya memset(¶m, 0, sizeof(param)); 4899f464c52Smaya param.param = DRM_LIMA_PARAM_GPU_ID; 4909f464c52Smaya if (drmIoctl(screen->fd, DRM_IOCTL_LIMA_GET_PARAM, ¶m)) 4919f464c52Smaya return false; 4929f464c52Smaya 4939f464c52Smaya switch (param.value) { 4949f464c52Smaya case DRM_LIMA_PARAM_GPU_ID_MALI400: 4959f464c52Smaya case DRM_LIMA_PARAM_GPU_ID_MALI450: 4969f464c52Smaya screen->gpu_type = param.value; 4979f464c52Smaya break; 4989f464c52Smaya default: 4999f464c52Smaya return false; 5009f464c52Smaya } 5019f464c52Smaya 5029f464c52Smaya memset(¶m, 0, sizeof(param)); 5039f464c52Smaya param.param = DRM_LIMA_PARAM_NUM_PP; 5049f464c52Smaya if (drmIoctl(screen->fd, DRM_IOCTL_LIMA_GET_PARAM, ¶m)) 5059f464c52Smaya return false; 5069f464c52Smaya 5079f464c52Smaya screen->num_pp = param.value; 5089f464c52Smaya 5097ec681f3Smrg lima_screen_set_plb_max_blk(screen); 5107ec681f3Smrg 5119f464c52Smaya return true; 5129f464c52Smaya} 5139f464c52Smaya 5147ec681f3Smrgstatic const uint64_t lima_available_modifiers[] = { 5157ec681f3Smrg DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, 5167ec681f3Smrg DRM_FORMAT_MOD_LINEAR, 5177ec681f3Smrg}; 5187ec681f3Smrg 5197ec681f3Smrgstatic bool lima_is_modifier_external_only(enum pipe_format format) 5207ec681f3Smrg{ 5217ec681f3Smrg return util_format_is_yuv(format); 5227ec681f3Smrg} 5237ec681f3Smrg 5249f464c52Smayastatic void 5259f464c52Smayalima_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen, 5269f464c52Smaya enum pipe_format format, int max, 5279f464c52Smaya uint64_t *modifiers, 5289f464c52Smaya unsigned int *external_only, 5299f464c52Smaya int *count) 5309f464c52Smaya{ 5317ec681f3Smrg int num_modifiers = ARRAY_SIZE(lima_available_modifiers); 5329f464c52Smaya 5339f464c52Smaya if (!modifiers) { 5347ec681f3Smrg *count = num_modifiers; 5359f464c52Smaya return; 5369f464c52Smaya } 5379f464c52Smaya 5387ec681f3Smrg *count = MIN2(max, num_modifiers); 5399f464c52Smaya for (int i = 0; i < *count; i++) { 5407ec681f3Smrg modifiers[i] = lima_available_modifiers[i]; 5419f464c52Smaya if (external_only) 5427ec681f3Smrg external_only[i] = lima_is_modifier_external_only(format); 5439f464c52Smaya } 5449f464c52Smaya} 5459f464c52Smaya 5467ec681f3Smrgstatic bool 5477ec681f3Smrglima_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen, 5487ec681f3Smrg uint64_t modifier, 5497ec681f3Smrg enum pipe_format format, 5507ec681f3Smrg bool *external_only) 5517ec681f3Smrg{ 5527ec681f3Smrg for (int i = 0; i < ARRAY_SIZE(lima_available_modifiers); i++) { 5537ec681f3Smrg if (lima_available_modifiers[i] == modifier) { 5547ec681f3Smrg if (external_only) 5557ec681f3Smrg *external_only = lima_is_modifier_external_only(format); 5567ec681f3Smrg 5577ec681f3Smrg return true; 5587ec681f3Smrg } 5597ec681f3Smrg } 5607ec681f3Smrg 5617ec681f3Smrg return false; 5627ec681f3Smrg} 5637ec681f3Smrg 5647ec681f3Smrgstatic const struct debug_named_value lima_debug_options[] = { 5659f464c52Smaya { "gp", LIMA_DEBUG_GP, 5669f464c52Smaya "print GP shader compiler result of each stage" }, 5679f464c52Smaya { "pp", LIMA_DEBUG_PP, 5689f464c52Smaya "print PP shader compiler result of each stage" }, 5699f464c52Smaya { "dump", LIMA_DEBUG_DUMP, 5709f464c52Smaya "dump GPU command stream to $PWD/lima.dump" }, 5717ec681f3Smrg { "shaderdb", LIMA_DEBUG_SHADERDB, 5727ec681f3Smrg "print shader information for shaderdb" }, 5737ec681f3Smrg { "nobocache", LIMA_DEBUG_NO_BO_CACHE, 5747ec681f3Smrg "disable BO cache" }, 5757ec681f3Smrg { "bocache", LIMA_DEBUG_BO_CACHE, 5767ec681f3Smrg "print debug info for BO cache" }, 5777ec681f3Smrg { "notiling", LIMA_DEBUG_NO_TILING, 5787ec681f3Smrg "don't use tiled buffers" }, 5797ec681f3Smrg { "nogrowheap", LIMA_DEBUG_NO_GROW_HEAP, 5807ec681f3Smrg "disable growable heap buffer" }, 5817ec681f3Smrg { "singlejob", LIMA_DEBUG_SINGLE_JOB, 5827ec681f3Smrg "disable multi job optimization" }, 5837ec681f3Smrg { "precompile", LIMA_DEBUG_PRECOMPILE, 5847ec681f3Smrg "Precompile shaders for shader-db" }, 5857ec681f3Smrg { "diskcache", LIMA_DEBUG_DISK_CACHE, 5867ec681f3Smrg "print debug info for shader disk cache" }, 5879f464c52Smaya { NULL } 5889f464c52Smaya}; 5899f464c52Smaya 5907ec681f3SmrgDEBUG_GET_ONCE_FLAGS_OPTION(lima_debug, "LIMA_DEBUG", lima_debug_options, 0) 5919f464c52Smayauint32_t lima_debug; 5929f464c52Smaya 5939f464c52Smayastatic void 5949f464c52Smayalima_screen_parse_env(void) 5959f464c52Smaya{ 5969f464c52Smaya lima_debug = debug_get_option_lima_debug(); 5979f464c52Smaya 5989f464c52Smaya lima_ctx_num_plb = debug_get_num_option("LIMA_CTX_NUM_PLB", LIMA_CTX_PLB_DEF_NUM); 5999f464c52Smaya if (lima_ctx_num_plb > LIMA_CTX_PLB_MAX_NUM || 6009f464c52Smaya lima_ctx_num_plb < LIMA_CTX_PLB_MIN_NUM) { 6019f464c52Smaya fprintf(stderr, "lima: LIMA_CTX_NUM_PLB %d out of range [%d %d], " 6029f464c52Smaya "reset to default %d\n", lima_ctx_num_plb, LIMA_CTX_PLB_MIN_NUM, 6039f464c52Smaya LIMA_CTX_PLB_MAX_NUM, LIMA_CTX_PLB_DEF_NUM); 6049f464c52Smaya lima_ctx_num_plb = LIMA_CTX_PLB_DEF_NUM; 6059f464c52Smaya } 6069f464c52Smaya 6077ec681f3Smrg lima_plb_max_blk = debug_get_num_option("LIMA_PLB_MAX_BLK", 0); 6087ec681f3Smrg if (lima_plb_max_blk < 0 || lima_plb_max_blk > 65536) { 6097ec681f3Smrg fprintf(stderr, "lima: LIMA_PLB_MAX_BLK %d out of range [%d %d], " 6107ec681f3Smrg "reset to default %d\n", lima_plb_max_blk, 0, 65536, 0); 6117ec681f3Smrg lima_plb_max_blk = 0; 6127ec681f3Smrg } 6137ec681f3Smrg 6149f464c52Smaya lima_ppir_force_spilling = debug_get_num_option("LIMA_PPIR_FORCE_SPILLING", 0); 6159f464c52Smaya if (lima_ppir_force_spilling < 0) { 6169f464c52Smaya fprintf(stderr, "lima: LIMA_PPIR_FORCE_SPILLING %d less than 0, " 6179f464c52Smaya "reset to default 0\n", lima_ppir_force_spilling); 6189f464c52Smaya lima_ppir_force_spilling = 0; 6199f464c52Smaya } 6207ec681f3Smrg 6217ec681f3Smrg lima_plb_pp_stream_cache_size = debug_get_num_option("LIMA_PLB_PP_STREAM_CACHE_SIZE", 0); 6227ec681f3Smrg if (lima_plb_pp_stream_cache_size < 0) { 6237ec681f3Smrg fprintf(stderr, "lima: LIMA_PLB_PP_STREAM_CACHE_SIZE %d less than 0, " 6247ec681f3Smrg "reset to default 0\n", lima_plb_pp_stream_cache_size); 6257ec681f3Smrg lima_plb_pp_stream_cache_size = 0; 6267ec681f3Smrg } 6277ec681f3Smrg} 6287ec681f3Smrg 6297ec681f3Smrgstatic struct disk_cache * 6307ec681f3Smrglima_get_disk_shader_cache (struct pipe_screen *pscreen) 6317ec681f3Smrg{ 6327ec681f3Smrg struct lima_screen *screen = lima_screen(pscreen); 6337ec681f3Smrg 6347ec681f3Smrg return screen->disk_cache; 6359f464c52Smaya} 6369f464c52Smaya 6379f464c52Smayastruct pipe_screen * 6389f464c52Smayalima_screen_create(int fd, struct renderonly *ro) 6399f464c52Smaya{ 6407ec681f3Smrg uint64_t system_memory; 6419f464c52Smaya struct lima_screen *screen; 6429f464c52Smaya 6439f464c52Smaya screen = rzalloc(NULL, struct lima_screen); 6449f464c52Smaya if (!screen) 6459f464c52Smaya return NULL; 6469f464c52Smaya 6479f464c52Smaya screen->fd = fd; 6487ec681f3Smrg screen->ro = ro; 6497ec681f3Smrg 6507ec681f3Smrg lima_screen_parse_env(); 6517ec681f3Smrg 6527ec681f3Smrg /* Limit PP PLB stream cache size to 0.1% of system memory */ 6537ec681f3Smrg if (!lima_plb_pp_stream_cache_size && 6547ec681f3Smrg os_get_total_physical_memory(&system_memory)) 6557ec681f3Smrg lima_plb_pp_stream_cache_size = system_memory >> 10; 6567ec681f3Smrg 6577ec681f3Smrg /* Set lower limit on PP PLB cache size */ 6587ec681f3Smrg lima_plb_pp_stream_cache_size = MAX2(128 * 1024 * lima_ctx_num_plb, 6597ec681f3Smrg lima_plb_pp_stream_cache_size); 6609f464c52Smaya 6619f464c52Smaya if (!lima_screen_query_info(screen)) 6629f464c52Smaya goto err_out0; 6639f464c52Smaya 6647ec681f3Smrg if (!lima_bo_cache_init(screen)) 6659f464c52Smaya goto err_out0; 6669f464c52Smaya 6677ec681f3Smrg if (!lima_bo_table_init(screen)) 6687ec681f3Smrg goto err_out1; 6697ec681f3Smrg 6709f464c52Smaya screen->pp_ra = ppir_regalloc_init(screen); 6719f464c52Smaya if (!screen->pp_ra) 6727ec681f3Smrg goto err_out2; 6739f464c52Smaya 6749f464c52Smaya screen->pp_buffer = lima_bo_create(screen, pp_buffer_size, 0); 6759f464c52Smaya if (!screen->pp_buffer) 6767ec681f3Smrg goto err_out2; 6777ec681f3Smrg screen->pp_buffer->cacheable = false; 6789f464c52Smaya 6799f464c52Smaya /* fs program for clear buffer? 6809f464c52Smaya * const0 1 0 0 -1.67773, mov.v0 $0 ^const0.xxxx, stop 6819f464c52Smaya */ 6829f464c52Smaya static const uint32_t pp_clear_program[] = { 6839f464c52Smaya 0x00020425, 0x0000000c, 0x01e007cf, 0xb0000000, 6849f464c52Smaya 0x000005f5, 0x00000000, 0x00000000, 0x00000000, 6859f464c52Smaya }; 6869f464c52Smaya memcpy(lima_bo_map(screen->pp_buffer) + pp_clear_program_offset, 6879f464c52Smaya pp_clear_program, sizeof(pp_clear_program)); 6889f464c52Smaya 6899f464c52Smaya /* copy texture to framebuffer, used to reload gpu tile buffer 6909f464c52Smaya * load.v $1 0.xy, texld_2d 0, mov.v0 $0 ^tex_sampler, sync, stop 6919f464c52Smaya */ 6929f464c52Smaya static const uint32_t pp_reload_program[] = { 6939f464c52Smaya 0x000005e6, 0xf1003c20, 0x00000000, 0x39001000, 6949f464c52Smaya 0x00000e4e, 0x000007cf, 0x00000000, 0x00000000, 6959f464c52Smaya }; 6969f464c52Smaya memcpy(lima_bo_map(screen->pp_buffer) + pp_reload_program_offset, 6979f464c52Smaya pp_reload_program, sizeof(pp_reload_program)); 6989f464c52Smaya 6999f464c52Smaya /* 0/1/2 vertex index for reload/clear draw */ 7009f464c52Smaya static const uint8_t pp_shared_index[] = { 0, 1, 2 }; 7019f464c52Smaya memcpy(lima_bo_map(screen->pp_buffer) + pp_shared_index_offset, 7029f464c52Smaya pp_shared_index, sizeof(pp_shared_index)); 7039f464c52Smaya 7049f464c52Smaya /* 4096x4096 gl pos used for partial clear */ 7059f464c52Smaya static const float pp_clear_gl_pos[] = { 7069f464c52Smaya 4096, 0, 1, 1, 7079f464c52Smaya 0, 0, 1, 1, 7089f464c52Smaya 0, 4096, 1, 1, 7099f464c52Smaya }; 7109f464c52Smaya memcpy(lima_bo_map(screen->pp_buffer) + pp_clear_gl_pos_offset, 7119f464c52Smaya pp_clear_gl_pos, sizeof(pp_clear_gl_pos)); 7129f464c52Smaya 7139f464c52Smaya /* is pp frame render state static? */ 7149f464c52Smaya uint32_t *pp_frame_rsw = lima_bo_map(screen->pp_buffer) + pp_frame_rsw_offset; 7159f464c52Smaya memset(pp_frame_rsw, 0, 0x40); 7169f464c52Smaya pp_frame_rsw[8] = 0x0000f008; 7179f464c52Smaya pp_frame_rsw[9] = screen->pp_buffer->va + pp_clear_program_offset; 7189f464c52Smaya pp_frame_rsw[13] = 0x00000100; 7199f464c52Smaya 7209f464c52Smaya screen->base.destroy = lima_screen_destroy; 7219f464c52Smaya screen->base.get_name = lima_screen_get_name; 7229f464c52Smaya screen->base.get_vendor = lima_screen_get_vendor; 7239f464c52Smaya screen->base.get_device_vendor = lima_screen_get_device_vendor; 7249f464c52Smaya screen->base.get_param = lima_screen_get_param; 7259f464c52Smaya screen->base.get_paramf = lima_screen_get_paramf; 7269f464c52Smaya screen->base.get_shader_param = lima_screen_get_shader_param; 7279f464c52Smaya screen->base.context_create = lima_context_create; 7289f464c52Smaya screen->base.is_format_supported = lima_screen_is_format_supported; 7299f464c52Smaya screen->base.get_compiler_options = lima_screen_get_compiler_options; 7309f464c52Smaya screen->base.query_dmabuf_modifiers = lima_screen_query_dmabuf_modifiers; 7317ec681f3Smrg screen->base.is_dmabuf_modifier_supported = lima_screen_is_dmabuf_modifier_supported; 7327ec681f3Smrg screen->base.get_disk_shader_cache = lima_get_disk_shader_cache; 7339f464c52Smaya 7349f464c52Smaya lima_resource_screen_init(screen); 7359f464c52Smaya lima_fence_screen_init(screen); 7367ec681f3Smrg lima_disk_cache_init(screen); 7379f464c52Smaya 7389f464c52Smaya slab_create_parent(&screen->transfer_pool, sizeof(struct lima_transfer), 16); 7399f464c52Smaya 7409f464c52Smaya screen->refcnt = 1; 7419f464c52Smaya 7429f464c52Smaya return &screen->base; 7439f464c52Smaya 7449f464c52Smayaerr_out2: 7459f464c52Smaya lima_bo_table_fini(screen); 7467ec681f3Smrgerr_out1: 7477ec681f3Smrg lima_bo_cache_fini(screen); 7489f464c52Smayaerr_out0: 7499f464c52Smaya ralloc_free(screen); 7509f464c52Smaya return NULL; 7519f464c52Smaya} 752