2 * © Copyright 2018 Alyssa Rosenzweig
3 * Copyright (C) 2019 Collabora, Ltd.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 #include "util/hash_table.h"
30 /* TODO: What does this actually have to be? */
33 /* Transient command stream pooling: command stream uploads try to simply copy
34 * into whereever we left off. If there isn't space, we allocate a new entry
35 * into the pool and copy there */
37 static struct panfrost_bo
*
38 panfrost_pool_alloc_backing(struct pan_pool
*pool
, size_t bo_sz
)
40 /* We don't know what the BO will be used for, so let's flag it
41 * RW and attach it to both the fragment and vertex/tiler jobs.
42 * TODO: if we want fine grained BO assignment we should pass
43 * flags to this function and keep the read/write,
44 * fragment/vertex+tiler pools separate.
46 struct panfrost_bo
*bo
= panfrost_bo_create(pool
->dev
, bo_sz
,
49 uintptr_t flags
= PAN_BO_ACCESS_PRIVATE
|
51 PAN_BO_ACCESS_VERTEX_TILER
|
52 PAN_BO_ACCESS_FRAGMENT
;
54 _mesa_hash_table_insert(pool
->bos
, bo
, (void *) flags
);
56 pool
->transient_bo
= bo
;
57 pool
->transient_offset
= 0;
63 panfrost_create_pool(void *memctx
, struct panfrost_device
*dev
,
64 unsigned create_flags
, bool prealloc
)
66 struct pan_pool pool
= {
68 .create_flags
= create_flags
,
69 .transient_offset
= 0,
73 pool
.bos
= _mesa_hash_table_create(memctx
, _mesa_hash_pointer
,
74 _mesa_key_pointer_equal
);
77 panfrost_pool_alloc_backing(&pool
, TRANSIENT_SLAB_SIZE
);
82 struct panfrost_transfer
83 panfrost_pool_alloc(struct pan_pool
*pool
, size_t sz
)
86 sz
= ALIGN_POT(sz
, ALIGNMENT
);
88 /* Find or create a suitable BO */
89 struct panfrost_bo
*bo
= pool
->transient_bo
;
90 unsigned offset
= pool
->transient_offset
;
92 /* If we don't fit, allocate a new backing */
93 if (unlikely(bo
== NULL
|| (offset
+ sz
) >= TRANSIENT_SLAB_SIZE
)) {
94 bo
= panfrost_pool_alloc_backing(pool
,
95 ALIGN_POT(MAX2(TRANSIENT_SLAB_SIZE
, sz
), 4096));
99 pool
->transient_offset
+= sz
;
101 struct panfrost_transfer ret
= {
102 .cpu
= bo
->cpu
+ offset
,
103 .gpu
= bo
->gpu
+ offset
,
111 panfrost_pool_upload(struct pan_pool
*pool
, const void *data
, size_t sz
)
113 struct panfrost_transfer transfer
= panfrost_pool_alloc(pool
, sz
);
114 memcpy(transfer
.cpu
, data
, sz
);