mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-05 20:38:04 +02:00
openchrome: Add deferred fence emission.
This commit is contained in:
parent
bcfe35e32c
commit
780e793629
6 changed files with 80 additions and 26 deletions
|
|
@ -60,7 +60,7 @@
|
|||
dev_priv->dma_low += 8; \
|
||||
}
|
||||
|
||||
#define VIA_TRACKER_INTERVAL 0x10000
|
||||
#define VIA_TRACKER_INTERVAL 0x100000
|
||||
|
||||
struct via_dma_tracker {
|
||||
struct list_head head;
|
||||
|
|
@ -110,16 +110,18 @@ static inline int via_cmdbuf_wait(struct drm_via_private *dev_priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool via_no_tracker(struct drm_via_private *dev_priv)
|
||||
{
|
||||
via_traverse_trackers(dev_priv);
|
||||
return (((dev_priv->dma_low - dev_priv->dma_tracker) & VIA_AGPC_MASK) <
|
||||
VIA_TRACKER_INTERVAL);
|
||||
}
|
||||
|
||||
|
||||
static int via_add_tracker(struct drm_via_private *dev_priv, uint32_t sequence)
|
||||
{
|
||||
struct via_dma_tracker *tracker;
|
||||
|
||||
if (likely
|
||||
(((dev_priv->dma_low - dev_priv->dma_tracker) & VIA_AGPC_MASK) <
|
||||
VIA_TRACKER_INTERVAL))
|
||||
return 0;
|
||||
|
||||
via_traverse_trackers(dev_priv);
|
||||
dev_priv->dma_tracker = dev_priv->dma_low;
|
||||
tracker = kmalloc(sizeof(*tracker), GFP_KERNEL);
|
||||
|
||||
|
|
@ -192,13 +194,8 @@ static void via_emit_blit_sequence(struct drm_via_private *dev_priv,
|
|||
VIA_OUT_RING_H1(VIA_REG_DIMENSION, 0);
|
||||
VIA_OUT_RING_H1(VIA_REG_GECMD, VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT
|
||||
| (VIA_ROP_PAT << 24));
|
||||
#if 0
|
||||
VIA_OUT_RING_QW(VIA_VIDEO_HEADER6, 0x00000002);
|
||||
VIA_OUT_RING_QW(0x00F60000, 0x00000000);
|
||||
VIA_OUT_RING_QW(0x326C, (3 << 30) | (0x1f << 25));
|
||||
VIA_OUT_RING_QW(0x33D0, (1 << 27) | (1 << 7) | (1 << 6) |
|
||||
(1 << 4) | (1 << 0));
|
||||
#endif
|
||||
|
||||
atomic_set(&dev_priv->emitted_cmd_seq, value);
|
||||
}
|
||||
|
||||
static void via_blit_sequence(struct drm_via_private *dev_priv,
|
||||
|
|
@ -215,6 +212,8 @@ static void via_blit_sequence(struct drm_via_private *dev_priv,
|
|||
VIA_WRITE(VIA_REG_DIMENSION, 0);
|
||||
VIA_WRITE(VIA_REG_GECMD, VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT
|
||||
| (VIA_ROP_PAT << 24));
|
||||
|
||||
atomic_set(&dev_priv->emitted_cmd_seq, value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -610,7 +609,7 @@ int via_copy_cmdbuf(struct drm_via_private *dev_priv,
|
|||
}
|
||||
|
||||
int via_dispatch_commands(struct drm_device *dev, unsigned long size,
|
||||
uint32_t mechanism)
|
||||
uint32_t mechanism, bool emit_seq)
|
||||
{
|
||||
struct drm_via_private *dev_priv = via_priv(dev);
|
||||
uint32_t *vb;
|
||||
|
|
@ -630,8 +629,11 @@ int via_dispatch_commands(struct drm_device *dev, unsigned long size,
|
|||
dev_priv->dma_low += size;
|
||||
seq =
|
||||
atomic_add_return(1, &dev_priv->fence_seq[VIA_ENGINE_CMD]);
|
||||
via_emit_fence_seq(dev_priv, VIA_FENCE_OFFSET_CMD, seq);
|
||||
via_add_tracker(dev_priv, seq);
|
||||
|
||||
if (emit_seq || !via_no_tracker(dev_priv)) {
|
||||
via_emit_fence_seq(dev_priv, VIA_FENCE_OFFSET_CMD, seq);
|
||||
via_add_tracker(dev_priv, seq);
|
||||
}
|
||||
via_cmdbuf_pause(dev_priv);
|
||||
return 0;
|
||||
case _VIA_MECHANISM_PCI:
|
||||
|
|
@ -641,9 +643,11 @@ int via_dispatch_commands(struct drm_device *dev, unsigned long size,
|
|||
size);
|
||||
seq =
|
||||
atomic_add_return(1, &dev_priv->fence_seq[VIA_ENGINE_CMD]);
|
||||
via_wait_idle(dev_priv);
|
||||
via_blit_sequence(dev_priv, VIA_FENCE_OFFSET_CMD, seq);
|
||||
via_wait_idle(dev_priv);
|
||||
if (emit_seq) {
|
||||
via_wait_idle(dev_priv);
|
||||
via_blit_sequence(dev_priv, VIA_FENCE_OFFSET_CMD, seq);
|
||||
via_wait_idle(dev_priv);
|
||||
}
|
||||
return ret;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ struct drm_via_private {
|
|||
struct drm_via_blitq blit_queues[VIA_NUM_BLIT_ENGINES];
|
||||
uint32_t dma_diff;
|
||||
atomic_t fence_seq[VIA_NUM_ENGINES];
|
||||
atomic_t emitted_cmd_seq;
|
||||
uint64_t vram_size; /* kiB */
|
||||
uint64_t vram_start;
|
||||
int vram_direct;
|
||||
|
|
@ -262,6 +263,8 @@ extern void via_driver_irq_preinstall(struct drm_device *dev);
|
|||
extern int via_driver_irq_postinstall(struct drm_device *dev);
|
||||
extern void via_driver_irq_uninstall(struct drm_device *dev);
|
||||
|
||||
extern void via_emit_fence_seq_standalone(struct drm_via_private *dev_priv,
|
||||
uint32_t offset, uint32_t value);
|
||||
extern int via_dma_cleanup(struct drm_device *dev);
|
||||
extern void via_init_command_verifier(void);
|
||||
extern int via_driver_dma_quiescent(struct drm_device *dev);
|
||||
|
|
@ -298,7 +301,8 @@ extern int via_vt_ioctl(struct drm_device *dev, void *data,
|
|||
extern int via_execbuffer(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
extern int via_dispatch_commands(struct drm_device *dev,
|
||||
unsigned long size, uint32_t mechanism);
|
||||
unsigned long size, uint32_t mechanism,
|
||||
bool emit_seq);
|
||||
extern void via_ttm_signal_fences(struct drm_via_private *dev_priv);
|
||||
extern void via_ttm_fence_cmd_handler(struct drm_via_private *dev_priv, uint32_t signal_types);
|
||||
extern void via_ttm_fence_dmablit_handler(struct drm_via_private *dev_priv, int engine);
|
||||
|
|
|
|||
|
|
@ -733,6 +733,7 @@ static int via_dispatch_clip(struct drm_device *dev,
|
|||
uint32_t i;
|
||||
uint64_t cliprect_addr = 0;
|
||||
int ret = 0;
|
||||
bool emit_seq;
|
||||
|
||||
if (exec_buf->exec_flags & DRM_VIA_HAVE_CLIP) {
|
||||
first_clip = control->first_clip;
|
||||
|
|
@ -746,6 +747,9 @@ static int via_dispatch_clip(struct drm_device *dev,
|
|||
}
|
||||
|
||||
for (i = first_clip; i < num_clip; ++i) {
|
||||
emit_seq = ((i == num_clip - 1) &&
|
||||
!(exec_buf->exec_flags & DRM_VIA_DEFER_FENCING));
|
||||
|
||||
if (i > first_clip && drm_via_disable_verifier &&
|
||||
exec_buf->mechanism == _VIA_MECHANISM_AGP) {
|
||||
ret = via_copy_cmdbuf(dev_priv, exec_buf->cmd_buffer,
|
||||
|
|
@ -790,7 +794,7 @@ static int via_dispatch_clip(struct drm_device *dev,
|
|||
}
|
||||
|
||||
ret = via_dispatch_commands(dev, exec_buf->cmd_buffer_size,
|
||||
exec_buf->mechanism);
|
||||
exec_buf->mechanism, emit_seq);
|
||||
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -666,8 +666,9 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
|
|||
dev_priv->fence_timer.function = via_ttm_fence_timer_func;
|
||||
|
||||
for (i = 0; i < VIA_NUM_ENGINES; ++i) {
|
||||
atomic_set(&dev_priv->fence_seq[i], 0);
|
||||
atomic_set(&dev_priv->fence_seq[i], -100);
|
||||
}
|
||||
atomic_set(&dev_priv->emitted_cmd_seq, -100);
|
||||
|
||||
ret = via_setup_mmio_map(dev);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -206,12 +206,52 @@ enum hrtimer_restart via_ttm_fence_timer_func(struct hrtimer *timer)
|
|||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since emitting a sequence blit after each command submission has a
|
||||
* negative performance impact, we defer that emission until fence flushing.
|
||||
*/
|
||||
|
||||
static void via_ttm_fence_flush(struct ttm_fence_device *fdev,
|
||||
uint32_t fence_class)
|
||||
{
|
||||
if (fence_class == VIA_ENGINE_CMD) {
|
||||
struct drm_via_private *dev_priv =
|
||||
container_of(fdev, struct drm_via_private, fdev);
|
||||
uint32_t sequence;
|
||||
|
||||
mutex_lock(&dev_priv->cmdbuf_mutex);
|
||||
sequence = atomic_read(&dev_priv->fence_seq[VIA_ENGINE_CMD]);
|
||||
via_emit_fence_seq_standalone(dev_priv, VIA_FENCE_OFFSET_CMD,
|
||||
sequence);
|
||||
DRM_INFO("Flushing fence 0x%08x\n", (unsigned) sequence);
|
||||
mutex_unlock(&dev_priv->cmdbuf_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the fence sequence is higher than what we've actually put in the
|
||||
* command stream, indicate that we need to flush this fence type.
|
||||
*/
|
||||
|
||||
static uint32_t via_ttm_fence_needed_flush(struct ttm_fence_object *fence)
|
||||
{
|
||||
struct ttm_fence_device *fdev = fence->fdev;
|
||||
struct ttm_fence_class_manager *fc = &fdev->fence_class[VIA_ENGINE_CMD];
|
||||
struct drm_via_private *dev_priv =
|
||||
container_of(fdev, struct drm_via_private, fdev);
|
||||
uint32_t diff = (uint32_t) atomic_read(&dev_priv->emitted_cmd_seq) -
|
||||
fence->sequence;
|
||||
|
||||
return (diff > fc->wrap_diff) ? TTM_FENCE_TYPE_EXE : 0;
|
||||
}
|
||||
|
||||
|
||||
static struct ttm_fence_driver via_ttm_fence_driver = {
|
||||
.has_irq = via_ttm_fence_has_irq,
|
||||
.emit = via_ttm_fence_emit_sequence,
|
||||
.flush = NULL,
|
||||
.flush = via_ttm_fence_flush,
|
||||
.poll = via_ttm_fence_poll,
|
||||
.needed_flush = NULL,
|
||||
.needed_flush = via_ttm_fence_needed_flush,
|
||||
.wait = NULL,
|
||||
.signaled = NULL,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#define DRM_VIA_DRIVER_DATE "20090119"
|
||||
|
||||
#define DRM_VIA_DRIVER_MAJOR 0
|
||||
#define DRM_VIA_DRIVER_MINOR 1
|
||||
#define DRM_VIA_DRIVER_MINOR 2
|
||||
#define DRM_VIA_DRIVER_PATCHLEVEL 0
|
||||
#define DRM_VIA_DRIVER_VERSION (((VIA_DRM_DRIVER_MAJOR) << 16) | (VIA_DRM_DRIVER_MINOR))
|
||||
|
||||
|
|
@ -361,6 +361,7 @@ struct drm_via_clip_rect {
|
|||
#define DRM_VIA_HAVE_CLIP (1 << 0)
|
||||
#define DRM_VIA_FENCE_NO_USER (1 << 1)
|
||||
#define DRM_VIA_WAIT_BARRIER (1 << 2)
|
||||
#define DRM_VIA_DEFER_FENCING (1 << 3)
|
||||
|
||||
struct drm_via_ttm_execbuf_control {
|
||||
struct drm_via_ttm_fence_rep rep;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue