gallium: add PIPE_CAP_MAX_VARYINGS
[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 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 **************************************************************************/
29
30
31 #include "util/u_memory.h"
32 #include "util/u_format.h"
33 #include "util/u_format_s3tc.h"
34 #include "util/u_video.h"
35 #include "util/u_screen.h"
36 #include "util/os_time.h"
37 #include "pipe/p_defines.h"
38 #include "pipe/p_screen.h"
39 #include "draw/draw_context.h"
40 #include <xf86drm.h>
41
42 #include <fcntl.h>
43
44 #include "drm_fourcc.h"
45
46 #include "pan_screen.h"
47 #include "pan_resource.h"
48 #include "pan_public.h"
49
50 #include "pan_context.h"
51 #include "midgard/midgard_compile.h"
52
53 struct panfrost_driver *panfrost_create_drm_driver(int fd);
54 struct panfrost_driver *panfrost_create_nondrm_driver(int fd);
55
56 static const char *
57 panfrost_get_name(struct pipe_screen *screen)
58 {
59 return "panfrost";
60 }
61
62 static const char *
63 panfrost_get_vendor(struct pipe_screen *screen)
64 {
65 return "panfrost";
66 }
67
68 static const char *
69 panfrost_get_device_vendor(struct pipe_screen *screen)
70 {
71 return "Arm";
72 }
73
74 static int
75 panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
76 {
77 switch (param) {
78 case PIPE_CAP_NPOT_TEXTURES:
79 case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
80 case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
81 return 1;
82
83 case PIPE_CAP_SM3:
84 case PIPE_CAP_POINT_SPRITE:
85 return 1;
86
87 case PIPE_CAP_MAX_RENDER_TARGETS:
88 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
89 return 1;
90
91 case PIPE_CAP_OCCLUSION_QUERY:
92 case PIPE_CAP_QUERY_TIME_ELAPSED:
93 case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
94 return 1; /* TODO: Queries */
95
96 case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
97 case PIPE_CAP_TEXTURE_SWIZZLE:
98 return 1;
99
100 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
101 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
102 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
103 return 13;
104
105 case PIPE_CAP_BLEND_EQUATION_SEPARATE:
106 return 1;
107
108 case PIPE_CAP_INDEP_BLEND_ENABLE:
109 return 1;
110
111 case PIPE_CAP_INDEP_BLEND_FUNC:
112 return 1;
113
114 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
115 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
116 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
117 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
118 return 1;
119
120 case PIPE_CAP_DEPTH_CLIP_DISABLE:
121 return 1;
122
123 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
124 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
125 return 16 * 4;
126
127 case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
128 case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
129 return 1024;
130
131 case PIPE_CAP_MAX_VERTEX_STREAMS:
132 return 1;
133
134 case PIPE_CAP_SHADER_STENCIL_EXPORT:
135 return 1;
136
137 case PIPE_CAP_SEAMLESS_CUBE_MAP:
138 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
139 return 1;
140
141 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
142 return 256; /* for GL3 */
143
144 case PIPE_CAP_CONDITIONAL_RENDER:
145 return 1;
146
147 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
148 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
149 case PIPE_CAP_VERTEX_COLOR_CLAMPED:
150 return 1;
151
152 case PIPE_CAP_GLSL_FEATURE_LEVEL:
153 return 330;
154
155 case PIPE_CAP_USER_VERTEX_BUFFERS: /* TODO */
156 case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
157 return 0;
158
159 case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
160 case PIPE_CAP_DOUBLES:
161 case PIPE_CAP_INT64:
162 case PIPE_CAP_INT64_DIVMOD:
163 return 1;
164
165 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
166 return 16;
167
168 case PIPE_CAP_MAX_VERTEX_ELEMENT_SRC_OFFSET:
169 return 0xffff;
170
171 case PIPE_CAP_QUERY_TIMESTAMP:
172 case PIPE_CAP_CUBE_MAP_ARRAY:
173 return 1;
174
175 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
176 return 1;
177
178 case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
179 return 65536;
180
181 case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
182 return 0;
183
184 case PIPE_CAP_TGSI_TEXCOORD:
185 return 1; /* XXX: What should this me exactly? */
186
187 case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
188 return 0;
189
190 case PIPE_CAP_MAX_VIEWPORTS:
191 return PIPE_MAX_VIEWPORTS;
192
193 case PIPE_CAP_ENDIANNESS:
194 return PIPE_ENDIAN_NATIVE;
195
196 case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
197 return 4;
198
199 case PIPE_CAP_TEXTURE_GATHER_SM5:
200 case PIPE_CAP_TEXTURE_QUERY_LOD:
201 case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
202 case PIPE_CAP_SAMPLER_VIEW_TARGET:
203 case PIPE_CAP_FAKE_SW_MSAA:
204 return 1;
205
206 case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
207 return -32;
208
209 case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
210 return 31;
211
212 case PIPE_CAP_DRAW_INDIRECT:
213 return 1;
214
215 case PIPE_CAP_QUERY_SO_OVERFLOW:
216 return 1;
217
218 case PIPE_CAP_VENDOR_ID:
219 return 0xFFFFFFFF;
220
221 case PIPE_CAP_DEVICE_ID:
222 return 0xFFFFFFFF;
223
224 case PIPE_CAP_ACCELERATED:
225 return 1;
226
227 case PIPE_CAP_VIDEO_MEMORY: {
228 uint64_t system_memory;
229
230 if (!os_get_total_physical_memory(&system_memory))
231 return 0;
232
233 return (int)(system_memory >> 20);
234 }
235
236 case PIPE_CAP_UMA:
237 return 1;
238
239 case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
240 case PIPE_CAP_CLIP_HALFZ:
241 case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
242 case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
243 case PIPE_CAP_FRAMEBUFFER_NO_ATTACHMENT:
244 case PIPE_CAP_CULL_DISTANCE:
245 case PIPE_CAP_COPY_BETWEEN_COMPRESSED_AND_PLAIN_FORMATS:
246 case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
247 case PIPE_CAP_CLEAR_TEXTURE:
248 return 1;
249
250 case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
251 return 4;
252
253 case PIPE_CAP_MAX_VARYINGS:
254 return 16;
255
256 default:
257 return u_pipe_screen_get_param_defaults(screen, param);
258 }
259 }
260
261 static int
262 panfrost_get_shader_param(struct pipe_screen *screen,
263 enum pipe_shader_type shader,
264 enum pipe_shader_cap param)
265 {
266 if (shader != PIPE_SHADER_VERTEX &&
267 shader != PIPE_SHADER_FRAGMENT) {
268 return 0;
269 }
270
271 /* this is probably not totally correct.. but it's a start: */
272 switch (param) {
273 case PIPE_SHADER_CAP_SCALAR_ISA:
274 return 0;
275
276 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
277 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
278 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
279 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
280 return 16384;
281
282 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
283 return 1024;
284
285 case PIPE_SHADER_CAP_MAX_INPUTS:
286 return 16;
287
288 case PIPE_SHADER_CAP_MAX_OUTPUTS:
289 return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;
290
291 case PIPE_SHADER_CAP_MAX_TEMPS:
292 return 256; /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
293
294 case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
295 return 16 * 1024 * sizeof(float);
296
297 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
298 return 1;
299
300 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
301 return 0;
302
303 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
304 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
305 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
306 return 0;
307
308 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
309 return 1;
310
311 case PIPE_SHADER_CAP_SUBROUTINES:
312 return 0;
313
314 case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
315 return 0;
316
317 case PIPE_SHADER_CAP_INTEGERS:
318 return 1;
319
320 case PIPE_SHADER_CAP_INT64_ATOMICS:
321 case PIPE_SHADER_CAP_FP16:
322 case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
323 case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
324 case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
325 case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
326 case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
327 return 0;
328
329 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
330 case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
331 return 16; /* XXX: How many? */
332
333 case PIPE_SHADER_CAP_PREFERRED_IR:
334 return PIPE_SHADER_IR_NIR;
335
336 case PIPE_SHADER_CAP_SUPPORTED_IRS:
337 return 0;
338
339 case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
340 return 32;
341
342 case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
343 case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
344 case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
345 case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
346 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
347 case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
348 return 0;
349
350 default:
351 fprintf(stderr, "unknown shader param %d\n", param);
352 return 0;
353 }
354
355 return 0;
356 }
357
358 static float
359 panfrost_get_paramf(struct pipe_screen *screen, enum pipe_capf param)
360 {
361 switch (param) {
362 case PIPE_CAPF_MAX_LINE_WIDTH:
363
364 /* fall-through */
365 case PIPE_CAPF_MAX_LINE_WIDTH_AA:
366 return 255.0; /* arbitrary */
367
368 case PIPE_CAPF_MAX_POINT_WIDTH:
369
370 /* fall-through */
371 case PIPE_CAPF_MAX_POINT_WIDTH_AA:
372 return 255.0; /* arbitrary */
373
374 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
375 return 16.0;
376
377 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
378 return 16.0; /* arbitrary */
379
380 default:
381 debug_printf("Unexpected PIPE_CAPF %d query\n", param);
382 return 0.0;
383 }
384 }
385
386 /**
387 * Query format support for creating a texture, drawing surface, etc.
388 * \param format the format to test
389 * \param type one of PIPE_TEXTURE, PIPE_SURFACE
390 */
391 static boolean
392 panfrost_is_format_supported( struct pipe_screen *screen,
393 enum pipe_format format,
394 enum pipe_texture_target target,
395 unsigned sample_count,
396 unsigned storage_sample_count,
397 unsigned bind)
398 {
399 const struct util_format_description *format_desc;
400
401 assert(target == PIPE_BUFFER ||
402 target == PIPE_TEXTURE_1D ||
403 target == PIPE_TEXTURE_1D_ARRAY ||
404 target == PIPE_TEXTURE_2D ||
405 target == PIPE_TEXTURE_2D_ARRAY ||
406 target == PIPE_TEXTURE_RECT ||
407 target == PIPE_TEXTURE_3D ||
408 target == PIPE_TEXTURE_CUBE ||
409 target == PIPE_TEXTURE_CUBE_ARRAY);
410
411 format_desc = util_format_description(format);
412
413 if (!format_desc)
414 return FALSE;
415
416 if (sample_count > 1)
417 return FALSE;
418
419 /* Format wishlist */
420 if (format == PIPE_FORMAT_Z24X8_UNORM || format == PIPE_FORMAT_X8Z24_UNORM)
421 return FALSE;
422
423 if (bind & PIPE_BIND_RENDER_TARGET) {
424 /* We don't support rendering into anything but RGBA8 yet. We
425 * need more formats for spec compliance, but for now, honesty
426 * is the best policy <3 */
427
428 if (!util_format_is_rgba8_variant(format_desc))
429 return FALSE;
430
431 if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
432 return FALSE;
433
434 /*
435 * Although possible, it is unnatural to render into compressed or YUV
436 * surfaces. So disable these here to avoid going into weird paths
437 * inside the state trackers.
438 */
439 if (format_desc->block.width != 1 ||
440 format_desc->block.height != 1)
441 return FALSE;
442 }
443
444 if (bind & PIPE_BIND_DEPTH_STENCIL) {
445 if (format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
446 return FALSE;
447 }
448
449 if (format_desc->layout == UTIL_FORMAT_LAYOUT_BPTC ||
450 format_desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
451 /* Compressed formats not yet hooked up. */
452 return FALSE;
453 }
454
455 if ((bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) &&
456 ((bind & PIPE_BIND_DISPLAY_TARGET) == 0) &&
457 target != PIPE_BUFFER) {
458 const struct util_format_description *desc =
459 util_format_description(format);
460
461 if (desc->nr_channels == 3 && desc->is_array) {
462 /* Don't support any 3-component formats for rendering/texturing
463 * since we don't support the corresponding 8-bit 3 channel UNORM
464 * formats. This allows us to support GL_ARB_copy_image between
465 * GL_RGB8 and GL_RGB8UI, for example. Otherwise, we may be asked to
466 * do a resource copy between PIPE_FORMAT_R8G8B8_UINT and
467 * PIPE_FORMAT_R8G8B8X8_UNORM, for example, which will not work
468 * (different bpp).
469 */
470 return FALSE;
471 }
472 }
473
474 return TRUE;
475 }
476
477
478 static void
479 panfrost_destroy_screen( struct pipe_screen *screen )
480 {
481 FREE(screen);
482 }
483
484 static void
485 panfrost_flush_frontbuffer(struct pipe_screen *_screen,
486 struct pipe_resource *resource,
487 unsigned level, unsigned layer,
488 void *context_private,
489 struct pipe_box *sub_box)
490 {
491 /* TODO: Display target integration */
492 }
493
494 static uint64_t
495 panfrost_get_timestamp(struct pipe_screen *_screen)
496 {
497 return os_time_get_nano();
498 }
499
500 static void
501 panfrost_fence_reference(struct pipe_screen *screen,
502 struct pipe_fence_handle **ptr,
503 struct pipe_fence_handle *fence)
504 {
505 *ptr = fence;
506 }
507
508 static boolean
509 panfrost_fence_finish(struct pipe_screen *screen,
510 struct pipe_context *ctx,
511 struct pipe_fence_handle *fence,
512 uint64_t timeout)
513 {
514 assert(fence);
515 return TRUE;
516 }
517
518 static const void *
519 panfrost_screen_get_compiler_options(struct pipe_screen *pscreen,
520 enum pipe_shader_ir ir,
521 enum pipe_shader_type shader)
522 {
523 return &midgard_nir_options;
524 }
525
526 struct pipe_screen *
527 panfrost_create_screen(int fd, struct renderonly *ro, bool is_drm)
528 {
529 struct panfrost_screen *screen = CALLOC_STRUCT(panfrost_screen);
530
531 if (!screen)
532 return NULL;
533
534 if (ro) {
535 screen->ro = renderonly_dup(ro);
536 if (!screen->ro) {
537 fprintf(stderr, "Failed to dup renderonly object\n");
538 free(screen);
539 return NULL;
540 }
541 }
542
543 if (is_drm) {
544 screen->driver = panfrost_create_drm_driver(fd);
545 } else {
546 #ifdef PAN_NONDRM_OVERLAY
547 screen->driver = panfrost_create_nondrm_driver(fd);
548 #else
549 fprintf(stderr, "Legacy (non-DRM) operation requires out-of-tree overlay\n");
550 return NULL;
551 #endif
552 }
553
554 #ifdef DUMP_PERFORMANCE_COUNTERS
555 screen->driver->allocate_slab(screen, &screen->perf_counters, 64, true, 0, 0, 0);
556 screen->driver->enable_counters(screen);
557 #endif
558
559 screen->base.destroy = panfrost_destroy_screen;
560
561 screen->base.get_name = panfrost_get_name;
562 screen->base.get_vendor = panfrost_get_vendor;
563 screen->base.get_device_vendor = panfrost_get_device_vendor;
564 screen->base.get_param = panfrost_get_param;
565 screen->base.get_shader_param = panfrost_get_shader_param;
566 screen->base.get_paramf = panfrost_get_paramf;
567 screen->base.get_timestamp = panfrost_get_timestamp;
568 screen->base.is_format_supported = panfrost_is_format_supported;
569 screen->base.context_create = panfrost_create_context;
570 screen->base.flush_frontbuffer = panfrost_flush_frontbuffer;
571 screen->base.get_compiler_options = panfrost_screen_get_compiler_options;
572 screen->base.fence_reference = panfrost_fence_reference;
573 screen->base.fence_finish = panfrost_fence_finish;
574
575 screen->last_fragment_id = -1;
576 screen->last_fragment_flushed = true;
577
578 panfrost_resource_screen_init(screen);
579
580 return &screen->base;
581 }