diff --git a/src/gallium/state_trackers/vdpau/bitmap.c b/src/gallium/state_trackers/vdpau/bitmap.c index 469f3e8..d316134 100644 --- a/src/gallium/state_trackers/vdpau/bitmap.c +++ b/src/gallium/state_trackers/vdpau/bitmap.c @@ -45,6 +45,7 @@ vlVdpBitmapSurfaceCreate(VdpDevice device, struct pipe_context *pipe; struct pipe_resource res_tmpl, *res; struct pipe_sampler_view sv_templ; + VdpStatus ret; vlVdpBitmapSurface *vlsurface = NULL; @@ -79,32 +80,43 @@ vlVdpBitmapSurfaceCreate(VdpDevice device, res_tmpl.usage = frequently_accessed ? PIPE_USAGE_DYNAMIC : PIPE_USAGE_STATIC; pipe_mutex_lock(dev->mutex); + + if (!CheckSurfaceParams(pipe->screen, &res_tmpl)) + goto err_unlock; + res = pipe->screen->resource_create(pipe->screen, &res_tmpl); if (!res) { - pipe_mutex_unlock(dev->mutex); - FREE(dev); - FREE(vlsurface); - return VDP_STATUS_RESOURCES; + 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); - pipe_mutex_unlock(dev->mutex); if (!vlsurface->sampler_view) { - FREE(dev); - return VDP_STATUS_RESOURCES; + ret = VDP_STATUS_RESOURCES; + goto err_unlock; } + pipe_mutex_unlock(dev->mutex); + *surface = vlAddDataHTAB(vlsurface); if (*surface == 0) { - FREE(dev); - return VDP_STATUS_ERROR; + pipe_mutex_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: + pipe_mutex_unlock(dev->mutex); + FREE(vlsurface); + return ret; } /** diff --git a/src/gallium/state_trackers/vdpau/device.c b/src/gallium/state_trackers/vdpau/device.c index fb9c68c..36ac11a 100644 --- a/src/gallium/state_trackers/vdpau/device.c +++ b/src/gallium/state_trackers/vdpau/device.c @@ -72,6 +72,11 @@ vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device, goto no_context; } + if (!pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) { + ret = VDP_STATUS_NO_IMPLEMENTATION; + goto no_context; + } + *device = vlAddDataHTAB(dev); if (*device == 0) { ret = VDP_STATUS_ERROR; diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c index e4e1433..50036ae 100644 --- a/src/gallium/state_trackers/vdpau/output.c +++ b/src/gallium/state_trackers/vdpau/output.c @@ -83,41 +83,29 @@ vlVdpOutputSurfaceCreate(VdpDevice device, res_tmpl.usage = PIPE_USAGE_STATIC; pipe_mutex_lock(dev->mutex); + + if (!CheckSurfaceParams(pipe->screen, &res_tmpl)) + goto err_unlock; + res = pipe->screen->resource_create(pipe->screen, &res_tmpl); - if (!res) { - pipe_mutex_unlock(dev->mutex); - FREE(dev); - FREE(vlsurface); - return VDP_STATUS_ERROR; - } + if (!res) + goto err_unlock; 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; - } + if (!vlsurface->sampler_view) + goto err_resource; 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; - } + if (!vlsurface->surface) + goto err_resource; *surface = vlAddDataHTAB(vlsurface); - if (*surface == 0) { - pipe_resource_reference(&res, NULL); - pipe_mutex_unlock(dev->mutex); - FREE(dev); - return VDP_STATUS_ERROR; - } - + if (*surface == 0) + goto err_resource; + pipe_resource_reference(&res, NULL); vl_compositor_init_state(&vlsurface->cstate, pipe); @@ -125,6 +113,15 @@ vlVdpOutputSurfaceCreate(VdpDevice device, pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; + +err_resource: + pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); + pipe_surface_reference(&vlsurface->surface, NULL); + pipe_surface_reference(&res, NULL); +err_unlock: + pipe_mutex_unlock(dev->mutex); + FREE(vlsurface); + return VDP_STATUS_ERROR; } /** @@ -326,6 +323,9 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, pipe_mutex_lock(vlsurface->device->mutex); vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); + if (!CheckSurfaceParams(context->screen, &res_tmpl)) + goto error_resource; + res = context->screen->resource_create(context->screen, &res_tmpl); if (!res) goto error_resource; diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h index 60196ac..6c2c019 100644 --- a/src/gallium/state_trackers/vdpau/vdpau_private.h +++ b/src/gallium/state_trackers/vdpau/vdpau_private.h @@ -332,6 +332,14 @@ RectToPipeBox(const VdpRect *rect, struct pipe_resource *res) return box; } +static inline bool +CheckSurfaceParams(struct pipe_screen *screen, + const struct pipe_resource *templ) +{ + return screen->is_format_supported( + screen, templ->format, templ->target, templ->nr_samples, templ->bind); +} + typedef struct { struct vl_screen *vscreen;