X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fgallium%2Fstate_trackers%2Fxorg%2Fxorg_xv.c;h=a221594454e79baabf0358618fa897558d27c3a1;hp=b3315dccad8c43c23708dff85141dae53aaf6914;hb=c7f5c9a3dc6350252e73b541bb85ab3ed9e64a9c;hpb=0c75854cc1650dc870e042aa66a053e70b3d4556 diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index b3315dccad8..a221594454e 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -9,9 +9,9 @@ #include "xorg_exa_tgsi.h" #include "cso_cache/cso_context.h" +#include "util/u_sampler.h" #include "pipe/p_screen.h" -#include "pipe/p_inlines.h" /*XXX get these from pipe's texture limits */ #define IMAGE_MAX_WIDTH 2048 @@ -73,10 +73,11 @@ static XF86VideoEncodingRec DummyEncoding[1] = { } }; -#define NUM_IMAGES 2 +#define NUM_IMAGES 3 static XF86ImageRec Images[NUM_IMAGES] = { XVIMAGE_UYVY, XVIMAGE_YUY2, + XVIMAGE_YV12, }; struct xorg_xv_port_priv { @@ -90,7 +91,8 @@ struct xorg_xv_port_priv { int current_set; /* juggle two sets of seperate Y, U and V * textures */ - struct pipe_texture *yuv[2][3]; + struct pipe_resource *yuv[2][3]; + struct pipe_sampler_view *yuv_views[2][3]; }; @@ -154,25 +156,24 @@ query_best_size(ScrnInfoPtr pScrn, *p_h = drw_h; } -static INLINE struct pipe_texture * +static INLINE struct pipe_resource * create_component_texture(struct pipe_context *pipe, int width, int height) { struct pipe_screen *screen = pipe->screen; - struct pipe_texture *tex = 0; - struct pipe_texture templ; + struct pipe_resource *tex = 0; + struct pipe_resource templ; memset(&templ, 0, sizeof(templ)); templ.target = PIPE_TEXTURE_2D; templ.format = PIPE_FORMAT_L8_UNORM; templ.last_level = 0; - templ.width[0] = width; - templ.height[0] = height; - templ.depth[0] = 1; - pf_get_block(PIPE_FORMAT_L8_UNORM, &templ.block); - templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.bind = PIPE_BIND_SAMPLER_VIEW; - tex = screen->texture_create(screen, &templ); + tex = screen->resource_create(screen, &templ); return tex; } @@ -180,90 +181,173 @@ create_component_texture(struct pipe_context *pipe, static int check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height) { - struct pipe_texture **dst = priv->yuv[priv->current_set]; + struct pipe_resource **dst = priv->yuv[priv->current_set]; + struct pipe_sampler_view **dst_view = priv->yuv_views[priv->current_set]; + struct pipe_sampler_view view_templ; + struct pipe_context *pipe = priv->r->pipe; + if (!dst[0] || - dst[0]->width[0] != width || - dst[0]->height[0] != height) { - pipe_texture_reference(&dst[0], NULL); + dst[0]->width0 != width || + dst[0]->height0 != height) { + pipe_resource_reference(&dst[0], NULL); + pipe_sampler_view_reference(&dst_view[0], NULL); } if (!dst[1] || - dst[1]->width[0] != width || - dst[1]->height[0] != height) { - pipe_texture_reference(&dst[1], NULL); + dst[1]->width0 != width || + dst[1]->height0 != height) { + pipe_resource_reference(&dst[1], NULL); + pipe_sampler_view_reference(&dst_view[1], NULL); } if (!dst[2] || - dst[2]->width[0] != width || - dst[2]->height[0] != height) { - pipe_texture_reference(&dst[2], NULL); + dst[2]->width0 != width || + dst[2]->height0 != height) { + pipe_resource_reference(&dst[2], NULL); + pipe_sampler_view_reference(&dst_view[2], NULL); } - if (!dst[0]) + if (!dst[0]) { dst[0] = create_component_texture(priv->r->pipe, width, height); + if (dst[0]) { + u_sampler_view_default_template(&view_templ, + dst[0], + dst[0]->format); + dst_view[0] = pipe->create_sampler_view(pipe, dst[0], &view_templ); + } + } - if (!dst[1]) + if (!dst[1]) { dst[1] = create_component_texture(priv->r->pipe, width, height); + if (dst[1]) { + u_sampler_view_default_template(&view_templ, + dst[1], + dst[1]->format); + dst_view[1] = pipe->create_sampler_view(pipe, dst[1], &view_templ); + } + } - if (!dst[2]) + if (!dst[2]) { dst[2] = create_component_texture(priv->r->pipe, width, height); + if (dst[2]) { + u_sampler_view_default_template(&view_templ, + dst[2], + dst[2]->format); + dst_view[2] = pipe->create_sampler_view(pipe, dst[2], &view_templ); + } + } - if (!dst[0] || !dst[1] || !dst[2]) + if (!dst[0] || !dst[1] || !dst[2] || !dst_view[0] || !dst_view[1] || !dst_view[2] ) return BadAlloc; return Success; } +static int +query_image_attributes(ScrnInfoPtr pScrn, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) +{ + int size, tmp; + + if (*w > IMAGE_MAX_WIDTH) + *w = IMAGE_MAX_WIDTH; + if (*h > IMAGE_MAX_HEIGHT) + *h = IMAGE_MAX_HEIGHT; + + *w = (*w + 1) & ~1; + if (offsets) + offsets[0] = 0; + + switch (id) { + case FOURCC_YV12: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if (pitches) { + pitches[0] = size; + } + size *= *h; + if (offsets) { + offsets[1] = size; + } + tmp = ((*w >> 1) + 3) & ~3; + if (pitches) { + pitches[1] = pitches[2] = tmp; + } + tmp *= (*h >> 1); + size += tmp; + if (offsets) { + offsets[2] = size; + } + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if (pitches) + pitches[0] = size; + size *= *h; + break; + } + + return size; +} + static void copy_packed_data(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *port, int id, unsigned char *buf, - int srcPitch, int left, int top, - int w, int h) + unsigned short w, unsigned short h) { - unsigned char *src; int i, j; - struct pipe_texture **dst = port->yuv[port->current_set]; + struct pipe_resource **dst = port->yuv[port->current_set]; struct pipe_transfer *ytrans, *utrans, *vtrans; - struct pipe_screen *screen = port->r->pipe->screen; + struct pipe_context *pipe = port->r->pipe; char *ymap, *vmap, *umap; unsigned char y1, y2, u, v; int yidx, uidx, vidx; int y_array_size = w * h; - src = buf + (top * srcPitch) + (left << 1); - - ytrans = screen->get_tex_transfer(screen, dst[0], - 0, 0, 0, - PIPE_TRANSFER_WRITE, - left, top, w, h); - utrans = screen->get_tex_transfer(screen, dst[1], - 0, 0, 0, - PIPE_TRANSFER_WRITE, - left, top, w, h); - vtrans = screen->get_tex_transfer(screen, dst[2], - 0, 0, 0, - PIPE_TRANSFER_WRITE, - left, top, w, h); - - ymap = (char*)screen->transfer_map(screen, ytrans); - umap = (char*)screen->transfer_map(screen, utrans); - vmap = (char*)screen->transfer_map(screen, vtrans); + ytrans = pipe_get_transfer(pipe, dst[0], + 0, 0, 0, + PIPE_TRANSFER_WRITE, + left, top, w, h); + utrans = pipe_get_transfer(pipe, dst[1], + 0, 0, 0, + PIPE_TRANSFER_WRITE, + left, top, w, h); + vtrans = pipe_get_transfer(pipe, dst[2], + 0, 0, 0, + PIPE_TRANSFER_WRITE, + left, top, w, h); + + ymap = (char*)pipe->transfer_map(pipe, ytrans); + umap = (char*)pipe->transfer_map(pipe, utrans); + vmap = (char*)pipe->transfer_map(pipe, vtrans); yidx = uidx = vidx = 0; switch (id) { case FOURCC_YV12: { - for (i = 0; i < w; ++i) { - for (j = 0; j < h; ++j) { - /*XXX use src? */ - y1 = buf[j*w + i]; - u = buf[(j/2) * (w/2) + i/2 + y_array_size]; - v = buf[(j/2) * (w/2) + i/2 + y_array_size + y_array_size/4]; - ymap[yidx++] = y1; - umap[uidx++] = u; - vmap[vidx++] = v; + int pitches[3], offsets[3]; + unsigned char *y, *u, *v; + query_image_attributes(pScrn, FOURCC_YV12, + &w, &h, pitches, offsets); + + y = buf + offsets[0]; + v = buf + offsets[1]; + u = buf + offsets[2]; + for (i = 0; i < h; ++i) { + for (j = 0; j < w; ++j) { + int yoffset = (w*i+j); + int ii = (i|1), jj = (j|1); + int vuoffset = (w/2)*(ii/2) + (jj/2); + ymap[yidx++] = y[yoffset]; + umap[uidx++] = u[vuoffset]; + vmap[vidx++] = v[vuoffset]; } } } @@ -308,12 +392,12 @@ copy_packed_data(ScrnInfoPtr pScrn, break; } - screen->transfer_unmap(screen, ytrans); - screen->transfer_unmap(screen, utrans); - screen->transfer_unmap(screen, vtrans); - screen->tex_transfer_destroy(ytrans); - screen->tex_transfer_destroy(utrans); - screen->tex_transfer_destroy(vtrans); + pipe->transfer_unmap(pipe, ytrans); + pipe->transfer_unmap(pipe, utrans); + pipe->transfer_unmap(pipe, vtrans); + pipe->transfer_destroy(pipe, ytrans); + pipe->transfer_destroy(pipe, utrans); + pipe->transfer_destroy(pipe, vtrans); } @@ -332,8 +416,11 @@ draw_yuv(struct xorg_xv_port_priv *port, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h) { - struct pipe_texture **textures = port->yuv[port->current_set]; + struct pipe_resource **textures = port->yuv[port->current_set]; + /*debug_printf(" draw_yuv([%d, %d, %d ,%d], [%d, %d, %d, %d])\n", + src_x, src_y, src_w, src_h, + dst_x, dst_y, dst_w, dst_h);*/ renderer_draw_yuv(port->r, src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h, @@ -346,14 +433,14 @@ bind_blend_state(struct xorg_xv_port_priv *port) struct pipe_blend_state blend; memset(&blend, 0, sizeof(struct pipe_blend_state)); - blend.blend_enable = 1; - blend.colormask |= PIPE_MASK_RGBA; + blend.rt[0].blend_enable = 0; + blend.rt[0].colormask = PIPE_MASK_RGBA; /* porter&duff src */ - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; cso_set_blend(port->r->cso, &blend); } @@ -374,12 +461,12 @@ bind_shaders(struct xorg_xv_port_priv *port) } static INLINE void -conditional_flush(struct pipe_context *pipe, struct pipe_texture **tex, +conditional_flush(struct pipe_context *pipe, struct pipe_resource **tex, int num) { int i; for (i = 0; i < num; ++i) { - if (tex[i] && pipe->is_texture_referenced(pipe, tex[i], 0, 0) & + if (tex[i] && pipe->is_resource_referenced(pipe, tex[i], 0, 0) & PIPE_REFERENCED_FOR_WRITE) { pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); return; @@ -392,7 +479,8 @@ bind_samplers(struct xorg_xv_port_priv *port) { struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; struct pipe_sampler_state sampler; - struct pipe_texture **dst = port->yuv[port->current_set]; + struct pipe_resource **dst = port->yuv[port->current_set]; + struct pipe_sampler_view **dst_views = port->yuv_views[port->current_set]; memset(&sampler, 0, sizeof(struct pipe_sampler_state)); @@ -412,8 +500,7 @@ bind_samplers(struct xorg_xv_port_priv *port) cso_set_samplers(port->r->cso, 3, (const struct pipe_sampler_state **)samplers); - cso_set_sampler_textures(port->r->cso, 3, - dst); + cso_set_fragment_sampler_views(port->r->cso, 3, dst_views); } static int @@ -429,8 +516,14 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, int dxo, dyo; Bool hdtv; int x, y, w, h; - struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap); - struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst); + struct exa_pixmap_priv *dst; + struct pipe_surface *dst_surf = NULL; + + exaMoveInPixmap(pPixmap); + dst = exaGetPixmapDriverPrivate(pPixmap); + + /*debug_printf("display_video([%d, %d, %d, %d], [%d, %d, %d, %d])\n", + src_x, src_y, src_w, src_h, dstX, dstY, dst_w, dst_h);*/ if (dst && !dst->tex) { xorg_exa_set_shared_usage(pPixmap); @@ -440,6 +533,7 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, if (!dst || !dst->tex) XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex"); + dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst); hdtv = ((src_w >= RES_720P_X) && (src_h >= RES_720P_Y)); REGION_TRANSLATE(pScrn->pScreen, dstRegion, -pPixmap->screen_x, @@ -459,7 +553,6 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, bind_samplers(pPriv); setup_fs_video_constants(pPriv->r, hdtv); - exaMoveInPixmap(pPixmap); DamageDamageRegion(&pPixmap->drawable, dstRegion); while (nbox--) { @@ -482,8 +575,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id, offset_w = dst_w - w; offset_h = dst_h - h; - draw_yuv(pPriv, src_x + offset_x*diff_x, src_y + offset_y*diff_y, - src_w - offset_w*diff_x, src_h - offset_h*diff_x, + draw_yuv(pPriv, + src_x + offset_x*diff_x, src_y + offset_y*diff_y, + src_w - offset_w*diff_x, src_h - offset_h*diff_y, x, y, w, h); pbox++; @@ -510,7 +604,6 @@ put_image(ScrnInfoPtr pScrn, ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; PixmapPtr pPixmap; INT32 x1, x2, y1, y2; - int srcPitch; BoxRec dstBox; int ret; @@ -529,20 +622,12 @@ put_image(ScrnInfoPtr pScrn, width, height)) return Success; - switch (id) { - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - srcPitch = width << 1; - break; - } - ret = check_yuv_textures(pPriv, width, height); if (ret) return ret; - copy_packed_data(pScrn, pPriv, id, buf, srcPitch, + copy_packed_data(pScrn, pPriv, id, buf, src_x, src_y, width, height); if (pDraw->type == DRAWABLE_WINDOW) { @@ -560,37 +645,6 @@ put_image(ScrnInfoPtr pScrn, return Success; } -static int -query_image_attributes(ScrnInfoPtr pScrn, - int id, - unsigned short *w, unsigned short *h, - int *pitches, int *offsets) -{ - int size; - - if (*w > IMAGE_MAX_WIDTH) - *w = IMAGE_MAX_WIDTH; - if (*h > IMAGE_MAX_HEIGHT) - *h = IMAGE_MAX_HEIGHT; - - *w = (*w + 1) & ~1; - if (offsets) - offsets[0] = 0; - - switch (id) { - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - size = *w << 1; - if (pitches) - pitches[0] = size; - size *= *h; - break; - } - - return size; -} - static struct xorg_xv_port_priv * port_priv_create(struct xorg_renderer *r) {