freedreno: add fd_ringbuffer_new_object()

Add new API for reusable "state objects" which can be re-used multiple
times.  Backend implementation for msm will follow.  (Probably not
needed to support this for any device that uses kgsl backend, since this
is mostly useful for a5xx+.)

Signed-off-by: Rob Clark <robclark@freedesktop.org>
main
Rob Clark 2018-07-22 11:44:15 -04:00
parent 4519db23ef
commit fcbf206aa2
8 changed files with 62 additions and 10 deletions

View File

@ -46,10 +46,12 @@ fd_ringbuffer_emit_reloc_ring_full
fd_ringbuffer_flush fd_ringbuffer_flush
fd_ringbuffer_grow fd_ringbuffer_grow
fd_ringbuffer_new fd_ringbuffer_new
fd_ringbuffer_new_object
fd_ringbuffer_reloc fd_ringbuffer_reloc
fd_ringbuffer_reloc2 fd_ringbuffer_reloc2
fd_ringbuffer_reset fd_ringbuffer_reset
fd_ringbuffer_set_parent fd_ringbuffer_set_parent
fd_ringbuffer_size
fd_ringbuffer_timestamp fd_ringbuffer_timestamp
fd_ringmarker_del fd_ringmarker_del
fd_ringmarker_dwords fd_ringmarker_dwords

View File

@ -114,8 +114,13 @@ drm_private int fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo);
/* for where @table_lock is already held: */ /* for where @table_lock is already held: */
drm_private void fd_device_del_locked(struct fd_device *dev); drm_private void fd_device_del_locked(struct fd_device *dev);
enum fd_ringbuffer_flags {
FD_RINGBUFFER_OBJECT = 0x1,
};
struct fd_pipe_funcs { struct fd_pipe_funcs {
struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size); struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size,
enum fd_ringbuffer_flags flags);
int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value); int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value);
int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout); int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout);
void (*destroy)(struct fd_pipe *pipe); void (*destroy)(struct fd_pipe *pipe);

View File

@ -32,15 +32,17 @@
#include "freedreno_priv.h" #include "freedreno_priv.h"
#include "freedreno_ringbuffer.h" #include "freedreno_ringbuffer.h"
struct fd_ringbuffer * static struct fd_ringbuffer *
fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size) ringbuffer_new(struct fd_pipe *pipe, uint32_t size,
enum fd_ringbuffer_flags flags)
{ {
struct fd_ringbuffer *ring; struct fd_ringbuffer *ring;
ring = pipe->funcs->ringbuffer_new(pipe, size); ring = pipe->funcs->ringbuffer_new(pipe, size, flags);
if (!ring) if (!ring)
return NULL; return NULL;
ring->flags = flags;
ring->pipe = pipe; ring->pipe = pipe;
ring->start = ring->funcs->hostptr(ring); ring->start = ring->funcs->hostptr(ring);
ring->end = &(ring->start[ring->size/4]); ring->end = &(ring->start[ring->size/4]);
@ -50,6 +52,23 @@ fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
return ring; return ring;
} }
struct fd_ringbuffer *
fd_ringbuffer_new(struct fd_pipe *pipe, uint32_t size)
{
return ringbuffer_new(pipe, size, 0);
}
struct fd_ringbuffer *
fd_ringbuffer_new_object(struct fd_pipe *pipe, uint32_t size)
{
/* we can't really support "growable" rb's in general for
* stateobj's since we need a single gpu addr (ie. can't
* do the trick of a chain of IB packets):
*/
assert(size);
return ringbuffer_new(pipe, size, FD_RINGBUFFER_OBJECT);
}
void fd_ringbuffer_del(struct fd_ringbuffer *ring) void fd_ringbuffer_del(struct fd_ringbuffer *ring)
{ {
fd_ringbuffer_reset(ring); fd_ringbuffer_reset(ring);
@ -63,6 +82,8 @@ void fd_ringbuffer_del(struct fd_ringbuffer *ring)
void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring, void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
struct fd_ringbuffer *parent) struct fd_ringbuffer *parent)
{ {
/* state objects should not be parented! */
assert(!(ring->flags & FD_RINGBUFFER_OBJECT));
ring->parent = parent; ring->parent = parent;
} }
@ -151,6 +172,21 @@ fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring,
return ring->funcs->emit_reloc_ring(ring, target, cmd_idx, 0, size); return ring->funcs->emit_reloc_ring(ring, target, cmd_idx, 0, size);
} }
uint32_t
fd_ringbuffer_size(struct fd_ringbuffer *ring)
{
/* only really needed for stateobj ringbuffers, and won't really
* do what you expect for growable rb's.. so lets just restrict
* this to stateobj's for now:
*/
assert(ring->flags & FD_RINGBUFFER_OBJECT);
return offset_bytes(ring->cur, ring->start);
}
/*
* Deprecated ringmarker API:
*/
struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring) struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring)
{ {
struct fd_ringmarker *marker = NULL; struct fd_ringmarker *marker = NULL;

View File

@ -33,8 +33,7 @@
/* the ringbuffer object is not opaque so that OUT_RING() type stuff /* the ringbuffer object is not opaque so that OUT_RING() type stuff
* can be inlined. Note that users should not make assumptions about * can be inlined. Note that users should not make assumptions about
* the size of this struct.. more stuff will be added when we eventually * the size of this struct.
* have a kernel driver that can deal w/ reloc's..
*/ */
struct fd_ringbuffer_funcs; struct fd_ringbuffer_funcs;
@ -52,10 +51,15 @@ struct fd_ringbuffer {
* ringbuffer data * ringbuffer data
*/ */
void *user; void *user;
uint32_t flags;
}; };
struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe, struct fd_ringbuffer * fd_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size); uint32_t size);
struct fd_ringbuffer * fd_ringbuffer_new_object(struct fd_pipe *pipe,
uint32_t size);
void fd_ringbuffer_del(struct fd_ringbuffer *ring); void fd_ringbuffer_del(struct fd_ringbuffer *ring);
void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring, void fd_ringbuffer_set_parent(struct fd_ringbuffer *ring,
struct fd_ringbuffer *parent); struct fd_ringbuffer *parent);
@ -95,6 +99,7 @@ will_be_deprecated void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring
uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring); uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring);
uint32_t fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring, uint32_t fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer *ring,
struct fd_ringbuffer *target, uint32_t cmd_idx); struct fd_ringbuffer *target, uint32_t cmd_idx);
uint32_t fd_ringbuffer_size(struct fd_ringbuffer *ring);
will_be_deprecated struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring); will_be_deprecated struct fd_ringmarker * fd_ringmarker_new(struct fd_ringbuffer *ring);
will_be_deprecated void fd_ringmarker_del(struct fd_ringmarker *marker); will_be_deprecated void fd_ringmarker_del(struct fd_ringmarker *marker);

