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);
+}
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 */
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);
-}
/* 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
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,
)
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 */