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
parent
4519db23ef
commit
fcbf206aa2
|
@ -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);
|
||||||
/* 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 @@
|
||||||
#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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
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 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
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");
|
||||||
|
|
Loading…
Reference in New Issue