From: Younes Manton Date: Sun, 6 Dec 2009 21:44:11 +0000 (-0500) Subject: Merge branch 'master' into pipe-video X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=447dddb93d8dc2551ef7a9c43004237c7a8dd2dd;p=mesa.git Merge branch 'master' into pipe-video Conflicts: src/gallium/auxiliary/vl/vl_compositor.c src/gallium/auxiliary/vl/vl_compositor.h src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c src/gallium/auxiliary/vl/vl_shader_build.c --- 447dddb93d8dc2551ef7a9c43004237c7a8dd2dd diff --cc src/gallium/auxiliary/vl/vl_compositor.c index 529c0b6e364,fc2a1c59a6b..44b3714dcc3 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@@ -291,141 -426,9 +291,141 @@@ void vl_compositor_cleanup(struct vl_co cleanup_pipe_state(compositor); } +void vl_compositor_set_background(struct vl_compositor *compositor, + struct pipe_texture *bg, struct pipe_video_rect *bg_src_rect) +{ + assert(compositor); + assert((bg && bg_src_rect) || (!bg && !bg_src_rect)); + + if (compositor->bg != bg || + !u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect)) { + pipe_texture_reference(&compositor->bg, bg); + /*if (!u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect))*/ + compositor->bg_src_rect = *bg_src_rect; + compositor->dirty_bg = true; + } +} + +void vl_compositor_set_layers(struct vl_compositor *compositor, + struct pipe_texture *layers[], + struct pipe_video_rect *src_rects[], + struct pipe_video_rect *dst_rects[], + unsigned num_layers) +{ + unsigned i; + + assert(compositor); + assert(num_layers <= VL_COMPOSITOR_MAX_LAYERS); + + for (i = 0; i < num_layers; ++i) + { + assert((layers[i] && src_rects[i] && dst_rects[i]) || + (!layers[i] && !src_rects[i] && !dst_rects[i])); + + if (compositor->layers[i] != layers[i] || + !u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]) || + !u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i])) + { + pipe_texture_reference(&compositor->layers[i], layers[i]); + /*if (!u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]))*/ + compositor->layer_src_rects[i] = *src_rects[i]; + /*if (!u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i]))*/ + compositor->layer_dst_rects[i] = *dst_rects[i]; + compositor->dirty_layers |= 1 << i; + } + } + + for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i) + pipe_texture_reference(&compositor->layers[i], NULL); +} + +static void gen_rect_verts(unsigned pos, + struct pipe_video_rect *src_rect, + struct vertex2f *src_inv_size, + struct pipe_video_rect *dst_rect, + struct vertex2f *dst_inv_size, + struct vertex4f *vb) +{ + assert(pos < VL_COMPOSITOR_MAX_LAYERS + 2); + assert(src_rect); + assert(src_inv_size); + assert((dst_rect && dst_inv_size) || (!dst_rect && !dst_inv_size)); + assert(vb); + + vb[pos * 6 + 0].x = dst_rect->x * dst_inv_size->x; + vb[pos * 6 + 0].y = dst_rect->y * dst_inv_size->y; + vb[pos * 6 + 0].z = src_rect->x * src_inv_size->x; + vb[pos * 6 + 0].w = src_rect->y * src_inv_size->y; + + vb[pos * 6 + 1].x = dst_rect->x * dst_inv_size->x; + vb[pos * 6 + 1].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y; + vb[pos * 6 + 1].z = src_rect->x * src_inv_size->x; + vb[pos * 6 + 1].w = (src_rect->y + src_rect->h) * src_inv_size->y; + + vb[pos * 6 + 2].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x; + vb[pos * 6 + 2].y = dst_rect->y * dst_inv_size->y; + vb[pos * 6 + 2].z = (src_rect->x + src_rect->w) * src_inv_size->x; + vb[pos * 6 + 2].w = src_rect->y * src_inv_size->y; + + vb[pos * 6 + 3].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x; + vb[pos * 6 + 3].y = dst_rect->y * dst_inv_size->y; + vb[pos * 6 + 3].z = (src_rect->x + src_rect->w) * src_inv_size->x; + vb[pos * 6 + 3].w = src_rect->y * src_inv_size->y; + + vb[pos * 6 + 4].x = dst_rect->x * dst_inv_size->x; + vb[pos * 6 + 4].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y; + vb[pos * 6 + 4].z = src_rect->x * src_inv_size->x; + vb[pos * 6 + 4].w = (src_rect->y + src_rect->h) * src_inv_size->y; + + vb[pos * 6 + 5].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x; + vb[pos * 6 + 5].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y; + vb[pos * 6 + 5].z = (src_rect->x + src_rect->w) * src_inv_size->x; + vb[pos * 6 + 5].w = (src_rect->y + src_rect->h) * src_inv_size->y; +} + +static unsigned gen_verts(struct vl_compositor *c, + struct pipe_video_rect *src_rect, + struct vertex2f *src_inv_size, + struct pipe_video_rect *dst_rect) +{ + void *vb; + unsigned num_rects = 0; + unsigned i; + + assert(c); + assert(src_rect); + assert(src_inv_size); + assert(dst_rect); + + vb = pipe_buffer_map(c->pipe->screen, c->vertex_buf.buffer, + PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD); + + if (c->dirty_bg) { - struct vertex2f bg_inv_size = {1.0f / c->bg->width[0], 1.0f / c->bg->height[0]}; ++ struct vertex2f bg_inv_size = {1.0f / c->bg->width0, 1.0f / c->bg->height0}; + gen_rect_verts(num_rects++, &c->bg_src_rect, &bg_inv_size, NULL, NULL, vb); + c->dirty_bg = false; + } + + gen_rect_verts(num_rects++, src_rect, src_inv_size, dst_rect, &c->fb_inv_size, vb); + + for (i = 0; c->dirty_layers > 0; i++) + { + assert(i < VL_COMPOSITOR_MAX_LAYERS); + + if (c->dirty_layers & (1 << i)) { - struct vertex2f layer_inv_size = {1.0f / c->layers[i]->width[0], 1.0f / c->layers[i]->height[0]}; ++ struct vertex2f layer_inv_size = {1.0f / c->layers[i]->width0, 1.0f / c->layers[i]->height0}; + gen_rect_verts(num_rects++, &c->layer_src_rects[i], &layer_inv_size, + &c->layer_dst_rects[i], &c->fb_inv_size, vb); + c->dirty_layers &= ~(1 << i); + } + } + + pipe_buffer_unmap(c->pipe->screen, c->vertex_buf.buffer); + + return num_rects; +} + void vl_compositor_render(struct vl_compositor *compositor, - /*struct pipe_texture *backround, - struct pipe_video_rect *backround_area,*/ struct pipe_texture *src_surface, enum pipe_mpeg12_picture_type picture_type, /*unsigned num_past_surfaces, @@@ -446,15 -453,8 +446,15 @@@ assert(dst_area); assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME); - if (compositor->fb_state.width != dst_surface->width[0]) { - compositor->fb_inv_size.x = 1.0f / dst_surface->width[0]; - compositor->fb_state.width = dst_surface->width[0]; - compositor->fb_state.width = dst_surface->width0; - compositor->fb_state.height = dst_surface->height0; ++ if (compositor->fb_state.width != dst_surface->width0) { ++ compositor->fb_inv_size.x = 1.0f / dst_surface->width0; ++ compositor->fb_state.width = dst_surface->width0; + } - if (compositor->fb_state.height != dst_surface->height[0]) { - compositor->fb_inv_size.y = 1.0f / dst_surface->height[0]; - compositor->fb_state.height = dst_surface->height[0]; ++ if (compositor->fb_state.height != dst_surface->height0) { ++ compositor->fb_inv_size.y = 1.0f / dst_surface->height0; ++ compositor->fb_state.height = dst_surface->height0; + } + compositor->fb_state.cbufs[0] = compositor->pipe->screen->get_tex_surface ( compositor->pipe->screen, @@@ -471,25 -471,49 +471,25 @@@ compositor->viewport.translate[2] = 0; compositor->viewport.translate[3] = 0; - compositor->scissor.maxx = compositor->fb_state.width; - compositor->scissor.maxy = compositor->fb_state.height; - compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state); compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport); - compositor->pipe->bind_sampler_states(compositor->pipe, 1, &compositor->sampler); - compositor->pipe->set_sampler_textures(compositor->pipe, 1, &src_surface); - compositor->pipe->set_scissor_state(compositor->pipe, &compositor->scissor); + compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler); + compositor->pipe->set_fragment_sampler_textures(compositor->pipe, 1, &src_surface); compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader); compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader); - compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs); + compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf); compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems); - compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, &compositor->vs_const_buf); compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, &compositor->fs_const_buf); - vs_consts = pipe_buffer_map - ( - compositor->pipe->screen, - compositor->vs_const_buf.buffer, - PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD - ); + { - struct vertex2f src_inv_size = {1.0f / src_surface->width[0], 1.0f / src_surface->height[0]}; ++ struct vertex2f src_inv_size = {1.0f / src_surface->width0, 1.0f / src_surface->height0}; + num_rects = gen_verts(compositor, src_area, &src_inv_size, dst_area); + } + + assert(!compositor->dirty_bg && !compositor->dirty_layers); + assert(num_rects > 0); - vs_consts->dst_scale.x = dst_area->w / (float)compositor->fb_state.cbufs[0]->width; - vs_consts->dst_scale.y = dst_area->h / (float)compositor->fb_state.cbufs[0]->height; - vs_consts->dst_scale.z = 1; - vs_consts->dst_scale.w = 1; - vs_consts->dst_trans.x = dst_area->x / (float)compositor->fb_state.cbufs[0]->width; - vs_consts->dst_trans.y = dst_area->y / (float)compositor->fb_state.cbufs[0]->height; - vs_consts->dst_trans.z = 0; - vs_consts->dst_trans.w = 0; - - vs_consts->src_scale.x = src_area->w / (float)src_surface->width0; - vs_consts->src_scale.y = src_area->h / (float)src_surface->height0; - vs_consts->src_scale.z = 1; - vs_consts->src_scale.w = 1; - vs_consts->src_trans.x = src_area->x / (float)src_surface->width0; - vs_consts->src_trans.y = src_area->y / (float)src_surface->height0; - vs_consts->src_trans.z = 0; - vs_consts->src_trans.w = 0; - - pipe_buffer_unmap(compositor->pipe->screen, compositor->vs_const_buf.buffer); - - compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + compositor->pipe->draw_arrays(compositor->pipe, PIPE_PRIM_TRIANGLES, 0, num_rects * 6); compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence); pipe_surface_reference(&compositor->fb_state.cbufs[0], NULL); diff --cc src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h index 609c83b63fe,64184337a06..9602a0fad9d --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h @@@ -63,7 -62,9 +63,8 @@@ struct vl_mpeg12_mc_rendere unsigned macroblocks_per_batch; struct pipe_viewport_state viewport; + struct pipe_scissor_state scissor; struct pipe_constant_buffer vs_const_buf; - struct pipe_constant_buffer fs_const_buf; struct pipe_framebuffer_state fb_state; struct pipe_vertex_element vertex_elems[8]; diff --cc src/gallium/drivers/nv40/nv40_miptree.c index 3e742007744,89ddf373e9e..0c14024dab2 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@@ -204,58 -200,6 +200,57 @@@ nv40_miptree_surface_del(struct pipe_su FREE(ps); } +static struct pipe_video_surface* +nv40_video_surface_new(struct pipe_screen *screen, + enum pipe_video_chroma_format chroma_format, + unsigned width, unsigned height) +{ + struct nv40_video_surface *nv40_vsfc; + struct pipe_texture template; + + assert(screen); + assert(width && height); + + nv40_vsfc = CALLOC_STRUCT(nv40_video_surface); + if (!nv40_vsfc) + return NULL; + + pipe_reference_init(&nv40_vsfc->base.reference, 1); + nv40_vsfc->base.screen = screen; + nv40_vsfc->base.chroma_format = chroma_format; + /*nv40_vsfc->base.surface_format = PIPE_VIDEO_SURFACE_FORMAT_VUYA;*/ + nv40_vsfc->base.width = width; + nv40_vsfc->base.height = height; + + memset(&template, 0, sizeof(struct pipe_texture)); + template.target = PIPE_TEXTURE_2D; + template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.last_level = 0; + /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */ - template.width[0] = util_next_power_of_two(width); - template.height[0] = util_next_power_of_two(height); - template.depth[0] = 1; - pf_get_block(template.format, &template.block); ++ template.width0 = util_next_power_of_two(width); ++ template.height0 = util_next_power_of_two(height); ++ template.depth0 = 1; + template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; + + nv40_vsfc->tex = screen->texture_create(screen, &template); + if (!nv40_vsfc->tex) { + FREE(nv40_vsfc); + return NULL; + } + + return &nv40_vsfc->base; +} + + +static void +nv40_video_surface_del(struct pipe_video_surface *vsfc) +{ + struct nv40_video_surface *nv40_vsfc = nv40_video_surface(vsfc); + + pipe_texture_reference(&nv40_vsfc->tex, NULL); + FREE(nv40_vsfc); +} + void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen) { diff --cc src/gallium/state_trackers/xorg/xvmc/subpicture.c index 0e299466a5c,69898d5fcd3..7f10f366d21 --- a/src/gallium/state_trackers/xorg/xvmc/subpicture.c +++ b/src/gallium/state_trackers/xorg/xvmc/subpicture.c @@@ -52,48 -37,13 +52,47 @@@ Status XvMCCreateSubpicture(Display *dp if (!context) return XvMCBadContext; - assert(subpicture); + context_priv = context->privData; + vpipe = context_priv->vctx->vpipe; + + if (!subpicture) + return XvMCBadSubpicture; - /*if (width > || height > ) - return BadValue;*/ + if (width > 2048 || height > 2048) + return BadValue; + + if (xvimage_id != FOURCC_RGB) + return BadMatch; - /*if (xvimage_id != ) - return BadMatch;*/ + subpicture_priv = CALLOC(1, sizeof(XvMCSubPicturePrivate)); + if (!subpicture_priv) + return BadAlloc; + + memset(&template, 0, sizeof(struct pipe_texture)); + template.target = PIPE_TEXTURE_2D; + template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.last_level = 0; + if (vpipe->screen->get_param(vpipe->screen, PIPE_CAP_NPOT_TEXTURES)) { - template.width[0] = width; - template.height[0] = height; ++ template.width0 = width; ++ template.height0 = height; + } + else { - template.width[0] = util_next_power_of_two(width); - template.height[0] = util_next_power_of_two(height); ++ template.width0 = util_next_power_of_two(width); ++ template.height0 = util_next_power_of_two(height); + } - template.depth[0] = 1; - pf_get_block(template.format, &template.block); ++ template.depth0 = 1; + template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET; + + subpicture_priv->context = context; + tex = vpipe->screen->texture_create(vpipe->screen, &template); + subpicture_priv->sfc = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ_WRITE); + pipe_texture_reference(&tex, NULL); + if (!subpicture_priv->sfc) + { + FREE(subpicture_priv); + return BadAlloc; + } subpicture->subpicture_id = XAllocID(dpy); subpicture->context_id = context->context_id; diff --cc src/gallium/state_trackers/xorg/xvmc/surface.c index 24c413bc04d,0e39a390c69..f640b1464f4 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@@ -105,12 -100,12 +105,11 @@@ CreateOrResizeBackBuffer(struct vl_cont memset(&template, 0, sizeof(struct pipe_texture)); template.target = PIPE_TEXTURE_2D; - /* XXX: Needs to match the drawable's format? */ - template.format = PIPE_FORMAT_X8R8G8B8_UNORM; + template.format = vctx->vscreen->format; template.last_level = 0; - template.width[0] = width; - template.height[0] = height; - template.depth[0] = 1; - pf_get_block(template.format, &template.block); + template.width0 = width; + template.height0 = height; + template.depth0 = 1; template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; tex = vpipe->screen->texture_create(vpipe->screen, &template);