X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fvdpau%2Foutput.c;h=8237eaceb266f46c46d24cd80903c8cdf4e8c07f;hb=1bac4a1e6fef40cb0adef1a4af0050fc6fb71c7f;hp=c5d268955837429d13d286ab09a2fe12772ffe02;hpb=494e0025d995fb2cab04474d13880ee438b0c868;p=mesa.git diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c index c5d26895583..8237eaceb26 100644 --- a/src/gallium/state_trackers/vdpau/output.c +++ b/src/gallium/state_trackers/vdpau/output.c @@ -33,6 +33,8 @@ #include "util/u_sampler.h" #include "util/u_format.h" +#include "vl/vl_csc.h" + #include "vdpau_private.h" /** @@ -79,9 +81,12 @@ vlVdpOutputSurfaceCreate(VdpDevice device, 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); + FREE(vlsurface); return VDP_STATUS_ERROR; } @@ -89,16 +94,17 @@ vlVdpOutputSurfaceCreate(VdpDevice device, 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; - surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 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; } @@ -106,6 +112,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device, *surface = vlAddDataHTAB(vlsurface); if (*surface == 0) { pipe_resource_reference(&res, NULL); + pipe_mutex_unlock(dev->mutex); FREE(dev); return VDP_STATUS_ERROR; } @@ -114,6 +121,7 @@ vlVdpOutputSurfaceCreate(VdpDevice device, vl_compositor_init_state(&vlsurface->cstate, pipe); vl_compositor_reset_dirty_area(&vlsurface->dirty_area); + pipe_mutex_unlock(dev->mutex); return VDP_STATUS_OK; } @@ -125,16 +133,22 @@ VdpStatus vlVdpOutputSurfaceDestroy(VdpOutputSurface surface) { vlVdpOutputSurface *vlsurface; + struct pipe_context *pipe; vlsurface = vlGetDataHTAB(surface); if (!vlsurface) return VDP_STATUS_INVALID_HANDLE; + pipe = vlsurface->device->context; + + pipe_mutex_lock(vlsurface->device->mutex); vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); pipe_surface_reference(&vlsurface->surface, NULL); pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); + pipe->screen->fence_reference(pipe->screen, &vlsurface->fence, NULL); vl_compositor_cleanup_state(&vlsurface->cstate); + pipe_mutex_unlock(vlsurface->device->mutex); vlRemoveDataHTAB(surface); FREE(vlsurface); @@ -173,7 +187,39 @@ vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface, void *const *destination_data, uint32_t const *destination_pitches) { - return VDP_STATUS_NO_IMPLEMENTATION; + vlVdpOutputSurface *vlsurface; + struct pipe_context *pipe; + struct pipe_resource *res; + struct pipe_box box; + struct pipe_transfer *transfer; + uint8_t *map; + + vlsurface = vlGetDataHTAB(surface); + if (!vlsurface) + return VDP_STATUS_INVALID_HANDLE; + + pipe = vlsurface->device->context; + if (!pipe) + return VDP_STATUS_INVALID_HANDLE; + + pipe_mutex_lock(vlsurface->device->mutex); + vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); + + res = vlsurface->sampler_view->texture; + box = RectToPipeBox(source_rect, res); + map = pipe->transfer_map(pipe, res, 0, PIPE_TRANSFER_READ, &box, &transfer); + if (!map) { + pipe_mutex_unlock(vlsurface->device->mutex); + return VDP_STATUS_RESOURCES; + } + + util_copy_rect(*destination_data, res->format, *destination_pitches, 0, 0, + box.width, box.height, map, transfer->stride, 0, 0); + + pipe_transfer_unmap(pipe, transfer); + pipe_mutex_unlock(vlsurface->device->mutex); + + return VDP_STATUS_OK; } /** @@ -198,12 +244,14 @@ vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface, if (!pipe) return VDP_STATUS_INVALID_HANDLE; + pipe_mutex_lock(vlsurface->device->mutex); vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture); pipe->transfer_inline_write(pipe, vlsurface->sampler_view->texture, 0, PIPE_TRANSFER_WRITE, &dst_box, *source_data, *source_pitches, 0); + pipe_mutex_unlock(vlsurface->device->mutex); return VDP_STATUS_OK; } @@ -240,8 +288,6 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, if (!vlsurface) return VDP_STATUS_INVALID_HANDLE; - vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); - context = vlsurface->device->context; compositor = &vlsurface->device->compositor; cstate = &vlsurface->cstate; @@ -276,6 +322,9 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, res_tmpl.usage = PIPE_USAGE_STAGING; res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; + pipe_mutex_lock(vlsurface->device->mutex); + vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); + res = context->screen->resource_create(context->screen, &res_tmpl); if (!res) goto error_resource; @@ -337,12 +386,14 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, pipe_sampler_view_reference(&sv_idx, NULL); pipe_sampler_view_reference(&sv_tbl, NULL); + pipe_mutex_unlock(vlsurface->device->mutex); return VDP_STATUS_OK; error_resource: pipe_sampler_view_reference(&sv_idx, NULL); pipe_sampler_view_reference(&sv_tbl, NULL); + pipe_mutex_unlock(vlsurface->device->mutex); return VDP_STATUS_RESOURCES; } @@ -358,7 +409,91 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface, VdpRect const *destination_rect, VdpCSCMatrix const *csc_matrix) { - return VDP_STATUS_NO_IMPLEMENTATION; + vlVdpOutputSurface *vlsurface; + struct vl_compositor *compositor; + struct vl_compositor_state *cstate; + + struct pipe_context *pipe; + enum pipe_format format; + struct pipe_video_buffer vtmpl, *vbuffer; + struct u_rect dst_rect; + struct pipe_sampler_view **sampler_views; + + unsigned i; + + vlsurface = vlGetDataHTAB(surface); + if (!vlsurface) + return VDP_STATUS_INVALID_HANDLE; + + + pipe = vlsurface->device->context; + compositor = &vlsurface->device->compositor; + cstate = &vlsurface->cstate; + + format = FormatYCBCRToPipe(source_ycbcr_format); + if (format == PIPE_FORMAT_NONE) + return VDP_STATUS_INVALID_Y_CB_CR_FORMAT; + + if (!source_data || !source_pitches) + return VDP_STATUS_INVALID_POINTER; + + pipe_mutex_lock(vlsurface->device->mutex); + vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); + memset(&vtmpl, 0, sizeof(vtmpl)); + vtmpl.buffer_format = format; + vtmpl.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; + + if (destination_rect) { + vtmpl.width = abs(destination_rect->x0-destination_rect->x1); + vtmpl.height = abs(destination_rect->y0-destination_rect->y1); + } else { + vtmpl.width = vlsurface->surface->texture->width0; + vtmpl.height = vlsurface->surface->texture->height0; + } + + vbuffer = pipe->create_video_buffer(pipe, &vtmpl); + if (!vbuffer) { + pipe_mutex_unlock(vlsurface->device->mutex); + return VDP_STATUS_RESOURCES; + } + + sampler_views = vbuffer->get_sampler_view_planes(vbuffer); + if (!sampler_views) { + vbuffer->destroy(vbuffer); + pipe_mutex_unlock(vlsurface->device->mutex); + return VDP_STATUS_RESOURCES; + } + + for (i = 0; i < 3; ++i) { + struct pipe_sampler_view *sv = sampler_views[i]; + if (!sv) continue; + + struct pipe_box dst_box = { + 0, 0, 0, + sv->texture->width0, sv->texture->height0, 1 + }; + + pipe->transfer_inline_write(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE, &dst_box, + source_data[i], source_pitches[i], 0); + } + + if (!csc_matrix) { + vl_csc_matrix csc; + vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, 1, &csc); + vl_compositor_set_csc_matrix(cstate, (const vl_csc_matrix*)&csc); + } else { + vl_compositor_set_csc_matrix(cstate, csc_matrix); + } + + vl_compositor_clear_layers(cstate); + vl_compositor_set_buffer_layer(cstate, compositor, 0, vbuffer, NULL, NULL, VL_COMPOSITOR_WEAVE); + vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); + vl_compositor_render(cstate, compositor, vlsurface->surface, NULL); + + vbuffer->destroy(vbuffer); + pipe_mutex_unlock(vlsurface->device->mutex); + + return VDP_STATUS_OK; } static unsigned @@ -508,6 +643,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, if (dst_vlsurface->device != src_vlsurface->device) return VDP_STATUS_HANDLE_DEVICE_MISMATCH; + pipe_mutex_lock(dst_vlsurface->device->mutex); vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); context = dst_vlsurface->device->context; @@ -525,6 +661,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); context->delete_blend_state(context, blend); + pipe_mutex_unlock(dst_vlsurface->device->mutex); return VDP_STATUS_OK; } @@ -565,12 +702,13 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, if (dst_vlsurface->device != src_vlsurface->device) return VDP_STATUS_HANDLE_DEVICE_MISMATCH; - vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); - context = dst_vlsurface->device->context; compositor = &dst_vlsurface->device->compositor; cstate = &dst_vlsurface->cstate; + pipe_mutex_lock(dst_vlsurface->device->mutex); + vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); + blend = BlenderToPipe(context, blend_state); vl_compositor_clear_layers(cstate); @@ -582,6 +720,7 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); context->delete_blend_state(context, blend); + pipe_mutex_unlock(dst_vlsurface->device->mutex); return VDP_STATUS_OK; }