Commit fcbf206a authored by Rob Clark's avatar Rob Clark
Browse files

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: default avatarRob Clark <robclark@freedesktop.org>
parent 4519db23
...@@ -46,10 +46,12 @@ fd_ringbuffer_emit_reloc_ring_full ...@@ -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
......
...@@ -114,8 +114,13 @@ drm_private int fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo); ...@@ -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);
......
...@@ -32,15 +32,17 @@ ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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;
......
...@@ -33,8 +33,7 @@ ...@@ -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 { ...@@ -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 ...@@ -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);
......
...@@ -106,7 +106,7 @@ drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev, ...@@ -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);
......
...@@ -202,11 +202,13 @@ static const struct fd_ringbuffer_funcs funcs = { ...@@ -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");
......
...@@ -68,7 +68,7 @@ drm_private struct fd_pipe * msm_pipe_new(struct fd_device *dev, ...@@ -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;
......
...@@ -583,11 +583,13 @@ static const struct fd_ringbuffer_funcs funcs = { ...@@ -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");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment