diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c index b1769ee4f05..b159007c2b9 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.c +++ b/src/gallium/auxiliary/vl/vl_video_buffer.c @@ -455,3 +455,43 @@ vl_video_buffer_create_ex2(struct pipe_context *pipe, return &buffer->base; } + +/* Create pipe_video_buffer by using resource_create with planar formats. */ +struct pipe_video_buffer * +vl_video_buffer_create_as_resource(struct pipe_context *pipe, + const struct pipe_video_buffer *tmpl) +{ + struct pipe_resource templ, *resources[VL_NUM_COMPONENTS] = {}; + unsigned array_size = tmpl->interlaced ? 2 : 1; + + memset(&templ, 0, sizeof(templ)); + templ.target = array_size > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D; + templ.width0 = align(tmpl->width, VL_MACROBLOCK_WIDTH); + templ.height0 = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT); + templ.depth0 = 1; + templ.array_size = array_size; + templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET | tmpl->bind; + templ.usage = PIPE_USAGE_DEFAULT; + + if (tmpl->buffer_format == PIPE_FORMAT_YUYV) + templ.format = PIPE_FORMAT_R8G8_R8B8_UNORM; + else if (tmpl->buffer_format == PIPE_FORMAT_UYVY) + templ.format = PIPE_FORMAT_G8R8_B8R8_UNORM; + else + templ.format = tmpl->buffer_format; + + resources[0] = pipe->screen->resource_create(pipe->screen, &templ); + if (!resources[0]) + return NULL; + + if (resources[0]->next) { + pipe_resource_reference(&resources[1], resources[0]->next); + if (resources[1]->next) + pipe_resource_reference(&resources[2], resources[1]->next); + } + + struct pipe_video_buffer vidtemplate = *tmpl; + vidtemplate.width = templ.width0; + vidtemplate.height = templ.height0 * array_size; + return vl_video_buffer_create_ex2(pipe, &vidtemplate, resources); +} diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h index ae98341ae25..ee8b5f14698 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.h +++ b/src/gallium/auxiliary/vl/vl_video_buffer.h @@ -145,4 +145,9 @@ vl_video_buffer_create_ex2(struct pipe_context *pipe, const struct pipe_video_buffer *templat, struct pipe_resource *resources[VL_NUM_COMPONENTS]); +/* Create pipe_video_buffer by using resource_create with planar formats. */ +struct pipe_video_buffer * +vl_video_buffer_create_as_resource(struct pipe_context *pipe, + const struct pipe_video_buffer *tmpl); + #endif /* vl_video_buffer_h */ diff --git a/src/gallium/drivers/radeon/radeon_video.c b/src/gallium/drivers/radeon/radeon_video.c index 31b28f76d3a..0b45a5a0f36 100644 --- a/src/gallium/drivers/radeon/radeon_video.c +++ b/src/gallium/drivers/radeon/radeon_video.c @@ -125,89 +125,3 @@ void si_vid_clear_buffer(struct pipe_context *context, struct rvid_buffer* buffe si_sdma_clear_buffer(sctx, &buffer->res->b.b, 0, buffer->res->b.b.width0, 0); context->flush(context, NULL, 0); } - -/** - * join surfaces into the same buffer with identical tiling params - * sumup their sizes and replace the backend buffers with a single bo - */ -void si_vid_join_surfaces(struct si_context *sctx, - struct pb_buffer** buffers[VL_NUM_COMPONENTS], - struct radeon_surf *surfaces[VL_NUM_COMPONENTS]) -{ - struct radeon_winsys *ws = sctx->ws;; - unsigned best_tiling, best_wh, off; - unsigned size, alignment; - struct pb_buffer *pb; - unsigned i, j; - - for (i = 0, best_tiling = 0, best_wh = ~0; i < VL_NUM_COMPONENTS; ++i) { - unsigned wh; - - if (!surfaces[i]) - continue; - - if (sctx->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; - } - } - } - - for (i = 0, off = 0; i < VL_NUM_COMPONENTS; ++i) { - if (!surfaces[i]) - continue; - - /* adjust the texture layer offsets */ - off = align(off, surfaces[i]->surf_alignment); - - if (sctx->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; - for (j = 0; j < ARRAY_SIZE(surfaces[i]->u.gfx9.offset); ++j) - surfaces[i]->u.gfx9.offset[j] += off; - } - - surfaces[i]->flags |= RADEON_SURF_IMPORTED; - off += surfaces[i]->surf_size; - } - - for (i = 0, size = 0, alignment = 0; i < VL_NUM_COMPONENTS; ++i) { - if (!buffers[i] || !*buffers[i]) - continue; - - size = align(size, (*buffers[i])->alignment); - size += (*buffers[i])->size; - alignment = MAX2(alignment, (*buffers[i])->alignment * 1); - } - - if (!size) - return; - - /* TODO: 2D tiling workaround */ - alignment *= 2; - - pb = ws->buffer_create(ws, size, alignment, RADEON_DOMAIN_VRAM, - RADEON_FLAG_GTT_WC); - if (!pb) - return; - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - if (!buffers[i] || !*buffers[i]) - continue; - - pb_reference(buffers[i], pb); - } - - pb_reference(&pb, NULL); -} diff --git a/src/gallium/drivers/radeon/radeon_video.h b/src/gallium/drivers/radeon/radeon_video.h index b7797c05d16..232b7736f7b 100644 --- a/src/gallium/drivers/radeon/radeon_video.h +++ b/src/gallium/drivers/radeon/radeon_video.h @@ -60,10 +60,4 @@ bool si_vid_resize_buffer(struct pipe_screen *screen, struct radeon_cmdbuf *cs, /* clear the buffer with zeros */ void si_vid_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 si_vid_join_surfaces(struct si_context *sctx, - struct pb_buffer** buffers[VL_NUM_COMPONENTS], - struct radeon_surf *surfaces[VL_NUM_COMPONENTS]); - #endif // RADEON_VIDEO_H diff --git a/src/gallium/drivers/radeonsi/meson.build b/src/gallium/drivers/radeonsi/meson.build index 6e155243a27..600f632dfd0 100644 --- a/src/gallium/drivers/radeonsi/meson.build +++ b/src/gallium/drivers/radeonsi/meson.build @@ -129,7 +129,7 @@ driver_radeonsi = declare_dependency( compile_args : '-DGALLIUM_RADEONSI', sources : si_driinfo_h, link_with : [ - libradeonsi, libradeonwinsys, libamdgpuwinsys, libamd_common, libamd_common_llvm + libradeonsi, libradeonwinsys, libamdgpuwinsys, libamd_common, libamd_common_llvm, libgalliumvl ], dependencies : idep_nir, ) diff --git a/src/gallium/drivers/radeonsi/si_uvd.c b/src/gallium/drivers/radeonsi/si_uvd.c index 1469b6ac7f1..5511c2d7ad2 100644 --- a/src/gallium/drivers/radeonsi/si_uvd.c +++ b/src/gallium/drivers/radeonsi/si_uvd.c @@ -40,71 +40,11 @@ struct pipe_video_buffer *si_video_buffer_create(struct pipe_context *pipe, const struct pipe_video_buffer *tmpl) { - struct si_context *ctx = (struct si_context *)pipe; - struct si_texture *resources[VL_NUM_COMPONENTS] = {}; - struct radeon_surf *surfaces[VL_NUM_COMPONENTS] = {}; - struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {}; - enum pipe_format resource_formats[VL_NUM_COMPONENTS]; - struct pipe_video_buffer vidtemplate; - struct pipe_resource templ; - unsigned i, array_size; + struct pipe_video_buffer vidbuf = *tmpl; + /* TODO: get tiling working */ + vidbuf.bind |= PIPE_BIND_LINEAR; - assert(pipe); - - /* first create the needed resources as "normal" textures */ - vl_get_video_buffer_formats(pipe->screen, tmpl->buffer_format, resource_formats); - - array_size = tmpl->interlaced ? 2 : 1; - vidtemplate = *tmpl; - vidtemplate.width = align(tmpl->width, VL_MACROBLOCK_WIDTH); - vidtemplate.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT); - - assert(resource_formats[0] != PIPE_FORMAT_NONE); - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - if (resource_formats[i] != PIPE_FORMAT_NONE) { - vl_video_buffer_template(&templ, &vidtemplate, - resource_formats[i], 1, - array_size, PIPE_USAGE_DEFAULT, i); - /* Set PIPE_BIND_SHARED to avoid reallocation in si_texture_get_handle, - * which can't handle joined surfaces. */ - /* TODO: get tiling working */ - templ.bind = PIPE_BIND_LINEAR | PIPE_BIND_SHARED; - resources[i] = (struct si_texture *) - pipe->screen->resource_create(pipe->screen, &templ); - if (!resources[i]) - goto error; - } - } - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - if (!resources[i]) - continue; - - surfaces[i] = & resources[i]->surface; - pbs[i] = &resources[i]->buffer.buf; - } - - si_vid_join_surfaces(ctx, pbs, surfaces); - - for (i = 0; i < VL_NUM_COMPONENTS; ++i) { - if (!resources[i]) - continue; - - /* reset the address */ - resources[i]->buffer.gpu_address = ctx->ws->buffer_get_virtual_address( - resources[i]->buffer.buf); - resources[i]->buffer.bo_size = resources[i]->buffer.buf->size; - } - - vidtemplate.height *= array_size; - return vl_video_buffer_create_ex2(pipe, &vidtemplate, (struct pipe_resource **)resources); - -error: - for (i = 0; i < VL_NUM_COMPONENTS; ++i) - si_texture_reference(&resources[i], NULL); - - return NULL; + return vl_video_buffer_create_as_resource(pipe, &vidbuf); } /* set the decoding target buffer offsets */