From 42d9f6323a523d786fc3797587fdf63048becceb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 30 Apr 2015 16:07:12 +0200 Subject: [PATCH] winsys/radeon: add an interface for contexts MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Same idea as in libdrm_amdgpu. A command stream can only be created for a specific context and it's always submitted to that context. This will mainly be used by amdgpu and it's required by the GPU reset status query too. (radeon only has a basic version of the query and thus doesn't need this) Reviewed-by: Christian König --- src/gallium/drivers/r300/r300_context.c | 8 +++++++- src/gallium/drivers/r300/r300_context.h | 2 ++ src/gallium/drivers/r600/r600_pipe.c | 2 +- src/gallium/drivers/radeon/r600_pipe_common.c | 14 +++++++++----- src/gallium/drivers/radeon/r600_pipe_common.h | 1 + src/gallium/drivers/radeon/radeon_uvd.c | 3 ++- src/gallium/drivers/radeon/radeon_vce.c | 3 ++- src/gallium/drivers/radeon/radeon_winsys.h | 16 ++++++++++++++-- src/gallium/drivers/radeonsi/si_pipe.c | 2 +- src/gallium/winsys/radeon/drm/radeon_drm_cs.c | 18 ++++++++++++++++-- 10 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index c35aa3b24aa..8c24ad6d98a 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -94,6 +94,8 @@ static void r300_destroy_context(struct pipe_context* context) if (r300->cs) r300->rws->cs_destroy(r300->cs); + if (r300->ctx) + r300->rws->ctx_destroy(r300->ctx); rc_destroy_regalloc_state(&r300->fs_regalloc_state); @@ -382,7 +384,11 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, sizeof(struct pipe_transfer), 64, UTIL_SLAB_SINGLETHREADED); - r300->cs = rws->cs_create(rws, RING_GFX, r300_flush_callback, r300, NULL); + r300->ctx = rws->ctx_create(rws); + if (!r300->ctx) + goto fail; + + r300->cs = rws->cs_create(r300->ctx, RING_GFX, r300_flush_callback, r300, NULL); if (r300->cs == NULL) goto fail; diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 5a58500b074..18ae11a3a24 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -449,6 +449,8 @@ struct r300_context { /* The interface to the windowing system, etc. */ struct radeon_winsys *rws; + /* The submission context. */ + struct radeon_winsys_ctx *ctx; /* The command stream. */ struct radeon_winsys_cs *cs; /* Screen. */ diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index e755784209a..f02014e17f0 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -176,7 +176,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void goto fail; } - rctx->b.rings.gfx.cs = ws->cs_create(ws, RING_GFX, + rctx->b.rings.gfx.cs = ws->cs_create(rctx->b.ctx, RING_GFX, r600_context_gfx_flush, rctx, rscreen->b.trace_bo ? rscreen->b.trace_bo->cs_buf : NULL); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 4c29f5235e1..3f1c0f0eae9 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -262,8 +262,12 @@ bool r600_common_context_init(struct r600_common_context *rctx, if (!rctx->uploader) return false; + rctx->ctx = rctx->ws->ctx_create(rctx->ws); + if (!rctx->ctx) + return false; + if (rscreen->info.r600_has_dma && !(rscreen->debug_flags & DBG_NO_ASYNC_DMA)) { - rctx->rings.dma.cs = rctx->ws->cs_create(rctx->ws, RING_DMA, + rctx->rings.dma.cs = rctx->ws->cs_create(rctx->ctx, RING_DMA, r600_flush_dma_ring, rctx, NULL); rctx->rings.dma.flush = r600_flush_dma_ring; @@ -274,12 +278,12 @@ bool r600_common_context_init(struct r600_common_context *rctx, void r600_common_context_cleanup(struct r600_common_context *rctx) { - if (rctx->rings.gfx.cs) { + if (rctx->rings.gfx.cs) rctx->ws->cs_destroy(rctx->rings.gfx.cs); - } - if (rctx->rings.dma.cs) { + if (rctx->rings.dma.cs) rctx->ws->cs_destroy(rctx->rings.dma.cs); - } + if (rctx->ctx) + rctx->ws->ctx_destroy(rctx->ctx); if (rctx->uploader) { u_upload_destroy(rctx->uploader); diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index dbd82880583..ce3f396011f 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -372,6 +372,7 @@ struct r600_common_context { struct r600_common_screen *screen; struct radeon_winsys *ws; + struct radeon_winsys_ctx *ctx; enum radeon_family family; enum chip_class chip_class; struct r600_rings rings; diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index be58d0b9ce3..79fc0c726c4 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -761,6 +761,7 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context, { struct radeon_winsys* ws = ((struct r600_common_context *)context)->ws; unsigned dpb_size = calc_dpb_size(templ); + struct r600_common_context *rctx = (struct r600_common_context*)context; unsigned width = templ->width, height = templ->height; unsigned bs_buf_size; struct radeon_info info; @@ -807,7 +808,7 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context, dec->stream_handle = rvid_alloc_stream_handle(); dec->screen = context->screen; dec->ws = ws; - dec->cs = ws->cs_create(ws, RING_UVD, NULL, NULL, NULL); + dec->cs = ws->cs_create(rctx->ctx, RING_UVD, NULL, NULL, NULL); if (!dec->cs) { RVID_ERR("Can't get command submission context.\n"); goto error; diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index a6567379fe3..4557ce55556 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -377,6 +377,7 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, rvce_get_buffer get_buffer) { struct r600_common_screen *rscreen = (struct r600_common_screen *)context->screen; + struct r600_common_context *rctx = (struct r600_common_context*)context; struct rvce_encoder *enc; struct pipe_video_buffer *tmp_buf, templat = {}; struct radeon_surf *tmp_surf; @@ -411,7 +412,7 @@ struct pipe_video_codec *rvce_create_encoder(struct pipe_context *context, enc->screen = context->screen; enc->ws = ws; - enc->cs = ws->cs_create(ws, RING_VCE, rvce_cs_flush, enc, NULL); + enc->cs = ws->cs_create(rctx->ctx, RING_VCE, rvce_cs_flush, enc, NULL); if (!enc->cs) { RVID_ERR("Can't get command submission context.\n"); goto error; diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index ea1e1970157..93618ccbc1a 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -191,6 +191,7 @@ enum radeon_bo_priority { struct winsys_handle; struct radeon_winsys_cs_handle; +struct radeon_winsys_ctx; struct radeon_winsys_cs { unsigned cdw; /* Number of used dwords. */ @@ -505,16 +506,27 @@ struct radeon_winsys { * commands independently of other contexts. *************************************************************************/ + /** + * Create a command submission context. + * Various command streams can be submitted to the same context. + */ + struct radeon_winsys_ctx *(*ctx_create)(struct radeon_winsys *ws); + + /** + * Destroy a context. + */ + void (*ctx_destroy)(struct radeon_winsys_ctx *ctx); + /** * Create a command stream. * - * \param ws The winsys this function is called from. + * \param ctx The submission context * \param ring_type The ring type (GFX, DMA, UVD) * \param flush Flush callback function associated with the command stream. * \param user User pointer that will be passed to the flush callback. * \param trace_buf Trace buffer when tracing is enabled */ - struct radeon_winsys_cs *(*cs_create)(struct radeon_winsys *ws, + struct radeon_winsys_cs *(*cs_create)(struct radeon_winsys_ctx *ctx, enum ring_type ring_type, void (*flush)(void *ctx, unsigned flags, struct pipe_fence_handle **fence), diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 73797976b5b..cacef9f0ae7 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -118,7 +118,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, void * sctx->b.b.create_video_buffer = vl_video_buffer_create; } - sctx->b.rings.gfx.cs = ws->cs_create(ws, RING_GFX, si_context_gfx_flush, + sctx->b.rings.gfx.cs = ws->cs_create(sctx->b.ctx, RING_GFX, si_context_gfx_flush, sctx, sscreen->b.trace_bo ? sscreen->b.trace_bo->cs_buf : NULL); sctx->b.rings.gfx.flush = si_context_gfx_flush; diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index 6067bac36b8..5fde875c34c 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -80,6 +80,18 @@ radeon_cs_create_fence(struct radeon_winsys_cs *rcs); static void radeon_fence_reference(struct pipe_fence_handle **dst, struct pipe_fence_handle *src); +static struct radeon_winsys_ctx *radeon_drm_ctx_create(struct radeon_winsys *ws) +{ + /* No context support here. Just return the winsys pointer + * as the "context". */ + return (struct radeon_winsys_ctx*)ws; +} + +static void radeon_drm_ctx_destroy(struct radeon_winsys_ctx *ctx) +{ + /* No context support here. */ +} + static boolean radeon_init_cs_context(struct radeon_cs_context *csc, struct radeon_drm_winsys *ws) { @@ -158,14 +170,14 @@ static void radeon_destroy_cs_context(struct radeon_cs_context *csc) static struct radeon_winsys_cs * -radeon_drm_cs_create(struct radeon_winsys *rws, +radeon_drm_cs_create(struct radeon_winsys_ctx *ctx, enum ring_type ring_type, void (*flush)(void *ctx, unsigned flags, struct pipe_fence_handle **fence), void *flush_ctx, struct radeon_winsys_cs_handle *trace_buf) { - struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); + struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)ctx; struct radeon_drm_cs *cs; cs = CALLOC_STRUCT(radeon_drm_cs); @@ -667,6 +679,8 @@ static void radeon_fence_reference(struct pipe_fence_handle **dst, void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) { + ws->base.ctx_create = radeon_drm_ctx_create; + ws->base.ctx_destroy = radeon_drm_ctx_destroy; ws->base.cs_create = radeon_drm_cs_create; ws->base.cs_destroy = radeon_drm_cs_destroy; ws->base.cs_add_reloc = radeon_drm_cs_add_reloc; -- 2.30.2