X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fvdpau%2Foutput.c;h=8c29a3ff4e573d7f11551d19b2d36a6253d637c9;hb=fef23f6712064416f02211f1517e387169735e0b;hp=56ce315db7f44e891e781e67d65522bd26427f56;hpb=507fd8026ad2ade8bc79f5852ec20ad74503cc7f;p=mesa.git diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c index 56ce315db7f..8c29a3ff4e5 100644 --- a/src/gallium/state_trackers/vdpau/output.c +++ b/src/gallium/state_trackers/vdpau/output.c @@ -19,7 +19,7 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,6 +32,11 @@ #include "util/u_memory.h" #include "util/u_sampler.h" #include "util/u_format.h" +#include "util/u_surface.h" + +#include "vl/vl_csc.h" + +#include "state_tracker/drm_driver.h" #include "vdpau_private.h" @@ -66,56 +71,61 @@ vlVdpOutputSurfaceCreate(VdpDevice device, if (!vlsurface) return VDP_STATUS_RESOURCES; - vlsurface->device = dev; + DeviceReference(&vlsurface->device, dev); memset(&res_tmpl, 0, sizeof(res_tmpl)); res_tmpl.target = PIPE_TEXTURE_2D; - res_tmpl.format = FormatRGBAToPipe(rgba_format); + 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 = PIPE_USAGE_STATIC; + res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET | + PIPE_BIND_SHARED; + res_tmpl.usage = PIPE_USAGE_DEFAULT; + + 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) { - FREE(dev); - 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); - 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; - 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); - FREE(dev); - return VDP_STATUS_ERROR; - } + if (!vlsurface->surface) + goto err_resource; *surface = vlAddDataHTAB(vlsurface); - if (*surface == 0) { - pipe_resource_reference(&res, NULL); - FREE(dev); - return VDP_STATUS_ERROR; - } - + if (*surface == 0) + goto err_resource; + 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; + +err_resource: + pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); + pipe_surface_reference(&vlsurface->surface, NULL); + pipe_resource_reference(&res, NULL); +err_unlock: + pipe_mutex_unlock(dev->mutex); + DeviceReference(&vlsurface->device, NULL); + FREE(vlsurface); + return VDP_STATUS_ERROR; } /** @@ -125,18 +135,25 @@ 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); + DeviceReference(&vlsurface->device, NULL); FREE(vlsurface); return VDP_STATUS_OK; @@ -188,17 +205,17 @@ vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface, if (!pipe) return VDP_STATUS_INVALID_HANDLE; + if (!destination_data || !destination_pitches) + return VDP_STATUS_INVALID_POINTER; + + pipe_mutex_lock(vlsurface->device->mutex); vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); res = vlsurface->sampler_view->texture; box = RectToPipeBox(source_rect, res); - transfer = pipe->get_transfer(pipe, res, 0, PIPE_TRANSFER_READ, &box); - if (transfer == NULL) - return VDP_STATUS_RESOURCES; - - map = pipe_transfer_map(pipe, transfer); - if (map == NULL) { - pipe_transfer_destroy(pipe, transfer); + map = pipe->transfer_map(pipe, res, 0, PIPE_TRANSFER_READ, &box, &transfer); + if (!map) { + pipe_mutex_unlock(vlsurface->device->mutex); return VDP_STATUS_RESOURCES; } @@ -206,7 +223,7 @@ vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface, box.width, box.height, map, transfer->stride, 0, 0); pipe_transfer_unmap(pipe, transfer); - pipe_transfer_destroy(pipe, transfer); + pipe_mutex_unlock(vlsurface->device->mutex); return VDP_STATUS_OK; } @@ -233,12 +250,17 @@ vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface, if (!pipe) return VDP_STATUS_INVALID_HANDLE; + if (!source_data || !source_pitches) + return VDP_STATUS_INVALID_POINTER; + + 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->texture_subdata(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; } @@ -275,8 +297,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; @@ -311,6 +331,12 @@ 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); + + if (!CheckSurfaceParams(context->screen, &res_tmpl)) + goto error_resource; + res = context->screen->resource_create(context->screen, &res_tmpl); if (!res) goto error_resource; @@ -320,9 +346,9 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, box.height = res->height0; box.depth = res->depth0; - context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, - source_data[0], source_pitch[0], - source_pitch[0] * res->height0); + context->texture_subdata(context, res, 0, PIPE_TRANSFER_WRITE, &box, + source_data[0], source_pitch[0], + source_pitch[0] * res->height0); memset(&sv_tmpl, 0, sizeof(sv_tmpl)); u_sampler_view_default_template(&sv_tmpl, res, res->format); @@ -353,8 +379,8 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, box.height = res->height0; box.depth = res->depth0; - context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table, - util_format_get_stride(colortbl_format, res->width0), 0); + context->texture_subdata(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table, + util_format_get_stride(colortbl_format, res->width0), 0); memset(&sv_tmpl, 0, sizeof(sv_tmpl)); u_sampler_view_default_template(&sv_tmpl, res, res->format); @@ -368,16 +394,18 @@ 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_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); - vl_compositor_render(cstate, compositor, vlsurface->surface, NULL); + 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; } @@ -393,7 +421,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 = FormatYCBCRToPipeChroma(source_ycbcr_format); + + 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->texture_subdata(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, 1.0f, 0.0f); + } else { + vl_compositor_set_csc_matrix(cstate, csc_matrix, 1.0f, 0.0f); + } + + 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 @@ -521,9 +633,9 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, uint32_t flags) { vlVdpOutputSurface *dst_vlsurface; - vlVdpOutputSurface *src_vlsurface; struct pipe_context *context; + struct pipe_sampler_view *src_sv; struct vl_compositor *compositor; struct vl_compositor_state *cstate; @@ -536,13 +648,21 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, if (!dst_vlsurface) return VDP_STATUS_INVALID_HANDLE; - src_vlsurface = vlGetDataHTAB(source_surface); - if (!src_vlsurface) - return VDP_STATUS_INVALID_HANDLE; + if (source_surface == VDP_INVALID_HANDLE) { + src_sv = dst_vlsurface->device->dummy_sv; - if (dst_vlsurface->device != src_vlsurface->device) - return VDP_STATUS_HANDLE_DEVICE_MISMATCH; + } else { + vlVdpOutputSurface *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; + + src_sv = src_vlsurface->sampler_view; + } + pipe_mutex_lock(dst_vlsurface->device->mutex); vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); context = dst_vlsurface->device->context; @@ -553,13 +673,19 @@ 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, + vl_compositor_set_rgba_layer(cstate, compositor, 0, src_sv, RectToPipe(source_rect, &src_rect), NULL, ColorsToPipe(colors, flags, vlcolors)); + STATIC_ASSERT(VL_COMPOSITOR_ROTATE_0 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); + STATIC_ASSERT(VL_COMPOSITOR_ROTATE_90 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_90); + STATIC_ASSERT(VL_COMPOSITOR_ROTATE_180 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_180); + STATIC_ASSERT(VL_COMPOSITOR_ROTATE_270 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_270); + vl_compositor_set_layer_rotation(cstate, 0, flags & 3); vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); - vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); + 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; } @@ -578,9 +704,9 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, uint32_t flags) { vlVdpOutputSurface *dst_vlsurface; - vlVdpBitmapSurface *src_vlsurface; struct pipe_context *context; + struct pipe_sampler_view *src_sv; struct vl_compositor *compositor; struct vl_compositor_state *cstate; @@ -593,30 +719,94 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, if (!dst_vlsurface) return VDP_STATUS_INVALID_HANDLE; - src_vlsurface = vlGetDataHTAB(source_surface); - if (!src_vlsurface) - return VDP_STATUS_INVALID_HANDLE; + if (source_surface == VDP_INVALID_HANDLE) { + src_sv = dst_vlsurface->device->dummy_sv; + + } else { + vlVdpBitmapSurface *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; + if (dst_vlsurface->device != src_vlsurface->device) + return VDP_STATUS_HANDLE_DEVICE_MISMATCH; - vlVdpResolveDelayedRendering(dst_vlsurface->device, NULL, NULL); + src_sv = src_vlsurface->sampler_view; + } 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, + vl_compositor_set_rgba_layer(cstate, compositor, 0, src_sv, RectToPipe(source_rect, &src_rect), NULL, ColorsToPipe(colors, flags, vlcolors)); + vl_compositor_set_layer_rotation(cstate, 0, flags & 3); vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); - vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL); + 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; +} + +struct pipe_resource *vlVdpOutputSurfaceGallium(VdpOutputSurface surface) +{ + vlVdpOutputSurface *vlsurface; + + vlsurface = vlGetDataHTAB(surface); + if (!vlsurface || !vlsurface->surface) + return NULL; + + pipe_mutex_lock(vlsurface->device->mutex); + vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); + vlsurface->device->context->flush(vlsurface->device->context, NULL, 0); + pipe_mutex_unlock(vlsurface->device->mutex); + + return vlsurface->surface->texture; +} + +VdpStatus vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface, + struct VdpSurfaceDMABufDesc *result) +{ + vlVdpOutputSurface *vlsurface; + struct pipe_screen *pscreen; + struct winsys_handle whandle; + + memset(result, 0, sizeof(*result)); + result->handle = -1; + + vlsurface = vlGetDataHTAB(surface); + if (!vlsurface || !vlsurface->surface) + return VDP_STATUS_INVALID_HANDLE; + + pipe_mutex_lock(vlsurface->device->mutex); + vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL); + vlsurface->device->context->flush(vlsurface->device->context, NULL, 0); + pipe_mutex_unlock(vlsurface->device->mutex); + + memset(&whandle, 0, sizeof(struct winsys_handle)); + whandle.type = DRM_API_HANDLE_TYPE_FD; + + pscreen = vlsurface->surface->texture->screen; + if (!pscreen->resource_get_handle(pscreen, vlsurface->device->context, + vlsurface->surface->texture, &whandle, + PIPE_HANDLE_USAGE_READ_WRITE)) + return VDP_STATUS_NO_IMPLEMENTATION; + + result->handle = whandle.handle; + result->width = vlsurface->surface->width; + result->height = vlsurface->surface->height; + result->offset = whandle.offset; + result->stride = whandle.stride; + result->format = PipeToFormatRGBA(vlsurface->surface->format); return VDP_STATUS_OK; }