1/*
2 * Copyright (c) 2017-2019 Lima Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 */
24
25#include <string.h>
26
27#include "util/ralloc.h"
28#include "util/u_debug.h"
29#include "util/u_screen.h"
30#include "renderonly/renderonly.h"
31
32#include "drm-uapi/drm_fourcc.h"
33#include "drm-uapi/lima_drm.h"
34
35#include "lima_screen.h"
36#include "lima_context.h"
37#include "lima_resource.h"
38#include "lima_program.h"
39#include "lima_bo.h"
40#include "lima_fence.h"
41#include "lima_format.h"
42#include "lima_disk_cache.h"
43#include "ir/lima_ir.h"
44
45#include "xf86drm.h"
46
47int lima_plb_max_blk = 0;
48int lima_plb_pp_stream_cache_size = 0;
49
50static void
51lima_screen_destroy(struct pipe_screen *pscreen)
52{
53   struct lima_screen *screen = lima_screen(pscreen);
54
55   slab_destroy_parent(&screen->transfer_pool);
56
57   if (screen->ro)
58      screen->ro->destroy(screen->ro);
59
60   if (screen->pp_buffer)
61      lima_bo_unreference(screen->pp_buffer);
62
63   lima_bo_cache_fini(screen);
64   lima_bo_table_fini(screen);
65   disk_cache_destroy(screen->disk_cache);
66   ralloc_free(screen);
67}
68
69static const char *
70lima_screen_get_name(struct pipe_screen *pscreen)
71{
72   struct lima_screen *screen = lima_screen(pscreen);
73
74   switch (screen->gpu_type) {
75   case DRM_LIMA_PARAM_GPU_ID_MALI400:
76     return "Mali400";
77   case DRM_LIMA_PARAM_GPU_ID_MALI450:
78     return "Mali450";
79   }
80
81   return NULL;
82}
83
84static const char *
85lima_screen_get_vendor(struct pipe_screen *pscreen)
86{
87   return "lima";
88}
89
90static const char *
91lima_screen_get_device_vendor(struct pipe_screen *pscreen)
92{
93   return "ARM";
94}
95
96static int
97lima_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
98{
99   switch (param) {
100   case PIPE_CAP_NPOT_TEXTURES:
101   case PIPE_CAP_BLEND_EQUATION_SEPARATE:
102   case PIPE_CAP_ACCELERATED:
103   case PIPE_CAP_UMA:
104   case PIPE_CAP_CLIP_HALFZ:
105   case PIPE_CAP_NATIVE_FENCE_FD:
106   case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
107   case PIPE_CAP_TEXTURE_SWIZZLE:
108   case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
109      return 1;
110
111   /* Unimplemented, but for exporting OpenGL 2.0 */
112   case PIPE_CAP_OCCLUSION_QUERY:
113   case PIPE_CAP_POINT_SPRITE:
114      return 1;
115
116   /* not clear supported */
117   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
118   case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
119   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
120   case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
121      return 1;
122
123   case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL:
124   case PIPE_CAP_TGSI_FS_POINT_IS_SYSVAL:
125   case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
126      return 1;
127
128   case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
129      return 1;
130
131   case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
132      return 1 << (LIMA_MAX_MIP_LEVELS - 1);
133   case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
134   case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
135      return LIMA_MAX_MIP_LEVELS;
136
137   case PIPE_CAP_VENDOR_ID:
138      return 0x13B5;
139
140   case PIPE_CAP_VIDEO_MEMORY:
141      return 0;
142
143   case PIPE_CAP_PCI_GROUP:
144   case PIPE_CAP_PCI_BUS:
145   case PIPE_CAP_PCI_DEVICE:
146   case PIPE_CAP_PCI_FUNCTION:
147      return 0;
148
149   case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
150   case PIPE_CAP_SHAREABLE_SHADERS:
151      return 0;
152
153   case PIPE_CAP_ALPHA_TEST:
154      return 1;
155
156   case PIPE_CAP_FLATSHADE:
157   case PIPE_CAP_TWO_SIDED_COLOR:
158   case PIPE_CAP_CLIP_PLANES:
159      return 0;
160
161   case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
162      return 1;
163
164   default:
165      return u_pipe_screen_get_param_defaults(pscreen, param);
166   }
167}
168
169static float
170lima_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
171{
172   switch (param) {
173   case PIPE_CAPF_MAX_LINE_WIDTH:
174   case PIPE_CAPF_MAX_LINE_WIDTH_AA:
175   case PIPE_CAPF_MAX_POINT_WIDTH:
176   case PIPE_CAPF_MAX_POINT_WIDTH_AA:
177      return 100.0f;
178   case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
179      return 16.0f;
180   case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
181      return 15.0f;
182
183   default:
184      return 0.0f;
185   }
186}
187
188static int
189get_vertex_shader_param(struct lima_screen *screen,
190                        enum pipe_shader_cap param)
191{
192   switch (param) {
193   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
194   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
195   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
196   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
197      return 16384; /* need investigate */
198
199   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
200      return 1024;
201
202   case PIPE_SHADER_CAP_MAX_INPUTS:
203      return 16; /* attributes */
204
205   case PIPE_SHADER_CAP_MAX_OUTPUTS:
206      return LIMA_MAX_VARYING_NUM; /* varying */
207
208   /* Mali-400 GP provides space for 304 vec4 uniforms, globals and
209    * temporary variables. */
210   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
211      return 304 * 4 * sizeof(float);
212
213   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
214      return 1;
215
216   case PIPE_SHADER_CAP_PREFERRED_IR:
217      return PIPE_SHADER_IR_NIR;
218
219   case PIPE_SHADER_CAP_MAX_TEMPS:
220      return 256; /* need investigate */
221
222   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
223      return 32;
224
225   default:
226      return 0;
227   }
228}
229
230static int
231get_fragment_shader_param(struct lima_screen *screen,
232                          enum pipe_shader_cap param)
233{
234   switch (param) {
235   case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
236   case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
237   case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
238   case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
239      return 16384; /* need investigate */
240
241   case PIPE_SHADER_CAP_MAX_INPUTS:
242      return LIMA_MAX_VARYING_NUM - 1; /* varying, minus gl_Position */
243
244   case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
245      return 1024;
246
247   /* The Mali-PP supports a uniform table up to size 32768 total.
248    * However, indirect access to an uniform only supports indices up
249    * to 8192 (a 2048 vec4 array). To prevent indices bigger than that,
250    * limit max const buffer size to 8192 for now. */
251   case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
252      return 2048 * 4 * sizeof(float);
253
254   case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
255      return 1;
256
257   case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
258   case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
259      return 16; /* need investigate */
260
261   case PIPE_SHADER_CAP_PREFERRED_IR:
262      return PIPE_SHADER_IR_NIR;
263
264   case PIPE_SHADER_CAP_MAX_TEMPS:
265      return 256; /* need investigate */
266
267   case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
268   case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
269      return 1;
270
271   case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
272   case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
273      return 0;
274
275   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
276      return 32;
277
278   default:
279      return 0;
280   }
281}
282
283static int
284lima_screen_get_shader_param(struct pipe_screen *pscreen,
285                             enum pipe_shader_type shader,
286                             enum pipe_shader_cap param)
287{
288   struct lima_screen *screen = lima_screen(pscreen);
289
290   switch (shader) {
291   case PIPE_SHADER_FRAGMENT:
292      return get_fragment_shader_param(screen, param);
293   case PIPE_SHADER_VERTEX:
294      return get_vertex_shader_param(screen, param);
295
296   default:
297      return 0;
298   }
299}
300
301static bool
302lima_screen_is_format_supported(struct pipe_screen *pscreen,
303                                enum pipe_format format,
304                                enum pipe_texture_target target,
305                                unsigned sample_count,
306                                unsigned storage_sample_count,
307                                unsigned usage)
308{
309   switch (target) {
310   case PIPE_BUFFER:
311   case PIPE_TEXTURE_1D:
312   case PIPE_TEXTURE_2D:
313   case PIPE_TEXTURE_RECT:
314   case PIPE_TEXTURE_CUBE:
315      break;
316   default:
317      return false;
318   }
319
320   if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
321      return false;
322
323   /* be able to support 16, now limit to 4 */
324   if (sample_count > 1 && sample_count != 4)
325      return false;
326
327   if (usage & PIPE_BIND_RENDER_TARGET) {
328      if (!lima_format_pixel_supported(format))
329         return false;
330
331      /* multisample unsupported with half float target */
332      if (sample_count > 1 && util_format_is_float(format))
333         return false;
334   }
335
336   if (usage & PIPE_BIND_DEPTH_STENCIL) {
337      switch (format) {
338      case PIPE_FORMAT_Z16_UNORM:
339      case PIPE_FORMAT_Z24_UNORM_S8_UINT:
340      case PIPE_FORMAT_Z24X8_UNORM:
341         break;
342      default:
343         return false;
344      }
345   }
346
347   if (usage & PIPE_BIND_VERTEX_BUFFER) {
348      switch (format) {
349      case PIPE_FORMAT_R32_FLOAT:
350      case PIPE_FORMAT_R32G32_FLOAT:
351      case PIPE_FORMAT_R32G32B32_FLOAT:
352      case PIPE_FORMAT_R32G32B32A32_FLOAT:
353      case PIPE_FORMAT_R32_FIXED:
354      case PIPE_FORMAT_R32G32_FIXED:
355      case PIPE_FORMAT_R32G32B32_FIXED:
356      case PIPE_FORMAT_R32G32B32A32_FIXED:
357      case PIPE_FORMAT_R16_FLOAT:
358      case PIPE_FORMAT_R16G16_FLOAT:
359      case PIPE_FORMAT_R16G16B16_FLOAT:
360      case PIPE_FORMAT_R16G16B16A16_FLOAT:
361      case PIPE_FORMAT_R32_UNORM:
362      case PIPE_FORMAT_R32G32_UNORM:
363      case PIPE_FORMAT_R32G32B32_UNORM:
364      case PIPE_FORMAT_R32G32B32A32_UNORM:
365      case PIPE_FORMAT_R32_SNORM:
366      case PIPE_FORMAT_R32G32_SNORM:
367      case PIPE_FORMAT_R32G32B32_SNORM:
368      case PIPE_FORMAT_R32G32B32A32_SNORM:
369      case PIPE_FORMAT_R32_USCALED:
370      case PIPE_FORMAT_R32G32_USCALED:
371      case PIPE_FORMAT_R32G32B32_USCALED:
372      case PIPE_FORMAT_R32G32B32A32_USCALED:
373      case PIPE_FORMAT_R32_SSCALED:
374      case PIPE_FORMAT_R32G32_SSCALED:
375      case PIPE_FORMAT_R32G32B32_SSCALED:
376      case PIPE_FORMAT_R32G32B32A32_SSCALED:
377      case PIPE_FORMAT_R16_UNORM:
378      case PIPE_FORMAT_R16G16_UNORM:
379      case PIPE_FORMAT_R16G16B16_UNORM:
380      case PIPE_FORMAT_R16G16B16A16_UNORM:
381      case PIPE_FORMAT_R16_SNORM:
382      case PIPE_FORMAT_R16G16_SNORM:
383      case PIPE_FORMAT_R16G16B16_SNORM:
384      case PIPE_FORMAT_R16G16B16A16_SNORM:
385      case PIPE_FORMAT_R16_USCALED:
386      case PIPE_FORMAT_R16G16_USCALED:
387      case PIPE_FORMAT_R16G16B16_USCALED:
388      case PIPE_FORMAT_R16G16B16A16_USCALED:
389      case PIPE_FORMAT_R16_SSCALED:
390      case PIPE_FORMAT_R16G16_SSCALED:
391      case PIPE_FORMAT_R16G16B16_SSCALED:
392      case PIPE_FORMAT_R16G16B16A16_SSCALED:
393      case PIPE_FORMAT_R8_UNORM:
394      case PIPE_FORMAT_R8G8_UNORM:
395      case PIPE_FORMAT_R8G8B8_UNORM:
396      case PIPE_FORMAT_R8G8B8A8_UNORM:
397      case PIPE_FORMAT_R8_SNORM:
398      case PIPE_FORMAT_R8G8_SNORM:
399      case PIPE_FORMAT_R8G8B8_SNORM:
400      case PIPE_FORMAT_R8G8B8A8_SNORM:
401      case PIPE_FORMAT_R8_USCALED:
402      case PIPE_FORMAT_R8G8_USCALED:
403      case PIPE_FORMAT_R8G8B8_USCALED:
404      case PIPE_FORMAT_R8G8B8A8_USCALED:
405      case PIPE_FORMAT_R8_SSCALED:
406      case PIPE_FORMAT_R8G8_SSCALED:
407      case PIPE_FORMAT_R8G8B8_SSCALED:
408      case PIPE_FORMAT_R8G8B8A8_SSCALED:
409         break;
410      default:
411         return false;
412      }
413   }
414
415   if (usage & PIPE_BIND_INDEX_BUFFER) {
416      switch (format) {
417      case PIPE_FORMAT_R8_UINT:
418      case PIPE_FORMAT_R16_UINT:
419      case PIPE_FORMAT_R32_UINT:
420         break;
421      default:
422         return false;
423      }
424   }
425
426   if (usage & PIPE_BIND_SAMPLER_VIEW)
427      return lima_format_texel_supported(format);
428
429   return true;
430}
431
432static const void *
433lima_screen_get_compiler_options(struct pipe_screen *pscreen,
434                                 enum pipe_shader_ir ir,
435                                 enum pipe_shader_type shader)
436{
437   return lima_program_get_compiler_options(shader);
438}
439
440static bool
441lima_screen_set_plb_max_blk(struct lima_screen *screen)
442{
443   if (lima_plb_max_blk) {
444      screen->plb_max_blk = lima_plb_max_blk;
445      return true;
446   }
447
448   if (screen->gpu_type == DRM_LIMA_PARAM_GPU_ID_MALI450)
449      screen->plb_max_blk = 4096;
450   else
451      screen->plb_max_blk = 512;
452
453   drmDevicePtr devinfo;
454
455   if (drmGetDevice2(screen->fd, 0, &devinfo))
456      return false;
457
458   if (devinfo->bustype == DRM_BUS_PLATFORM && devinfo->deviceinfo.platform) {
459      char **compatible = devinfo->deviceinfo.platform->compatible;
460
461      if (compatible && *compatible)
462         if (!strcmp("allwinner,sun50i-h5-mali", *compatible))
463            screen->plb_max_blk = 2048;
464   }
465
466   drmFreeDevice(&devinfo);
467
468   return true;
469}
470
471static bool
472lima_screen_query_info(struct lima_screen *screen)
473{
474   drmVersionPtr version = drmGetVersion(screen->fd);
475   if (!version)
476      return false;
477
478   if (version->version_major > 1 || version->version_minor > 0)
479      screen->has_growable_heap_buffer = true;
480
481   drmFreeVersion(version);
482
483   if (lima_debug & LIMA_DEBUG_NO_GROW_HEAP)
484      screen->has_growable_heap_buffer = false;
485
486   struct drm_lima_get_param param;
487
488   memset(&param, 0, sizeof(param));
489   param.param = DRM_LIMA_PARAM_GPU_ID;
490   if (drmIoctl(screen->fd, DRM_IOCTL_LIMA_GET_PARAM, &param))
491      return false;
492
493   switch (param.value) {
494   case DRM_LIMA_PARAM_GPU_ID_MALI400:
495   case DRM_LIMA_PARAM_GPU_ID_MALI450:
496      screen->gpu_type = param.value;
497      break;
498   default:
499      return false;
500   }
501
502   memset(&param, 0, sizeof(param));
503   param.param = DRM_LIMA_PARAM_NUM_PP;
504   if (drmIoctl(screen->fd, DRM_IOCTL_LIMA_GET_PARAM, &param))
505      return false;
506
507   screen->num_pp = param.value;
508
509   lima_screen_set_plb_max_blk(screen);
510
511   return true;
512}
513
514static const uint64_t lima_available_modifiers[] = {
515   DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
516   DRM_FORMAT_MOD_LINEAR,
517};
518
519static bool lima_is_modifier_external_only(enum pipe_format format)
520{
521   return util_format_is_yuv(format);
522}
523
524static void
525lima_screen_query_dmabuf_modifiers(struct pipe_screen *pscreen,
526                                   enum pipe_format format, int max,
527                                   uint64_t *modifiers,
528                                   unsigned int *external_only,
529                                   int *count)
530{
531   int num_modifiers = ARRAY_SIZE(lima_available_modifiers);
532
533   if (!modifiers) {
534      *count = num_modifiers;
535      return;
536   }
537
538   *count = MIN2(max, num_modifiers);
539   for (int i = 0; i < *count; i++) {
540      modifiers[i] = lima_available_modifiers[i];
541      if (external_only)
542         external_only[i] = lima_is_modifier_external_only(format);
543   }
544}
545
546static bool
547lima_screen_is_dmabuf_modifier_supported(struct pipe_screen *pscreen,
548                                         uint64_t modifier,
549                                         enum pipe_format format,
550                                         bool *external_only)
551{
552   for (int i = 0; i < ARRAY_SIZE(lima_available_modifiers); i++) {
553      if (lima_available_modifiers[i] == modifier) {
554         if (external_only)
555            *external_only = lima_is_modifier_external_only(format);
556
557         return true;
558      }
559   }
560
561   return false;
562}
563
564static const struct debug_named_value lima_debug_options[] = {
565        { "gp",       LIMA_DEBUG_GP,
566          "print GP shader compiler result of each stage" },
567        { "pp",       LIMA_DEBUG_PP,
568          "print PP shader compiler result of each stage" },
569        { "dump",     LIMA_DEBUG_DUMP,
570          "dump GPU command stream to $PWD/lima.dump" },
571        { "shaderdb", LIMA_DEBUG_SHADERDB,
572          "print shader information for shaderdb" },
573        { "nobocache", LIMA_DEBUG_NO_BO_CACHE,
574          "disable BO cache" },
575        { "bocache", LIMA_DEBUG_BO_CACHE,
576          "print debug info for BO cache" },
577        { "notiling", LIMA_DEBUG_NO_TILING,
578          "don't use tiled buffers" },
579        { "nogrowheap",   LIMA_DEBUG_NO_GROW_HEAP,
580          "disable growable heap buffer" },
581        { "singlejob", LIMA_DEBUG_SINGLE_JOB,
582          "disable multi job optimization" },
583        { "precompile", LIMA_DEBUG_PRECOMPILE,
584          "Precompile shaders for shader-db" },
585        { "diskcache", LIMA_DEBUG_DISK_CACHE,
586          "print debug info for shader disk cache" },
587        { NULL }
588};
589
590DEBUG_GET_ONCE_FLAGS_OPTION(lima_debug, "LIMA_DEBUG", lima_debug_options, 0)
591uint32_t lima_debug;
592
593static void
594lima_screen_parse_env(void)
595{
596   lima_debug = debug_get_option_lima_debug();
597
598   lima_ctx_num_plb = debug_get_num_option("LIMA_CTX_NUM_PLB", LIMA_CTX_PLB_DEF_NUM);
599   if (lima_ctx_num_plb > LIMA_CTX_PLB_MAX_NUM ||
600       lima_ctx_num_plb < LIMA_CTX_PLB_MIN_NUM) {
601      fprintf(stderr, "lima: LIMA_CTX_NUM_PLB %d out of range [%d %d], "
602              "reset to default %d\n", lima_ctx_num_plb, LIMA_CTX_PLB_MIN_NUM,
603              LIMA_CTX_PLB_MAX_NUM, LIMA_CTX_PLB_DEF_NUM);
604      lima_ctx_num_plb = LIMA_CTX_PLB_DEF_NUM;
605   }
606
607   lima_plb_max_blk = debug_get_num_option("LIMA_PLB_MAX_BLK", 0);
608   if (lima_plb_max_blk < 0 || lima_plb_max_blk > 65536) {
609      fprintf(stderr, "lima: LIMA_PLB_MAX_BLK %d out of range [%d %d], "
610              "reset to default %d\n", lima_plb_max_blk, 0, 65536, 0);
611      lima_plb_max_blk = 0;
612   }
613
614   lima_ppir_force_spilling = debug_get_num_option("LIMA_PPIR_FORCE_SPILLING", 0);
615   if (lima_ppir_force_spilling < 0) {
616      fprintf(stderr, "lima: LIMA_PPIR_FORCE_SPILLING %d less than 0, "
617              "reset to default 0\n", lima_ppir_force_spilling);
618      lima_ppir_force_spilling = 0;
619   }
620
621   lima_plb_pp_stream_cache_size = debug_get_num_option("LIMA_PLB_PP_STREAM_CACHE_SIZE", 0);
622   if (lima_plb_pp_stream_cache_size < 0) {
623      fprintf(stderr, "lima: LIMA_PLB_PP_STREAM_CACHE_SIZE %d less than 0, "
624              "reset to default 0\n", lima_plb_pp_stream_cache_size);
625      lima_plb_pp_stream_cache_size = 0;
626   }
627}
628
629static struct disk_cache *
630lima_get_disk_shader_cache (struct pipe_screen *pscreen)
631{
632   struct lima_screen *screen = lima_screen(pscreen);
633
634   return screen->disk_cache;
635}
636
637struct pipe_screen *
638lima_screen_create(int fd, struct renderonly *ro)
639{
640   uint64_t system_memory;
641   struct lima_screen *screen;
642
643   screen = rzalloc(NULL, struct lima_screen);
644   if (!screen)
645      return NULL;
646
647   screen->fd = fd;
648   screen->ro = ro;
649
650   lima_screen_parse_env();
651
652   /* Limit PP PLB stream cache size to 0.1% of system memory */
653   if (!lima_plb_pp_stream_cache_size &&
654       os_get_total_physical_memory(&system_memory))
655      lima_plb_pp_stream_cache_size = system_memory >> 10;
656
657   /* Set lower limit on PP PLB cache size */
658   lima_plb_pp_stream_cache_size = MAX2(128 * 1024 * lima_ctx_num_plb,
659                                        lima_plb_pp_stream_cache_size);
660
661   if (!lima_screen_query_info(screen))
662      goto err_out0;
663
664   if (!lima_bo_cache_init(screen))
665      goto err_out0;
666
667   if (!lima_bo_table_init(screen))
668      goto err_out1;
669
670   screen->pp_ra = ppir_regalloc_init(screen);
671   if (!screen->pp_ra)
672      goto err_out2;
673
674   screen->pp_buffer = lima_bo_create(screen, pp_buffer_size, 0);
675   if (!screen->pp_buffer)
676      goto err_out2;
677   screen->pp_buffer->cacheable = false;
678
679   /* fs program for clear buffer?
680    * const0 1 0 0 -1.67773, mov.v0 $0 ^const0.xxxx, stop
681    */
682   static const uint32_t pp_clear_program[] = {
683      0x00020425, 0x0000000c, 0x01e007cf, 0xb0000000,
684      0x000005f5, 0x00000000, 0x00000000, 0x00000000,
685   };
686   memcpy(lima_bo_map(screen->pp_buffer) + pp_clear_program_offset,
687          pp_clear_program, sizeof(pp_clear_program));
688
689   /* copy texture to framebuffer, used to reload gpu tile buffer
690    * load.v $1 0.xy, texld_2d 0, mov.v0 $0 ^tex_sampler, sync, stop
691    */
692   static const uint32_t pp_reload_program[] = {
693      0x000005e6, 0xf1003c20, 0x00000000, 0x39001000,
694      0x00000e4e, 0x000007cf, 0x00000000, 0x00000000,
695   };
696   memcpy(lima_bo_map(screen->pp_buffer) + pp_reload_program_offset,
697          pp_reload_program, sizeof(pp_reload_program));
698
699   /* 0/1/2 vertex index for reload/clear draw */
700   static const uint8_t pp_shared_index[] = { 0, 1, 2 };
701   memcpy(lima_bo_map(screen->pp_buffer) + pp_shared_index_offset,
702          pp_shared_index, sizeof(pp_shared_index));
703
704   /* 4096x4096 gl pos used for partial clear */
705   static const float pp_clear_gl_pos[] = {
706      4096, 0,    1, 1,
707      0,    0,    1, 1,
708      0,    4096, 1, 1,
709   };
710   memcpy(lima_bo_map(screen->pp_buffer) + pp_clear_gl_pos_offset,
711          pp_clear_gl_pos, sizeof(pp_clear_gl_pos));
712
713   /* is pp frame render state static? */
714   uint32_t *pp_frame_rsw = lima_bo_map(screen->pp_buffer) + pp_frame_rsw_offset;
715   memset(pp_frame_rsw, 0, 0x40);
716   pp_frame_rsw[8] = 0x0000f008;
717   pp_frame_rsw[9] = screen->pp_buffer->va + pp_clear_program_offset;
718   pp_frame_rsw[13] = 0x00000100;
719
720   screen->base.destroy = lima_screen_destroy;
721   screen->base.get_name = lima_screen_get_name;
722   screen->base.get_vendor = lima_screen_get_vendor;
723   screen->base.get_device_vendor = lima_screen_get_device_vendor;
724   screen->base.get_param = lima_screen_get_param;
725   screen->base.get_paramf = lima_screen_get_paramf;
726   screen->base.get_shader_param = lima_screen_get_shader_param;
727   screen->base.context_create = lima_context_create;
728   screen->base.is_format_supported = lima_screen_is_format_supported;
729   screen->base.get_compiler_options = lima_screen_get_compiler_options;
730   screen->base.query_dmabuf_modifiers = lima_screen_query_dmabuf_modifiers;
731   screen->base.is_dmabuf_modifier_supported = lima_screen_is_dmabuf_modifier_supported;
732   screen->base.get_disk_shader_cache = lima_get_disk_shader_cache;
733
734   lima_resource_screen_init(screen);
735   lima_fence_screen_init(screen);
736   lima_disk_cache_init(screen);
737
738   slab_create_parent(&screen->transfer_pool, sizeof(struct lima_transfer), 16);
739
740   screen->refcnt = 1;
741
742   return &screen->base;
743
744err_out2:
745   lima_bo_table_fini(screen);
746err_out1:
747   lima_bo_cache_fini(screen);
748err_out0:
749   ralloc_free(screen);
750   return NULL;
751}
752