1b8e80941Smrg/************************************************************************** 2b8e80941Smrg * 3b8e80941Smrg * Copyright 2013 Advanced Micro Devices, Inc. 4b8e80941Smrg * All Rights Reserved. 5b8e80941Smrg * 6b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7b8e80941Smrg * copy of this software and associated documentation files (the 8b8e80941Smrg * "Software"), to deal in the Software without restriction, including 9b8e80941Smrg * without limitation the rights to use, copy, modify, merge, publish, 10b8e80941Smrg * distribute, sub license, and/or sell copies of the Software, and to 11b8e80941Smrg * permit persons to whom the Software is furnished to do so, subject to 12b8e80941Smrg * the following conditions: 13b8e80941Smrg * 14b8e80941Smrg * The above copyright notice and this permission notice (including the 15b8e80941Smrg * next paragraph) shall be included in all copies or substantial portions 16b8e80941Smrg * of the Software. 17b8e80941Smrg * 18b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19b8e80941Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20b8e80941Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21b8e80941Smrg * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 22b8e80941Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23b8e80941Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24b8e80941Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25b8e80941Smrg * 26b8e80941Smrg **************************************************************************/ 27b8e80941Smrg 28b8e80941Smrg/* 29b8e80941Smrg * Authors: 30b8e80941Smrg * Christian König <christian.koenig@amd.com> 31b8e80941Smrg * 32b8e80941Smrg */ 33b8e80941Smrg 34b8e80941Smrg#include <unistd.h> 35b8e80941Smrg 36b8e80941Smrg#include "util/u_memory.h" 37b8e80941Smrg#include "util/u_video.h" 38b8e80941Smrg 39b8e80941Smrg#include "vl/vl_defines.h" 40b8e80941Smrg#include "vl/vl_video_buffer.h" 41b8e80941Smrg 42b8e80941Smrg#include "r600_pipe_common.h" 43b8e80941Smrg#include "radeon_video.h" 44b8e80941Smrg#include "radeon_vce.h" 45b8e80941Smrg 46b8e80941Smrg#define UVD_FW_1_66_16 ((1 << 24) | (66 << 16) | (16 << 8)) 47b8e80941Smrg 48b8e80941Smrg/* generate an stream handle */ 49b8e80941Smrgunsigned rvid_alloc_stream_handle() 50b8e80941Smrg{ 51b8e80941Smrg static unsigned counter = 0; 52b8e80941Smrg unsigned stream_handle = 0; 53b8e80941Smrg unsigned pid = getpid(); 54b8e80941Smrg int i; 55b8e80941Smrg 56b8e80941Smrg for (i = 0; i < 32; ++i) 57b8e80941Smrg stream_handle |= ((pid >> i) & 1) << (31 - i); 58b8e80941Smrg 59b8e80941Smrg stream_handle ^= ++counter; 60b8e80941Smrg return stream_handle; 61b8e80941Smrg} 62b8e80941Smrg 63b8e80941Smrg/* create a buffer in the winsys */ 64b8e80941Smrgbool rvid_create_buffer(struct pipe_screen *screen, struct rvid_buffer *buffer, 65b8e80941Smrg unsigned size, unsigned usage) 66b8e80941Smrg{ 67b8e80941Smrg memset(buffer, 0, sizeof(*buffer)); 68b8e80941Smrg buffer->usage = usage; 69b8e80941Smrg 70b8e80941Smrg /* Hardware buffer placement restrictions require the kernel to be 71b8e80941Smrg * able to move buffers around individually, so request a 72b8e80941Smrg * non-sub-allocated buffer. 73b8e80941Smrg */ 74b8e80941Smrg buffer->res = (struct r600_resource *) 75b8e80941Smrg pipe_buffer_create(screen, PIPE_BIND_SHARED, 76b8e80941Smrg usage, size); 77b8e80941Smrg 78b8e80941Smrg return buffer->res != NULL; 79b8e80941Smrg} 80b8e80941Smrg 81b8e80941Smrg/* destroy a buffer */ 82b8e80941Smrgvoid rvid_destroy_buffer(struct rvid_buffer *buffer) 83b8e80941Smrg{ 84b8e80941Smrg r600_resource_reference(&buffer->res, NULL); 85b8e80941Smrg} 86b8e80941Smrg 87b8e80941Smrg/* reallocate a buffer, preserving its content */ 88b8e80941Smrgbool rvid_resize_buffer(struct pipe_screen *screen, struct radeon_cmdbuf *cs, 89b8e80941Smrg struct rvid_buffer *new_buf, unsigned new_size) 90b8e80941Smrg{ 91b8e80941Smrg struct r600_common_screen *rscreen = (struct r600_common_screen *)screen; 92b8e80941Smrg struct radeon_winsys* ws = rscreen->ws; 93b8e80941Smrg unsigned bytes = MIN2(new_buf->res->buf->size, new_size); 94b8e80941Smrg struct rvid_buffer old_buf = *new_buf; 95b8e80941Smrg void *src = NULL, *dst = NULL; 96b8e80941Smrg 97b8e80941Smrg if (!rvid_create_buffer(screen, new_buf, new_size, new_buf->usage)) 98b8e80941Smrg goto error; 99b8e80941Smrg 100b8e80941Smrg src = ws->buffer_map(old_buf.res->buf, cs, 101b8e80941Smrg PIPE_TRANSFER_READ | RADEON_TRANSFER_TEMPORARY); 102b8e80941Smrg if (!src) 103b8e80941Smrg goto error; 104b8e80941Smrg 105b8e80941Smrg dst = ws->buffer_map(new_buf->res->buf, cs, 106b8e80941Smrg PIPE_TRANSFER_WRITE | RADEON_TRANSFER_TEMPORARY); 107b8e80941Smrg if (!dst) 108b8e80941Smrg goto error; 109b8e80941Smrg 110b8e80941Smrg memcpy(dst, src, bytes); 111b8e80941Smrg if (new_size > bytes) { 112b8e80941Smrg new_size -= bytes; 113b8e80941Smrg dst += bytes; 114b8e80941Smrg memset(dst, 0, new_size); 115b8e80941Smrg } 116b8e80941Smrg ws->buffer_unmap(new_buf->res->buf); 117b8e80941Smrg ws->buffer_unmap(old_buf.res->buf); 118b8e80941Smrg rvid_destroy_buffer(&old_buf); 119b8e80941Smrg return true; 120b8e80941Smrg 121b8e80941Smrgerror: 122b8e80941Smrg if (src) 123b8e80941Smrg ws->buffer_unmap(old_buf.res->buf); 124b8e80941Smrg rvid_destroy_buffer(new_buf); 125b8e80941Smrg *new_buf = old_buf; 126b8e80941Smrg return false; 127b8e80941Smrg} 128b8e80941Smrg 129b8e80941Smrg/* clear the buffer with zeros */ 130b8e80941Smrgvoid rvid_clear_buffer(struct pipe_context *context, struct rvid_buffer* buffer) 131b8e80941Smrg{ 132b8e80941Smrg struct r600_common_context *rctx = (struct r600_common_context*)context; 133b8e80941Smrg 134b8e80941Smrg rctx->dma_clear_buffer(context, &buffer->res->b.b, 0, 135b8e80941Smrg buffer->res->buf->size, 0); 136b8e80941Smrg context->flush(context, NULL, 0); 137b8e80941Smrg} 138b8e80941Smrg 139b8e80941Smrg/** 140b8e80941Smrg * join surfaces into the same buffer with identical tiling params 141b8e80941Smrg * sumup their sizes and replace the backend buffers with a single bo 142b8e80941Smrg */ 143b8e80941Smrgvoid rvid_join_surfaces(struct r600_common_context *rctx, 144b8e80941Smrg struct pb_buffer** buffers[VL_NUM_COMPONENTS], 145b8e80941Smrg struct radeon_surf *surfaces[VL_NUM_COMPONENTS]) 146b8e80941Smrg{ 147b8e80941Smrg struct radeon_winsys* ws; 148b8e80941Smrg unsigned best_tiling, best_wh, off; 149b8e80941Smrg unsigned size, alignment; 150b8e80941Smrg struct pb_buffer *pb; 151b8e80941Smrg unsigned i, j; 152b8e80941Smrg 153b8e80941Smrg ws = rctx->ws; 154b8e80941Smrg 155b8e80941Smrg for (i = 0, best_tiling = 0, best_wh = ~0; i < VL_NUM_COMPONENTS; ++i) { 156b8e80941Smrg unsigned wh; 157b8e80941Smrg 158b8e80941Smrg if (!surfaces[i]) 159b8e80941Smrg continue; 160b8e80941Smrg 161b8e80941Smrg /* choose the smallest bank w/h for now */ 162b8e80941Smrg wh = surfaces[i]->u.legacy.bankw * surfaces[i]->u.legacy.bankh; 163b8e80941Smrg if (wh < best_wh) { 164b8e80941Smrg best_wh = wh; 165b8e80941Smrg best_tiling = i; 166b8e80941Smrg } 167b8e80941Smrg } 168b8e80941Smrg 169b8e80941Smrg for (i = 0, off = 0; i < VL_NUM_COMPONENTS; ++i) { 170b8e80941Smrg if (!surfaces[i]) 171b8e80941Smrg continue; 172b8e80941Smrg 173b8e80941Smrg /* adjust the texture layer offsets */ 174b8e80941Smrg off = align(off, surfaces[i]->surf_alignment); 175b8e80941Smrg 176b8e80941Smrg /* copy the tiling parameters */ 177b8e80941Smrg surfaces[i]->u.legacy.bankw = surfaces[best_tiling]->u.legacy.bankw; 178b8e80941Smrg surfaces[i]->u.legacy.bankh = surfaces[best_tiling]->u.legacy.bankh; 179b8e80941Smrg surfaces[i]->u.legacy.mtilea = surfaces[best_tiling]->u.legacy.mtilea; 180b8e80941Smrg surfaces[i]->u.legacy.tile_split = surfaces[best_tiling]->u.legacy.tile_split; 181b8e80941Smrg 182b8e80941Smrg for (j = 0; j < ARRAY_SIZE(surfaces[i]->u.legacy.level); ++j) 183b8e80941Smrg surfaces[i]->u.legacy.level[j].offset += off; 184b8e80941Smrg 185b8e80941Smrg off += surfaces[i]->surf_size; 186b8e80941Smrg } 187b8e80941Smrg 188b8e80941Smrg for (i = 0, size = 0, alignment = 0; i < VL_NUM_COMPONENTS; ++i) { 189b8e80941Smrg if (!buffers[i] || !*buffers[i]) 190b8e80941Smrg continue; 191b8e80941Smrg 192b8e80941Smrg size = align(size, (*buffers[i])->alignment); 193b8e80941Smrg size += (*buffers[i])->size; 194b8e80941Smrg alignment = MAX2(alignment, (*buffers[i])->alignment * 1); 195b8e80941Smrg } 196b8e80941Smrg 197b8e80941Smrg if (!size) 198b8e80941Smrg return; 199b8e80941Smrg 200b8e80941Smrg /* TODO: 2D tiling workaround */ 201b8e80941Smrg alignment *= 2; 202b8e80941Smrg 203b8e80941Smrg pb = ws->buffer_create(ws, size, alignment, RADEON_DOMAIN_VRAM, 204b8e80941Smrg RADEON_FLAG_GTT_WC); 205b8e80941Smrg if (!pb) 206b8e80941Smrg return; 207b8e80941Smrg 208b8e80941Smrg for (i = 0; i < VL_NUM_COMPONENTS; ++i) { 209b8e80941Smrg if (!buffers[i] || !*buffers[i]) 210b8e80941Smrg continue; 211b8e80941Smrg 212b8e80941Smrg pb_reference(buffers[i], pb); 213b8e80941Smrg } 214b8e80941Smrg 215b8e80941Smrg pb_reference(&pb, NULL); 216b8e80941Smrg} 217b8e80941Smrg 218b8e80941Smrgint rvid_get_video_param(struct pipe_screen *screen, 219b8e80941Smrg enum pipe_video_profile profile, 220b8e80941Smrg enum pipe_video_entrypoint entrypoint, 221b8e80941Smrg enum pipe_video_cap param) 222b8e80941Smrg{ 223b8e80941Smrg struct r600_common_screen *rscreen = (struct r600_common_screen *)screen; 224b8e80941Smrg enum pipe_video_format codec = u_reduce_video_profile(profile); 225b8e80941Smrg struct radeon_info info; 226b8e80941Smrg 227b8e80941Smrg rscreen->ws->query_info(rscreen->ws, &info); 228b8e80941Smrg 229b8e80941Smrg if (entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) { 230b8e80941Smrg switch (param) { 231b8e80941Smrg case PIPE_VIDEO_CAP_SUPPORTED: 232b8e80941Smrg return codec == PIPE_VIDEO_FORMAT_MPEG4_AVC && 233b8e80941Smrg rvce_is_fw_version_supported(rscreen); 234b8e80941Smrg case PIPE_VIDEO_CAP_NPOT_TEXTURES: 235b8e80941Smrg return 1; 236b8e80941Smrg case PIPE_VIDEO_CAP_MAX_WIDTH: 237b8e80941Smrg return 2048; 238b8e80941Smrg case PIPE_VIDEO_CAP_MAX_HEIGHT: 239b8e80941Smrg return 1152; 240b8e80941Smrg case PIPE_VIDEO_CAP_PREFERED_FORMAT: 241b8e80941Smrg return PIPE_FORMAT_NV12; 242b8e80941Smrg case PIPE_VIDEO_CAP_PREFERS_INTERLACED: 243b8e80941Smrg return false; 244b8e80941Smrg case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: 245b8e80941Smrg return false; 246b8e80941Smrg case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: 247b8e80941Smrg return true; 248b8e80941Smrg case PIPE_VIDEO_CAP_STACKED_FRAMES: 249b8e80941Smrg return 1; 250b8e80941Smrg default: 251b8e80941Smrg return 0; 252b8e80941Smrg } 253b8e80941Smrg } 254b8e80941Smrg 255b8e80941Smrg switch (param) { 256b8e80941Smrg case PIPE_VIDEO_CAP_SUPPORTED: 257b8e80941Smrg switch (codec) { 258b8e80941Smrg case PIPE_VIDEO_FORMAT_MPEG12: 259b8e80941Smrg return profile != PIPE_VIDEO_PROFILE_MPEG1; 260b8e80941Smrg case PIPE_VIDEO_FORMAT_MPEG4: 261b8e80941Smrg /* no support for MPEG4 on older hw */ 262b8e80941Smrg return rscreen->family >= CHIP_PALM; 263b8e80941Smrg case PIPE_VIDEO_FORMAT_MPEG4_AVC: 264b8e80941Smrg return true; 265b8e80941Smrg case PIPE_VIDEO_FORMAT_VC1: 266b8e80941Smrg return true; 267b8e80941Smrg case PIPE_VIDEO_FORMAT_HEVC: 268b8e80941Smrg return false; 269b8e80941Smrg case PIPE_VIDEO_FORMAT_JPEG: 270b8e80941Smrg return false; 271b8e80941Smrg default: 272b8e80941Smrg return false; 273b8e80941Smrg } 274b8e80941Smrg case PIPE_VIDEO_CAP_NPOT_TEXTURES: 275b8e80941Smrg return 1; 276b8e80941Smrg case PIPE_VIDEO_CAP_MAX_WIDTH: 277b8e80941Smrg return 2048; 278b8e80941Smrg case PIPE_VIDEO_CAP_MAX_HEIGHT: 279b8e80941Smrg return 1152; 280b8e80941Smrg case PIPE_VIDEO_CAP_PREFERED_FORMAT: 281b8e80941Smrg if (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) 282b8e80941Smrg return PIPE_FORMAT_P016; 283b8e80941Smrg else 284b8e80941Smrg return PIPE_FORMAT_NV12; 285b8e80941Smrg 286b8e80941Smrg case PIPE_VIDEO_CAP_PREFERS_INTERLACED: 287b8e80941Smrg case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: 288b8e80941Smrg if (rscreen->family < CHIP_PALM) { 289b8e80941Smrg /* MPEG2 only with shaders and no support for 290b8e80941Smrg interlacing on R6xx style UVD */ 291b8e80941Smrg return codec != PIPE_VIDEO_FORMAT_MPEG12 && 292b8e80941Smrg rscreen->family > CHIP_RV770; 293b8e80941Smrg } else { 294b8e80941Smrg enum pipe_video_format format = u_reduce_video_profile(profile); 295b8e80941Smrg 296b8e80941Smrg if (format == PIPE_VIDEO_FORMAT_HEVC) 297b8e80941Smrg return false; //The firmware doesn't support interlaced HEVC. 298b8e80941Smrg else if (format == PIPE_VIDEO_FORMAT_JPEG) 299b8e80941Smrg return false; 300b8e80941Smrg return true; 301b8e80941Smrg } 302b8e80941Smrg case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: 303b8e80941Smrg return true; 304b8e80941Smrg case PIPE_VIDEO_CAP_MAX_LEVEL: 305b8e80941Smrg switch (profile) { 306b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG1: 307b8e80941Smrg return 0; 308b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE: 309b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG2_MAIN: 310b8e80941Smrg return 3; 311b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE: 312b8e80941Smrg return 3; 313b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE: 314b8e80941Smrg return 5; 315b8e80941Smrg case PIPE_VIDEO_PROFILE_VC1_SIMPLE: 316b8e80941Smrg return 1; 317b8e80941Smrg case PIPE_VIDEO_PROFILE_VC1_MAIN: 318b8e80941Smrg return 2; 319b8e80941Smrg case PIPE_VIDEO_PROFILE_VC1_ADVANCED: 320b8e80941Smrg return 4; 321b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: 322b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: 323b8e80941Smrg case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: 324b8e80941Smrg return 41; 325b8e80941Smrg case PIPE_VIDEO_PROFILE_HEVC_MAIN: 326b8e80941Smrg case PIPE_VIDEO_PROFILE_HEVC_MAIN_10: 327b8e80941Smrg return 186; 328b8e80941Smrg default: 329b8e80941Smrg return 0; 330b8e80941Smrg } 331b8e80941Smrg default: 332b8e80941Smrg return 0; 333b8e80941Smrg } 334b8e80941Smrg} 335b8e80941Smrg 336b8e80941Smrgboolean rvid_is_format_supported(struct pipe_screen *screen, 337b8e80941Smrg enum pipe_format format, 338b8e80941Smrg enum pipe_video_profile profile, 339b8e80941Smrg enum pipe_video_entrypoint entrypoint) 340b8e80941Smrg{ 341b8e80941Smrg /* HEVC 10 bit decoding should use P016 instead of NV12 if possible */ 342b8e80941Smrg if (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) 343b8e80941Smrg return (format == PIPE_FORMAT_NV12) || 344b8e80941Smrg (format == PIPE_FORMAT_P016); 345b8e80941Smrg 346b8e80941Smrg /* we can only handle this one with UVD */ 347b8e80941Smrg if (profile != PIPE_VIDEO_PROFILE_UNKNOWN) 348b8e80941Smrg return format == PIPE_FORMAT_NV12; 349b8e80941Smrg 350b8e80941Smrg return vl_video_buffer_is_format_supported(screen, format, profile, entrypoint); 351b8e80941Smrg} 352