View File

@ -106,7 +106,7 @@ drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
enum fd_pipe_id id, uint32_t prio); enum fd_pipe_id id, uint32_t prio);
drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size); uint32_t size, enum fd_ringbuffer_flags flags);
drm_private int kgsl_bo_new_handle(struct fd_device *dev, drm_private int kgsl_bo_new_handle(struct fd_device *dev,
uint32_t size, uint32_t flags, uint32_t *handle); uint32_t size, uint32_t flags, uint32_t *handle);

View File

@ -202,11 +202,13 @@ static const struct fd_ringbuffer_funcs funcs = {
}; };
drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe, drm_private struct fd_ringbuffer * kgsl_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size) uint32_t size, enum fd_ringbuffer_flags flags)
{ {
struct kgsl_ringbuffer *kgsl_ring; struct kgsl_ringbuffer *kgsl_ring;
struct fd_ringbuffer *ring = NULL; struct fd_ringbuffer *ring = NULL;
assert(!flags);
kgsl_ring = calloc(1, sizeof(*kgsl_ring)); kgsl_ring = calloc(1, sizeof(*kgsl_ring));
if (!kgsl_ring) { if (!kgsl_ring) {
ERROR_MSG("allocation failed"); ERROR_MSG("allocation failed");

View File

@ -68,7 +68,7 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev,
enum fd_pipe_id id, uint32_t prio); enum fd_pipe_id id, uint32_t prio);
drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size); uint32_t size, enum fd_ringbuffer_flags flags);
struct msm_bo { struct msm_bo {
struct fd_bo base; struct fd_bo base;

View File

@ -583,11 +583,13 @@ static const struct fd_ringbuffer_funcs funcs = {
}; };
drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe, drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
uint32_t size) uint32_t size, enum fd_ringbuffer_flags flags)
{ {
struct msm_ringbuffer *msm_ring; struct msm_ringbuffer *msm_ring;
struct fd_ringbuffer *ring; struct fd_ringbuffer *ring;
assert(!flags);
msm_ring = calloc(1, sizeof(*msm_ring)); msm_ring = calloc(1, sizeof(*msm_ring));
if (!msm_ring) { if (!msm_ring) {
ERROR_MSG("allocation failed"); ERROR_MSG("allocation failed");