From: Nicolai Hähnle <[email protected]> Really fix the bug that was supposed to be fixed by commits 3e7cced4b and a48bf02d: even when virtual addresses are used, the legacy relocation-based method with offsets relative to the kernel's buffer object are used for video submissions.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97969 --- src/gallium/drivers/radeon/radeon_uvd.c | 2 +- src/gallium/drivers/radeon/radeon_vce.c | 2 +- src/gallium/drivers/radeon/radeon_winsys.h | 12 ++++++++++++ src/gallium/winsys/radeon/drm/radeon_drm_bo.c | 11 +++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 9c376cb..fb1491a 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -116,21 +116,21 @@ static void send_cmd(struct ruvd_decoder *dec, unsigned cmd, reloc_idx = dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, RADEON_PRIO_UVD); if (!dec->use_legacy) { uint64_t addr; addr = dec->ws->buffer_get_virtual_address(buf); addr = addr + off; set_reg(dec, RUVD_GPCOM_VCPU_DATA0, addr); set_reg(dec, RUVD_GPCOM_VCPU_DATA1, addr >> 32); } else { - off += dec->ws->buffer_get_virtual_address(buf); + off += dec->ws->buffer_get_reloc_offset(buf); set_reg(dec, RUVD_GPCOM_VCPU_DATA0, off); set_reg(dec, RUVD_GPCOM_VCPU_DATA1, reloc_idx * 4); } set_reg(dec, RUVD_GPCOM_VCPU_CMD, cmd << 1); } /* do the codec needs an IT buffer ?*/ static bool have_it(struct ruvd_decoder *dec) { return dec->stream_type == RUVD_CODEC_H264_PERF || diff --git a/src/gallium/drivers/radeon/radeon_vce.c b/src/gallium/drivers/radeon/radeon_vce.c index 30705c1..ef93e46 100644 --- a/src/gallium/drivers/radeon/radeon_vce.c +++ b/src/gallium/drivers/radeon/radeon_vce.c @@ -542,15 +542,15 @@ void rvce_add_buffer(struct rvce_encoder *enc, struct pb_buffer *buf, reloc_idx = enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, RADEON_PRIO_VCE); if (enc->use_vm) { uint64_t addr; addr = enc->ws->buffer_get_virtual_address(buf); addr = addr + offset; RVCE_CS(addr >> 32); RVCE_CS(addr); } else { - offset += enc->ws->buffer_get_virtual_address(buf); + offset += enc->ws->buffer_get_reloc_offset(buf); RVCE_CS(reloc_idx * 4); RVCE_CS(offset); } } diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h index e8fc6d6..7146737 100644 --- a/src/gallium/drivers/radeon/radeon_winsys.h +++ b/src/gallium/drivers/radeon/radeon_winsys.h @@ -508,20 +508,32 @@ struct radeon_winsys { * * When virtual memory is not in use, this is the offset relative to the * relocation base (non-zero for sub-allocated buffers). * * \param buf A winsys buffer object * \return virtual address */ uint64_t (*buffer_get_virtual_address)(struct pb_buffer *buf); /** + * Return the offset of this buffer relative to the relocation base. + * This is only non-zero for sub-allocated buffers. + * + * This is only supported in the radeon winsys, since amdgpu uses virtual + * addresses in submissions even for the video engines. + * + * \param buf A winsys buffer object + * \return the offset for relocations + */ + unsigned (*buffer_get_reloc_offset)(struct pb_buffer *buf); + + /** * Query the initial placement of the buffer from the kernel driver. */ enum radeon_bo_domain (*buffer_get_initial_domain)(struct pb_buffer *buf); /************************************************************************** * Command submission. * * Each pipe context should create its own command stream and submit * commands independently of other contexts. *************************************************************************/ diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index 5818006..a15d559 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -1332,25 +1332,36 @@ static bool radeon_winsys_bo_get_handle(struct pb_buffer *buffer, static bool radeon_winsys_bo_is_user_ptr(struct pb_buffer *buf) { return ((struct radeon_bo*)buf)->user_ptr != NULL; } static uint64_t radeon_winsys_bo_va(struct pb_buffer *buf) { return ((struct radeon_bo*)buf)->va; } +static unsigned radeon_winsys_bo_get_reloc_offset(struct pb_buffer *buf) +{ + struct radeon_bo *bo = radeon_bo(buf); + + if (bo->handle) + return 0; + + return bo->va - bo->u.slab.real->va; +} + void radeon_drm_bo_init_functions(struct radeon_drm_winsys *ws) { ws->base.buffer_set_metadata = radeon_bo_set_metadata; ws->base.buffer_get_metadata = radeon_bo_get_metadata; ws->base.buffer_map = radeon_bo_map; ws->base.buffer_unmap = radeon_bo_unmap; ws->base.buffer_wait = radeon_bo_wait; ws->base.buffer_create = radeon_winsys_bo_create; ws->base.buffer_from_handle = radeon_winsys_bo_from_handle; ws->base.buffer_from_ptr = radeon_winsys_bo_from_ptr; ws->base.buffer_is_user_ptr = radeon_winsys_bo_is_user_ptr; ws->base.buffer_get_handle = radeon_winsys_bo_get_handle; ws->base.buffer_get_virtual_address = radeon_winsys_bo_va; + ws->base.buffer_get_reloc_offset = radeon_winsys_bo_get_reloc_offset; ws->base.buffer_get_initial_domain = radeon_bo_get_initial_domain; } -- 2.7.4 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
