X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fvdpau%2Foutput.c;h=7266cdb8afadcc7c9312a2fd3450bafc51eb1866;hb=e27f87b549cf2d4cfef97958ff175862fdf494b0;hp=0ea502939c3bcb4933963bb5a8c587a7bb6d6932;hpb=d645dc65b6c5e7d46538e98208a703f0f7a5d20b;p=mesa.git diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c index 0ea502939c3..7266cdb8afa 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,27 +81,30 @@ 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; } - memset(&sv_templ, 0, sizeof(sv_templ)); - u_sampler_view_default_template(&sv_templ, res, res->format); + 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; - 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; } @@ -107,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; } @@ -115,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; } @@ -126,14 +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); @@ -172,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; } /** @@ -185,7 +232,28 @@ vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface, uint32_t const *source_pitches, VdpRect const *destination_rect) { - return VDP_STATUS_NO_IMPLEMENTATION; + vlVdpOutputSurface *vlsurface; + struct pipe_box dst_box; + struct pipe_context *pipe; + + 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); + + 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; } /** @@ -254,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; @@ -310,17 +381,19 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, vl_compositor_clear_layers(cstate); vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false); - vl_compositor_set_dst_area(cstate, RectToPipe(destination_rect, &dst_rect)); - vl_compositor_render(cstate, compositor, vlsurface->surface, NULL); + vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); + vl_compositor_render(cstate, compositor, vlsurface->surface, &vlsurface->dirty_area, false); 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; } @@ -336,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, &vlsurface->dirty_area, false); + + vbuffer->destroy(vbuffer); + pipe_mutex_unlock(vlsurface->device->mutex); + + return VDP_STATUS_OK; } static unsigned @@ -428,6 +585,28 @@ BlenderToPipe(struct pipe_context *context, return context->create_blend_state(context, &blend); } +static struct vertex4f * +ColorsToPipe(VdpColor const *colors, uint32_t flags, struct vertex4f result[4]) +{ + unsigned i; + struct vertex4f *dst = result; + + if (!colors) + return NULL; + + for (i = 0; i < 4; ++i) { + dst->x = colors->red; + dst->y = colors->green; + dst->z = colors->blue; + dst->w = colors->alpha; + + ++dst; + if (flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) + ++colors; + } + return result; +} + /** * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of * another VdpOutputSurface; Output Surface object VdpOutputSurface. @@ -450,6 +629,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, struct u_rect src_rect, dst_rect; + struct vertex4f vlcolors[4]; void *blend; dst_vlsurface = vlGetDataHTAB(destination_surface); @@ -463,6 +643,9 @@ 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; compositor = &dst_vlsurface->device->compositor; cstate = &dst_vlsurface->cstate; @@ -472,11 +655,13 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, vl_compositor_clear_layers(cstate); vl_compositor_set_layer_blend(cstate, 0, blend, false); vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view, - RectToPipe(source_rect, &src_rect), NULL); - vl_compositor_set_dst_area(cstate, RectToPipe(destination_rect, &dst_rect)); - vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); + RectToPipe(source_rect, &src_rect), NULL, + ColorsToPipe(colors, flags, vlcolors)); + vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); + vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false); context->delete_blend_state(context, blend); + pipe_mutex_unlock(dst_vlsurface->device->mutex); return VDP_STATUS_OK; } @@ -494,5 +679,48 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, VdpOutputSurfaceRenderBlendState const *blend_state, uint32_t flags) { - return VDP_STATUS_NO_IMPLEMENTATION; + vlVdpOutputSurface *dst_vlsurface; + vlVdpBitmapSurface *src_vlsurface; + + struct pipe_context *context; + struct vl_compositor *compositor; + struct vl_compositor_state *cstate; + + struct u_rect src_rect, dst_rect; + + struct vertex4f vlcolors[4]; + void *blend; + + dst_vlsurface = vlGetDataHTAB(destination_surface); + if (!dst_vlsurface) + return VDP_STATUS_INVALID_HANDLE; + + src_vlsurface = vlGetDataHTAB(source_surface); + if (!src_vlsurface) + return VDP_STATUS_INVALID_HANDLE; + + if (dst_vlsurface->device != src_vlsurface->device) + return VDP_STATUS_HANDLE_DEVICE_MISMATCH; + + 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); + vl_compositor_set_layer_blend(cstate, 0, blend, false); + vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view, + RectToPipe(source_rect, &src_rect), NULL, + ColorsToPipe(colors, flags, vlcolors)); + vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); + vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false); + + context->delete_blend_state(context, blend); + pipe_mutex_unlock(dst_vlsurface->device->mutex); + + return VDP_STATUS_OK; }