st/vdpau: implement BitmapSurfaceGetParameters
[mesa.git] / src / gallium / state_trackers / vdpau / query.c
index a3a8500a6f75b8ccb1b428d85359ba9958f25a98..c5f7037594abe63fc50d7b2452ca14377e686ff1 100644 (file)
  *
  **************************************************************************/
 
-#include "vdpau_private.h"
-#include <vl_winsys.h>
 #include <assert.h>
-#include <pipe/p_screen.h>
-#include <pipe/p_defines.h>
 #include <math.h>
-#include <util/u_debug.h>
-
 
+#include "vdpau_private.h"
+#include "vl_winsys.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_defines.h"
+#include "util/u_debug.h"
+
+/**
+ * Retrieve the VDPAU version implemented by the backend.
+ */
 VdpStatus
 vlVdpGetApiVersion(uint32_t *api_version)
 {
@@ -44,6 +47,10 @@ vlVdpGetApiVersion(uint32_t *api_version)
    return VDP_STATUS_OK;
 }
 
+/**
+ * Retrieve an implementation-specific string description of the implementation.
+ * This typically includes detailed version information.
+ */
 VdpStatus
 vlVdpGetInformationString(char const **information_string)
 {
@@ -54,193 +61,251 @@ vlVdpGetInformationString(char const **information_string)
    return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's VdpVideoSurface capabilities.
+ */
 VdpStatus
 vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
 {
-   struct vl_screen *vlscreen;
+   vlVdpDevice *dev;
+   struct pipe_screen *pscreen;
    uint32_t max_2d_texture_level;
-   VdpStatus ret;
-   
-   debug_printf("[VDPAU] Querying video surfaces\n");
 
    if (!(is_supported && max_width && max_height))
       return VDP_STATUS_INVALID_POINTER;
 
-   vlVdpDevice *dev = vlGetDataHTAB(device);
+   dev = vlGetDataHTAB(device);
    if (!dev)
       return VDP_STATUS_INVALID_HANDLE;
-   
-   vlscreen = vl_screen_create(dev->display, dev->screen);
-   if (!vlscreen)
+
+   pscreen = dev->vscreen->pscreen;
+   if (!pscreen)
       return VDP_STATUS_RESOURCES;
 
-   /* XXX: Current limits */ 
+   /* XXX: Current limits */
    *is_supported = true;
-   if (surface_chroma_type != VDP_CHROMA_TYPE_420)  {
-         *is_supported = false;
-         goto no_sup;
-   }
+   if (surface_chroma_type != VDP_CHROMA_TYPE_420)
+      *is_supported = false;
 
-   max_2d_texture_level = vlscreen->pscreen->get_param( vlscreen->pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS );
-   if (!max_2d_texture_level)  {
-      ret = VDP_STATUS_RESOURCES;
-         goto no_sup;
-   }
+   max_2d_texture_level = pscreen->get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+   if (!max_2d_texture_level)
+      return VDP_STATUS_RESOURCES;
 
    /* I am not quite sure if it is max_2d_texture_level-1 or just max_2d_texture_level */
    *max_width = *max_height = pow(2,max_2d_texture_level-1);
-   
-   vl_screen_destroy(vlscreen);
-   
+
    return VDP_STATUS_OK;
-   no_sup:
-   return ret;
 }
 
+/**
+ * Query the implementation's VdpVideoSurface GetBits/PutBits capabilities.
+ */
 VdpStatus
 vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
                                                   VdpYCbCrFormat bits_ycbcr_format,
                                                   VdpBool *is_supported)
 {
-       struct vl_screen *vlscreen;
-       
-       debug_printf("[VDPAU] Querying get put video surfaces\n");
-       
+   vlVdpDevice *dev;
+   struct pipe_screen *pscreen;
+
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
-   vlVdpDevice *dev = vlGetDataHTAB(device);
+   dev = vlGetDataHTAB(device);
    if (!dev)
       return VDP_STATUS_INVALID_HANDLE;
 
-   vlscreen = vl_screen_create(dev->display, dev->screen);
-   if (!vlscreen)
+   pscreen = dev->vscreen->pscreen;
+   if (!pscreen)
       return VDP_STATUS_RESOURCES;
 
-   if (bits_ycbcr_format != VDP_YCBCR_FORMAT_Y8U8V8A8 && bits_ycbcr_format != VDP_YCBCR_FORMAT_V8U8Y8A8) 
-                                      *is_supported = vlscreen->pscreen->is_format_supported(vlscreen->pscreen,
-                                   FormatToPipe(bits_ycbcr_format),
-                                   PIPE_TEXTURE_2D,
-                                                                  1,
-                                   PIPE_BIND_RENDER_TARGET, 
-                                   PIPE_TEXTURE_GEOM_NON_SQUARE );
-                                                                  
-   vl_screen_destroy(vlscreen);
-                                                                  
+   *is_supported = pscreen->is_video_format_supported
+   (
+      pscreen,
+      FormatYCBCRToPipe(bits_ycbcr_format),
+      PIPE_VIDEO_PROFILE_UNKNOWN
+   );
+
    return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's VdpDecoder capabilities.
+ */
 VdpStatus
 vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
                               VdpBool *is_supported, uint32_t *max_level, uint32_t *max_macroblocks,
                               uint32_t *max_width, uint32_t *max_height)
 {
+   vlVdpDevice *dev;
+   struct pipe_screen *pscreen;
    enum pipe_video_profile p_profile;
-   uint32_t max_decode_width;
-   uint32_t max_decode_height;
-   uint32_t max_2d_texture_level;
-   struct vl_screen *vlscreen;
-   
-   debug_printf("[VDPAU] Querying decoder\n");
-       
+
    if (!(is_supported && max_level && max_macroblocks && max_width && max_height))
       return VDP_STATUS_INVALID_POINTER;
-         
-   vlVdpDevice *dev = vlGetDataHTAB(device);
+
+   dev = vlGetDataHTAB(device);
    if (!dev)
       return VDP_STATUS_INVALID_HANDLE;
-   
-   vlscreen = vl_screen_create(dev->display, dev->screen);
-   if (!vlscreen)
+
+   pscreen = dev->vscreen->pscreen;
+   if (!pscreen)
       return VDP_STATUS_RESOURCES;
 
    p_profile = ProfileToPipe(profile);
    if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)        {
-          *is_supported = false;
-          return VDP_STATUS_OK;
+      *is_supported = false;
+      return VDP_STATUS_OK;
    }
    
