summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/panfrost/pan_screen.h
blob: 2f17e2dae726d05ab57d282de0f56016ccb93271 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/**************************************************************************
 *
 * Copyright 2018-2019 Alyssa Rosenzweig
 * Copyright 2018-2019 Collabora, Ltd.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/

#ifndef PAN_SCREEN_H
#define PAN_SCREEN_H

#include <xf86drm.h>
#include "pipe/p_screen.h"
#include "pipe/p_defines.h"
#include "renderonly/renderonly.h"
#include "util/u_dynarray.h"
#include "util/bitset.h"

#include <panfrost-misc.h>
#include "pan_allocate.h"

struct panfrost_batch;
struct panfrost_context;
struct panfrost_resource;
struct panfrost_screen;

/* Driver limits */
#define PAN_MAX_CONST_BUFFERS 16

/* Flags for allocated memory */

/* This memory region is executable */
#define PAN_ALLOCATE_EXECUTE            (1 << 0)

/* This memory region should be lazily allocated and grow-on-page-fault. Must
 * be used in conjunction with INVISIBLE */
#define PAN_ALLOCATE_GROWABLE           (1 << 1)

/* This memory region should not be mapped to the CPU */
#define PAN_ALLOCATE_INVISIBLE          (1 << 2)

/* This memory region will be used for varyings and needs to have the cache
 * bits twiddled accordingly */
#define PAN_ALLOCATE_COHERENT_LOCAL     (1 << 3)

/* This region may not be used immediately and will not mmap on allocate
 * (semantically distinct from INVISIBLE, which cannot never be mmaped) */
#define PAN_ALLOCATE_DELAY_MMAP         (1 << 4)

/* Transient slab size. This is a balance between fragmentation against cache
 * locality and ease of bookkeeping */

#define TRANSIENT_SLAB_PAGES (32) /* 128kb */
#define TRANSIENT_SLAB_SIZE (4096 * TRANSIENT_SLAB_PAGES)

/* Maximum number of transient slabs so we don't need dynamic arrays. Most
 * interesting Mali boards are 4GB RAM max, so if the entire RAM was filled
 * with transient slabs, you could never exceed (4GB / TRANSIENT_SLAB_SIZE)
 * allocations anyway. By capping, we can use a fixed-size bitset for tracking
 * free slabs, eliminating quite a bit of complexity. We can pack the free
 * state of 8 slabs into a single byte, so for 128kb transient slabs the bitset
 * occupies a cheap 4kb of memory */

#define MAX_TRANSIENT_SLABS (1024*1024 / TRANSIENT_SLAB_PAGES)

/* How many power-of-two levels in the BO cache do we want? 2^12
 * minimum chosen as it is the page size that all allocations are
 * rounded to */

#define MIN_BO_CACHE_BUCKET (12) /* 2^12 = 4KB */
#define MAX_BO_CACHE_BUCKET (22) /* 2^22 = 4MB */

/* Fencepost problem, hence the off-by-one */
#define NR_BO_CACHE_BUCKETS (MAX_BO_CACHE_BUCKET - MIN_BO_CACHE_BUCKET + 1)

struct panfrost_screen {
        struct pipe_screen base;
        int fd;

        /* Properties of the GPU in use */
        unsigned gpu_id;
        bool require_sfbd;

        drmVersionPtr kernel_version;

        struct renderonly *ro;

        pthread_mutex_t bo_cache_lock;

        /* The BO cache is a set of buckets with power-of-two sizes ranging
         * from 2^12 (4096, the page size) to 2^(12 + MAX_BO_CACHE_BUCKETS).
         * Each bucket is a linked list of free panfrost_bo objects. */

        struct list_head bo_cache[NR_BO_CACHE_BUCKETS];
};

static inline struct panfrost_screen *
pan_screen(struct pipe_screen *p)
{
        return (struct panfrost_screen *)p;
}

struct panfrost_bo *
panfrost_drm_create_bo(struct panfrost_screen *screen, size_t size,
                       uint32_t flags);
void
panfrost_drm_mmap_bo(struct panfrost_screen *screen, struct panfrost_bo *bo);
void
panfrost_drm_release_bo(struct panfrost_screen *screen, struct panfrost_bo *bo, bool cacheable);
struct panfrost_bo *
panfrost_drm_import_bo(struct panfrost_screen *screen, int fd);
int
panfrost_drm_export_bo(struct panfrost_screen *screen, const struct panfrost_bo *bo);
int
panfrost_drm_submit_vs_fs_batch(struct panfrost_batch *batch);
unsigned
panfrost_drm_query_gpu_version(struct panfrost_screen *screen);
int
panfrost_drm_init_context(struct panfrost_context *ctx);
void
panfrost_drm_fence_reference(struct pipe_screen *screen,
                             struct pipe_fence_handle **ptr,
                             struct pipe_fence_handle *fence);
boolean
panfrost_drm_fence_finish(struct pipe_screen *pscreen,
                          struct pipe_context *ctx,
                          struct pipe_fence_handle *fence,
                          uint64_t timeout);
struct panfrost_bo *
panfrost_bo_cache_fetch(
                struct panfrost_screen *screen,
                size_t size, uint32_t flags);

bool
panfrost_bo_cache_put(
                struct panfrost_screen *screen,
                struct panfrost_bo *bo);

void
panfrost_bo_cache_evict_all(
                struct panfrost_screen *screen);

#endif /* PAN_SCREEN_H */