From: Leo Liu Date: Thu, 9 Feb 2017 15:25:20 +0000 (-0500) Subject: radeon/uvd: adapt gfx9 surface to uvd X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c836f2ce288f202a1c5a1514cd4890e47f60f3d7;p=mesa.git radeon/uvd: adapt gfx9 surface to uvd Signed-off-by: Leo Liu Acked-by: Alex Deucher Reviewed-by: Christian König --- diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c index f1b1ca8113c..cb732385d8b 100644 --- a/src/gallium/drivers/r600/r600_uvd.c +++ b/src/gallium/drivers/r600/r600_uvd.c @@ -115,7 +115,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe, surfaces[i] = &resources[i]->surface; } - rvid_join_surfaces(ctx->b.ws, pbs, surfaces); + rvid_join_surfaces(&ctx->b, pbs, surfaces); for (i = 0; i < VL_NUM_COMPONENTS; ++i) { if (!resources[i]) @@ -162,7 +162,7 @@ static struct pb_buffer* r600_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_ msg->body.decode.dt_field_mode = buf->base.interlaced; msg->body.decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->b.info.r600_num_banks)); - ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface); + ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface, RUVD_SURFACE_TYPE_LEGACY); return luma->resource.buf; } diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c index 7c6ea9324ca..ea614c1dd2a 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.c +++ b/src/gallium/drivers/radeon/radeon_uvd.c @@ -1337,10 +1337,20 @@ error: } /* calculate top/bottom offset */ -static unsigned texture_offset(struct radeon_surf *surface, unsigned layer) +static unsigned texture_offset(struct radeon_surf *surface, unsigned layer, + enum ruvd_surface_type type) { - return surface->u.legacy.level[0].offset + - layer * surface->u.legacy.level[0].slice_size; + switch (type) { + default: + case RUVD_SURFACE_TYPE_LEGACY: + return surface->u.legacy.level[0].offset + + layer * surface->u.legacy.level[0].slice_size; + break; + case RUVD_SURFACE_TYPE_GFX9: + return surface->u.gfx9.surf_offset + + layer * surface->u.gfx9.surf_slice_size; + break; + } } /* hw encode the aspect of macro tiles */ @@ -1373,42 +1383,63 @@ static unsigned bank_wh(unsigned bankwh) * fill decoding target field from the luma and chroma surfaces */ void ruvd_set_dt_surfaces(struct ruvd_msg *msg, struct radeon_surf *luma, - struct radeon_surf *chroma) + struct radeon_surf *chroma, enum ruvd_surface_type type) { - msg->body.decode.dt_pitch = luma->u.legacy.level[0].nblk_x; - switch (luma->u.legacy.level[0].mode) { - case RADEON_SURF_MODE_LINEAR_ALIGNED: - msg->body.decode.dt_tiling_mode = RUVD_TILE_LINEAR; - msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_LINEAR; - break; - case RADEON_SURF_MODE_1D: - msg->body.decode.dt_tiling_mode = RUVD_TILE_8X8; - msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_1D_THIN; - break; - case RADEON_SURF_MODE_2D: - msg->body.decode.dt_tiling_mode = RUVD_TILE_8X8; - msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_2D_THIN; - break; + switch (type) { default: - assert(0); - break; - } + case RUVD_SURFACE_TYPE_LEGACY: + msg->body.decode.dt_pitch = luma->u.legacy.level[0].nblk_x; + switch (luma->u.legacy.level[0].mode) { + case RADEON_SURF_MODE_LINEAR_ALIGNED: + msg->body.decode.dt_tiling_mode = RUVD_TILE_LINEAR; + msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_LINEAR; + break; + case RADEON_SURF_MODE_1D: + msg->body.decode.dt_tiling_mode = RUVD_TILE_8X8; + msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_1D_THIN; + break; + case RADEON_SURF_MODE_2D: + msg->body.decode.dt_tiling_mode = RUVD_TILE_8X8; + msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_2D_THIN; + break; + default: + assert(0); + break; + } - msg->body.decode.dt_luma_top_offset = texture_offset(luma, 0); - msg->body.decode.dt_chroma_top_offset = texture_offset(chroma, 0); - if (msg->body.decode.dt_field_mode) { - msg->body.decode.dt_luma_bottom_offset = texture_offset(luma, 1); - msg->body.decode.dt_chroma_bottom_offset = texture_offset(chroma, 1); - } else { - msg->body.decode.dt_luma_bottom_offset = msg->body.decode.dt_luma_top_offset; - msg->body.decode.dt_chroma_bottom_offset = msg->body.decode.dt_chroma_top_offset; - } + msg->body.decode.dt_luma_top_offset = texture_offset(luma, 0, type); + msg->body.decode.dt_chroma_top_offset = texture_offset(chroma, 0, type); + if (msg->body.decode.dt_field_mode) { + msg->body.decode.dt_luma_bottom_offset = texture_offset(luma, 1, type); + msg->body.decode.dt_chroma_bottom_offset = texture_offset(chroma, 1, type); + } else { + msg->body.decode.dt_luma_bottom_offset = msg->body.decode.dt_luma_top_offset; + msg->body.decode.dt_chroma_bottom_offset = msg->body.decode.dt_chroma_top_offset; + } - assert(luma->u.legacy.bankw == chroma->u.legacy.bankw); - assert(luma->u.legacy.bankh == chroma->u.legacy.bankh); - assert(luma->u.legacy.mtilea == chroma->u.legacy.mtilea); + assert(luma->u.legacy.bankw == chroma->u.legacy.bankw); + assert(luma->u.legacy.bankh == chroma->u.legacy.bankh); + assert(luma->u.legacy.mtilea == chroma->u.legacy.mtilea); - msg->body.decode.dt_surf_tile_config |= RUVD_BANK_WIDTH(bank_wh(luma->u.legacy.bankw)); - msg->body.decode.dt_surf_tile_config |= RUVD_BANK_HEIGHT(bank_wh(luma->u.legacy.bankh)); - msg->body.decode.dt_surf_tile_config |= RUVD_MACRO_TILE_ASPECT_RATIO(macro_tile_aspect(luma->u.legacy.mtilea)); + msg->body.decode.dt_surf_tile_config |= RUVD_BANK_WIDTH(bank_wh(luma->u.legacy.bankw)); + msg->body.decode.dt_surf_tile_config |= RUVD_BANK_HEIGHT(bank_wh(luma->u.legacy.bankh)); + msg->body.decode.dt_surf_tile_config |= RUVD_MACRO_TILE_ASPECT_RATIO(macro_tile_aspect(luma->u.legacy.mtilea)); + break; + case RUVD_SURFACE_TYPE_GFX9: + msg->body.decode.dt_pitch = luma->u.gfx9.surf_pitch * luma->bpe; + /* SWIZZLE LINEAR MODE */ + msg->body.decode.dt_tiling_mode = RUVD_TILE_LINEAR; + msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_LINEAR; + msg->body.decode.dt_luma_top_offset = texture_offset(luma, 0, type); + msg->body.decode.dt_chroma_top_offset = texture_offset(chroma, 0, type); + if (msg->body.decode.dt_field_mode) { + msg->body.decode.dt_luma_bottom_offset = texture_offset(luma, 1, type); + msg->body.decode.dt_chroma_bottom_offset = texture_offset(chroma, 1, type); + } else { + msg->body.decode.dt_luma_bottom_offset = msg->body.decode.dt_luma_top_offset; + msg->body.decode.dt_chroma_bottom_offset = msg->body.decode.dt_chroma_top_offset; + } + msg->body.decode.dt_surf_tile_config = 0; + break; + } } diff --git a/src/gallium/drivers/radeon/radeon_uvd.h b/src/gallium/drivers/radeon/radeon_uvd.h index a5af9eaafad..0c3797e22c4 100644 --- a/src/gallium/drivers/radeon/radeon_uvd.h +++ b/src/gallium/drivers/radeon/radeon_uvd.h @@ -116,6 +116,11 @@ #define RUVD_VC1_PROFILE_MAIN 0x00000001 #define RUVD_VC1_PROFILE_ADVANCED 0x00000002 +enum ruvd_surface_type { + RUVD_SURFACE_TYPE_LEGACY = 0, + RUVD_SURFACE_TYPE_GFX9 +}; + struct ruvd_mvc_element { uint16_t viewOrderIndex; uint16_t viewId; @@ -437,5 +442,5 @@ struct pipe_video_codec *ruvd_create_decoder(struct pipe_context *context, /* fill decoding target field from the luma and chroma surfaces */ void ruvd_set_dt_surfaces(struct ruvd_msg *msg, struct radeon_surf *luma, - struct radeon_surf *chroma); + struct radeon_surf *chroma, enum ruvd_surface_type type); #endif diff --git a/src/gallium/drivers/radeon/radeon_video.c b/src/gallium/drivers/radeon/radeon_video.c index 0c795fd848e..c7ad7f7a3b4 100644 --- a/src/gallium/drivers/radeon/radeon_video.c +++ b/src/gallium/drivers/radeon/radeon_video.c @@ -138,26 +138,31 @@ void rvid_clear_buffer(struct pipe_context *context, struct rvid_buffer* buffer) * join surfaces into the same buffer with identical tiling params * sumup their sizes and replace the backend buffers with a single bo */ -void rvid_join_surfaces(struct radeon_winsys* ws, +void rvid_join_surfaces(struct r600_common_context *rctx, struct pb_buffer** buffers[VL_NUM_COMPONENTS], struct radeon_surf *surfaces[VL_NUM_COMPONENTS]) { + struct radeon_winsys* ws; unsigned best_tiling, best_wh, off; unsigned size, alignment; struct pb_buffer *pb; unsigned i, j; + ws = rctx->ws; + for (i = 0, best_tiling = 0, best_wh = ~0; i < VL_NUM_COMPONENTS; ++i) { unsigned wh; if (!surfaces[i]) continue; - /* choose the smallest bank w/h for now */ - wh = surfaces[i]->u.legacy.bankw * surfaces[i]->u.legacy.bankh; - if (wh < best_wh) { - best_wh = wh; - best_tiling = i; + if (rctx->chip_class < GFX9) { + /* choose the smallest bank w/h for now */ + wh = surfaces[i]->u.legacy.bankw * surfaces[i]->u.legacy.bankh; + if (wh < best_wh) { + best_wh = wh; + best_tiling = i; + } } } @@ -165,16 +170,21 @@ void rvid_join_surfaces(struct radeon_winsys* ws, if (!surfaces[i]) continue; - /* copy the tiling parameters */ - surfaces[i]->u.legacy.bankw = surfaces[best_tiling]->u.legacy.bankw; - surfaces[i]->u.legacy.bankh = surfaces[best_tiling]->u.legacy.bankh; - surfaces[i]->u.legacy.mtilea = surfaces[best_tiling]->u.legacy.mtilea; - surfaces[i]->u.legacy.tile_split = surfaces[best_tiling]->u.legacy.tile_split; - /* adjust the texture layer offsets */ off = align(off, surfaces[i]->surf_alignment); - for (j = 0; j < ARRAY_SIZE(surfaces[i]->u.legacy.level); ++j) - surfaces[i]->u.legacy.level[j].offset += off; + + if (rctx->chip_class < GFX9) { + /* copy the tiling parameters */ + surfaces[i]->u.legacy.bankw = surfaces[best_tiling]->u.legacy.bankw; + surfaces[i]->u.legacy.bankh = surfaces[best_tiling]->u.legacy.bankh; + surfaces[i]->u.legacy.mtilea = surfaces[best_tiling]->u.legacy.mtilea; + surfaces[i]->u.legacy.tile_split = surfaces[best_tiling]->u.legacy.tile_split; + + for (j = 0; j < ARRAY_SIZE(surfaces[i]->u.legacy.level); ++j) + surfaces[i]->u.legacy.level[j].offset += off; + } else + surfaces[i]->u.gfx9.surf_offset += off; + off += surfaces[i]->surf_size; } diff --git a/src/gallium/drivers/radeon/radeon_video.h b/src/gallium/drivers/radeon/radeon_video.h index 39305b4fdd9..3347c4ebced 100644 --- a/src/gallium/drivers/radeon/radeon_video.h +++ b/src/gallium/drivers/radeon/radeon_video.h @@ -66,7 +66,7 @@ void rvid_clear_buffer(struct pipe_context *context, struct rvid_buffer* buffer) /* join surfaces into the same buffer with identical tiling params sumup their sizes and replace the backend buffers with a single bo */ -void rvid_join_surfaces(struct radeon_winsys* ws, +void rvid_join_surfaces(struct r600_common_context *rctx, struct pb_buffer** buffers[VL_NUM_COMPONENTS], struct radeon_surf *surfaces[VL_NUM_COMPONENTS]); diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 0d5bc378b2b..53a7ce9402c 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -97,7 +97,7 @@ struct pipe_video_buffer *si_video_buffer_create(struct pipe_context *pipe, pbs[i] = &resources[i]->resource.buf; } - rvid_join_surfaces(ctx->b.ws, pbs, surfaces); + rvid_join_surfaces(&ctx->b, pbs, surfaces); for (i = 0; i < VL_NUM_COMPONENTS; ++i) { if (!resources[i]) @@ -121,12 +121,16 @@ error: /* set the decoding target buffer offsets */ static struct pb_buffer* si_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_buffer *buf) { + struct si_screen *sscreen = (struct si_screen*)buf->base.context->screen; struct r600_texture *luma = (struct r600_texture *)buf->resources[0]; struct r600_texture *chroma = (struct r600_texture *)buf->resources[1]; + enum ruvd_surface_type type = (sscreen->b.chip_class >= GFX9) ? + RUVD_SURFACE_TYPE_GFX9 : + RUVD_SURFACE_TYPE_LEGACY; msg->body.decode.dt_field_mode = buf->base.interlaced; - ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface); + ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface, type); return luma->resource.buf; }