/** * 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 = VdpFormatRGBAToPipe(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; }
static struct pipe_resource * st_vdpau_resource_from_description(struct gl_context *ctx, const struct VdpSurfaceDMABufDesc *desc) { struct st_context *st = st_context(ctx); struct pipe_resource templ, *res; struct winsys_handle whandle; if (desc->handle == -1) return NULL; memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_2D; templ.last_level = 0; templ.depth0 = 1; templ.array_size = 1; templ.width0 = desc->width; templ.height0 = desc->height; templ.format = VdpFormatRGBAToPipe(desc->format); templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; templ.usage = PIPE_USAGE_DEFAULT; memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_FD; whandle.handle = desc->handle; whandle.offset = desc->offset; whandle.stride = desc->stride; res = st->pipe->screen->resource_from_handle(st->pipe->screen, &templ, &whandle, PIPE_HANDLE_USAGE_READ_WRITE); close(desc->handle); return res; }
/** * 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 = VdpFormatRGBAToPipe(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 = VdpFormatRGBAToPipe(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 = VdpFormatRGBAToPipe(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 VdpBitmapSurface. */ VdpStatus vlVdpBitmapSurfaceCreate(VdpDevice device, VdpRGBAFormat rgba_format, uint32_t width, uint32_t height, VdpBool frequently_accessed, VdpBitmapSurface *surface) { struct pipe_context *pipe; struct pipe_resource res_tmpl, *res; struct pipe_sampler_view sv_templ; VdpStatus ret; vlVdpBitmapSurface *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; if (!surface) return VDP_STATUS_INVALID_POINTER; vlsurface = CALLOC(1, sizeof(vlVdpBitmapSurface)); if (!vlsurface) return VDP_STATUS_RESOURCES; DeviceReference(&vlsurface->device, dev); memset(&res_tmpl, 0, sizeof(res_tmpl)); res_tmpl.target = PIPE_TEXTURE_2D; res_tmpl.format = VdpFormatRGBAToPipe(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 = frequently_accessed ? PIPE_USAGE_DYNAMIC : PIPE_USAGE_DEFAULT; mtx_lock(&dev->mutex); if (!CheckSurfaceParams(pipe->screen, &res_tmpl)) { ret = VDP_STATUS_RESOURCES; goto err_unlock; } res = pipe->screen->resource_create(pipe->screen, &res_tmpl); if (!res) { ret = VDP_STATUS_RESOURCES; goto err_unlock; } vlVdpDefaultSamplerViewTemplate(&sv_templ, res); vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ); pipe_resource_reference(&res, NULL); if (!vlsurface->sampler_view) { ret = VDP_STATUS_RESOURCES; goto err_unlock; } mtx_unlock(&dev->mutex); *surface = vlAddDataHTAB(vlsurface); if (*surface == 0) { mtx_lock(&dev->mutex); ret = VDP_STATUS_ERROR; goto err_sampler; } return VDP_STATUS_OK; err_sampler: pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); err_unlock: mtx_unlock(&dev->mutex); DeviceReference(&vlsurface->device, NULL); FREE(vlsurface); return ret; }