15b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König/**************************************************************************
25b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König *
35b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * Copyright 2011 Advanced Micro Devices, Inc.
45b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * All Rights Reserved.
55b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König *
65b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * Permission is hereby granted, free of charge, to any person obtaining a
75b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * copy of this software and associated documentation files (the
85b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * "Software"), to deal in the Software without restriction, including
95b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * without limitation the rights to use, copy, modify, merge, publish,
105b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * distribute, sub license, and/or sell copies of the Software, and to
115b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * permit persons to whom the Software is furnished to do so, subject to
125b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * the following conditions:
135b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König *
145b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * The above copyright notice and this permission notice (including the
155b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * next paragraph) shall be included in all copies or substantial portions
165b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * of the Software.
175b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König *
185b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
195b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
205b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
215b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
225b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
235b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
245b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
255b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König *
265b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König **************************************************************************/
275b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
285b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König/*
295b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * Authors:
305b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König *      Christian König <christian.koenig@amd.com>
315b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König *
325b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König */
335b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
345b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include <sys/types.h>
355b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include <assert.h>
365b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include <errno.h>
375b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include <unistd.h>
385b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
39f2f7064e560a83fc78d0e5b1d3a7d4aaac119a49Christian König#include "pipe/p_video_codec.h"
405b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
415b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include "util/u_memory.h"
425b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include "util/u_video.h"
435b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
445b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include "vl/vl_defines.h"
455b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include "vl/vl_mpeg12_decoder.h"
465b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
475b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include "r600_pipe.h"
487bcfb0bc8ffed0db244cf0b3d4e200add590a02aChristian König#include "radeon/radeon_video.h"
495b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include "radeon/radeon_uvd.h"
50685335639a982b398d305b8f314fc3857fcdbeadChristian König#include "radeon/radeon_vce.h"
515b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König#include "r600d.h"
525b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
5383de93309e38ce3af0c8f92ef54446db70b2cb38Christian König#define R600_UVD_ENABLE_TILING 0
5483de93309e38ce3af0c8f92ef54446db70b2cb38Christian König
555b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König/**
565b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König * creates an video buffer with an UVD compatible memory layout
575b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König */
585b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian Königstruct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
595b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König						   const struct pipe_video_buffer *tmpl)
605b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König{
615b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct r600_context *ctx = (struct r600_context *)pipe;
625b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct r600_texture *resources[VL_NUM_COMPONENTS] = {};
63a582b22c6382f24d921e9fe8a24917100c1396f1Marek Olšák	struct radeon_surf* surfaces[VL_NUM_COMPONENTS] = {};
645b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {};
655b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	const enum pipe_format *resource_formats;
665b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct pipe_video_buffer template;
675b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct pipe_resource templ;
687d2f2a0c890b1993532a45c8c392c28950ddc06eChristian König	unsigned i, array_size;
695b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
705b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	assert(pipe);
715b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
725b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	/* first create the needed resources as "normal" textures */
735b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format);
745b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	if (!resource_formats)
755b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		return NULL;
765b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
777d2f2a0c890b1993532a45c8c392c28950ddc06eChristian König	array_size = tmpl->interlaced ? 2 : 1;
785b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	template = *tmpl;
795b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
807d2f2a0c890b1993532a45c8c392c28950ddc06eChristian König	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
815b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
82c32114460dbb7f33885c181a0d7dee07b15b8751Marek Olšák	vl_video_buffer_template(&templ, &template, resource_formats[0], 1, array_size, PIPE_USAGE_DEFAULT, 0);
8383de93309e38ce3af0c8f92ef54446db70b2cb38Christian König	if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
84270fab5164d04bd8ce5f322c1a4d6ca39734d39aGrigori Goronzy		templ.bind = PIPE_BIND_LINEAR;
855b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	resources[0] = (struct r600_texture *)
865b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		pipe->screen->resource_create(pipe->screen, &templ);
875b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	if (!resources[0])
885b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		goto error;
895b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
905b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	if (resource_formats[1] != PIPE_FORMAT_NONE) {
91c32114460dbb7f33885c181a0d7dee07b15b8751Marek Olšák		vl_video_buffer_template(&templ, &template, resource_formats[1], 1, array_size, PIPE_USAGE_DEFAULT, 1);
9283de93309e38ce3af0c8f92ef54446db70b2cb38Christian König		if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
93270fab5164d04bd8ce5f322c1a4d6ca39734d39aGrigori Goronzy			templ.bind = PIPE_BIND_LINEAR;
945b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		resources[1] = (struct r600_texture *)
955b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König			pipe->screen->resource_create(pipe->screen, &templ);
965b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		if (!resources[1])
975b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König			goto error;
985b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	}
995b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1005b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	if (resource_formats[2] != PIPE_FORMAT_NONE) {
101c32114460dbb7f33885c181a0d7dee07b15b8751Marek Olšák		vl_video_buffer_template(&templ, &template, resource_formats[2], 1, array_size, PIPE_USAGE_DEFAULT, 2);
10283de93309e38ce3af0c8f92ef54446db70b2cb38Christian König		if (ctx->b.chip_class < EVERGREEN || tmpl->interlaced || !R600_UVD_ENABLE_TILING)
103270fab5164d04bd8ce5f322c1a4d6ca39734d39aGrigori Goronzy			templ.bind = PIPE_BIND_LINEAR;
1045b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		resources[2] = (struct r600_texture *)
1055b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König			pipe->screen->resource_create(pipe->screen, &templ);
1065b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		if (!resources[2])
1075b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König			goto error;
1085b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	}
1095b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1105b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
1115b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		if (!resources[i])
1125b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König			continue;
1135b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1145b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		pbs[i] = &resources[i]->resource.buf;
1155b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		surfaces[i] = &resources[i]->surface;
1165b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	}
1175b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
118c868974396e95d900c7754bce38c0c950f6e3ab6Nicolai Hähnle	rvid_join_surfaces(ctx->b.ws, pbs, surfaces);
1195b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1205b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
1215b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		if (!resources[i])
1225b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König			continue;
1235b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
124cf811faeff1eaa1aef817ae45314cc3419c44222Marek Olšák		/* reset the address */
12583012b50854c795294b4b9e8b2766bb5258dafeaChristian König		resources[i]->resource.gpu_address = ctx->b.ws->buffer_get_virtual_address(
126cf811faeff1eaa1aef817ae45314cc3419c44222Marek Olšák			resources[i]->resource.buf);
1275b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	}
1285b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1297d2f2a0c890b1993532a45c8c392c28950ddc06eChristian König	template.height *= array_size;
1305b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);
1315b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1325b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian Königerror:
1335b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	for (i = 0; i < VL_NUM_COMPONENTS; ++i)
13436cf5a57c2b53b50778482f7341b7afcdc434dafMarek Olšák		r600_texture_reference(&resources[i], NULL);
1355b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1365b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	return NULL;
1375b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König}
1385b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1395b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König/* hw encode the number of memory banks */
1405b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian Königstatic uint32_t eg_num_banks(uint32_t nbanks)
1415b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König{
1425b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	switch (nbanks) {
1435b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	case 2:
1445b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		return 0;
1455b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	case 4:
1465b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		return 1;
1475b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	case 8:
1485b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	default:
1495b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		return 2;
1505b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	case 16:
1515b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König		return 3;
1525b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	}
1535b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König}
1545b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1555b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König/* set the decoding target buffer offsets */
156cf811faeff1eaa1aef817ae45314cc3419c44222Marek Olšákstatic struct pb_buffer* r600_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_buffer *buf)
1575b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König{
1585b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct r600_screen *rscreen = (struct r600_screen*)buf->base.context->screen;
1595b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct r600_texture *luma = (struct r600_texture *)buf->resources[0];
1605b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	struct r600_texture *chroma = (struct r600_texture *)buf->resources[1];
1615b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1622c2c54b819d8e0bd940f56501a2c3699d7cc2397Christian König	msg->body.decode.dt_field_mode = buf->base.interlaced;
163276621da451ae93321de05bf63baaf20ee2f32caMarek Olšák	msg->body.decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->b.info.r600_num_banks));
1645b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
1655b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König	ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);
1665b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
167cf811faeff1eaa1aef817ae45314cc3419c44222Marek Olšák	return luma->resource.buf;
1685b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König}
1695b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König
170685335639a982b398d305b8f314fc3857fcdbeadChristian König/* get the radeon resources for VCE */
171685335639a982b398d305b8f314fc3857fcdbeadChristian Königstatic void r600_vce_get_buffer(struct pipe_resource *resource,
172cf811faeff1eaa1aef817ae45314cc3419c44222Marek Olšák				struct pb_buffer **handle,
173685335639a982b398d305b8f314fc3857fcdbeadChristian König				struct radeon_surf **surface)
174685335639a982b398d305b8f314fc3857fcdbeadChristian König{
175685335639a982b398d305b8f314fc3857fcdbeadChristian König	struct r600_texture *res = (struct r600_texture *)resource;
176685335639a982b398d305b8f314fc3857fcdbeadChristian König
177685335639a982b398d305b8f314fc3857fcdbeadChristian König	if (handle)
178cf811faeff1eaa1aef817ae45314cc3419c44222Marek Olšák		*handle = res->resource.buf;
179685335639a982b398d305b8f314fc3857fcdbeadChristian König
180685335639a982b398d305b8f314fc3857fcdbeadChristian König	if (surface)
181685335639a982b398d305b8f314fc3857fcdbeadChristian König		*surface = &res->surface;
182685335639a982b398d305b8f314fc3857fcdbeadChristian König}
183685335639a982b398d305b8f314fc3857fcdbeadChristian König
1845b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König/* create decoder */
185f2f7064e560a83fc78d0e5b1d3a7d4aaac119a49Christian Königstruct pipe_video_codec *r600_uvd_create_decoder(struct pipe_context *context,
186685335639a982b398d305b8f314fc3857fcdbeadChristian König						 const struct pipe_video_codec *templat)
1875b2855bfe79bfc3995969f2bf775d89b1bc1808aChristian König{
188685335639a982b398d305b8f314fc3857fcdbeadChristian König	struct r600_context *ctx = (struct r600_context *)context;
189685335639a982b398d305b8f314fc3857fcdbeadChristian König
190685335639a982b398d305b8f314fc3857fcdbeadChristian König        if (templat->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
191685335639a982b398d305b8f314fc3857fcdbeadChristian König                return rvce_create_encoder(context, templat, ctx->b.ws, r600_vce_get_buffer);
192685335639a982b398d305b8f314fc3857fcdbeadChristian König
1932487324591c1629492288a814e1d8a3046d37b15Christian König	return ruvd_create_decoder(context, templat, r600_uvd_set_dtb);
194e3ac293daac1773631911182622b6732f68dc9f1Christian König}
195