/** * 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) { 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_ERROR; format = FormatRGBAToPipe(surface_rgba_format); if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM) return VDP_STATUS_INVALID_RGBA_FORMAT; if (!is_supported) return VDP_STATUS_INVALID_POINTER; pipe_mutex_lock(dev->mutex); *is_supported = pscreen->is_format_supported ( pscreen, format, PIPE_TEXTURE_2D, 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET ); pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; }
/** * 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) { vlVdpDevice *dev; struct pipe_screen *pscreen; enum pipe_format rgba_format, index_format, colortbl_format; dev = vlGetDataHTAB(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; pscreen = dev->vscreen->pscreen; if (!pscreen) return VDP_STATUS_ERROR; rgba_format = FormatRGBAToPipe(surface_rgba_format); if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM) return VDP_STATUS_INVALID_RGBA_FORMAT; index_format = FormatIndexedToPipe(bits_indexed_format); if (index_format == PIPE_FORMAT_NONE) return VDP_STATUS_INVALID_INDEXED_FORMAT; colortbl_format = FormatColorTableToPipe(color_table_format); if (colortbl_format == PIPE_FORMAT_NONE) return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT; if (!is_supported) return VDP_STATUS_INVALID_POINTER; pipe_mutex_lock(dev->mutex); *is_supported = pscreen->is_format_supported ( pscreen, rgba_format, PIPE_TEXTURE_2D, 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET ); *is_supported &= pscreen->is_format_supported ( pscreen, index_format, PIPE_TEXTURE_2D, 1, PIPE_BIND_SAMPLER_VIEW ); *is_supported &= pscreen->is_format_supported ( pscreen, colortbl_format, PIPE_TEXTURE_1D, 1, PIPE_BIND_SAMPLER_VIEW ); pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; }
/** * 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) { 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) return VDP_STATUS_INVALID_RGBA_FORMAT; if (!(is_supported && max_width && max_height)) return VDP_STATUS_INVALID_POINTER; pipe_mutex_lock(dev->mutex); *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) { pipe_mutex_unlock(dev->mutex); return VDP_STATUS_ERROR; } *max_width = *max_height = pow(2, max_2d_texture_level - 1); } else { *max_width = 0; *max_height = 0; } pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; }
/** * 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) { vlVdpDevice *dev; struct pipe_screen *pscreen; enum pipe_format rgba_format, ycbcr_format; dev = vlGetDataHTAB(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; pscreen = dev->vscreen->pscreen; if (!pscreen) return VDP_STATUS_ERROR; rgba_format = FormatRGBAToPipe(surface_rgba_format); if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM) return VDP_STATUS_INVALID_RGBA_FORMAT; ycbcr_format = FormatYCBCRToPipe(bits_ycbcr_format); if (ycbcr_format == PIPE_FORMAT_NONE) return VDP_STATUS_INVALID_INDEXED_FORMAT; if (!is_supported) return VDP_STATUS_INVALID_POINTER; pipe_mutex_lock(dev->mutex); *is_supported = pscreen->is_format_supported ( pscreen, rgba_format, PIPE_TEXTURE_2D, 1, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET ); *is_supported &= pscreen->is_video_format_supported ( pscreen, ycbcr_format, PIPE_VIDEO_PROFILE_UNKNOWN, PIPE_VIDEO_ENTRYPOINT_BITSTREAM ); pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; }
/** * Create a VdpOutputSurface. */ VdpStatus vlVdpOutputSurfaceCreate(VdpDevice device, VdpRGBAFormat rgba_format, uint32_t width, uint32_t height, VdpOutputSurface *surface) { struct pipe_context *pipe; struct pipe_resource res_tmpl, *res; struct pipe_sampler_view sv_templ; struct pipe_surface surf_templ; vlVdpOutputSurface *vlsurface = NULL; if (!(width && height)) return VDP_STATUS_INVALID_SIZE; vlVdpDevice *dev = vlGetDataHTAB(device); if (!dev) return VDP_STATUS_INVALID_HANDLE; pipe = dev->context; if (!pipe) return VDP_STATUS_INVALID_HANDLE; vlsurface = CALLOC(1, sizeof(vlVdpOutputSurface)); if (!vlsurface) return VDP_STATUS_RESOURCES; vlsurface->device = dev; memset(&res_tmpl, 0, sizeof(res_tmpl)); res_tmpl.target = PIPE_TEXTURE_2D; res_tmpl.format = FormatRGBAToPipe(rgba_format); res_tmpl.width0 = width; res_tmpl.height0 = height; res_tmpl.depth0 = 1; res_tmpl.array_size = 1; res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; res_tmpl.usage = PIPE_USAGE_STATIC; pipe_mutex_lock(dev->mutex); res = pipe->screen->resource_create(pipe->screen, &res_tmpl); if (!res) { pipe_mutex_unlock(dev->mutex); FREE(dev); return VDP_STATUS_ERROR; } vlVdpDefaultSamplerViewTemplate(&sv_templ, res); vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ); if (!vlsurface->sampler_view) { pipe_resource_reference(&res, NULL); pipe_mutex_unlock(dev->mutex); FREE(dev); return VDP_STATUS_ERROR; } memset(&surf_templ, 0, sizeof(surf_templ)); surf_templ.format = res->format; vlsurface->surface = pipe->create_surface(pipe, res, &surf_templ); if (!vlsurface->surface) { pipe_resource_reference(&res, NULL); pipe_mutex_unlock(dev->mutex); FREE(dev); return VDP_STATUS_ERROR; } *surface = vlAddDataHTAB(vlsurface); if (*surface == 0) { pipe_resource_reference(&res, NULL); pipe_mutex_unlock(dev->mutex); FREE(dev); return VDP_STATUS_ERROR; } pipe_resource_reference(&res, NULL); vl_compositor_init_state(&vlsurface->cstate, pipe); vl_compositor_reset_dirty_area(&vlsurface->dirty_area); pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; }