• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
3  * The term “Broadcom” refers to Broadcom Inc.
4  * and/or its subsidiaries.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #ifndef SVGA_SCREEN_CACHE_H_
9 #define SVGA_SCREEN_CACHE_H_
10 
11 #include "svga_reg.h"
12 #include "svga3d_reg.h"
13 
14 #include "util/u_thread.h"
15 
16 #include "util/list.h"
17 
18 
19 /* Guess the storage size of cached surfaces and try and keep it under
20  * this amount:
21  */
22 #define SVGA_HOST_SURFACE_CACHE_BYTES (16 * 1024 * 1024)
23 
24 /* Maximum number of discrete surfaces in the cache:
25  */
26 #define SVGA_HOST_SURFACE_CACHE_SIZE 1024
27 
28 /* Number of hash buckets:
29  */
30 #define SVGA_HOST_SURFACE_CACHE_BUCKETS 256
31 
32 
33 struct svga_winsys_surface;
34 struct svga_screen;
35 struct svga_context;
36 
37 /**
38  * Same as svga_winsys_screen::surface_create.
39  */
40 struct svga_host_surface_cache_key
41 {
42    SVGA3dSurfaceAllFlags flags;
43    SVGA3dSurfaceFormat format;
44    SVGA3dSize size;
45    uint32_t numFaces:3;
46    uint32_t arraySize:16;
47    uint32_t numMipLevels:6;
48    uint32_t cachable:1;         /* False if this is a shared surface */
49    uint32_t sampleCount:5;
50    uint32_t scanout:1;
51    uint32_t coherent:1;
52    uint32_t persistent:1;
53 };
54 
55 
56 struct svga_host_surface_cache_entry
57 {
58    /**
59     * Head for the LRU list, svga_host_surface_cache::unused, and
60     * svga_host_surface_cache::empty
61     */
62    struct list_head head;
63 
64    /** Head for the bucket lists. */
65    struct list_head bucket_head;
66 
67    struct svga_host_surface_cache_key key;
68    struct svga_winsys_surface *handle;
69 
70    struct pipe_fence_handle *fence;
71 };
72 
73 
74 /**
75  * Cache of the host surfaces.
76  *
77  * A cache entry can be in the following stages:
78  * 1. empty (entry->handle = NULL)
79  * 2. holding a buffer in a validate list
80  * 3. holding a buffer in an invalidate list
81  * 4. holding a flushed buffer (not in any validate list) with an active fence
82  * 5. holding a flushed buffer with an expired fence
83  *
84  * An entry progresses from 1 -> 2 -> 3 -> 4 -> 5. When we need an entry to put a
85  * buffer into we preferentially take from 1, or from the least recently used
86  * buffer from 4/5.
87  */
88 struct svga_host_surface_cache
89 {
90    mtx_t mutex;
91 
92    /* Unused buffers are put in buckets to speed up lookups */
93    struct list_head bucket[SVGA_HOST_SURFACE_CACHE_BUCKETS];
94 
95    /* Entries with unused buffers, ordered from most to least recently used
96     * (3 and 4) */
97    struct list_head unused;
98 
99    /* Entries with buffers still in validate list (2) */
100    struct list_head validated;
101 
102    /* Entries with buffers still in invalidate list (3) */
103    struct list_head invalidated;
104 
105    /** Empty entries (1) */
106    struct list_head empty;
107 
108    /** The actual storage for the entries */
109    struct svga_host_surface_cache_entry entries[SVGA_HOST_SURFACE_CACHE_SIZE];
110 
111    /** Sum of sizes of all surfaces (in bytes) */
112    unsigned total_size;
113 };
114 
115 
116 void
117 svga_screen_cache_cleanup(struct svga_screen *svgascreen);
118 
119 void
120 svga_screen_cache_flush(struct svga_screen *svgascreen,
121                         struct svga_context *svga,
122                         struct pipe_fence_handle *fence);
123 
124 enum pipe_error
125 svga_screen_cache_init(struct svga_screen *svgascreen);
126 
127 
128 struct svga_winsys_surface *
129 svga_screen_surface_create(struct svga_screen *svgascreen,
130                            unsigned bind_flags, enum pipe_resource_usage usage,
131                            bool *invalidated,
132                            struct svga_host_surface_cache_key *key);
133 
134 void
135 svga_screen_surface_destroy(struct svga_screen *svgascreen,
136                             const struct svga_host_surface_cache_key *key,
137                             bool to_invalidate,
138                             struct svga_winsys_surface **handle);
139 
140 void
141 svga_screen_cache_dump(const struct svga_screen *svgascreen);
142 
143 unsigned
144 svga_surface_size(const struct svga_host_surface_cache_key *key);
145 
146 
147 #endif /* SVGA_SCREEN_CACHE_H_ */
148