1 /*
2 * Copyright (c) 2009-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
9 #include "vmw_screen.h"
10
11 #include "vmw_buffer.h"
12 #include "vmw_fence.h"
13
14 #include "pipebuffer/pb_buffer.h"
15 #include "pipebuffer/pb_bufmgr.h"
16
17 /**
18 * vmw_pools_cleanup - Destroy the buffer pools.
19 *
20 * @vws: pointer to a struct vmw_winsys_screen.
21 */
22 void
vmw_pools_cleanup(struct vmw_winsys_screen * vws)23 vmw_pools_cleanup(struct vmw_winsys_screen *vws)
24 {
25 if (vws->pools.dma_slab_fenced)
26 vws->pools.dma_slab_fenced->destroy
27 (vws->pools.dma_slab_fenced);
28 if (vws->pools.dma_slab)
29 vws->pools.dma_slab->destroy(vws->pools.dma_slab);
30 if (vws->pools.dma_fenced)
31 vws->pools.dma_fenced->destroy(vws->pools.dma_fenced);
32 if (vws->pools.dma_cache)
33 vws->pools.dma_cache->destroy(vws->pools.dma_cache);
34
35 if (vws->pools.query_fenced)
36 vws->pools.query_fenced->destroy(vws->pools.query_fenced);
37 if (vws->pools.query_mm)
38 vws->pools.query_mm->destroy(vws->pools.query_mm);
39
40 if (vws->pools.dma_mm)
41 vws->pools.dma_mm->destroy(vws->pools.dma_mm);
42 if (vws->pools.dma_base)
43 vws->pools.dma_base->destroy(vws->pools.dma_base);
44 }
45
46
47 /**
48 * vmw_query_pools_init - Create a pool of query buffers.
49 *
50 * @vws: Pointer to a struct vmw_winsys_screen.
51 *
52 * Typically this pool should be created on demand when we
53 * detect that the app will be using queries. There's nothing
54 * special with this pool other than the backing kernel buffer sizes,
55 * which are limited to 8192.
56 * If there is a performance issue with allocation and freeing of the
57 * query slabs, it should be easily fixable by allocating them out
58 * of a buffer cache.
59 */
60 bool
vmw_query_pools_init(struct vmw_winsys_screen * vws)61 vmw_query_pools_init(struct vmw_winsys_screen *vws)
62 {
63 struct pb_desc desc;
64
65 desc.alignment = 16;
66 desc.usage = ~(VMW_BUFFER_USAGE_SHARED | VMW_BUFFER_USAGE_SYNC);
67
68 vws->pools.query_mm = pb_slab_range_manager_create(vws->pools.dma_base, 16, 128,
69 VMW_QUERY_POOL_SIZE,
70 &desc);
71 if (!vws->pools.query_mm)
72 return false;
73
74 vws->pools.query_fenced = simple_fenced_bufmgr_create(
75 vws->pools.query_mm, vws->fence_ops);
76
77 if(!vws->pools.query_fenced)
78 goto out_no_query_fenced;
79
80 return true;
81
82 out_no_query_fenced:
83 vws->pools.query_mm->destroy(vws->pools.query_mm);
84 return false;
85 }
86
87 /**
88 * vmw_pool_init - Create a pool of buffers.
89 *
90 * @vws: Pointer to a struct vmw_winsys_screen.
91 */
92 bool
vmw_pools_init(struct vmw_winsys_screen * vws)93 vmw_pools_init(struct vmw_winsys_screen *vws)
94 {
95 struct pb_desc desc;
96
97 vws->pools.dma_base = vmw_dma_bufmgr_create(vws);
98 if (!vws->pools.dma_base)
99 goto error;
100
101 /*
102 * A managed pool for DMA buffers.
103 */
104 vws->pools.dma_mm = mm_bufmgr_create(vws->pools.dma_base,
105 VMW_GMR_POOL_SIZE,
106 12 /* 4096 alignment */);
107 if(!vws->pools.dma_mm)
108 goto error;
109
110 vws->pools.dma_cache =
111 pb_cache_manager_create(vws->pools.dma_base, 100000, 2.0f,
112 VMW_BUFFER_USAGE_SHARED,
113 64 * 1024 * 1024);
114
115 if (!vws->pools.dma_cache)
116 goto error;
117
118 vws->pools.dma_fenced =
119 simple_fenced_bufmgr_create(vws->pools.dma_cache,
120 vws->fence_ops);
121
122 if(!vws->pools.dma_fenced)
123 goto error;
124
125 /*
126 * The slab pool allocates buffers directly from the kernel except
127 * for very small buffers which are allocated from a slab in order
128 * not to waste memory, since a kernel buffer is a minimum 4096 bytes.
129 *
130 * Here we use it only for emergency in the case our pre-allocated
131 * managed buffer pool runs out of memory.
132 */
133 desc.alignment = 64;
134 desc.usage = ~(SVGA_BUFFER_USAGE_PINNED | VMW_BUFFER_USAGE_SHARED |
135 VMW_BUFFER_USAGE_SYNC);
136 vws->pools.dma_slab =
137 pb_slab_range_manager_create(vws->pools.dma_cache,
138 64,
139 8192,
140 16384,
141 &desc);
142 if(!vws->pools.dma_slab)
143 goto error;
144
145 vws->pools.dma_slab_fenced =
146 simple_fenced_bufmgr_create(vws->pools.dma_slab,
147 vws->fence_ops);
148 if (!vws->pools.dma_slab_fenced)
149 goto error;
150
151 vws->pools.query_fenced = NULL;
152 vws->pools.query_mm = NULL;
153
154 return true;
155
156 error:
157 vmw_pools_cleanup(vws);
158 return false;
159 }
160