[Mesa-dev] [PATCH] gallium: Query uvd handles info

Sahu, Satyajit Satyajit.Sahu at amd.com
Tue Apr 30 10:45:03 UTC 2019


Query the uvd handles info. If the used uvd handles are equals to
max possible handles then return error.

Signed-off-by: Satyajit Sahu <satyajit.sahu at amd.com>
---
 src/gallium/drivers/radeon/radeon_winsys.h    |  1 +
 src/gallium/drivers/radeonsi/si_get.c         |  8 ++++++++
 src/gallium/include/pipe/p_screen.h           |  1 +
 src/gallium/state_trackers/va/context.c       |  2 ++
 src/gallium/state_trackers/va/picture.c       | 11 ++++++++++-
 src/gallium/state_trackers/va/va_private.h    |  1 +
 src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 11 +++++++++++
 7 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index 0c71b59ae04..b4f3a3ad09f 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -125,6 +125,7 @@ enum radeon_value_id {
     RADEON_CURRENT_MCLK,
     RADEON_GPU_RESET_COUNTER, /* DRM 2.43.0 */
     RADEON_CS_THREAD_TIME,
+    RADEON_UVD_HANDLES,
 };
 
 enum radeon_bo_priority {
diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c
index 4e23d283ab7..6e27b0162e0 100644
--- a/src/gallium/drivers/radeonsi/si_get.c
+++ b/src/gallium/drivers/radeonsi/si_get.c
@@ -887,6 +887,13 @@ static uint64_t si_get_timestamp(struct pipe_screen *screen)
 			sscreen->info.clock_crystal_freq;
 }
 
+//ADD function for querying uvd handles info
+static uint64_t si_get_handles_info(struct pipe_screen *screen)
+{
+	struct si_screen *sscreen = (struct si_screen*)screen;
+
+	return sscreen->ws->query_value(sscreen->ws, RADEON_UVD_HANDLES);
+}
 static void si_query_memory_info(struct pipe_screen *screen,
 				 struct pipe_memory_info *info)
 {
@@ -975,6 +982,7 @@ void si_init_screen_get_functions(struct si_screen *sscreen)
 	sscreen->b.get_device_uuid = si_get_device_uuid;
 	sscreen->b.get_driver_uuid = si_get_driver_uuid;
 	sscreen->b.query_memory_info = si_query_memory_info;
+	sscreen->b.query_handles_info = si_get_handles_info;
 	sscreen->b.get_disk_shader_cache = si_get_disk_shader_cache;
 
 	if (sscreen->info.has_hw_decode) {
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index d4e2d9f63ac..c41af7b842f 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -148,6 +148,7 @@ struct pipe_screen {
     * wait for rendering to complete (which cannot be achieved with queries).
     */
    uint64_t (*get_timestamp)(struct pipe_screen *);
+   uint64_t (*query_handles_info)(struct pipe_screen *);
 
    /**
     * Create a context.
diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c
index 9176b7e8c5d..01dc618291f 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -237,8 +237,10 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width,
    if (!context)
       return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
+   context->is_vpp =false;
    if (is_vpp) {
       context->decoder = NULL;
+      context->is_vpp =true;
    } else {
       context->templat.profile = config->profile;
       context->templat.entrypoint = config->entrypoint;
diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c
index 04d2da0afeb..43ed53f8e82 100644
--- a/src/gallium/state_trackers/va/picture.c
+++ b/src/gallium/state_trackers/va/picture.c
@@ -42,6 +42,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
    vlVaDriver *drv;
    vlVaContext *context;
    vlVaSurface *surf;
+   struct pipe_screen *pscreen;
+   int available_uvd_handles;
 
    if (!ctx)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
@@ -50,6 +52,8 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
    if (!drv)
       return VA_STATUS_ERROR_INVALID_CONTEXT;
 
+   pscreen = VL_VA_PSCREEN(ctx);
+
    mtx_lock(&drv->mutex);
    context = handle_table_get(drv->htab, context_id);
    if (!context) {
@@ -73,7 +77,12 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
    context->mjpeg.sampling_factor = 0;
 
    if (!context->decoder) {
-
+      if (!context->is_vpp) {
+         //Query available uvd handles. If uvd handles not available fallback to software.
+         available_uvd_handles =  pscreen->query_handles_info(pscreen);
+         if (available_uvd_handles <= 0)
+            return VA_STATUS_ERROR_ALLOCATION_FAILED;
+      }
       /* VPP */
       if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN &&
           context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM &&
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
index b2b997d4799..a34cd6785ce 100644
--- a/src/gallium/state_trackers/va/va_private.h
+++ b/src/gallium/state_trackers/va/va_private.h
@@ -313,6 +313,7 @@ typedef struct {
    int gop_coeff;
    bool needs_begin_frame;
    void *blit_cs;
+   bool is_vpp;
 } vlVaContext;
 
 typedef struct {
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
index e847c5cff10..9e0574d389d 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
@@ -46,6 +46,12 @@
 #define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS	0x1E
 #endif
 
+struct amdgpu_info_num_handles {
+        /** Max handles as supported by firmware for UVD */
+        uint32_t  uvd_max_handles;
+        /** Handles currently in use for UVD */
+        uint32_t  uvd_used_handles;
+};
 static struct util_hash_table *dev_tab = NULL;
 static simple_mtx_t dev_tab_mutex = _SIMPLE_MTX_INITIALIZER_NP;
 
@@ -166,6 +172,7 @@ static uint64_t amdgpu_query_value(struct radeon_winsys *rws,
    struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws;
    struct amdgpu_heap_info heap;
    uint64_t retval = 0;
+   struct amdgpu_info_num_handles info_handles;
 
    switch (value) {
    case RADEON_REQUESTED_VRAM_MEMORY:
@@ -183,6 +190,10 @@ static uint64_t amdgpu_query_value(struct radeon_winsys *rws,
    case RADEON_TIMESTAMP:
       amdgpu_query_info(ws->dev, AMDGPU_INFO_TIMESTAMP, 8, &retval);
       return retval;
+   case RADEON_UVD_HANDLES:
+      amdgpu_query_uvd_handles(ws->dev, sizeof(info_handles), &info_handles);
+      retval = info_handles.uvd_max_handles - info_handles.uvd_used_handles;
+      return retval;
    case RADEON_NUM_GFX_IBS:
       return ws->num_gfx_IBs;
    case RADEON_NUM_SDMA_IBS:
-- 
2.19.1



More information about the mesa-dev mailing list