1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2008 VMware, Inc.
3bf215546Sopenharmony_ci * Copyright (C) 2014 Broadcom
4bf215546Sopenharmony_ci * Copyright (C) 2018 Alyssa Rosenzweig
5bf215546Sopenharmony_ci * Copyright (C) 2019 Collabora, Ltd.
6bf215546Sopenharmony_ci * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
7bf215546Sopenharmony_ci *
8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
16bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
17bf215546Sopenharmony_ci * Software.
18bf215546Sopenharmony_ci *
19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25bf215546Sopenharmony_ci * SOFTWARE.
26bf215546Sopenharmony_ci *
27bf215546Sopenharmony_ci */
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "util/u_debug.h"
30bf215546Sopenharmony_ci#include "util/u_memory.h"
31bf215546Sopenharmony_ci#include "util/format/u_format.h"
32bf215546Sopenharmony_ci#include "util/format/u_format_s3tc.h"
33bf215546Sopenharmony_ci#include "util/u_video.h"
34bf215546Sopenharmony_ci#include "util/u_screen.h"
35bf215546Sopenharmony_ci#include "util/os_time.h"
36bf215546Sopenharmony_ci#include "util/u_process.h"
37bf215546Sopenharmony_ci#include "pipe/p_defines.h"
38bf215546Sopenharmony_ci#include "pipe/p_screen.h"
39bf215546Sopenharmony_ci#include "draw/draw_context.h"
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ci#include <fcntl.h>
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h"
44bf215546Sopenharmony_ci#include "drm-uapi/panfrost_drm.h"
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci#include "pan_bo.h"
47bf215546Sopenharmony_ci#include "pan_shader.h"
48bf215546Sopenharmony_ci#include "pan_screen.h"
49bf215546Sopenharmony_ci#include "pan_resource.h"
50bf215546Sopenharmony_ci#include "pan_public.h"
51bf215546Sopenharmony_ci#include "pan_util.h"
52bf215546Sopenharmony_ci#include "decode.h"
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci#include "pan_context.h"
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_cistatic const struct debug_named_value panfrost_debug_options[] = {
57bf215546Sopenharmony_ci        {"perf",      PAN_DBG_PERF,     "Enable performance warnings"},
58bf215546Sopenharmony_ci        {"trace",     PAN_DBG_TRACE,    "Trace the command stream"},
59bf215546Sopenharmony_ci        {"deqp",      PAN_DBG_DEQP,     "Hacks for dEQP"},
60bf215546Sopenharmony_ci        {"dirty",     PAN_DBG_DIRTY,    "Always re-emit all state"},
61bf215546Sopenharmony_ci        {"sync",      PAN_DBG_SYNC,     "Wait for each job's completion and abort on GPU faults"},
62bf215546Sopenharmony_ci        {"precompile", PAN_DBG_PRECOMPILE, "Precompile shaders for shader-db"},
63bf215546Sopenharmony_ci        {"nofp16",     PAN_DBG_NOFP16,     "Disable 16-bit support"},
64bf215546Sopenharmony_ci        {"gl3",       PAN_DBG_GL3,      "Enable experimental GL 3.x implementation, up to 3.3"},
65bf215546Sopenharmony_ci        {"noafbc",    PAN_DBG_NO_AFBC,  "Disable AFBC support"},
66bf215546Sopenharmony_ci        {"nocrc",     PAN_DBG_NO_CRC,   "Disable transaction elimination"},
67bf215546Sopenharmony_ci        {"msaa16",    PAN_DBG_MSAA16,   "Enable MSAA 8x and 16x support"},
68bf215546Sopenharmony_ci        {"indirect",  PAN_DBG_INDIRECT, "Use experimental compute kernel for indirect draws"},
69bf215546Sopenharmony_ci        {"linear",    PAN_DBG_LINEAR,   "Force linear textures"},
70bf215546Sopenharmony_ci        {"nocache",   PAN_DBG_NO_CACHE, "Disable BO cache"},
71bf215546Sopenharmony_ci        {"dump",      PAN_DBG_DUMP,     "Dump all graphics memory"},
72bf215546Sopenharmony_ci#ifdef PAN_DBG_OVERFLOW
73bf215546Sopenharmony_ci        {"overflow",  PAN_DBG_OVERFLOW, "Check for buffer overflows in pool uploads"},
74bf215546Sopenharmony_ci#endif
75bf215546Sopenharmony_ci        DEBUG_NAMED_VALUE_END
76bf215546Sopenharmony_ci};
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_cistatic const char *
79bf215546Sopenharmony_cipanfrost_get_name(struct pipe_screen *screen)
80bf215546Sopenharmony_ci{
81bf215546Sopenharmony_ci        return pan_device(screen)->model->name;
82bf215546Sopenharmony_ci}
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_cistatic const char *
85bf215546Sopenharmony_cipanfrost_get_vendor(struct pipe_screen *screen)
86bf215546Sopenharmony_ci{
87bf215546Sopenharmony_ci        return "Panfrost";
88bf215546Sopenharmony_ci}
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_cistatic const char *
91bf215546Sopenharmony_cipanfrost_get_device_vendor(struct pipe_screen *screen)
92bf215546Sopenharmony_ci{
93bf215546Sopenharmony_ci        return "Arm";
94bf215546Sopenharmony_ci}
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_cistatic int
97bf215546Sopenharmony_cipanfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
98bf215546Sopenharmony_ci{
99bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(screen);
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci        /* Our GL 3.x implementation is WIP */
102bf215546Sopenharmony_ci        bool is_gl3 = dev->debug & (PAN_DBG_GL3 | PAN_DBG_DEQP);
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci        /* Native MRT is introduced with v5 */
105bf215546Sopenharmony_ci        bool has_mrt = (dev->arch >= 5);
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci        /* Only kernel drivers >= 1.1 can allocate HEAP BOs */
108bf215546Sopenharmony_ci        bool has_heap = dev->kernel_version->version_major > 1 ||
109bf215546Sopenharmony_ci                        dev->kernel_version->version_minor >= 1;
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci        switch (param) {
112bf215546Sopenharmony_ci        case PIPE_CAP_NPOT_TEXTURES:
113bf215546Sopenharmony_ci        case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
114bf215546Sopenharmony_ci        case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
115bf215546Sopenharmony_ci        case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
116bf215546Sopenharmony_ci        case PIPE_CAP_POINT_SPRITE:
117bf215546Sopenharmony_ci        case PIPE_CAP_DEPTH_CLIP_DISABLE:
118bf215546Sopenharmony_ci        case PIPE_CAP_DEPTH_CLIP_DISABLE_SEPARATE:
119bf215546Sopenharmony_ci        case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
120bf215546Sopenharmony_ci        case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
121bf215546Sopenharmony_ci        case PIPE_CAP_FRONTEND_NOOP:
122bf215546Sopenharmony_ci        case PIPE_CAP_SAMPLE_SHADING:
123bf215546Sopenharmony_ci        case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
124bf215546Sopenharmony_ci        case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
125bf215546Sopenharmony_ci        case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
126bf215546Sopenharmony_ci        case PIPE_CAP_SHADER_PACK_HALF_FLOAT:
127bf215546Sopenharmony_ci        case PIPE_CAP_NATIVE_FENCE_FD:
128bf215546Sopenharmony_ci                return 1;
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci        case PIPE_CAP_MAX_RENDER_TARGETS:
131bf215546Sopenharmony_ci        case PIPE_CAP_FBFETCH:
132bf215546Sopenharmony_ci        case PIPE_CAP_FBFETCH_COHERENT:
133bf215546Sopenharmony_ci                return has_mrt ? 8 : 1;
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci        case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
136bf215546Sopenharmony_ci                return 1;
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci        case PIPE_CAP_OCCLUSION_QUERY:
139bf215546Sopenharmony_ci        case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
140bf215546Sopenharmony_ci                return true;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci        case PIPE_CAP_ANISOTROPIC_FILTER:
143bf215546Sopenharmony_ci                return dev->revision >= dev->model->min_rev_anisotropic;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci        /* Compile side is done for Bifrost, Midgard TODO. Needs some kernel
146bf215546Sopenharmony_ci         * work to turn on, since CYCLE_COUNT_START needs to be issued. In
147bf215546Sopenharmony_ci         * kbase, userspace requests this via BASE_JD_REQ_PERMON. There is not
148bf215546Sopenharmony_ci         * yet way to request this with mainline TODO */
149bf215546Sopenharmony_ci        case PIPE_CAP_SHADER_CLOCK:
150bf215546Sopenharmony_ci                return 0;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci        case PIPE_CAP_VS_INSTANCEID:
153bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_MULTISAMPLE:
154bf215546Sopenharmony_ci        case PIPE_CAP_SURFACE_SAMPLE_COUNT:
155bf215546Sopenharmony_ci                return true;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci        case PIPE_CAP_SAMPLER_VIEW_TARGET:
158bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_SWIZZLE:
159bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
160bf215546Sopenharmony_ci        case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
161bf215546Sopenharmony_ci        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
162bf215546Sopenharmony_ci        case PIPE_CAP_INDEP_BLEND_ENABLE:
163bf215546Sopenharmony_ci        case PIPE_CAP_INDEP_BLEND_FUNC:
164bf215546Sopenharmony_ci        case PIPE_CAP_GENERATE_MIPMAP:
165bf215546Sopenharmony_ci        case PIPE_CAP_ACCELERATED:
166bf215546Sopenharmony_ci        case PIPE_CAP_UMA:
167bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
168bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
169bf215546Sopenharmony_ci        case PIPE_CAP_SHADER_ARRAY_COMPONENTS:
170bf215546Sopenharmony_ci        case PIPE_CAP_CS_DERIVED_SYSTEM_VALUES_SUPPORTED:
171bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
172bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_BUFFER_SAMPLER:
173bf215546Sopenharmony_ci        case PIPE_CAP_PACKED_UNIFORMS:
174bf215546Sopenharmony_ci        case PIPE_CAP_IMAGE_LOAD_FORMATTED:
175bf215546Sopenharmony_ci        case PIPE_CAP_CUBE_MAP_ARRAY:
176bf215546Sopenharmony_ci        case PIPE_CAP_COMPUTE:
177bf215546Sopenharmony_ci                return 1;
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci        /* We need this for OES_copy_image, but currently there are some awful
180bf215546Sopenharmony_ci         * interactions with AFBC that need to be worked out. */
181bf215546Sopenharmony_ci        case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
182bf215546Sopenharmony_ci                return 0;
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci        case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
185bf215546Sopenharmony_ci                return PIPE_MAX_SO_BUFFERS;
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_ci        case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
188bf215546Sopenharmony_ci        case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
189bf215546Sopenharmony_ci                return PIPE_MAX_SO_OUTPUTS;
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci        case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
192bf215546Sopenharmony_ci        case PIPE_CAP_STREAM_OUTPUT_INTERLEAVE_BUFFERS:
193bf215546Sopenharmony_ci                return 1;
194bf215546Sopenharmony_ci
195bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
196bf215546Sopenharmony_ci                return 256;
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ci        case PIPE_CAP_GLSL_FEATURE_LEVEL:
199bf215546Sopenharmony_ci        case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
200bf215546Sopenharmony_ci                return is_gl3 ? 330 : 140;
201bf215546Sopenharmony_ci        case PIPE_CAP_ESSL_FEATURE_LEVEL:
202bf215546Sopenharmony_ci                return dev->arch >= 6 ? 320 : 310;
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci        case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
205bf215546Sopenharmony_ci                return 16;
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXEL_BUFFER_ELEMENTS_UINT:
208bf215546Sopenharmony_ci                return 65536;
209bf215546Sopenharmony_ci
210bf215546Sopenharmony_ci        /* Must be at least 64 for correct behaviour */
211bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
212bf215546Sopenharmony_ci                return 64;
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci        case PIPE_CAP_QUERY_TIMESTAMP:
215bf215546Sopenharmony_ci                return is_gl3;
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci        /* TODO: Where does this req come from in practice? */
218bf215546Sopenharmony_ci        case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
219bf215546Sopenharmony_ci                return 1;
220bf215546Sopenharmony_ci
221bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
222bf215546Sopenharmony_ci                return 1 << (MAX_MIP_LEVELS - 1);
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
225bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
226bf215546Sopenharmony_ci                return MAX_MIP_LEVELS;
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci        case PIPE_CAP_FS_COORD_ORIGIN_LOWER_LEFT:
229bf215546Sopenharmony_ci        case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER:
230bf215546Sopenharmony_ci                /* Hardware is upper left. Pixel center at (0.5, 0.5) */
231bf215546Sopenharmony_ci                return 0;
232bf215546Sopenharmony_ci
233bf215546Sopenharmony_ci        case PIPE_CAP_FS_COORD_ORIGIN_UPPER_LEFT:
234bf215546Sopenharmony_ci        case PIPE_CAP_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
235bf215546Sopenharmony_ci        case PIPE_CAP_TGSI_TEXCOORD:
236bf215546Sopenharmony_ci                return 1;
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci        /* We would prefer varyings on Midgard, but proper sysvals on Bifrost */
239bf215546Sopenharmony_ci        case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
240bf215546Sopenharmony_ci        case PIPE_CAP_FS_POSITION_IS_SYSVAL:
241bf215546Sopenharmony_ci        case PIPE_CAP_FS_POINT_IS_SYSVAL:
242bf215546Sopenharmony_ci                return dev->arch >= 6;
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci        case PIPE_CAP_SEAMLESS_CUBE_MAP:
245bf215546Sopenharmony_ci        case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
246bf215546Sopenharmony_ci                return true;
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci        case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
249bf215546Sopenharmony_ci                return 0xffff;
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_TRANSFER_MODES:
252bf215546Sopenharmony_ci                return 0;
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci        case PIPE_CAP_ENDIANNESS:
255bf215546Sopenharmony_ci                return PIPE_ENDIAN_NATIVE;
256bf215546Sopenharmony_ci
257bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
258bf215546Sopenharmony_ci                return 4;
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci        case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
261bf215546Sopenharmony_ci                return -8;
262bf215546Sopenharmony_ci
263bf215546Sopenharmony_ci        case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
264bf215546Sopenharmony_ci                return 7;
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_ci        case PIPE_CAP_VIDEO_MEMORY: {
267bf215546Sopenharmony_ci                uint64_t system_memory;
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci                if (!os_get_total_physical_memory(&system_memory))
270bf215546Sopenharmony_ci                        return 0;
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci                return (int)(system_memory >> 20);
273bf215546Sopenharmony_ci        }
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci        case PIPE_CAP_SHADER_STENCIL_EXPORT:
276bf215546Sopenharmony_ci        case PIPE_CAP_CONDITIONAL_RENDER:
277bf215546Sopenharmony_ci        case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
278bf215546Sopenharmony_ci                return true;
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci        case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
281bf215546Sopenharmony_ci                return 4;
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci        case PIPE_CAP_MAX_VARYINGS:
284bf215546Sopenharmony_ci                /* Return the GLSL maximum. The internal maximum
285bf215546Sopenharmony_ci                 * PAN_MAX_VARYINGS accommodates internal varyings. */
286bf215546Sopenharmony_ci                return MAX_VARYING;
287bf215546Sopenharmony_ci
288bf215546Sopenharmony_ci        /* Removed in v6 (Bifrost) */
289bf215546Sopenharmony_ci        case PIPE_CAP_GL_CLAMP:
290bf215546Sopenharmony_ci        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
291bf215546Sopenharmony_ci        case PIPE_CAP_ALPHA_TEST:
292bf215546Sopenharmony_ci                return dev->arch <= 5;
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci        /* Removed in v9 (Valhall). PRIMTIIVE_RESTART_FIXED_INDEX is of course
295bf215546Sopenharmony_ci         * still supported as it is core GLES3.0 functionality
296bf215546Sopenharmony_ci         */
297bf215546Sopenharmony_ci        case PIPE_CAP_PRIMITIVE_RESTART:
298bf215546Sopenharmony_ci                return dev->arch <= 7;
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci        case PIPE_CAP_FLATSHADE:
301bf215546Sopenharmony_ci        case PIPE_CAP_TWO_SIDED_COLOR:
302bf215546Sopenharmony_ci        case PIPE_CAP_CLIP_PLANES:
303bf215546Sopenharmony_ci                return 0;
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci        case PIPE_CAP_PACKED_STREAM_OUTPUT:
306bf215546Sopenharmony_ci                return 0;
307bf215546Sopenharmony_ci
308bf215546Sopenharmony_ci        case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
309bf215546Sopenharmony_ci        case PIPE_CAP_PSIZ_CLAMPED:
310bf215546Sopenharmony_ci                return 1;
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci        case PIPE_CAP_NIR_IMAGES_AS_DEREF:
313bf215546Sopenharmony_ci                return 0;
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci        case PIPE_CAP_DRAW_INDIRECT:
316bf215546Sopenharmony_ci                return has_heap;
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci        case PIPE_CAP_START_INSTANCE:
319bf215546Sopenharmony_ci        case PIPE_CAP_DRAW_PARAMETERS:
320bf215546Sopenharmony_ci                return pan_is_bifrost(dev);
321bf215546Sopenharmony_ci
322bf215546Sopenharmony_ci        case PIPE_CAP_SUPPORTED_PRIM_MODES:
323bf215546Sopenharmony_ci        case PIPE_CAP_SUPPORTED_PRIM_MODES_WITH_RESTART: {
324bf215546Sopenharmony_ci                /* Mali supports GLES and QUADS. Midgard and v6 Bifrost
325bf215546Sopenharmony_ci                 * support more */
326bf215546Sopenharmony_ci                uint32_t modes = BITFIELD_MASK(PIPE_PRIM_QUADS + 1);
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci                if (dev->arch <= 6) {
329bf215546Sopenharmony_ci                        modes |= BITFIELD_BIT(PIPE_PRIM_QUAD_STRIP);
330bf215546Sopenharmony_ci                        modes |= BITFIELD_BIT(PIPE_PRIM_POLYGON);
331bf215546Sopenharmony_ci                }
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci                if (dev->arch >= 9) {
334bf215546Sopenharmony_ci                        /* Although Valhall is supposed to support quads, they
335bf215546Sopenharmony_ci                         * don't seem to work correctly. Disable to fix
336bf215546Sopenharmony_ci                         * arb-provoking-vertex-render.
337bf215546Sopenharmony_ci                         */
338bf215546Sopenharmony_ci                        modes &= ~BITFIELD_BIT(PIPE_PRIM_QUADS);
339bf215546Sopenharmony_ci                }
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci                return modes;
342bf215546Sopenharmony_ci        }
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci        case PIPE_CAP_IMAGE_STORE_FORMATTED:
345bf215546Sopenharmony_ci                return 1;
346bf215546Sopenharmony_ci
347bf215546Sopenharmony_ci        default:
348bf215546Sopenharmony_ci                return u_pipe_screen_get_param_defaults(screen, param);
349bf215546Sopenharmony_ci        }
350bf215546Sopenharmony_ci}
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_cistatic int
353bf215546Sopenharmony_cipanfrost_get_shader_param(struct pipe_screen *screen,
354bf215546Sopenharmony_ci                          enum pipe_shader_type shader,
355bf215546Sopenharmony_ci                          enum pipe_shader_cap param)
356bf215546Sopenharmony_ci{
357bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(screen);
358bf215546Sopenharmony_ci        bool is_nofp16 = dev->debug & PAN_DBG_NOFP16;
359bf215546Sopenharmony_ci        bool is_deqp = dev->debug & PAN_DBG_DEQP;
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci        switch (shader) {
362bf215546Sopenharmony_ci        case PIPE_SHADER_VERTEX:
363bf215546Sopenharmony_ci        case PIPE_SHADER_FRAGMENT:
364bf215546Sopenharmony_ci        case PIPE_SHADER_COMPUTE:
365bf215546Sopenharmony_ci                break;
366bf215546Sopenharmony_ci        default:
367bf215546Sopenharmony_ci                return 0;
368bf215546Sopenharmony_ci        }
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci        /* We only allow observable side effects (memory writes) in compute and
371bf215546Sopenharmony_ci         * fragment shaders. Side effects in the geometry pipeline cause
372bf215546Sopenharmony_ci         * trouble with IDVS.
373bf215546Sopenharmony_ci         *
374bf215546Sopenharmony_ci         * This restriction doesn't apply to Midgard, which does not implement
375bf215546Sopenharmony_ci         * IDVS and therefore executes vertex shaders exactly once.
376bf215546Sopenharmony_ci         */
377bf215546Sopenharmony_ci        bool allow_side_effects = (shader != PIPE_SHADER_VERTEX) ||
378bf215546Sopenharmony_ci                                  (dev->arch <= 5);
379bf215546Sopenharmony_ci
380bf215546Sopenharmony_ci        switch (param) {
381bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
382bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
383bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
384bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
385bf215546Sopenharmony_ci                return 16384; /* arbitrary */
386bf215546Sopenharmony_ci
387bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
388bf215546Sopenharmony_ci                return 1024; /* arbitrary */
389bf215546Sopenharmony_ci
390bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_INPUTS:
391bf215546Sopenharmony_ci                /* Used as ABI on Midgard */
392bf215546Sopenharmony_ci                return 16;
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_OUTPUTS:
395bf215546Sopenharmony_ci                return shader == PIPE_SHADER_FRAGMENT ? 8 : PIPE_MAX_ATTRIBS;
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEMPS:
398bf215546Sopenharmony_ci                return 256; /* arbitrary */
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_CONST_BUFFER0_SIZE:
401bf215546Sopenharmony_ci                return 16 * 1024 * sizeof(float);
402bf215546Sopenharmony_ci
403bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
404bf215546Sopenharmony_ci                STATIC_ASSERT(PAN_MAX_CONST_BUFFERS < 0x100);
405bf215546Sopenharmony_ci                return PAN_MAX_CONST_BUFFERS;
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_CONT_SUPPORTED:
408bf215546Sopenharmony_ci                return 0;
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
411bf215546Sopenharmony_ci                return 1;
412bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
413bf215546Sopenharmony_ci                return 0;
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
416bf215546Sopenharmony_ci                return dev->arch >= 6;
417bf215546Sopenharmony_ci
418bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
419bf215546Sopenharmony_ci                return 1;
420bf215546Sopenharmony_ci
421bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_SUBROUTINES:
422bf215546Sopenharmony_ci                return 0;
423bf215546Sopenharmony_ci
424bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
425bf215546Sopenharmony_ci                return 0;
426bf215546Sopenharmony_ci
427bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INTEGERS:
428bf215546Sopenharmony_ci                return 1;
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci        /* The Bifrost compiler supports full 16-bit. Midgard could but int16
431bf215546Sopenharmony_ci         * support is untested, so restrict INT16 to Bifrost. Midgard
432bf215546Sopenharmony_ci         * architecturally cannot support fp16 derivatives. */
433bf215546Sopenharmony_ci
434bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_FP16:
435bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_GLSL_16BIT_CONSTS:
436bf215546Sopenharmony_ci                return !is_nofp16;
437bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_FP16_DERIVATIVES:
438bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_FP16_CONST_BUFFERS:
439bf215546Sopenharmony_ci                return dev->arch >= 6 && !is_nofp16;
440bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INT16:
441bf215546Sopenharmony_ci                /* XXX: Advertise this CAP when a proper fix to lower_precision
442bf215546Sopenharmony_ci                 * lands. GLSL IR validation failure in glmark2 -bterrain */
443bf215546Sopenharmony_ci                return dev->arch >= 6 && !is_nofp16 && is_deqp;
444bf215546Sopenharmony_ci
445bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_INT64_ATOMICS:
446bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_DROUND_SUPPORTED:
447bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_DFRACEXP_DLDEXP_SUPPORTED:
448bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_LDEXP_SUPPORTED:
449bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
450bf215546Sopenharmony_ci                return 0;
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
453bf215546Sopenharmony_ci                STATIC_ASSERT(PIPE_MAX_SAMPLERS < 0x10000);
454bf215546Sopenharmony_ci                return PIPE_MAX_SAMPLERS;
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
457bf215546Sopenharmony_ci                STATIC_ASSERT(PIPE_MAX_SHADER_SAMPLER_VIEWS < 0x10000);
458bf215546Sopenharmony_ci                return PIPE_MAX_SHADER_SAMPLER_VIEWS;
459bf215546Sopenharmony_ci
460bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_PREFERRED_IR:
461bf215546Sopenharmony_ci                return PIPE_SHADER_IR_NIR;
462bf215546Sopenharmony_ci
463bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_SUPPORTED_IRS:
464bf215546Sopenharmony_ci                return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_NIR_SERIALIZED);
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
467bf215546Sopenharmony_ci                return allow_side_effects ? 16 : 0;
468bf215546Sopenharmony_ci
469bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
470bf215546Sopenharmony_ci                return allow_side_effects ? PIPE_MAX_SHADER_IMAGES : 0;
471bf215546Sopenharmony_ci
472bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
473bf215546Sopenharmony_ci        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
474bf215546Sopenharmony_ci                return 0;
475bf215546Sopenharmony_ci
476bf215546Sopenharmony_ci        default:
477bf215546Sopenharmony_ci                return 0;
478bf215546Sopenharmony_ci        }
479bf215546Sopenharmony_ci
480bf215546Sopenharmony_ci        return 0;
481bf215546Sopenharmony_ci}
482bf215546Sopenharmony_ci
483bf215546Sopenharmony_cistatic float
484bf215546Sopenharmony_cipanfrost_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
485bf215546Sopenharmony_ci{
486bf215546Sopenharmony_ci        switch (param) {
487bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_LINE_WIDTH:
488bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_LINE_WIDTH_AA:
489bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_POINT_SIZE:
490bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_POINT_SIZE_AA:
491bf215546Sopenharmony_ci           return 1;
492bf215546Sopenharmony_ci
493bf215546Sopenharmony_ci        case PIPE_CAPF_POINT_SIZE_GRANULARITY:
494bf215546Sopenharmony_ci        case PIPE_CAPF_LINE_WIDTH_GRANULARITY:
495bf215546Sopenharmony_ci           return 0.0625;
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_LINE_WIDTH:
498bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_LINE_WIDTH_AA:
499bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_POINT_SIZE:
500bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_POINT_SIZE_AA:
501bf215546Sopenharmony_ci                return 4095.9375;
502bf215546Sopenharmony_ci
503bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
504bf215546Sopenharmony_ci                return 16.0;
505bf215546Sopenharmony_ci
506bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
507bf215546Sopenharmony_ci                return 16.0; /* arbitrary */
508bf215546Sopenharmony_ci
509bf215546Sopenharmony_ci        case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
510bf215546Sopenharmony_ci        case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
511bf215546Sopenharmony_ci        case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
512bf215546Sopenharmony_ci                return 0.0f;
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_ci        default:
515bf215546Sopenharmony_ci                debug_printf("Unexpected PIPE_CAPF %d query\n", param);
516bf215546Sopenharmony_ci                return 0.0;
517bf215546Sopenharmony_ci        }
518bf215546Sopenharmony_ci}
519bf215546Sopenharmony_ci
520bf215546Sopenharmony_ci/**
521bf215546Sopenharmony_ci * Query format support for creating a texture, drawing surface, etc.
522bf215546Sopenharmony_ci * \param format  the format to test
523bf215546Sopenharmony_ci * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
524bf215546Sopenharmony_ci */
525bf215546Sopenharmony_cistatic bool
526bf215546Sopenharmony_cipanfrost_is_format_supported( struct pipe_screen *screen,
527bf215546Sopenharmony_ci                              enum pipe_format format,
528bf215546Sopenharmony_ci                              enum pipe_texture_target target,
529bf215546Sopenharmony_ci                              unsigned sample_count,
530bf215546Sopenharmony_ci                              unsigned storage_sample_count,
531bf215546Sopenharmony_ci                              unsigned bind)
532bf215546Sopenharmony_ci{
533bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(screen);
534bf215546Sopenharmony_ci        const struct util_format_description *format_desc;
535bf215546Sopenharmony_ci
536bf215546Sopenharmony_ci        assert(target == PIPE_BUFFER ||
537bf215546Sopenharmony_ci               target == PIPE_TEXTURE_1D ||
538bf215546Sopenharmony_ci               target == PIPE_TEXTURE_1D_ARRAY ||
539bf215546Sopenharmony_ci               target == PIPE_TEXTURE_2D ||
540bf215546Sopenharmony_ci               target == PIPE_TEXTURE_2D_ARRAY ||
541bf215546Sopenharmony_ci               target == PIPE_TEXTURE_RECT ||
542bf215546Sopenharmony_ci               target == PIPE_TEXTURE_3D ||
543bf215546Sopenharmony_ci               target == PIPE_TEXTURE_CUBE ||
544bf215546Sopenharmony_ci               target == PIPE_TEXTURE_CUBE_ARRAY);
545bf215546Sopenharmony_ci
546bf215546Sopenharmony_ci        format_desc = util_format_description(format);
547bf215546Sopenharmony_ci
548bf215546Sopenharmony_ci        /* MSAA 2x gets rounded up to 4x. MSAA 8x/16x only supported on v5+.
549bf215546Sopenharmony_ci         * TODO: debug MSAA 8x/16x */
550bf215546Sopenharmony_ci
551bf215546Sopenharmony_ci        switch (sample_count) {
552bf215546Sopenharmony_ci        case 0:
553bf215546Sopenharmony_ci        case 1:
554bf215546Sopenharmony_ci        case 4:
555bf215546Sopenharmony_ci                break;
556bf215546Sopenharmony_ci        case 8:
557bf215546Sopenharmony_ci        case 16:
558bf215546Sopenharmony_ci                if (dev->debug & PAN_DBG_MSAA16)
559bf215546Sopenharmony_ci                        break;
560bf215546Sopenharmony_ci                else
561bf215546Sopenharmony_ci                        return false;
562bf215546Sopenharmony_ci        default:
563bf215546Sopenharmony_ci                return false;
564bf215546Sopenharmony_ci        }
565bf215546Sopenharmony_ci
566bf215546Sopenharmony_ci        if (MAX2(sample_count, 1) != MAX2(storage_sample_count, 1))
567bf215546Sopenharmony_ci                return false;
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_ci        /* Z16 causes dEQP failures on t720 */
570bf215546Sopenharmony_ci        if (format == PIPE_FORMAT_Z16_UNORM && dev->arch <= 4)
571bf215546Sopenharmony_ci                return false;
572bf215546Sopenharmony_ci
573bf215546Sopenharmony_ci        /* Check we support the format with the given bind */
574bf215546Sopenharmony_ci
575bf215546Sopenharmony_ci        unsigned relevant_bind = bind &
576bf215546Sopenharmony_ci                ( PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET
577bf215546Sopenharmony_ci                | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_SAMPLER_VIEW);
578bf215546Sopenharmony_ci
579bf215546Sopenharmony_ci        struct panfrost_format fmt = dev->formats[format];
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_ci        /* Also check that compressed texture formats are supported on this
582bf215546Sopenharmony_ci         * particular chip. They may not be depending on system integration
583bf215546Sopenharmony_ci         * differences. RGTC can be emulated so is always supported. */
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci        bool is_rgtc = format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
586bf215546Sopenharmony_ci        bool supported = panfrost_supports_compressed_format(dev,
587bf215546Sopenharmony_ci                        MALI_EXTRACT_INDEX(fmt.hw));
588bf215546Sopenharmony_ci
589bf215546Sopenharmony_ci        if (!is_rgtc && !supported)
590bf215546Sopenharmony_ci                return false;
591bf215546Sopenharmony_ci
592bf215546Sopenharmony_ci        return MALI_EXTRACT_INDEX(fmt.hw) && ((relevant_bind & ~fmt.bind) == 0);
593bf215546Sopenharmony_ci}
594bf215546Sopenharmony_ci
595bf215546Sopenharmony_ci/* We always support linear and tiled operations, both external and internal.
596bf215546Sopenharmony_ci * We support AFBC for a subset of formats, and colourspace transform for a
597bf215546Sopenharmony_ci * subset of those. */
598bf215546Sopenharmony_ci
599bf215546Sopenharmony_cistatic void
600bf215546Sopenharmony_cipanfrost_walk_dmabuf_modifiers(struct pipe_screen *screen,
601bf215546Sopenharmony_ci                enum pipe_format format, int max, uint64_t *modifiers, unsigned
602bf215546Sopenharmony_ci                int *external_only, int *out_count, uint64_t test_modifier)
603bf215546Sopenharmony_ci{
604bf215546Sopenharmony_ci        /* Query AFBC status */
605bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(screen);
606bf215546Sopenharmony_ci        bool afbc = dev->has_afbc && panfrost_format_supports_afbc(dev, format);
607bf215546Sopenharmony_ci        bool ytr = panfrost_afbc_can_ytr(format);
608bf215546Sopenharmony_ci        bool tiled_afbc = panfrost_afbc_can_tile(dev);
609bf215546Sopenharmony_ci
610bf215546Sopenharmony_ci        unsigned count = 0;
611bf215546Sopenharmony_ci
612bf215546Sopenharmony_ci        for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) {
613bf215546Sopenharmony_ci                if (drm_is_afbc(pan_best_modifiers[i]) && !afbc)
614bf215546Sopenharmony_ci                        continue;
615bf215546Sopenharmony_ci
616bf215546Sopenharmony_ci                if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_YTR) && !ytr)
617bf215546Sopenharmony_ci                        continue;
618bf215546Sopenharmony_ci
619bf215546Sopenharmony_ci                if ((pan_best_modifiers[i] & AFBC_FORMAT_MOD_TILED) && !tiled_afbc)
620bf215546Sopenharmony_ci                        continue;
621bf215546Sopenharmony_ci
622bf215546Sopenharmony_ci                if (test_modifier != DRM_FORMAT_MOD_INVALID &&
623bf215546Sopenharmony_ci                    test_modifier != pan_best_modifiers[i])
624bf215546Sopenharmony_ci                        continue;
625bf215546Sopenharmony_ci
626bf215546Sopenharmony_ci                count++;
627bf215546Sopenharmony_ci
628bf215546Sopenharmony_ci                if (max > (int) count) {
629bf215546Sopenharmony_ci                        modifiers[count] = pan_best_modifiers[i];
630bf215546Sopenharmony_ci
631bf215546Sopenharmony_ci                        if (external_only)
632bf215546Sopenharmony_ci                                external_only[count] = false;
633bf215546Sopenharmony_ci                }
634bf215546Sopenharmony_ci        }
635bf215546Sopenharmony_ci
636bf215546Sopenharmony_ci        *out_count = count;
637bf215546Sopenharmony_ci}
638bf215546Sopenharmony_ci
639bf215546Sopenharmony_cistatic void
640bf215546Sopenharmony_cipanfrost_query_dmabuf_modifiers(struct pipe_screen *screen,
641bf215546Sopenharmony_ci                enum pipe_format format, int max, uint64_t *modifiers, unsigned
642bf215546Sopenharmony_ci                int *external_only, int *out_count)
643bf215546Sopenharmony_ci{
644bf215546Sopenharmony_ci        panfrost_walk_dmabuf_modifiers(screen, format, max, modifiers,
645bf215546Sopenharmony_ci                external_only, out_count, DRM_FORMAT_MOD_INVALID);
646bf215546Sopenharmony_ci}
647bf215546Sopenharmony_ci
648bf215546Sopenharmony_cistatic bool
649bf215546Sopenharmony_cipanfrost_is_dmabuf_modifier_supported(struct pipe_screen *screen,
650bf215546Sopenharmony_ci                uint64_t modifier, enum pipe_format format,
651bf215546Sopenharmony_ci                bool *external_only)
652bf215546Sopenharmony_ci{
653bf215546Sopenharmony_ci        uint64_t unused;
654bf215546Sopenharmony_ci        unsigned int uint_extern_only = 0;
655bf215546Sopenharmony_ci        int count;
656bf215546Sopenharmony_ci
657bf215546Sopenharmony_ci        panfrost_walk_dmabuf_modifiers(screen, format, 1, &unused,
658bf215546Sopenharmony_ci                &uint_extern_only, &count, modifier);
659bf215546Sopenharmony_ci
660bf215546Sopenharmony_ci        if (external_only)
661bf215546Sopenharmony_ci           *external_only = uint_extern_only ? true : false;
662bf215546Sopenharmony_ci
663bf215546Sopenharmony_ci        return count > 0;
664bf215546Sopenharmony_ci}
665bf215546Sopenharmony_ci
666bf215546Sopenharmony_cistatic int
667bf215546Sopenharmony_cipanfrost_get_compute_param(struct pipe_screen *pscreen, enum pipe_shader_ir ir_type,
668bf215546Sopenharmony_ci                enum pipe_compute_cap param, void *ret)
669bf215546Sopenharmony_ci{
670bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(pscreen);
671bf215546Sopenharmony_ci        const char * const ir = "panfrost";
672bf215546Sopenharmony_ci
673bf215546Sopenharmony_ci#define RET(x) do {                  \
674bf215546Sopenharmony_ci   if (ret)                          \
675bf215546Sopenharmony_ci      memcpy(ret, x, sizeof(x));     \
676bf215546Sopenharmony_ci   return sizeof(x);                 \
677bf215546Sopenharmony_ci} while (0)
678bf215546Sopenharmony_ci
679bf215546Sopenharmony_ci	switch (param) {
680bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_ADDRESS_BITS:
681bf215546Sopenharmony_ci		RET((uint32_t []){ 64 });
682bf215546Sopenharmony_ci
683bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_IR_TARGET:
684bf215546Sopenharmony_ci		if (ret)
685bf215546Sopenharmony_ci			sprintf(ret, "%s", ir);
686bf215546Sopenharmony_ci		return strlen(ir) * sizeof(char);
687bf215546Sopenharmony_ci
688bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_GRID_DIMENSION:
689bf215546Sopenharmony_ci		RET((uint64_t []) { 3 });
690bf215546Sopenharmony_ci
691bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
692bf215546Sopenharmony_ci		RET(((uint64_t []) { 65535, 65535, 65535 }));
693bf215546Sopenharmony_ci
694bf215546Sopenharmony_ci        case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
695bf215546Sopenharmony_ci                /* Unpredictable behaviour at larger sizes. Mali-G52 advertises
696bf215546Sopenharmony_ci                 * 384x384x384.
697bf215546Sopenharmony_ci                 *
698bf215546Sopenharmony_ci                 * On Midgard, we don't allow more than 128 threads in each
699bf215546Sopenharmony_ci                 * direction to match PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK.
700bf215546Sopenharmony_ci                 * That still exceeds the minimum-maximum.
701bf215546Sopenharmony_ci                 */
702bf215546Sopenharmony_ci                if (dev->arch >= 6)
703bf215546Sopenharmony_ci                        RET(((uint64_t []) { 256, 256, 256 }));
704bf215546Sopenharmony_ci                else
705bf215546Sopenharmony_ci                        RET(((uint64_t []) { 128, 128, 128 }));
706bf215546Sopenharmony_ci
707bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
708bf215546Sopenharmony_ci                /* On Bifrost and newer, all GPUs can support at least 256 threads
709bf215546Sopenharmony_ci                 * regardless of register usage, so we report 256.
710bf215546Sopenharmony_ci                 *
711bf215546Sopenharmony_ci                 * On Midgard, with maximum register usage, the maximum
712bf215546Sopenharmony_ci                 * thread count is only 64. We would like to report 64 here, but
713bf215546Sopenharmony_ci                 * the GLES3.1 spec minimum is 128, so we report 128 and limit
714bf215546Sopenharmony_ci                 * the register allocation of affected compute kernels.
715bf215546Sopenharmony_ci                 */
716bf215546Sopenharmony_ci		RET((uint64_t []) { dev->arch >= 6 ? 256 : 128 });
717bf215546Sopenharmony_ci
718bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
719bf215546Sopenharmony_ci		RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ });
720bf215546Sopenharmony_ci
721bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
722bf215546Sopenharmony_ci		RET((uint64_t []) { 32768 });
723bf215546Sopenharmony_ci
724bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
725bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
726bf215546Sopenharmony_ci		RET((uint64_t []) { 4096 });
727bf215546Sopenharmony_ci
728bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
729bf215546Sopenharmony_ci		RET((uint64_t []) { 1024*1024*512 /* Maybe get memory */ });
730bf215546Sopenharmony_ci
731bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
732bf215546Sopenharmony_ci		RET((uint32_t []) { 800 /* MHz -- TODO */ });
733bf215546Sopenharmony_ci
734bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
735bf215546Sopenharmony_ci		RET((uint32_t []) { dev->core_count });
736bf215546Sopenharmony_ci
737bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED:
738bf215546Sopenharmony_ci		RET((uint32_t []) { 1 });
739bf215546Sopenharmony_ci
740bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:
741bf215546Sopenharmony_ci		RET((uint32_t []) { pan_subgroup_size(dev->arch) });
742bf215546Sopenharmony_ci
743bf215546Sopenharmony_ci	case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK:
744bf215546Sopenharmony_ci		RET((uint64_t []) { 1024 }); // TODO
745bf215546Sopenharmony_ci	}
746bf215546Sopenharmony_ci
747bf215546Sopenharmony_ci	return 0;
748bf215546Sopenharmony_ci}
749bf215546Sopenharmony_ci
750bf215546Sopenharmony_cistatic void
751bf215546Sopenharmony_cipanfrost_destroy_screen(struct pipe_screen *pscreen)
752bf215546Sopenharmony_ci{
753bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(pscreen);
754bf215546Sopenharmony_ci        struct panfrost_screen *screen = pan_screen(pscreen);
755bf215546Sopenharmony_ci
756bf215546Sopenharmony_ci        panfrost_resource_screen_destroy(pscreen);
757bf215546Sopenharmony_ci        panfrost_pool_cleanup(&screen->indirect_draw.bin_pool);
758bf215546Sopenharmony_ci        panfrost_pool_cleanup(&screen->blitter.bin_pool);
759bf215546Sopenharmony_ci        panfrost_pool_cleanup(&screen->blitter.desc_pool);
760bf215546Sopenharmony_ci        pan_blend_shaders_cleanup(dev);
761bf215546Sopenharmony_ci
762bf215546Sopenharmony_ci        if (screen->vtbl.screen_destroy)
763bf215546Sopenharmony_ci                screen->vtbl.screen_destroy(pscreen);
764bf215546Sopenharmony_ci
765bf215546Sopenharmony_ci        if (dev->ro)
766bf215546Sopenharmony_ci                dev->ro->destroy(dev->ro);
767bf215546Sopenharmony_ci        panfrost_close_device(dev);
768bf215546Sopenharmony_ci        ralloc_free(pscreen);
769bf215546Sopenharmony_ci}
770bf215546Sopenharmony_ci
771bf215546Sopenharmony_cistatic uint64_t
772bf215546Sopenharmony_cipanfrost_get_timestamp(struct pipe_screen *_screen)
773bf215546Sopenharmony_ci{
774bf215546Sopenharmony_ci        return os_time_get_nano();
775bf215546Sopenharmony_ci}
776bf215546Sopenharmony_ci
777bf215546Sopenharmony_cistatic void
778bf215546Sopenharmony_cipanfrost_fence_reference(struct pipe_screen *pscreen,
779bf215546Sopenharmony_ci                         struct pipe_fence_handle **ptr,
780bf215546Sopenharmony_ci                         struct pipe_fence_handle *fence)
781bf215546Sopenharmony_ci{
782bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(pscreen);
783bf215546Sopenharmony_ci        struct pipe_fence_handle *old = *ptr;
784bf215546Sopenharmony_ci
785bf215546Sopenharmony_ci        if (pipe_reference(&old->reference, &fence->reference)) {
786bf215546Sopenharmony_ci                drmSyncobjDestroy(dev->fd, old->syncobj);
787bf215546Sopenharmony_ci                free(old);
788bf215546Sopenharmony_ci        }
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_ci        *ptr = fence;
791bf215546Sopenharmony_ci}
792bf215546Sopenharmony_ci
793bf215546Sopenharmony_cistatic int
794bf215546Sopenharmony_cipanfrost_fence_get_fd(struct pipe_screen *_screen,
795bf215546Sopenharmony_ci                       struct pipe_fence_handle *fence)
796bf215546Sopenharmony_ci{
797bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(_screen);
798bf215546Sopenharmony_ci        int fd = -1;
799bf215546Sopenharmony_ci        drmSyncobjExportSyncFile(dev->fd, fence->syncobj, &fd);
800bf215546Sopenharmony_ci        return fd;
801bf215546Sopenharmony_ci}
802bf215546Sopenharmony_ci
803bf215546Sopenharmony_cistatic bool
804bf215546Sopenharmony_cipanfrost_fence_finish(struct pipe_screen *pscreen,
805bf215546Sopenharmony_ci                      struct pipe_context *ctx,
806bf215546Sopenharmony_ci                      struct pipe_fence_handle *fence,
807bf215546Sopenharmony_ci                      uint64_t timeout)
808bf215546Sopenharmony_ci{
809bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(pscreen);
810bf215546Sopenharmony_ci        int ret;
811bf215546Sopenharmony_ci
812bf215546Sopenharmony_ci        if (fence->signaled)
813bf215546Sopenharmony_ci                return true;
814bf215546Sopenharmony_ci
815bf215546Sopenharmony_ci        uint64_t abs_timeout = os_time_get_absolute_timeout(timeout);
816bf215546Sopenharmony_ci        if (abs_timeout == OS_TIMEOUT_INFINITE)
817bf215546Sopenharmony_ci                abs_timeout = INT64_MAX;
818bf215546Sopenharmony_ci
819bf215546Sopenharmony_ci        ret = drmSyncobjWait(dev->fd, &fence->syncobj,
820bf215546Sopenharmony_ci                             1,
821bf215546Sopenharmony_ci                             abs_timeout, DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL,
822bf215546Sopenharmony_ci                             NULL);
823bf215546Sopenharmony_ci
824bf215546Sopenharmony_ci        fence->signaled = (ret >= 0);
825bf215546Sopenharmony_ci        return fence->signaled;
826bf215546Sopenharmony_ci}
827bf215546Sopenharmony_ci
828bf215546Sopenharmony_cistruct pipe_fence_handle *
829bf215546Sopenharmony_cipanfrost_fence_create(struct panfrost_context *ctx)
830bf215546Sopenharmony_ci{
831bf215546Sopenharmony_ci        struct pipe_fence_handle *f = calloc(1, sizeof(*f));
832bf215546Sopenharmony_ci        if (!f)
833bf215546Sopenharmony_ci                return NULL;
834bf215546Sopenharmony_ci
835bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(ctx->base.screen);
836bf215546Sopenharmony_ci        int fd = -1, ret;
837bf215546Sopenharmony_ci
838bf215546Sopenharmony_ci        /* Snapshot the last rendering out fence. We'd rather have another
839bf215546Sopenharmony_ci         * syncobj instead of a sync file, but this is all we get.
840bf215546Sopenharmony_ci         * (HandleToFD/FDToHandle just gives you another syncobj ID for the
841bf215546Sopenharmony_ci         * same syncobj).
842bf215546Sopenharmony_ci         */
843bf215546Sopenharmony_ci        ret = drmSyncobjExportSyncFile(dev->fd, ctx->syncobj, &fd);
844bf215546Sopenharmony_ci        if (ret || fd == -1) {
845bf215546Sopenharmony_ci                fprintf(stderr, "export failed\n");
846bf215546Sopenharmony_ci                goto err_free_fence;
847bf215546Sopenharmony_ci        }
848bf215546Sopenharmony_ci
849bf215546Sopenharmony_ci        ret = drmSyncobjCreate(dev->fd, 0, &f->syncobj);
850bf215546Sopenharmony_ci        if (ret) {
851bf215546Sopenharmony_ci                fprintf(stderr, "create syncobj failed\n");
852bf215546Sopenharmony_ci                goto err_close_fd;
853bf215546Sopenharmony_ci        }
854bf215546Sopenharmony_ci
855bf215546Sopenharmony_ci        ret = drmSyncobjImportSyncFile(dev->fd, f->syncobj, fd);
856bf215546Sopenharmony_ci        if (ret) {
857bf215546Sopenharmony_ci                fprintf(stderr, "create syncobj failed\n");
858bf215546Sopenharmony_ci                goto err_destroy_syncobj;
859bf215546Sopenharmony_ci        }
860bf215546Sopenharmony_ci
861bf215546Sopenharmony_ci        assert(f->syncobj != ctx->syncobj);
862bf215546Sopenharmony_ci        close(fd);
863bf215546Sopenharmony_ci        pipe_reference_init(&f->reference, 1);
864bf215546Sopenharmony_ci
865bf215546Sopenharmony_ci        return f;
866bf215546Sopenharmony_ci
867bf215546Sopenharmony_cierr_destroy_syncobj:
868bf215546Sopenharmony_ci        drmSyncobjDestroy(dev->fd, f->syncobj);
869bf215546Sopenharmony_cierr_close_fd:
870bf215546Sopenharmony_ci        close(fd);
871bf215546Sopenharmony_cierr_free_fence:
872bf215546Sopenharmony_ci        free(f);
873bf215546Sopenharmony_ci        return NULL;
874bf215546Sopenharmony_ci}
875bf215546Sopenharmony_ci
876bf215546Sopenharmony_cistatic const void *
877bf215546Sopenharmony_cipanfrost_screen_get_compiler_options(struct pipe_screen *pscreen,
878bf215546Sopenharmony_ci                                     enum pipe_shader_ir ir,
879bf215546Sopenharmony_ci                                     enum pipe_shader_type shader)
880bf215546Sopenharmony_ci{
881bf215546Sopenharmony_ci        return pan_screen(pscreen)->vtbl.get_compiler_options();
882bf215546Sopenharmony_ci}
883bf215546Sopenharmony_ci
884bf215546Sopenharmony_cistruct pipe_screen *
885bf215546Sopenharmony_cipanfrost_create_screen(int fd, struct renderonly *ro)
886bf215546Sopenharmony_ci{
887bf215546Sopenharmony_ci        /* Create the screen */
888bf215546Sopenharmony_ci        struct panfrost_screen *screen = rzalloc(NULL, struct panfrost_screen);
889bf215546Sopenharmony_ci
890bf215546Sopenharmony_ci        if (!screen)
891bf215546Sopenharmony_ci                return NULL;
892bf215546Sopenharmony_ci
893bf215546Sopenharmony_ci        struct panfrost_device *dev = pan_device(&screen->base);
894bf215546Sopenharmony_ci
895bf215546Sopenharmony_ci        /* Debug must be set first for pandecode to work correctly */
896bf215546Sopenharmony_ci        dev->debug = debug_get_flags_option("PAN_MESA_DEBUG", panfrost_debug_options, 0);
897bf215546Sopenharmony_ci        panfrost_open_device(screen, fd, dev);
898bf215546Sopenharmony_ci
899bf215546Sopenharmony_ci        if (dev->debug & PAN_DBG_NO_AFBC)
900bf215546Sopenharmony_ci                dev->has_afbc = false;
901bf215546Sopenharmony_ci
902bf215546Sopenharmony_ci        /* Bail early on unsupported hardware */
903bf215546Sopenharmony_ci        if (dev->model == NULL) {
904bf215546Sopenharmony_ci                debug_printf("panfrost: Unsupported model %X", dev->gpu_id);
905bf215546Sopenharmony_ci                panfrost_destroy_screen(&(screen->base));
906bf215546Sopenharmony_ci                return NULL;
907bf215546Sopenharmony_ci        }
908bf215546Sopenharmony_ci
909bf215546Sopenharmony_ci        dev->ro = ro;
910bf215546Sopenharmony_ci
911bf215546Sopenharmony_ci        screen->base.destroy = panfrost_destroy_screen;
912bf215546Sopenharmony_ci
913bf215546Sopenharmony_ci        screen->base.get_name = panfrost_get_name;
914bf215546Sopenharmony_ci        screen->base.get_vendor = panfrost_get_vendor;
915bf215546Sopenharmony_ci        screen->base.get_device_vendor = panfrost_get_device_vendor;
916bf215546Sopenharmony_ci        screen->base.get_param = panfrost_get_param;
917bf215546Sopenharmony_ci        screen->base.get_shader_param = panfrost_get_shader_param;
918bf215546Sopenharmony_ci        screen->base.get_compute_param = panfrost_get_compute_param;
919bf215546Sopenharmony_ci        screen->base.get_paramf = panfrost_get_paramf;
920bf215546Sopenharmony_ci        screen->base.get_timestamp = panfrost_get_timestamp;
921bf215546Sopenharmony_ci        screen->base.is_format_supported = panfrost_is_format_supported;
922bf215546Sopenharmony_ci        screen->base.query_dmabuf_modifiers = panfrost_query_dmabuf_modifiers;
923bf215546Sopenharmony_ci        screen->base.is_dmabuf_modifier_supported =
924bf215546Sopenharmony_ci               panfrost_is_dmabuf_modifier_supported;
925bf215546Sopenharmony_ci        screen->base.context_create = panfrost_create_context;
926bf215546Sopenharmony_ci        screen->base.get_compiler_options = panfrost_screen_get_compiler_options;
927bf215546Sopenharmony_ci        screen->base.fence_reference = panfrost_fence_reference;
928bf215546Sopenharmony_ci        screen->base.fence_finish = panfrost_fence_finish;
929bf215546Sopenharmony_ci        screen->base.fence_get_fd = panfrost_fence_get_fd;
930bf215546Sopenharmony_ci        screen->base.set_damage_region = panfrost_resource_set_damage_region;
931bf215546Sopenharmony_ci
932bf215546Sopenharmony_ci        panfrost_resource_screen_init(&screen->base);
933bf215546Sopenharmony_ci        pan_blend_shaders_init(dev);
934bf215546Sopenharmony_ci        panfrost_pool_init(&screen->indirect_draw.bin_pool, NULL, dev,
935bf215546Sopenharmony_ci                           PAN_BO_EXECUTE, 65536, "Indirect draw shaders",
936bf215546Sopenharmony_ci                           false, true);
937bf215546Sopenharmony_ci        panfrost_pool_init(&screen->blitter.bin_pool, NULL, dev, PAN_BO_EXECUTE,
938bf215546Sopenharmony_ci                           4096, "Blitter shaders", false, true);
939bf215546Sopenharmony_ci        panfrost_pool_init(&screen->blitter.desc_pool, NULL, dev, 0, 65536,
940bf215546Sopenharmony_ci                           "Blitter RSDs", false, true);
941bf215546Sopenharmony_ci        if (dev->arch == 4)
942bf215546Sopenharmony_ci                panfrost_cmdstream_screen_init_v4(screen);
943bf215546Sopenharmony_ci        else if (dev->arch == 5)
944bf215546Sopenharmony_ci                panfrost_cmdstream_screen_init_v5(screen);
945bf215546Sopenharmony_ci        else if (dev->arch == 6)
946bf215546Sopenharmony_ci                panfrost_cmdstream_screen_init_v6(screen);
947bf215546Sopenharmony_ci        else if (dev->arch == 7)
948bf215546Sopenharmony_ci                panfrost_cmdstream_screen_init_v7(screen);
949bf215546Sopenharmony_ci        else if (dev->arch == 9)
950bf215546Sopenharmony_ci                panfrost_cmdstream_screen_init_v9(screen);
951bf215546Sopenharmony_ci        else
952bf215546Sopenharmony_ci                unreachable("Unhandled architecture major");
953bf215546Sopenharmony_ci
954bf215546Sopenharmony_ci        return &screen->base;
955bf215546Sopenharmony_ci}
956