Path: blob/21.2-virgl/src/gallium/drivers/r600/r600_uvd.c
4570 views
/**************************************************************************1*2* Copyright 2011 Advanced Micro Devices, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627/*28* Authors:29* Christian König <[email protected]>30*31*/3233#include <sys/types.h>34#include <assert.h>35#include <errno.h>36#include <unistd.h>3738#include "pipe/p_video_codec.h"3940#include "util/u_memory.h"41#include "util/u_video.h"4243#include "vl/vl_defines.h"44#include "vl/vl_mpeg12_decoder.h"4546#include "r600_pipe.h"47#include "radeon_video.h"48#include "radeon_uvd.h"49#include "radeon_vce.h"50#include "r600d.h"5152#define R600_UVD_ENABLE_TILING 05354/**55* creates an video buffer with an UVD compatible memory layout56*/57struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,58const struct pipe_video_buffer *tmpl)59{60struct r600_context *ctx = (struct r600_context *)pipe;61struct r600_texture *resources[VL_NUM_COMPONENTS] = {};62struct radeon_surf* surfaces[VL_NUM_COMPONENTS] = {};63struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {};64enum pipe_format resource_formats[3];65struct pipe_video_buffer template;66struct pipe_resource templ;67unsigned i, array_size;68enum pipe_video_chroma_format chroma_format =69pipe_format_to_chroma_format(tmpl->buffer_format);7071assert(pipe);7273/* first create the needed resources as "normal" textures */74vl_get_video_buffer_formats(pipe->screen, tmpl->buffer_format, resource_formats);7576array_size = tmpl->interlaced ? 2 : 1;77template = *tmpl;78template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);79template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);8081vl_video_buffer_template(&templ, &template, resource_formats[0], 1, array_size,82PIPE_USAGE_DEFAULT, 0, chroma_format);83if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)84templ.bind = PIPE_BIND_LINEAR;85resources[0] = (struct r600_texture *)86pipe->screen->resource_create(pipe->screen, &templ);87if (!resources[0])88goto error;8990if (resource_formats[1] != PIPE_FORMAT_NONE) {91vl_video_buffer_template(&templ, &template, resource_formats[1], 1, array_size,92PIPE_USAGE_DEFAULT, 1, chroma_format);93if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)94templ.bind = PIPE_BIND_LINEAR;95resources[1] = (struct r600_texture *)96pipe->screen->resource_create(pipe->screen, &templ);97if (!resources[1])98goto error;99}100101if (resource_formats[2] != PIPE_FORMAT_NONE) {102vl_video_buffer_template(&templ, &template, resource_formats[2], 1, array_size,103PIPE_USAGE_DEFAULT, 2, chroma_format);104if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)105templ.bind = PIPE_BIND_LINEAR;106resources[2] = (struct r600_texture *)107pipe->screen->resource_create(pipe->screen, &templ);108if (!resources[2])109goto error;110}111112for (i = 0; i < VL_NUM_COMPONENTS; ++i) {113if (!resources[i])114continue;115116pbs[i] = &resources[i]->resource.buf;117surfaces[i] = &resources[i]->surface;118}119120rvid_join_surfaces(&ctx->b, pbs, surfaces);121122for (i = 0; i < VL_NUM_COMPONENTS; ++i) {123if (!resources[i])124continue;125126/* reset the address */127resources[i]->resource.gpu_address = ctx->b.ws->buffer_get_virtual_address(128resources[i]->resource.buf);129}130131template.height *= array_size;132return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);133134error:135for (i = 0; i < VL_NUM_COMPONENTS; ++i)136r600_texture_reference(&resources[i], NULL);137138return NULL;139}140141/* hw encode the number of memory banks */142static uint32_t eg_num_banks(uint32_t nbanks)143{144switch (nbanks) {145case 2:146return 0;147case 4:148return 1;149case 8:150default:151return 2;152case 16:153return 3;154}155}156157/* set the decoding target buffer offsets */158static struct pb_buffer* r600_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_buffer *buf)159{160struct r600_screen *rscreen = (struct r600_screen*)buf->base.context->screen;161struct r600_texture *luma = (struct r600_texture *)buf->resources[0];162struct r600_texture *chroma = (struct r600_texture *)buf->resources[1];163164msg->body.decode.dt_field_mode = buf->base.interlaced;165msg->body.decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->b.info.r600_num_banks));166167ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);168169return luma->resource.buf;170}171172/* get the radeon resources for VCE */173static void r600_vce_get_buffer(struct pipe_resource *resource,174struct pb_buffer **handle,175struct radeon_surf **surface)176{177struct r600_texture *res = (struct r600_texture *)resource;178179if (handle)180*handle = res->resource.buf;181182if (surface)183*surface = &res->surface;184}185186/* create decoder */187struct pipe_video_codec *r600_uvd_create_decoder(struct pipe_context *context,188const struct pipe_video_codec *templat)189{190struct r600_context *ctx = (struct r600_context *)context;191192if (templat->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)193return rvce_create_encoder(context, templat, ctx->b.ws, r600_vce_get_buffer);194195return ruvd_create_decoder(context, templat, r600_uvd_set_dtb);196}197198199