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
30 #include <panfrost-misc.h>
31 #include <panfrost-job.h>
33 #include "pan_context.h"
35 /* TODO: What does this actually have to be? */
38 /* Transient command stream pooling: command stream uploads try to simply copy
39 * into whereever we left off. If there isn't space, we allocate a new entry
40 * into the pool and copy there */
43 panfrost_create_pool(void *memctx
, struct panfrost_device
*dev
)
45 struct pan_pool pool
= {
47 .transient_offset
= 0,
51 pool
.bos
= _mesa_hash_table_create(memctx
, _mesa_hash_pointer
,
52 _mesa_key_pointer_equal
);
58 struct panfrost_transfer
59 panfrost_pool_alloc(struct pan_pool
*pool
, size_t sz
)
62 sz
= ALIGN_POT(sz
, ALIGNMENT
);
64 /* Find or create a suitable BO */
65 struct panfrost_bo
*bo
= NULL
;
69 bool fits_in_current
= (pool
->transient_offset
+ sz
) < TRANSIENT_SLAB_SIZE
;
71 if (likely(pool
->transient_bo
&& fits_in_current
)) {
72 /* We can reuse the current BO, so get it */
73 bo
= pool
->transient_bo
;
75 /* Use the specified offset */
76 offset
= pool
->transient_offset
;
77 pool
->transient_offset
= offset
+ sz
;
79 size_t bo_sz
= sz
< TRANSIENT_SLAB_SIZE
?
80 TRANSIENT_SLAB_SIZE
: ALIGN_POT(sz
, 4096);
82 /* We can't reuse the current BO, but we can create a new one.
83 * We don't know what the BO will be used for, so let's flag it
84 * RW and attach it to both the fragment and vertex/tiler jobs.
85 * TODO: if we want fine grained BO assignment we should pass
86 * flags to this function and keep the read/write,
87 * fragment/vertex+tiler pools separate.
89 bo
= panfrost_bo_create(pool
->dev
, bo_sz
, 0);
91 uintptr_t flags
= PAN_BO_ACCESS_PRIVATE
|
93 PAN_BO_ACCESS_VERTEX_TILER
|
94 PAN_BO_ACCESS_FRAGMENT
;
96 _mesa_hash_table_insert(pool
->bos
, bo
, (void *) flags
);
98 if (sz
< TRANSIENT_SLAB_SIZE
) {
99 pool
->transient_bo
= bo
;
100 pool
->transient_offset
= offset
+ sz
;
104 struct panfrost_transfer ret
= {
105 .cpu
= bo
->cpu
+ offset
,
106 .gpu
= bo
->gpu
+ offset
,
114 panfrost_pool_upload(struct pan_pool
*pool
, const void *data
, size_t sz
)
116 struct panfrost_transfer transfer
= panfrost_pool_alloc(pool
, sz
);
117 memcpy(transfer
.cpu
, data
, sz
);