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 */
42 struct panfrost_transfer
43 panfrost_allocate_transient(struct panfrost_batch
*batch
, size_t sz
)
45 struct panfrost_screen
*screen
= pan_screen(batch
->ctx
->base
.screen
);
48 sz
= ALIGN_POT(sz
, ALIGNMENT
);
50 /* Find or create a suitable BO */
51 struct panfrost_bo
*bo
= NULL
;
55 bool fits_in_current
= (batch
->transient_offset
+ sz
) < TRANSIENT_SLAB_SIZE
;
57 if (likely(batch
->transient_bo
&& fits_in_current
)) {
58 /* We can reuse the current BO, so get it */
59 bo
= batch
->transient_bo
;
61 /* Use the specified offset */
62 offset
= batch
->transient_offset
;
63 batch
->transient_offset
= offset
+ sz
;
65 size_t bo_sz
= sz
< TRANSIENT_SLAB_SIZE
?
66 TRANSIENT_SLAB_SIZE
: ALIGN_POT(sz
, 4096);
68 /* We can't reuse the current BO, but we can create a new one. */
69 bo
= panfrost_bo_create(screen
, bo_sz
, 0);
70 panfrost_batch_add_bo(batch
, bo
);
72 /* Creating a BO adds a reference, and then the job adds a
73 * second one. So we need to pop back one reference */
74 panfrost_bo_unreference(bo
);
76 if (sz
< TRANSIENT_SLAB_SIZE
) {
77 batch
->transient_bo
= bo
;
78 batch
->transient_offset
= offset
+ sz
;
82 struct panfrost_transfer ret
= {
83 .cpu
= bo
->cpu
+ offset
,
84 .gpu
= bo
->gpu
+ offset
,
92 panfrost_upload_transient(struct panfrost_batch
*batch
, const void *data
,
95 struct panfrost_transfer transfer
= panfrost_allocate_transient(batch
, sz
);
96 memcpy(transfer
.cpu
, data
, sz
);