vdpau: implement vlVdpVideoSurfacePutBitsYCbCr
[mesa.git] / src / gallium / state_trackers / vdpau / query.c
index 57bd7fb752637942050fe291d8845d9a5562272e..e971b6dc02ed39a9146903206be7b8588dab58f7 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>
+
 
 VdpStatus
 vlVdpGetApiVersion(uint32_t *api_version)
@@ -43,7 +50,7 @@ vlVdpGetInformationString(char const **information_string)
    if (!information_string)
       return VDP_STATUS_INVALID_POINTER;
 
-   *information_string = "VDPAU-G3DVL";
+   *information_string = INFORMATION_STRING;
    return VDP_STATUS_OK;
 }
 
@@ -51,10 +58,44 @@ VdpStatus
 vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
 {
+   struct vl_screen *vlscreen;
+   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;
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   vlVdpDevice *dev = vlGetDataHTAB(device);
+   if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+
+   vlscreen = vl_screen_create(dev->display, dev->screen);
+   if (!vlscreen)
+      return VDP_STATUS_RESOURCES;
+
+   /* XXX: Current limits */
+   *is_supported = true;
+   if (surface_chroma_type != VDP_CHROMA_TYPE_420)  {
+         *is_supported = false;
+         goto no_sup;
+   }
+
+   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;
+   }
+
+   /* 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;
 }
 
 VdpStatus
@@ -62,10 +103,31 @@ vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaTyp
                                                   VdpYCbCrFormat bits_ycbcr_format,
                                                   VdpBool *is_supported)
 {
+   struct vl_screen *vlscreen;
+
+   debug_printf("[VDPAU] Querying get put video surfaces\n");
+
    if (!is_supported)
       return VDP_STATUS_INVALID_POINTER;
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   vlVdpDevice *dev = vlGetDataHTAB(device);
+   if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+
+   vlscreen = vl_screen_create(dev->display, dev->screen);
+   if (!vlscreen)
+      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);
+
+   vl_screen_destroy(vlscreen);
+
+   return VDP_STATUS_OK;
 }
 
 VdpStatus
@@ -73,10 +135,51 @@ vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
                               VdpBool *is_supported, uint32_t *max_level, uint32_t *max_macroblocks,
                               uint32_t *max_width, uint32_t *max_height)
 {
+   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;
 
-   return VDP_STATUS_NO_IMPLEMENTATION;
+   vlVdpDevice *dev = vlGetDataHTAB(device);
+   if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+
+   vlscreen = vl_screen_create(dev->display, dev->screen);
+   if (!vlscreen)
+      return VDP_STATUS_RESOURCES;
+
+   p_profile = ProfileToPipe(profile);
+   if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)        {
+          *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;
+   }
+
+   /* 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;
 }
 
 VdpStatus
@@ -86,6 +189,8 @@ vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba
    if (!(is_supported && max_width && max_height))
       return VDP_STATUS_INVALID_POINTER;
 
+   debug_printf("[VDPAU] Querying ouput surfaces\n");
+
    return VDP_STATUS_NO_IMPLEMENTATION;
 }
 
@@ -93,6 +198,8 @@ 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;
 
@@ -104,6 +211,7 @@ vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat
                                                 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;
 
@@ -114,6 +222,7 @@ 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;
 
@@ -124,6 +233,7 @@ 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;