panfrost: Be more honest about PIPE_CAPs
[mesa.git] / src / gallium / drivers / panfrost / pan_screen.c
1 /**************************************************************************
2 *
3 * Copyright 2008 VMware, Inc.
4 * Copyright 2014 Broadcom
5 * Copyright 2018 Alyssa Rosenzweig
6 * Copyright 2019 Collabora, Ltd.
7 * All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sub license, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
16 *
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial portions
19 * of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
25 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 *
29 **************************************************************************/
30
31
32 #include "util/u_debug.h"
33 #include "util/u_memory.h"
34 #include "util/u_format.h"
35 #include "util/u_format_s3tc.h"
36 #include "util/u_video.h"
37 #include "util/u_screen.h"
38 #include "util/os_time.h"
39 #include "pipe/p_defines.h"
40 #include "pipe/p_screen.h"
41 #include "draw/draw_context.h"
42 #include <xf86drm.h>
43
44 #include <fcntl.h>
45
46 #include "drm-uapi/drm_fourcc.h"
47
48 #include "pan_screen.h"
49 #include "pan_resource.h"
50 #include "pan_public.h"
51 #include "pan_util.h"
52 #include "pandecode/decode.h"
53
54 #include "pan_context.h"
55 #include "midgard/midgard_compile.h"
56
57 static const struct debug_named_value debug_options[] = {
58 {"msgs", PAN_DBG_MSGS, "Print debug messages"},
59 {"trace", PAN_DBG_TRACE, "Trace the command stream"},
60 {"deqp", PAN_DBG_DEQP, "Hacks for dEQP"},
61 /* ^^ If Rob can do it, so can I */
62 DEBUG_NAMED_VALUE_END
63 };
64
65 DEBUG_GET_ONCE_FLAGS_OPTION(pan_debug, "PAN_MESA_DEBUG", debug_options, 0)
66
67 int pan_debug = 0;
68
69 static const char *
70 panfrost_get_name(struct pipe_screen *screen)
71 {
72 return "panfrost";
73 }
74
75 static const char *
76 panfrost_get_vendor(struct pipe_screen *screen)
77 {
78 return "panfrost";
79 }
80
81 static const char *
82 panfrost_get_device_vendor(struct pipe_screen *screen)
83 {
84 return "Arm";
85 }
86
87 static int
88 panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
89 {
90 /* We expose in-dev stuff for dEQP that we don't want apps to use yet */
91 bool is_deqp = pan_debug & PAN_DBG_DEQP;
92
93 switch (param) {
94 case PIPE_CAP_NPOT_TEXTURES:
95 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
96 case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
97 case PIPE_CAP_SM3:
98 case PIPE_CAP_POINT_SPRITE:
99 return 1;
100
101 case PIPE_CAP_MAX_RENDER_TARGETS:
102 return 1;
103
104 case PIPE_CAP_OCCLUSION_QUERY:
105 return 1;
106 case PIPE_CAP_QUERY_TIME_ELAPSED:
107 case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
108 case PIPE_CAP_QUERY_TIMESTAMP:
109 case PIPE_CAP_QUERY_SO_OVERFLOW:
110 return 0;
111
112 case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
113 case PIPE_CAP_TEXTURE_SWIZZLE:
114 return 1;
115
116 case PIPE_CAP_TGSI_INSTANCEID:
117 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
118 return is_deqp ? 1 : 0;
119
120 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
121 return is_deqp ? 4 : 0;
122 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
123 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
124 return is_deqp ? 64 : 0;
125
126 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
127 return is_deqp ? 256 : 0; /* for GL3 */
128
129 case PIPE_CAP_GLSL_FEATURE_LEVEL:
130 case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
131 return is_deqp ? 140 : 120;
132 case PIPE_CAP_ESSL_FEATURE_LEVEL:
133 return is_deqp ? 300 : 120;
134
135 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
136 return is_deqp ? 16 : 0;
137
138 case PIPE_CAP_CUBE_MAP_ARRAY:
139 return is_deqp;
140
141 /* TODO: Where does this req come from in practice? */
142 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
143 return 1;
144
145 case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
146 return 4096;
147 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
148 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
149 return 13;
150
151 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
152 case PIPE_CAP_INDEP_BLEND_ENABLE:
153 case PIPE_CAP_INDEP_BLEND_FUNC:
154 return 1;
155
156 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
157 /* Hardware is natively upper left */
158 return 0;
159
160 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
161 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
162 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
163 case PIPE_CAP_GENERATE_MIPMAP:
164 return 1;
165
166 case PIPE_CAP_SEAMLESS_CUBE_MAP:
167 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
168 return 1;
169
170 case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
171 return 0xffff;
172
173 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
174 return 1;
175
176 case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
177 return 65536;
178
179 case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
180 return 0;
181
182 case PIPE_CAP_ENDIANNESS:
183 return PIPE_ENDIAN_NATIVE;
184
185 case PIPE_CAP_SAMPLER_VIEW_TARGET:
186 return 1;
187
188 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
189 return -8;
190
191 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
192 return 7;
193
194 case PIPE_CAP_VENDOR_ID:
195 case PIPE_CAP_DEVICE_ID:
196 return 0xFFFFFFFF;
197
198 case PIPE_CAP_ACCELERATED:
199 case PIPE_CAP_UMA:
200 case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
201 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
202 case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
203 case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
204 return 1;
205
206 case PIPE_CAP_VIDEO_MEMORY: {
207 uint64_t system_memory;
208
209 if (!os_get_total_physical_memory(&system_memory))
210 return 0;
211
212 return (int)(system_memory >> 20);
213 }
214
215 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
216 return 4;
217
218 case PIPE_CAP_MAX_VARYINGS:
219 return 16;
220
221 default:
222 return u_pipe_screen_get_param_defaults(screen, param);
223 }
224 }
225
226 static int
227 panfrost_get_shader_param(struct pipe_screen *screen,
228 enum pipe_shader_type shader,
229 enum pipe_shader_cap param)
230 {
231 if (shader != PIPE_SHADER_VERTEX &&
232 shader != PIPE_SHADER_FRAGMENT) {
233 return 0;
234 }
235
236 /* this is probably not totally correct.. but it's a start: */
237 switch (param) {
238 case PIPE_SHADER_CAP_SCALAR_ISA:
239 return 0;
240
241 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
242 return 0;
243 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
244 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
245 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
246 return 16384;
247
248 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
249 return 1024;
250
251 case PIPE_SHADER_CAP_MAX_INPUTS:
252 return 16;
253
254 case PIPE_SHADER_CAP_MAX_OUTPUTS:
255 return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;
256
257 case PIPE_SHADER_CAP_MAX_TEMPS:
258 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
259
260 case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
261 return 16 * 1024 * sizeof(float);
262
263 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
264 return 16;
265
266 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
267 return 0;
268
269 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
270 return 1;
271 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
272 return 0;
273
274 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
275 return 0;
276
277 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
278 return 1;
279
280 case PIPE_SHADER_CAP_SUBROUTINES:
281 return 0;
282
283 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
284 return 0;
285
286 case PIPE_SHADER_CAP_INTEGERS:
287 return 1;
288
289 case PIPE_SHADER_CAP_INT64_ATOMICS:
290 case PIPE_SHADER_CAP_FP16:
291 case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
292 case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
293 case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
294 case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
295 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
296 return 0;
297
298 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
299 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
300 return 16; /* XXX: How many? */
301
302 case PIPE_SHADER_CAP_PREFERRED_IR:
303 return PIPE_SHADER_IR_NIR;
304
305 case PIPE_SHADER_CAP_SUPPORTED_IRS:
306 return 0;
307
308 case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
309 return 32;
310
311 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
312 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
313 case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
314 case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
315 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
316 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
317 return 0;
318
319 default:
320 fprintf(stderr, "unknown shader param %d\n", param);
321 return 0;
322 }
323
324 return 0;
325 }
326
327 static float
328 panfrost_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
329 {
330 switch (param) {
331 case PIPE_CAPF_MAX_LINE_WIDTH:
332
333 /* fall-through */
334 case PIPE_CAPF_MAX_LINE_WIDTH_AA:
335 return 255.0; /* arbitrary */
336
337 case PIPE_CAPF_MAX_POINT_WIDTH:
338
339 /* fall-through */
340 case PIPE_CAPF_MAX_POINT_WIDTH_AA:
341 return 255.0; /* arbitrary */
342
343 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
344 return 16.0;
345
346 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
347 return 16.0; /* arbitrary */
348
349 case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
350 case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
351 case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
352 return 0.0f;
353
354 default:
355 debug_printf("Unexpected PIPE_CAPF %d query\n", param);
356 return 0.0;
357 }
358 }
359
360 /**
361 * Query format support for creating a texture, drawing surface, etc.
362 * \param format the format to test
363 * \param type one of PIPE_TEXTURE, PIPE_SURFACE
364 */
365 static boolean
366 panfrost_is_format_supported( struct pipe_screen *screen,
367 enum pipe_format format,
368 enum pipe_texture_target target,
369 unsigned sample_count,
370 unsigned storage_sample_count,
371 unsigned bind)
372 {
373 const struct util_format_description *format_desc;
374
375 assert(target == PIPE_BUFFER ||
376 target == PIPE_TEXTURE_1D ||
377 target == PIPE_TEXTURE_1D_ARRAY ||
378 target == PIPE_TEXTURE_2D ||
379 target == PIPE_TEXTURE_2D_ARRAY ||
380 target == PIPE_TEXTURE_RECT ||
381 target == PIPE_TEXTURE_3D ||
382 target == PIPE_TEXTURE_CUBE ||
383 target == PIPE_TEXTURE_CUBE_ARRAY);
384
385 format_desc = util_format_description(format);
386
387 if (!format_desc)
388 return FALSE;
389
390 if (sample_count > 1)
391 return FALSE;
392
393 /* Format wishlist */
394 if (format == PIPE_FORMAT_Z24X8_UNORM || format == PIPE_FORMAT_X8Z24_UNORM)
395 return FALSE;
396
397 if (format == PIPE_FORMAT_A1B5G5R5_UNORM || format == PIPE_FORMAT_X1B5G5R5_UNORM)
398 return FALSE;
399
400 /* TODO */
401 if (format == PIPE_FORMAT_B5G5R5A1_UNORM)
402 return FALSE;
403
404 /* Don't confuse poorly written apps (workaround dEQP bug) that expect
405 * more alpha than they ask for */
406 bool scanout = bind & (PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET);
407 if (scanout && !util_format_is_rgba8_variant(format_desc))
408 return FALSE;
409
410 if (format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN &&
411 format_desc->layout != UTIL_FORMAT_LAYOUT_OTHER) {
412 /* Compressed formats not yet hooked up. */
413 return FALSE;
414 }
415
416 return TRUE;
417 }
418
419
420 static void
421 panfrost_destroy_screen(struct pipe_screen *pscreen)
422 {
423 struct panfrost_screen *screen = pan_screen(pscreen);
424 panfrost_resource_screen_deinit(screen);
425 ralloc_free(screen);
426 }
427
428 static void
429 panfrost_flush_frontbuffer(struct pipe_screen *_screen,
430 struct pipe_resource *resource,
431 unsigned level, unsigned layer,
432 void *context_private,
433 struct pipe_box *sub_box)
434 {
435 /* TODO: Display target integration */
436 }
437
438 static uint64_t
439 panfrost_get_timestamp(struct pipe_screen *_screen)
440 {
441 return os_time_get_nano();
442 }
443
444 static void
445 panfrost_fence_reference(struct pipe_screen *pscreen,
446 struct pipe_fence_handle **ptr,
447 struct pipe_fence_handle *fence)
448 {
449 panfrost_drm_fence_reference(pscreen, ptr, fence);
450 }
451
452 static boolean
453 panfrost_fence_finish(struct pipe_screen *pscreen,
454 struct pipe_context *ctx,
455 struct pipe_fence_handle *fence,
456 uint64_t timeout)
457 {
458 return panfrost_drm_fence_finish(pscreen, ctx, fence, timeout);
459 }
460
461 static const void *
462 panfrost_screen_get_compiler_options(struct pipe_screen *pscreen,
463 enum pipe_shader_ir ir,
464 enum pipe_shader_type shader)
465 {
466 return &midgard_nir_options;
467 }
468
469 struct pipe_screen *
470 panfrost_create_screen(int fd, struct renderonly *ro)
471 {
472 struct panfrost_screen *screen = rzalloc(NULL, struct panfrost_screen);
473
474 pan_debug = debug_get_option_pan_debug();
475
476 if (!screen)
477 return NULL;
478
479 if (ro) {
480 screen->ro = renderonly_dup(ro);
481 if (!screen->ro) {
482 fprintf(stderr, "Failed to dup renderonly object\n");
483 free(screen);
484 return NULL;
485 }
486 }
487
488 screen->fd = fd;
489
490 if (pan_debug & PAN_DBG_TRACE)
491 pandecode_initialize();
492
493 screen->base.destroy = panfrost_destroy_screen;
494
495 screen->base.get_name = panfrost_get_name;
496 screen->base.get_vendor = panfrost_get_vendor;
497 screen->base.get_device_vendor = panfrost_get_device_vendor;
498 screen->base.get_param = panfrost_get_param;
499 screen->base.get_shader_param = panfrost_get_shader_param;
500 screen->base.get_paramf = panfrost_get_paramf;
501 screen->base.get_timestamp = panfrost_get_timestamp;
502 screen->base.is_format_supported = panfrost_is_format_supported;
503 screen->base.context_create = panfrost_create_context;
504 screen->base.flush_frontbuffer = panfrost_flush_frontbuffer;
505 screen->base.get_compiler_options = panfrost_screen_get_compiler_options;
506 screen->base.fence_reference = panfrost_fence_reference;
507 screen->base.fence_finish = panfrost_fence_finish;
508
509 screen->last_fragment_flushed = true;
510 screen->last_job = NULL;
511
512 panfrost_resource_screen_init(screen);
513
514 return &screen->base;
515 }