-   if (p_profile != PIPE_VIDEO_PROFILE_MPEG2_SIMPLE && p_profile != PIPE_VIDEO_PROFILE_MPEG2_MAIN)  {
-          *is_supported = false;
-          return VDP_STATUS_OK;
+   *is_supported = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_SUPPORTED);
+   if (*is_supported) {
+      *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_WIDTH); 
+      *max_height = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_HEIGHT);
+      *max_level = 16;
+      *max_macroblocks = (*max_width/16)*(*max_height/16);
+   } else {
+      *max_width = 0;
+      *max_height = 0;
+      *max_level = 0;
+      *max_macroblocks = 0;
    }
-          
-   /* XXX hack, need to implement something more sane when the decoders have been implemented */
-   max_2d_texture_level = vlscreen->pscreen->get_param( vlscreen->pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS );
-   max_decode_width = max_decode_height = pow(2,max_2d_texture_level-2);
-   if (!(max_decode_width && max_decode_height))  
-      return VDP_STATUS_RESOURCES;
-       
-   *is_supported = true;
-   *max_width = max_decode_width;
-   *max_height = max_decode_height;
-   *max_level = 16;
-   *max_macroblocks = (max_decode_width/16) * (max_decode_height/16);
-   
-   vl_screen_destroy(vlscreen);
 
    return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's VdpOutputSurface capabilities.
+ */
 VdpStatus
 vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
                                     VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
