X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fstate_trackers%2Fxa%2Fxa_tracker.c;h=0909044fb91ee0be5664d6f282252213bd252fd2;hb=7fce3ca3759e2e156e2e3bf1bcc4ee378dc7fa2d;hp=50922d38378671af282852b89572667eb24e2065;hpb=636d01bd61cac83e13c3c64874e7e34e828ca93a;p=mesa.git diff --git a/src/gallium/state_trackers/xa/xa_tracker.c b/src/gallium/state_trackers/xa/xa_tracker.c index 50922d38378..0909044fb91 100644 --- a/src/gallium/state_trackers/xa/xa_tracker.c +++ b/src/gallium/state_trackers/xa/xa_tracker.c @@ -26,10 +26,12 @@ * Thomas Hellstrom */ +#include #include "xa_tracker.h" #include "xa_priv.h" #include "pipe/p_state.h" #include "pipe/p_format.h" +#include "pipe-loader/pipe_loader.h" #include "state_tracker/drm_driver.h" #include "util/u_inlines.h" @@ -80,13 +82,22 @@ static const unsigned int stype_bind[XA_LAST_SURFACE_TYPE] = { 0, }; static struct xa_format_descriptor -xa_get_pipe_format(enum xa_formats xa_format) +xa_get_pipe_format(struct xa_tracker *xa, enum xa_formats xa_format) { struct xa_format_descriptor fdesc; fdesc.xa_format = xa_format; switch (xa_format) { + case xa_format_a8: + if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM, + PIPE_TEXTURE_2D, 0, 0, + stype_bind[xa_type_a] | + PIPE_BIND_RENDER_TARGET)) + fdesc.format = PIPE_FORMAT_R8_UNORM; + else + fdesc.format = PIPE_FORMAT_L8_UNORM; + break; case xa_format_a8r8g8b8: fdesc.format = PIPE_FORMAT_B8G8R8A8_UNORM; break; @@ -99,9 +110,21 @@ xa_get_pipe_format(enum xa_formats xa_format) case xa_format_x1r5g5b5: fdesc.format = PIPE_FORMAT_B5G5R5A1_UNORM; break; - case xa_format_a8: - fdesc.format = PIPE_FORMAT_L8_UNORM; - break; + case xa_format_a4r4g4b4: + fdesc.format = PIPE_FORMAT_B4G4R4A4_UNORM; + break; + case xa_format_a2b10g10r10: + fdesc.format = PIPE_FORMAT_R10G10B10A2_UNORM; + break; + case xa_format_x2b10g10r10: + fdesc.format = PIPE_FORMAT_R10G10B10X2_UNORM; + break; + case xa_format_b8g8r8a8: + fdesc.format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case xa_format_b8g8r8x8: + fdesc.format = PIPE_FORMAT_X8R8G8B8_UNORM; + break; case xa_format_z24: fdesc.format = PIPE_FORMAT_Z24X8_UNORM; break; @@ -118,13 +141,18 @@ xa_get_pipe_format(enum xa_formats xa_format) fdesc.format = PIPE_FORMAT_X8Z24_UNORM; break; case xa_format_s8z24: - fdesc.format = PIPE_FORMAT_Z24_UNORM_S8_USCALED; + fdesc.format = PIPE_FORMAT_Z24_UNORM_S8_UINT; break; case xa_format_z24s8: - fdesc.format = PIPE_FORMAT_S8_USCALED_Z24_UNORM; + fdesc.format = PIPE_FORMAT_S8_UINT_Z24_UNORM; break; case xa_format_yuv8: - fdesc.format = PIPE_FORMAT_L8_UNORM; + if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM, + PIPE_TEXTURE_2D, 0, 0, + stype_bind[xa_type_yuv_component])) + fdesc.format = PIPE_FORMAT_R8_UNORM; + else + fdesc.format = PIPE_FORMAT_L8_UNORM; break; default: fdesc.xa_format = xa_format_unknown; @@ -133,7 +161,7 @@ xa_get_pipe_format(enum xa_formats xa_format) return fdesc; } -struct xa_tracker * +XA_EXPORT struct xa_tracker * xa_tracker_create(int drm_fd) { struct xa_tracker *xa = calloc(1, sizeof(struct xa_tracker)); @@ -143,7 +171,9 @@ xa_tracker_create(int drm_fd) if (!xa) return NULL; - xa->screen = driver_descriptor.create_screen(drm_fd); + if (pipe_loader_drm_probe_fd(&xa->dev, drm_fd)) + xa->screen = pipe_loader_create_screen(xa->dev); + if (!xa->screen) goto out_no_screen; @@ -172,10 +202,11 @@ xa_tracker_create(int drm_fd) for (i = 0; i < num_preferred[stype]; ++i) { xa_format = preferred[stype][i]; - struct xa_format_descriptor fdesc = xa_get_pipe_format(xa_format); + struct xa_format_descriptor fdesc = + xa_get_pipe_format(xa, xa_format); if (xa->screen->is_format_supported(xa->screen, fdesc.format, - PIPE_TEXTURE_2D, 0, bind)) { + PIPE_TEXTURE_2D, 0, 0, bind)) { if (xa->format_map[stype][0] == 0) xa->format_map[stype][0] = num_formats; xa->format_map[stype][1] = num_formats; @@ -190,16 +221,21 @@ xa_tracker_create(int drm_fd) out_no_pipe: xa->screen->destroy(xa->screen); out_no_screen: + if (xa->dev) + pipe_loader_release(&xa->dev, 1); + free(xa); return NULL; } -void +XA_EXPORT void xa_tracker_destroy(struct xa_tracker *xa) { free(xa->supported_formats); xa_context_destroy(xa->default_ctx); xa->screen->destroy(xa->screen); + pipe_loader_release(&xa->dev, 1); + /* CHECK: The XA API user preserves ownership of the original fd */ free(xa); } @@ -219,6 +255,12 @@ xa_flags_compat(unsigned int old_flags, unsigned int new_flags) if (flag_diff & XA_FLAG_RENDER_TARGET) return ((new_flags & XA_FLAG_RENDER_TARGET) == 0); + /* + * Don't recreate if we're dropping the scanout flag. + */ + if (flag_diff & XA_FLAG_SCANOUT) + return ((new_flags & XA_FLAG_SCANOUT) == 0); + /* * Always recreate for unknown / unimplemented flags. */ @@ -234,7 +276,7 @@ xa_get_format_stype_depth(struct xa_tracker *xa, int found = 0; for (i = xa->format_map[stype][0]; i <= xa->format_map[stype][1]; ++i) { - fdesc = xa_get_pipe_format(xa->supported_formats[i]); + fdesc = xa_get_pipe_format(xa, xa->supported_formats[i]); if (fdesc.xa_format != xa_format_unknown && xa_format_depth(fdesc.xa_format) == depth) { found = 1; @@ -248,11 +290,11 @@ xa_get_format_stype_depth(struct xa_tracker *xa, return fdesc; } -int +XA_EXPORT int xa_format_check_supported(struct xa_tracker *xa, enum xa_formats xa_format, unsigned int flags) { - struct xa_format_descriptor fdesc = xa_get_pipe_format(xa_format); + struct xa_format_descriptor fdesc = xa_get_pipe_format(xa, xa_format); unsigned int bind; if (fdesc.xa_format == xa_format_unknown) @@ -263,21 +305,38 @@ xa_format_check_supported(struct xa_tracker *xa, bind |= PIPE_BIND_SHARED; if (flags & XA_FLAG_RENDER_TARGET) bind |= PIPE_BIND_RENDER_TARGET; + if (flags & XA_FLAG_SCANOUT) + bind |= PIPE_BIND_SCANOUT; if (!xa->screen->is_format_supported(xa->screen, fdesc.format, - PIPE_TEXTURE_2D, 0, bind)) + PIPE_TEXTURE_2D, 0, 0, bind)) return -XA_ERR_INVAL; return XA_ERR_NONE; } -struct xa_surface * -xa_surface_create(struct xa_tracker *xa, +static unsigned +handle_type(enum xa_handle_type type) +{ + switch (type) { + case xa_handle_type_kms: + return WINSYS_HANDLE_TYPE_KMS; + case xa_handle_type_fd: + return WINSYS_HANDLE_TYPE_FD; + case xa_handle_type_shared: + default: + return WINSYS_HANDLE_TYPE_SHARED; + } +} + +static struct xa_surface * +surface_create(struct xa_tracker *xa, int width, int height, int depth, enum xa_surface_type stype, - enum xa_formats xa_format, unsigned int flags) + enum xa_formats xa_format, unsigned int flags, + struct winsys_handle *whandle) { struct pipe_resource *template; struct xa_surface *srf; @@ -286,7 +345,7 @@ xa_surface_create(struct xa_tracker *xa, if (xa_format == xa_format_unknown) fdesc = xa_get_format_stype_depth(xa, stype, depth); else - fdesc = xa_get_pipe_format(xa_format); + fdesc = xa_get_pipe_format(xa, xa_format); if (fdesc.xa_format == xa_format_unknown) return NULL; @@ -309,12 +368,18 @@ xa_surface_create(struct xa_tracker *xa, template->bind |= PIPE_BIND_SHARED; if (flags & XA_FLAG_RENDER_TARGET) template->bind |= PIPE_BIND_RENDER_TARGET; + if (flags & XA_FLAG_SCANOUT) + template->bind |= PIPE_BIND_SCANOUT; - srf->tex = xa->screen->resource_create(xa->screen, template); + if (whandle) + srf->tex = xa->screen->resource_from_handle(xa->screen, template, whandle, + PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); + else + srf->tex = xa->screen->resource_create(xa->screen, template); if (!srf->tex) goto out_no_tex; - srf->srf = NULL; + srf->refcount = 1; srf->xa = xa; srf->flags = flags; srf->fdesc = fdesc; @@ -325,7 +390,52 @@ xa_surface_create(struct xa_tracker *xa, return NULL; } -int + +XA_EXPORT struct xa_surface * +xa_surface_create(struct xa_tracker *xa, + int width, + int height, + int depth, + enum xa_surface_type stype, + enum xa_formats xa_format, unsigned int flags) +{ + return surface_create(xa, width, height, depth, stype, xa_format, flags, NULL); +} + + +XA_EXPORT struct xa_surface * +xa_surface_from_handle(struct xa_tracker *xa, + int width, + int height, + int depth, + enum xa_surface_type stype, + enum xa_formats xa_format, unsigned int flags, + uint32_t handle, uint32_t stride) +{ + return xa_surface_from_handle2(xa, width, height, depth, stype, xa_format, + WINSYS_HANDLE_TYPE_SHARED, flags, handle, + stride); +} + +XA_EXPORT struct xa_surface * +xa_surface_from_handle2(struct xa_tracker *xa, + int width, + int height, + int depth, + enum xa_surface_type stype, + enum xa_formats xa_format, unsigned int flags, + enum xa_handle_type type, + uint32_t handle, uint32_t stride) +{ + struct winsys_handle whandle; + memset(&whandle, 0, sizeof(whandle)); + whandle.type = handle_type(type); + whandle.handle = handle; + whandle.stride = stride; + return surface_create(xa, width, height, depth, stype, xa_format, flags, &whandle); +} + +XA_EXPORT int xa_surface_redefine(struct xa_surface *srf, int width, int height, @@ -341,12 +451,14 @@ xa_surface_redefine(struct xa_surface *srf, struct xa_tracker *xa = srf->xa; int save_width; int save_height; + unsigned int save_format; struct xa_format_descriptor fdesc; + if (xa_format == xa_format_unknown) fdesc = xa_get_format_stype_depth(xa, stype, depth); else - fdesc = xa_get_pipe_format(xa_format); + fdesc = xa_get_pipe_format(xa, xa_format); if (width == template->width0 && height == template->height0 && template->format == fdesc.format && @@ -358,6 +470,8 @@ xa_surface_redefine(struct xa_surface *srf, template->bind |= PIPE_BIND_SHARED; if (new_flags & XA_FLAG_RENDER_TARGET) template->bind |= PIPE_BIND_RENDER_TARGET; + if (new_flags & XA_FLAG_SCANOUT) + template->bind |= PIPE_BIND_SCANOUT; if (copy_contents) { if (!xa_format_type_is_color(fdesc.xa_format) || @@ -365,7 +479,7 @@ xa_surface_redefine(struct xa_surface *srf, return -XA_ERR_INVAL; if (!xa->screen->is_format_supported(xa->screen, fdesc.format, - PIPE_TEXTURE_2D, 0, + PIPE_TEXTURE_2D, 0, 0, template->bind | PIPE_BIND_RENDER_TARGET)) return -XA_ERR_INVAL; @@ -373,19 +487,20 @@ xa_surface_redefine(struct xa_surface *srf, save_width = template->width0; save_height = template->height0; + save_format = template->format; template->width0 = width; template->height0 = height; + template->format = fdesc.format; texture = xa->screen->resource_create(xa->screen, template); if (!texture) { template->width0 = save_width; template->height0 = save_height; + template->format = save_format; return -XA_ERR_NORES; } - pipe_surface_reference(&srf->srf, NULL); - if (copy_contents) { struct pipe_context *pipe = xa->default_ctx->pipe; @@ -393,7 +508,7 @@ xa_surface_redefine(struct xa_surface *srf, xa_min(save_height, template->height0), &src_box); pipe->resource_copy_region(pipe, texture, 0, 0, 0, 0, srf->tex, 0, &src_box); - pipe->flush(pipe, &xa->default_ctx->last_fence); + xa_context_flush(xa->default_ctx); } pipe_resource_reference(&srf->tex, texture); @@ -404,15 +519,27 @@ xa_surface_redefine(struct xa_surface *srf, return XA_ERR_NONE; } -void -xa_surface_destroy(struct xa_surface *srf) +XA_EXPORT struct xa_surface* +xa_surface_ref(struct xa_surface *srf) +{ + if (srf == NULL) { + return NULL; + } + srf->refcount++; + return srf; +} + +XA_EXPORT void +xa_surface_unref(struct xa_surface *srf) { - pipe_surface_reference(&srf->srf, NULL); + if (srf == NULL || --srf->refcount) { + return; + } pipe_resource_reference(&srf->tex, NULL); free(srf); } -extern void +XA_EXPORT void xa_tracker_version(int *major, int *minor, int *patch) { *major = XA_TRACKER_VERSION_MAJOR; @@ -420,8 +547,9 @@ xa_tracker_version(int *major, int *minor, int *patch) *patch = XA_TRACKER_VERSION_PATCH; } -extern int +XA_EXPORT int xa_surface_handle(struct xa_surface *srf, + enum xa_handle_type type, uint32_t * handle, unsigned int *stride) { struct winsys_handle whandle; @@ -430,8 +558,10 @@ xa_surface_handle(struct xa_surface *srf, boolean res; memset(&whandle, 0, sizeof(whandle)); - whandle.type = DRM_API_HANDLE_TYPE_SHARED; - res = screen->resource_get_handle(screen, srf->tex, &whandle); + whandle.type = handle_type(type); + res = screen->resource_get_handle(screen, srf->xa->default_ctx->pipe, + srf->tex, &whandle, + PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); if (!res) return -XA_ERR_INVAL; @@ -441,7 +571,7 @@ xa_surface_handle(struct xa_surface *srf, return XA_ERR_NONE; } -enum xa_formats +XA_EXPORT enum xa_formats xa_surface_format(const struct xa_surface *srf) { return srf->fdesc.xa_format;