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