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(&param, 0, sizeof(param));
4899f464c52Smaya   param.param = DRM_LIMA_PARAM_GPU_ID;
4909f464c52Smaya   if (drmIoctl(screen->fd, DRM_IOCTL_LIMA_GET_PARAM, &param))
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(&param, 0, sizeof(param));
5039f464c52Smaya   param.param = DRM_LIMA_PARAM_NUM_PP;
5049f464c52Smaya   if (drmIoctl(screen->fd, DRM_IOCTL_LIMA_GET_PARAM, &param))
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