diff -Naur Mesa-9999.old/src/gallium/drivers/r600/r600_pipe.c Mesa-9999/src/gallium/drivers/r600/r600_pipe.c --- Mesa-9999.old/src/gallium/drivers/r600/r600_pipe.c 2013-04-19 08:32:24.346249734 +0200 +++ Mesa-9999/src/gallium/drivers/r600/r600_pipe.c 2013-04-19 08:36:18.318255286 +0200 @@ -35,9 +35,9 @@ #include "util/u_simple_shaders.h" #include "util/u_upload_mgr.h" #include "util/u_math.h" -#include "util/u_video.h" #include "vl/vl_decoder.h" #include "vl/vl_video_buffer.h" +#include "radeon/radeon_uvd.h" #include "os/os_time.h" static const struct debug_named_value debug_options[] = { @@ -380,8 +380,13 @@ r600_init_context_resource_functions(rctx); r600_init_surface_functions(rctx); - rctx->context.create_video_decoder = r600_uvd_create_decoder; - rctx->context.create_video_buffer = r600_video_buffer_create; + if (rscreen->info.has_uvd) { + rctx->context.create_video_decoder = r600_uvd_create_decoder; + rctx->context.create_video_buffer = r600_video_buffer_create; + } else { + rctx->context.create_video_decoder = vl_create_decoder; + rctx->context.create_video_buffer = vl_video_buffer_create; + } r600_init_common_state_functions(rctx); @@ -748,34 +753,12 @@ { switch (param) { case PIPE_VIDEO_CAP_SUPPORTED: - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG4: - case PIPE_VIDEO_CODEC_MPEG4_AVC: - case PIPE_VIDEO_CODEC_VC1: - return true; - default: - return vl_profile_supported(screen, profile); - } + return vl_profile_supported(screen, profile); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; case PIPE_VIDEO_CAP_MAX_WIDTH: - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG4: - case PIPE_VIDEO_CODEC_MPEG4_AVC: - case PIPE_VIDEO_CODEC_VC1: - return 2048; - default: - return vl_video_buffer_max_size(screen); - } case PIPE_VIDEO_CAP_MAX_HEIGHT: - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG4: - case PIPE_VIDEO_CODEC_MPEG4_AVC: - case PIPE_VIDEO_CODEC_VC1: - return 1152; - default: - return vl_video_buffer_max_size(screen); - } + return vl_video_buffer_max_size(screen); case PIPE_VIDEO_CAP_PREFERED_FORMAT: return PIPE_FORMAT_NV12; case PIPE_VIDEO_CAP_PREFERS_INTERLACED: @@ -946,19 +929,6 @@ } } -static boolean r600_is_video_format_supported(struct pipe_screen *screen, - enum pipe_format format, - enum pipe_video_profile profile) -{ - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG4_AVC: - case PIPE_VIDEO_CODEC_VC1: - return format == PIPE_FORMAT_NV12; - default: - return vl_video_buffer_is_format_supported(screen, format, profile); - } -} - static void r600_destroy_screen(struct pipe_screen* pscreen) { struct r600_screen *rscreen = (struct r600_screen *)pscreen; @@ -1293,7 +1263,6 @@ rscreen->screen.get_param = r600_get_param; rscreen->screen.get_shader_param = r600_get_shader_param; rscreen->screen.get_paramf = r600_get_paramf; - rscreen->screen.get_video_param = r600_get_video_param; rscreen->screen.get_compute_param = r600_get_compute_param; rscreen->screen.get_timestamp = r600_get_timestamp; @@ -1304,12 +1273,20 @@ rscreen->screen.is_format_supported = r600_is_format_supported; rscreen->dma_blit = &r600_dma_blit; } - rscreen->screen.is_video_format_supported = r600_is_video_format_supported; rscreen->screen.context_create = r600_create_context; rscreen->screen.fence_reference = r600_fence_reference; rscreen->screen.fence_signalled = r600_fence_signalled; rscreen->screen.fence_finish = r600_fence_finish; rscreen->screen.get_driver_query_info = r600_get_driver_query_info; + + if (rscreen->info.has_uvd) { + rscreen->screen.get_video_param = ruvd_get_video_param; + rscreen->screen.is_video_format_supported = ruvd_is_format_supported; + } else { + rscreen->screen.get_video_param = r600_get_video_param; + rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported; + } + r600_init_screen_resource_functions(&rscreen->screen); util_format_s3tc_init(); diff -Naur Mesa-9999.old/src/gallium/drivers/radeon/radeon_uvd.c Mesa-9999/src/gallium/drivers/radeon/radeon_uvd.c --- Mesa-9999.old/src/gallium/drivers/radeon/radeon_uvd.c 2013-04-19 08:32:24.351249734 +0200 +++ Mesa-9999/src/gallium/drivers/radeon/radeon_uvd.c 2013-04-19 08:36:18.323255286 +0200 @@ -1062,3 +1066,46 @@ msg->decode.dt_surf_tile_config |= RUVD_BANK_HEIGHT(bank_wh(luma->bankh)); msg->decode.dt_surf_tile_config |= RUVD_MACRO_TILE_ASPECT_RATIO(macro_tile_aspect(luma->mtilea)); } + +int ruvd_get_video_param(struct pipe_screen *screen, + enum pipe_video_profile profile, + enum pipe_video_cap param) +{ + switch (param) { + case PIPE_VIDEO_CAP_SUPPORTED: + switch (u_reduce_video_profile(profile)) { + case PIPE_VIDEO_CODEC_MPEG12: + case PIPE_VIDEO_CODEC_MPEG4: + /* TODO not all hw families support MPEG4 */ + case PIPE_VIDEO_CODEC_MPEG4_AVC: + case PIPE_VIDEO_CODEC_VC1: + return true; + default: + return false; + } + case PIPE_VIDEO_CAP_NPOT_TEXTURES: + return 1; + case PIPE_VIDEO_CAP_MAX_WIDTH: + return 2048; + case PIPE_VIDEO_CAP_MAX_HEIGHT: + return 1152; + case PIPE_VIDEO_CAP_PREFERED_FORMAT: + return PIPE_FORMAT_NV12; + case PIPE_VIDEO_CAP_PREFERS_INTERLACED: + return false; + case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: + return false; /* TODO: enable this */ + case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: + return true; + default: + return 0; + } +} + +boolean ruvd_is_format_supported(struct pipe_screen *screen, + enum pipe_format format, + enum pipe_video_profile profile) +{ + /* we can only handle this one anyway */ + return format == PIPE_FORMAT_NV12; +} diff -Naur Mesa-9999.old/src/gallium/drivers/radeon/radeon_uvd.h Mesa-9999/src/gallium/drivers/radeon/radeon_uvd.h --- Mesa-9999.old/src/gallium/drivers/radeon/radeon_uvd.h 2013-04-19 08:32:24.352249734 +0200 +++ Mesa-9999/src/gallium/drivers/radeon/radeon_uvd.h 2013-04-19 08:36:18.324255286 +0200 @@ -364,4 +364,14 @@ void ruvd_set_dt_surfaces(struct ruvd_msg *msg, struct radeon_surface *luma, struct radeon_surface *chroma); +/* returns supported codecs and other parameters */ +int ruvd_get_video_param(struct pipe_screen *screen, + enum pipe_video_profile profile, + enum pipe_video_cap param); + +/* the hardware only supports NV12 */ +boolean ruvd_is_format_supported(struct pipe_screen *screen, + enum pipe_format format, + enum pipe_video_profile profile); + #endif diff -Naur Mesa-9999.old/src/gallium/drivers/radeonsi/radeonsi_pipe.c Mesa-9999/src/gallium/drivers/radeonsi/radeonsi_pipe.c --- Mesa-9999.old/src/gallium/drivers/radeonsi/radeonsi_pipe.c 2013-04-19 08:32:24.353249734 +0200 +++ Mesa-9999/src/gallium/drivers/radeonsi/radeonsi_pipe.c 2013-04-19 08:36:18.325255286 +0200 @@ -39,11 +39,12 @@ #include "util/u_inlines.h" #include "util/u_simple_shaders.h" #include "util/u_upload_mgr.h" -#include "util/u_video.h" #include "vl/vl_decoder.h" #include "vl/vl_video_buffer.h" #include "os/os_time.h" #include "pipebuffer/pb_buffer.h" +#include "radeonsi_pipe.h" +#include "radeon/radeon_uvd.h" #include "r600.h" #include "sid.h" #include "r600_resource.h" @@ -220,8 +221,13 @@ si_init_surface_functions(rctx); si_init_compute_functions(rctx); - rctx->context.create_video_decoder = radeonsi_uvd_create_decoder; - rctx->context.create_video_buffer = radeonsi_video_buffer_create; + if (rscreen->info.has_uvd) { + rctx->context.create_video_decoder = radeonsi_uvd_create_decoder; + rctx->context.create_video_buffer = radeonsi_video_buffer_create; + } else { + rctx->context.create_video_decoder = vl_create_decoder; + rctx->context.create_video_buffer = vl_video_buffer_create; + } switch (rctx->chip_class) { case TAHITI: @@ -512,42 +518,14 @@ { switch (param) { case PIPE_VIDEO_CAP_SUPPORTED: - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG4: - case PIPE_VIDEO_CODEC_MPEG4_AVC: - case PIPE_VIDEO_CODEC_VC1: - return true; - default: - return vl_profile_supported(screen, profile); - } + return vl_profile_supported(screen, profile); case PIPE_VIDEO_CAP_NPOT_TEXTURES: return 1; case PIPE_VIDEO_CAP_MAX_WIDTH: - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG4: - case PIPE_VIDEO_CODEC_MPEG4_AVC: - case PIPE_VIDEO_CODEC_VC1: - return 2048; - default: - return vl_video_buffer_max_size(screen); - } case PIPE_VIDEO_CAP_MAX_HEIGHT: - switch (u_reduce_video_profile(profile)) { - case PIPE_VIDEO_CODEC_MPEG4: - case PIPE_VIDEO_CODEC_MPEG4_AVC: - case PIPE_VIDEO_CODEC_VC1: - return 1152; - default: - return vl_video_buffer_max_size(screen); - } + return vl_video_buffer_max_size(screen); case PIPE_VIDEO_CAP_PREFERED_FORMAT: return PIPE_FORMAT_NV12; - case PIPE_VIDEO_CAP_PREFERS_INTERLACED: - return false; - case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: - return false; - case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: - return true; default: return 0; } @@ -813,16 +791,22 @@ rscreen->screen.get_param = r600_get_param; rscreen->screen.get_shader_param = r600_get_shader_param; rscreen->screen.get_paramf = r600_get_paramf; - rscreen->screen.get_video_param = r600_get_video_param; rscreen->screen.get_compute_param = r600_get_compute_param; rscreen->screen.is_format_supported = si_is_format_supported; - rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported; rscreen->screen.context_create = r600_create_context; rscreen->screen.fence_reference = r600_fence_reference; rscreen->screen.fence_signalled = r600_fence_signalled; rscreen->screen.fence_finish = r600_fence_finish; r600_init_screen_resource_functions(&rscreen->screen); + if (rscreen->info.has_uvd) { + rscreen->screen.get_video_param = ruvd_get_video_param; + rscreen->screen.is_video_format_supported = ruvd_is_format_supported; + } else { + rscreen->screen.get_video_param = r600_get_video_param; + rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported; + } + util_format_s3tc_init(); rscreen->fences.bo = NULL; diff -Naur Mesa-9999.old/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c Mesa-9999/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c --- Mesa-9999.old/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c 2013-04-19 08:30:56.448247649 +0200 +++ Mesa-9999/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c 2013-04-19 08:36:15.461255218 +0200 @@ -90,6 +90,14 @@ #define RADEON_INFO_TIMESTAMP 0x11 #endif +#ifndef RADEON_INFO_RING_WORKING +#define RADEON_INFO_RING_WORKING 0x15 +#endif + +#ifndef RADEON_CS_RING_UVD +#define RADEON_CS_RING_UVD 3 +#endif + static struct util_hash_table *fd_tab = NULL; /* Enable/disable feature access for one command stream. @@ -323,6 +331,15 @@ ws->info.r600_has_dma = TRUE; } + /* Check for UVD */ + ws->info.has_uvd = FALSE; + if (ws->info.drm_minor >= 32) { + uint32_t value = RADEON_CS_RING_UVD; + if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING, + "UVD Ring working", &value)) + ws->info.has_uvd = value; + } + /* Get GEM info. */ retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO, &gem_info, sizeof(gem_info)); diff -Naur Mesa-9999.old/src/gallium/winsys/radeon/drm/radeon_winsys.h Mesa-9999/src/gallium/winsys/radeon/drm/radeon_winsys.h --- Mesa-9999.old/src/gallium/winsys/radeon/drm/radeon_winsys.h 2013-04-19 08:32:24.355249735 +0200 +++ Mesa-9999/src/gallium/winsys/radeon/drm/radeon_winsys.h 2013-04-19 08:36:15.461255218 +0200 @@ -171,6 +171,8 @@ uint32_t drm_minor; uint32_t drm_patchlevel; + boolean has_uvd; + uint32_t r300_num_gb_pipes; uint32_t r300_num_z_pipes;