[Mesa-dev] [PATCH] r600g: add support for virtual address space on cayman v8
Michel Dänzer
michel at daenzer.net
Mon Jan 9 04:01:45 PST 2012
On Fre, 2012-01-06 at 10:42 -0500, j.glisse at gmail.com wrote:
> From: Jerome Glisse <jglisse at redhat.com>
>
> Virtual address space put the userspace in charge of their GPU
> address space. It's up to userspace to bind bo into the virtual
> address space. Command stream can them be executed using the
> IB_VM chunck.
>
> This patch add support for this configuration. It doesn't remove
> the 64K ib size limit thought this limit can be extanded up to
> 1M for IB_VM chunk.
[...]
> diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c
> index 96e8d18..01764ed 100644
> --- a/src/gallium/drivers/r600/evergreen_hw_context.c
> +++ b/src/gallium/drivers/r600/evergreen_hw_context.c
> @@ -1174,8 +1175,10 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr
> pm4[2] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing);
> pm4[3] = draw->vgt_num_instances;
> if (draw->indices) {
> - pm4[4] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing);
> - pm4[5] = draw->indices_bo_offset;
> + va = r600_resource_va(&ctx->screen->screen, (void*)draw->indices);
> + va += draw->indices_bo_offset;
> + pm4[4] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing);
> + pm4[5] = va;
> pm4[6] = 0;
pm[6] = va >> 32;
> @@ -2517,15 +2529,20 @@ void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx,
> }
>
>
> -void evergreen_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate,
> +void evergreen_pipe_mod_buffer_resource(struct pipe_context *ctx,
> + struct r600_pipe_resource_state *rstate,
> struct r600_resource *rbuffer,
> unsigned offset, unsigned stride,
> enum radeon_bo_usage usage)
> {
> + uint64_t va;
> +
> + va = r600_resource_va(ctx->screen, (void *)rbuffer);
> rstate->bo[0] = rbuffer;
> rstate->bo_usage[0] = usage;
> - rstate->val[0] = offset;
> + rstate->val[0] = (offset + va) & 0xFFFFFFFFUL;
> rstate->val[1] = rbuffer->buf->size - offset - 1;
> rstate->val[2] = S_030008_ENDIAN_SWAP(r600_endian_swap(32)) |
> - S_030008_STRIDE(stride);
> + S_030008_STRIDE(stride) |
> + ((va >> 32UL) & 0xFF);
(((va + offset) >> 32) & 0xFF);
> diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
> index 52e0be7..93cb025 100644
> --- a/src/gallium/drivers/r600/r600_hw_context.c
> +++ b/src/gallium/drivers/r600/r600_hw_context.c
> @@ -1570,14 +1573,20 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
>
> void r600_context_emit_fence(struct r600_context *ctx, struct r600_resource *fence_bo, unsigned offset, unsigned value)
> {
> + uint64_t va;
> +
> r600_need_cs_space(ctx, 10, FALSE);
>
> + va = r600_resource_va(&ctx->screen->screen, (void*)fence_bo);
> + va = va + (offset << 2);
> +
> ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
> ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
> ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
> ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
> - ctx->pm4[ctx->pm4_cdwords++] = offset << 2; /* ADDRESS_LO */
> - ctx->pm4[ctx->pm4_cdwords++] = (1 << 29) | (0 << 24); /* DATA_SEL | INT_EN | ADDRESS_HI */
> + ctx->pm4[ctx->pm4_cdwords++] = va & 0xFFFFFFFFUL; /* ADDRESS_LO */
> + /* DATA_SEL | INT_EN | ADDRESS_HI */
> + ctx->pm4[ctx->pm4_cdwords++] = (1 << 29) | (0 << 24) | ((va >> 32UL) & 0xFFFFFFFFUL);
ctx->pm4[ctx->pm4_cdwords++] = (1 << 29) | (0 << 24) | ((va >> 32) & 0xFF);
> @@ -1684,19 +1694,22 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query)
> }
>
> /* emit begin query */
> + va = r600_resource_va(&ctx->screen->screen, (void*)query->buffer);
> + va += query->results_end;
> +
> switch (query->type) {
> case PIPE_QUERY_OCCLUSION_COUNTER:
> case PIPE_QUERY_OCCLUSION_PREDICATE:
> ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 2, 0);
> ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1);
> - ctx->pm4[ctx->pm4_cdwords++] = query->results_end;
> - ctx->pm4[ctx->pm4_cdwords++] = 0;
> + ctx->pm4[ctx->pm4_cdwords++] = va & 0xFFFFFFFFUL;
> + ctx->pm4[ctx->pm4_cdwords++] = (va >> 32UL) & 0xFFFFFFFFUL;
> break;
> case PIPE_QUERY_TIME_ELAPSED:
> ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE_EOP, 4, 0);
> ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5);
> - ctx->pm4[ctx->pm4_cdwords++] = query->results_end;
> - ctx->pm4[ctx->pm4_cdwords++] = (3 << 29);
> + ctx->pm4[ctx->pm4_cdwords++] = va & 0xFFFFFFFFUL;
> + ctx->pm4[ctx->pm4_cdwords++] = (3 << 29) | ((va >> 32UL) & 0xFFFFFFFFUL);
> ctx->pm4[ctx->pm4_cdwords++] = 0;
> ctx->pm4[ctx->pm4_cdwords++] = 0;
> break;
These '& 0xFFFFFFFFUL's are no-ops. Drop the ones for the low bits, the
ones for the high bits should probably be '& 0xFF'?
> diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
> index ccf9c4f..8ef0c18 100644
> --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
> +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
> @@ -151,9 +163,85 @@ static boolean radeon_bo_is_busy(struct pb_buffer *_buf,
[...]
> +
> +static void radeon_bomgr_force_va(struct radeon_bomgr *mgr, uint64_t va, uint64_t size)
> +{
> + pipe_mutex_lock(mgr->bo_handles_mutex);
> + if (va >= mgr->va_offset) {
> + mgr->va_offset = va + size;
Doesn't this need to add a hole if va > mgr->va_offset?
> + } else {
> + struct radeon_bo_va_hole *hole, *n;
> + uint64_t stmp, etmp;
> +
> + /* free all hole that fall into the range
> + * NOTE that we might loose virtual address space
Typos: 'holes', 'lose'
> +static void radeon_bomgr_free_va(struct radeon_bomgr *mgr, uint64_t va, uint64_t size)
> +{
> + pipe_mutex_lock(mgr->bo_handles_mutex);
> + if ((va + size) == mgr->va_offset) {
> + mgr->va_offset = va;
> + } else {
> + struct radeon_bo_va_hole *hole;
> +
> + /* FIXME on allocation failure we just loose virtual address space
'lose'
> + r = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_VA, &va, sizeof(va));
> + if (r && va.operation == RADEON_VA_RESULT_ERROR) {
> + fprintf(stderr, "radeon: Failed to open a buffer:\n");
This error message doesn't seem very specific / useful.
> diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
> index 442bd2a..8124016 100644
> --- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
> +++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
> @@ -138,9 +138,11 @@ static boolean radeon_get_drm_value(int fd, unsigned request,
> info.request = request;
>
> retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
> - if (retval && errname) {
> - fprintf(stderr, "radeon: Failed to get %s, error number %d\n",
> - errname, retval);
> + if (retval) {
> + if (errname) {
> + fprintf(stderr, "radeon: Failed to get %s, error number %d\n",
> + errname, retval);
> + }
> return FALSE;
> }
> return TRUE;
This fix should probably be a change of its own.
--
Earthling Michel Dänzer | http://www.amd.com
Libre software enthusiast | Debian, X and DRI developer
More information about the mesa-dev
mailing list