-{      
+{
+   vlVdpDevice *dev;
+   struct pipe_screen *pscreen;
+   enum pipe_format format;
+
+   dev = vlGetDataHTAB(device);
+   if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+
+   pscreen = dev->vscreen->pscreen;
+   if (!pscreen)
+      return VDP_STATUS_RESOURCES;
+
+   format = FormatRGBAToPipe(surface_rgba_format);
+   if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
+      return VDP_STATUS_INVALID_RGBA_FORMAT;
+
    if (!(is_supported && max_width && max_height))
       return VDP_STATUS_INVALID_POINTER;
-         
-   debug_printf("[VDPAU] Querying ouput surfaces\n");
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   *is_supported = pscreen->is_format_supported
+   (
+      pscreen, format, PIPE_TEXTURE_3D, 1,
+      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
+   );
+   if (*is_supported) {
+      uint32_t max_2d_texture_level = pscreen->get_param(
+         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+
+      if (!max_2d_texture_level)
+         return VDP_STATUS_ERROR;
+
+      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
+   } else {
+      *max_width = 0;
+      *max_height = 0;
+   }
+
+   return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's capability to perform a PutBits operation using
+ * application data matching the surface's format.
+ */
 VdpStatus
 vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
                                                     VdpBool *is_supported)
 {
-   debug_printf("[VDPAU] Querying output surfaces get put native cap\n");
-       
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
    return VDP_STATUS_NO_IMPLEMENTATION;
 }
 
+/**
+ * Query the implementation's capability to perform a PutBits operation using
+ * application data in a specific indexed format.
+ */
+VdpStatus
+vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
+                                                  VdpRGBAFormat surface_rgba_format,
+                                                  VdpIndexedFormat bits_indexed_format,
+                                                  VdpColorTableFormat color_table_format,
+                                                  VdpBool *is_supported)
+{
+   if (!is_supported)
+      return VDP_STATUS_INVALID_POINTER;
+
+   return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+/**
+ * Query the implementation's capability to perform a PutBits operation using
+ * application data in a specific YCbCr/YUB format.
+ */
 VdpStatus
 vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
                                                 VdpYCbCrFormat bits_ycbcr_format,
                                                 VdpBool *is_supported)
 {
-   debug_printf("[VDPAU] Querying output surfaces put ycrcb cap\n");
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
    return VDP_STATUS_NO_IMPLEMENTATION;
 }
 
+/**
+ * Query the implementation's VdpBitmapSurface capabilities.
+ */
 VdpStatus
 vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
                                     VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
 {
-   debug_printf("[VDPAU] Querying bitmap surfaces\n");
    if (!(is_supported && max_width && max_height))
       return VDP_STATUS_INVALID_POINTER;
 
    return VDP_STATUS_NO_IMPLEMENTATION;
 }
 
+/**
+ * Query the implementation's support for a specific feature.
+ */
 VdpStatus
 vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
                                    VdpBool *is_supported)
 {
-   debug_printf("[VDPAU] Querying mixer feature support\n");
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   switch (feature) {
+   case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
+   case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
+      *is_supported = VDP_TRUE;
+      break;
+   default:
+      *is_supported = VDP_FALSE;
+      break;
+   }
+   return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's support for a specific parameter.
+ */
 VdpStatus
 vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
                                      VdpBool *is_supported)
@@ -248,19 +313,60 @@ vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter pa
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   switch (parameter) {
+   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
+   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
+   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
+   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
+      *is_supported = VDP_TRUE;
+      break;
+   default:
+      *is_supported = VDP_FALSE;
+      break;
+   }
+   return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's supported for a specific parameter.
+ */
 VdpStatus
 vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
                                         void *min_value, void *max_value)
 {
+   vlVdpDevice *dev = vlGetDataHTAB(device);
+   struct pipe_screen *screen;
+   enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
+   if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
    if (!(min_value && max_value))
       return VDP_STATUS_INVALID_POINTER;
-
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   screen = dev->vscreen->pscreen;
+   switch (parameter) {
+   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
+      *(uint32_t*)min_value = 48;
+      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
+      break;
+   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
+      *(uint32_t*)min_value = 48;
+      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
+      break;
+
+   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
+      *(uint32_t*)min_value = 0;
+      *(uint32_t*)max_value = 4;
+      break;
+
+   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
+   default:
+      return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
+   }
+   return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's support for a specific attribute.
+ */
 VdpStatus
 vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
                                      VdpBool *is_supported)
@@ -268,9 +374,25 @@ vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute at
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   switch (attribute) {
+   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
+      *is_supported = VDP_TRUE;
+      break;
+   default:
+      *is_supported = VDP_FALSE;
+   }
+   return VDP_STATUS_OK;
 }
 
+/**
+ * Query the implementation's supported for a specific attribute.
+ */
 VdpStatus
 vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
                                         void *min_value, void *max_value)
@@ -278,5 +400,25 @@ vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute
    if (!(min_value && max_value))
       return VDP_STATUS_INVALID_POINTER;
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   switch (attribute) {
+   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
+      *(float*)min_value = 0.f;
+      *(float*)max_value = 1.f;
+      break;
+   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
+      *(float*)min_value = -1.f;
+      *(float*)max_value = 1.f;
+      break;
+   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
+      *(uint8_t*)min_value = 0;
+      *(uint8_t*)max_value = 1;
+      break;
+   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
+   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
+   default:
+      return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
+   }
+   return VDP_STATUS_OK;
 }