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