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