2 * Copyright (c) 2017-2019 Lima Project
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 #include "util/u_memory.h"
26 #include "util/u_blitter.h"
27 #include "util/u_upload_mgr.h"
28 #include "util/u_math.h"
29 #include "util/u_debug.h"
30 #include "util/ralloc.h"
31 #include "util/u_inlines.h"
32 #include "util/u_suballoc.h"
33 #include "util/hash_table.h"
35 #include "lima_screen.h"
36 #include "lima_context.h"
37 #include "lima_resource.h"
39 #include "lima_submit.h"
40 #include "lima_util.h"
41 #include "lima_fence.h"
43 #include <drm-uapi/lima_drm.h>
46 int lima_ctx_num_plb
= LIMA_CTX_PLB_DEF_NUM
;
49 lima_ctx_buff_va(struct lima_context
*ctx
, enum lima_ctx_buff buff
, unsigned submit
)
51 struct lima_ctx_buff_state
*cbs
= ctx
->buffer_state
+ buff
;
52 struct lima_resource
*res
= lima_resource(cbs
->res
);
54 if (submit
& LIMA_CTX_BUFF_SUBMIT_GP
)
55 lima_submit_add_bo(ctx
->gp_submit
, res
->bo
, LIMA_SUBMIT_BO_READ
);
56 if (submit
& LIMA_CTX_BUFF_SUBMIT_PP
)
57 lima_submit_add_bo(ctx
->pp_submit
, res
->bo
, LIMA_SUBMIT_BO_READ
);
59 return res
->bo
->va
+ cbs
->offset
;
63 lima_ctx_buff_map(struct lima_context
*ctx
, enum lima_ctx_buff buff
)
65 struct lima_ctx_buff_state
*cbs
= ctx
->buffer_state
+ buff
;
66 struct lima_resource
*res
= lima_resource(cbs
->res
);
68 return lima_bo_map(res
->bo
) + cbs
->offset
;
72 lima_ctx_buff_alloc(struct lima_context
*ctx
, enum lima_ctx_buff buff
,
73 unsigned size
, bool uploader
)
75 struct lima_ctx_buff_state
*cbs
= ctx
->buffer_state
+ buff
;
78 cbs
->size
= align(size
, 0x40);
81 u_upload_alloc(ctx
->uploader
, 0, cbs
->size
, 0x40, &cbs
->offset
,
84 u_suballocator_alloc(ctx
->suballocator
, cbs
->size
, 0x10,
85 &cbs
->offset
, &cbs
->res
);
91 lima_context_create_drm_ctx(struct lima_screen
*screen
)
93 struct drm_lima_ctx_create req
= {0};
95 int ret
= drmIoctl(screen
->fd
, DRM_IOCTL_LIMA_CTX_CREATE
, &req
);
103 lima_context_free_drm_ctx(struct lima_screen
*screen
, int id
)
105 struct drm_lima_ctx_free req
= {
109 drmIoctl(screen
->fd
, DRM_IOCTL_LIMA_CTX_FREE
, &req
);
113 lima_context_destroy(struct pipe_context
*pctx
)
115 struct lima_context
*ctx
= lima_context(pctx
);
116 struct lima_screen
*screen
= lima_screen(pctx
->screen
);
119 lima_submit_free(ctx
->pp_submit
);
121 lima_submit_free(ctx
->gp_submit
);
123 for (int i
= 0; i
< lima_ctx_buff_num
; i
++)
124 pipe_resource_reference(&ctx
->buffer_state
[i
].res
, NULL
);
126 lima_state_fini(ctx
);
129 util_blitter_destroy(ctx
->blitter
);
131 if (ctx
->suballocator
)
132 u_suballocator_destroy(ctx
->suballocator
);
135 u_upload_destroy(ctx
->uploader
);
137 slab_destroy_child(&ctx
->transfer_pool
);
139 for (int i
= 0; i
< LIMA_CTX_PLB_MAX_NUM
; i
++) {
141 lima_bo_free(ctx
->plb
[i
]);
142 if (ctx
->gp_tile_heap
[i
])
143 lima_bo_free(ctx
->gp_tile_heap
[i
]);
146 if (ctx
->plb_gp_stream
)
147 lima_bo_free(ctx
->plb_gp_stream
);
149 if (ctx
->plb_pp_stream
)
150 assert(!_mesa_hash_table_num_entries(ctx
->plb_pp_stream
));
152 lima_context_free_drm_ctx(screen
, ctx
->id
);
158 plb_pp_stream_hash(const void *key
)
160 return _mesa_hash_data(key
, sizeof(struct lima_ctx_plb_pp_stream_key
));
164 plb_pp_stream_compare(const void *key1
, const void *key2
)
166 return memcmp(key1
, key2
, sizeof(struct lima_ctx_plb_pp_stream_key
)) == 0;
169 struct pipe_context
*
170 lima_context_create(struct pipe_screen
*pscreen
, void *priv
, unsigned flags
)
172 struct lima_screen
*screen
= lima_screen(pscreen
);
173 struct lima_context
*ctx
;
175 ctx
= rzalloc(screen
, struct lima_context
);
179 ctx
->id
= lima_context_create_drm_ctx(screen
);
185 ctx
->base
.screen
= pscreen
;
186 ctx
->base
.destroy
= lima_context_destroy
;
188 lima_resource_context_init(ctx
);
189 lima_fence_context_init(ctx
);
190 lima_state_init(ctx
);
192 lima_program_init(ctx
);
193 lima_query_init(ctx
);
195 slab_create_child(&ctx
->transfer_pool
, &screen
->transfer_pool
);
197 ctx
->blitter
= util_blitter_create(&ctx
->base
);
201 ctx
->uploader
= u_upload_create_default(&ctx
->base
);
204 ctx
->base
.stream_uploader
= ctx
->uploader
;
205 ctx
->base
.const_uploader
= ctx
->uploader
;
207 /* for varying output which need not mmap */
209 u_suballocator_create(&ctx
->base
, 1024 * 1024, 0,
210 PIPE_USAGE_STREAM
, 0, false);
211 if (!ctx
->suballocator
)
214 util_dynarray_init(&ctx
->vs_cmd_array
, ctx
);
215 util_dynarray_init(&ctx
->plbu_cmd_array
, ctx
);
217 if (screen
->gpu_type
== DRM_LIMA_PARAM_GPU_ID_MALI450
)
218 ctx
->plb_max_blk
= 4096;
220 ctx
->plb_max_blk
= 512;
221 ctx
->plb_size
= ctx
->plb_max_blk
* LIMA_CTX_PLB_BLK_SIZE
;
222 ctx
->plb_gp_size
= ctx
->plb_max_blk
* 4;
224 for (int i
= 0; i
< lima_ctx_num_plb
; i
++) {
225 ctx
->plb
[i
] = lima_bo_create(screen
, ctx
->plb_size
, 0);
228 ctx
->gp_tile_heap
[i
] = lima_bo_create(screen
, gp_tile_heap_size
, 0);
229 if (!ctx
->gp_tile_heap
[i
])
233 unsigned plb_gp_stream_size
=
234 align(ctx
->plb_gp_size
* lima_ctx_num_plb
, LIMA_PAGE_SIZE
);
236 lima_bo_create(screen
, plb_gp_stream_size
, 0);
237 if (!ctx
->plb_gp_stream
)
239 lima_bo_map(ctx
->plb_gp_stream
);
241 /* plb gp stream is static for any framebuffer */
242 for (int i
= 0; i
< lima_ctx_num_plb
; i
++) {
243 uint32_t *plb_gp_stream
= ctx
->plb_gp_stream
->map
+ i
* ctx
->plb_gp_size
;
244 for (int j
= 0; j
< ctx
->plb_max_blk
; j
++)
245 plb_gp_stream
[j
] = ctx
->plb
[i
]->va
+ LIMA_CTX_PLB_BLK_SIZE
* j
;
248 if (screen
->gpu_type
== DRM_LIMA_PARAM_GPU_ID_MALI400
) {
249 ctx
->plb_pp_stream
= _mesa_hash_table_create(
250 ctx
, plb_pp_stream_hash
, plb_pp_stream_compare
);
251 if (!ctx
->plb_pp_stream
)
255 ctx
->gp_submit
= lima_submit_create(ctx
, LIMA_PIPE_GP
);
259 ctx
->pp_submit
= lima_submit_create(ctx
, LIMA_PIPE_PP
);
266 lima_context_destroy(&ctx
->base
);
271 lima_need_flush(struct lima_context
*ctx
, struct lima_bo
*bo
, bool write
)
273 return lima_submit_has_bo(ctx
->gp_submit
, bo
, write
) ||
274 lima_submit_has_bo(ctx
->pp_submit
, bo
, write
);
278 lima_is_scanout(struct lima_context
*ctx
)
280 /* If there is no color buffer, it's an FBO */
281 if (!ctx
->framebuffer
.base
.nr_cbufs
)
284 return ctx
->framebuffer
.base
.cbufs
[0]->texture
->bind
& PIPE_BIND_DISPLAY_TARGET
||
285 ctx
->framebuffer
.base
.cbufs
[0]->texture
->bind
& PIPE_BIND_SCANOUT
||
286 ctx
->framebuffer
.base
.cbufs
[0]->texture
->bind
& PIPE_BIND_SHARED
;