diff options
author | Rob Clark <robclark@freedesktop.org> | 2016-06-20 14:06:24 -0400 |
---|---|---|
committer | Rob Clark <robclark@freedesktop.org> | 2016-07-20 19:42:21 -0400 |
commit | 419a154dbef839b920689bea72aa9af41b2b114f (patch) | |
tree | ba0c9c5869dae77d3dc13e5019c6314e61ca624d /freedreno/kgsl | |
parent | d93d697deb4a808890bc9c64ec453b2d2f2ebb7f (diff) | |
download | libdrm-419a154dbef839b920689bea72aa9af41b2b114f.tar.gz libdrm-419a154dbef839b920689bea72aa9af41b2b114f.tar.bz2 libdrm-419a154dbef839b920689bea72aa9af41b2b114f.zip |
freedreno: support growable cmdstream buffers
The issue that userspace needed to solve is that there is ~two orders of
magnitude size difference in cmdstream buffers (both for gmem commands
and for draw commands), and that the previous practice of allocating
worst-case sizes is quite wasteful. Previously a submit would be
constructed (for example) like:
CMD TARGET DESCRIPTION
g0 N gmem/tiling commands
b0 Y binning commands
d0 Y draw commands
Which, after the one non-IB-target cmd buffer is inserted into the
kernel controlled ringbuffer, looks like (not to scale):
b0: d0:
+-----+ +-----+
IB1 | ... | | ... |
+-----+ +-----+
^ ^
| |
+-----+ +-+---------+
g0: | | |
+----+----+----+----+----+----+----
IB0 | .. | IB | .. | IB | .. | IB | ...
+----+----+----+----+----+----+----
^ tile0 tile1
|
+-----------+
userspace |
~~~~~~~~~~~~~~~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel |
----+----+----
ringbuffer ... | IB | ...
----+----+----
Now, multiple physical cmdstream buffers per fd_ringbuffer are supported,
so this becomes:
CMD TARGET DESCRIPTION
g0 N
... N gmem/tiling commands
gN N
b0 Y
... Y binning commands
bN Y
d0 Y
... Y draw commands
dN Y
Which, after the non-IB-target cmd buffers (g0..gN) are inserted into
the kernel controlled ringbuffer, looks like:
b0: b1 d0: d1
+-----+ +-----+ +-----+ +-----+
IB1 | ... | | ... | ... | ... | | ... | ...
+-----+ +-----+ +-----+ +-----+
^ ^ ^ ^
| | | |
| +-+ | +-----+------+
+-----+ | | | |
| | +--+----------+ |
g0: | | | | | |
+----+----+----+----+----+----+---+----+----+----
IB0 | .. | IB | IB | .. | IB | IB |.. | IB | IB |...
+----+----+----+----+----+----+---+----+----+----
^ tile0 tile1
| to b0 to b1
| | | to|d0 to|d1
| | +----+ | +-+-----------+
| | | | | |
| +------+ | +-+-------------+ |
| g1: | | | | | |
| +----+----+----+----+----+----+---+----+----+----
IB0 | | .. | IB | IB | .. | IB | IB |.. | IB | IB |...
| +----+----+----+----+----+----+---+----+----+----
| ^ tileX tileY
| |
| +-----------+
+-----------+ |
userspace | |
~~~~~~~~~~~~~~~~~~~|~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel | |
----+----+----+----
ringbuffer ... | IB | IB | ...
----+----+----+----
Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'freedreno/kgsl')
-rw-r--r-- | freedreno/kgsl/kgsl_ringbuffer.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/freedreno/kgsl/kgsl_ringbuffer.c b/freedreno/kgsl/kgsl_ringbuffer.c index a0bc9d07..7b3298ab 100644 --- a/freedreno/kgsl/kgsl_ringbuffer.c +++ b/freedreno/kgsl/kgsl_ringbuffer.c @@ -173,12 +173,14 @@ static void kgsl_ringbuffer_emit_reloc(struct fd_ringbuffer *ring, kgsl_pipe_add_submit(to_kgsl_pipe(ring->pipe), kgsl_bo); } -static void kgsl_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, - struct fd_ringbuffer *target, +static uint32_t kgsl_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, + struct fd_ringbuffer *target, uint32_t cmd_idx, uint32_t submit_offset, uint32_t size) { struct kgsl_ringbuffer *target_ring = to_kgsl_ringbuffer(target); + assert(cmd_idx == 0); (*ring->cur++) = target_ring->bo->gpuaddr + submit_offset; + return size; } static void kgsl_ringbuffer_destroy(struct fd_ringbuffer *ring) @@ -213,6 +215,7 @@ drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, ring = &kgsl_ring->base; ring->funcs = &funcs; + ring->size = size; kgsl_ring->bo = kgsl_rb_bo_new(to_kgsl_pipe(pipe), size); if (!kgsl_ring->bo) { |