aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark2016-06-20 13:06:24 -0500
committerRob Clark2016-07-20 18:42:21 -0500
commit419a154dbef839b920689bea72aa9af41b2b114f (patch)
treeba0c9c5869dae77d3dc13e5019c6314e61ca624d /freedreno/kgsl
parentd93d697deb4a808890bc9c64ec453b2d2f2ebb7f (diff)
downloadexternal-libdrm-419a154dbef839b920689bea72aa9af41b2b114f.tar.gz
external-libdrm-419a154dbef839b920689bea72aa9af41b2b114f.tar.xz
external-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.c7
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,
173 kgsl_pipe_add_submit(to_kgsl_pipe(ring->pipe), kgsl_bo); 173 kgsl_pipe_add_submit(to_kgsl_pipe(ring->pipe), kgsl_bo);
174} 174}
175 175
176static void kgsl_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, 176static uint32_t kgsl_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
177 struct fd_ringbuffer *target, 177 struct fd_ringbuffer *target, uint32_t cmd_idx,
178 uint32_t submit_offset, uint32_t size) 178 uint32_t submit_offset, uint32_t size)
179{ 179{
180 struct kgsl_ringbuffer *target_ring = to_kgsl_ringbuffer(target); 180 struct kgsl_ringbuffer *target_ring = to_kgsl_ringbuffer(target);
181 assert(cmd_idx == 0);
181 (*ring->cur++) = target_ring->bo->gpuaddr + submit_offset; 182 (*ring->cur++) = target_ring->bo->gpuaddr + submit_offset;
183 return size;
182} 184}
183 185
184static void kgsl_ringbuffer_destroy(struct fd_ringbuffer *ring) 186static void kgsl_ringbuffer_destroy(struct fd_ringbuffer *ring)
@@ -213,6 +215,7 @@ drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
213 215
214 ring = &kgsl_ring->base; 216 ring = &kgsl_ring->base;
215 ring->funcs = &funcs; 217 ring->funcs = &funcs;
218 ring->size = size;
216 219
217 kgsl_ring->bo = kgsl_rb_bo_new(to_kgsl_pipe(pipe), size); 220 kgsl_ring->bo = kgsl_rb_bo_new(to_kgsl_pipe(pipe), size);
218 if (!kgsl_ring->bo) { 221 if (!kgsl_ring->bo) {