diff options
Diffstat (limited to 'src/gallium')
19 files changed, 487 insertions, 206 deletions
diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index d92da3d..5325f97 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -252,7 +252,6 @@ C_SOURCES := \ util/u_helpers.h \ util/u_index_modify.c \ util/u_index_modify.h \ - util/u_init.h \ util/u_inlines.h \ util/u_keymap.c \ util/u_keymap.h \ diff --git a/src/gallium/auxiliary/util/u_init.h b/src/gallium/auxiliary/util/u_init.h deleted file mode 100644 index 7bc356a..0000000 --- a/src/gallium/auxiliary/util/u_init.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2010 Luca Barbieri - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * 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 NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. - * - **************************************************************************/ - -#ifndef U_INIT_H -#define U_INIT_H - -/* Use UTIL_INIT(f) to have f called at program initialization. - Note that it is only guaranteed to be called if any symbol in the - .c file it is in sis referenced by the program. - - UTIL_INIT functions are called in arbitrary order. -*/ - -#ifdef __cplusplus -/* use a C++ global constructor */ -#define UTIL_INIT(f) struct f##__gctor_t {f##__gctor_t() {x();}} f##__gctor; -#elif defined(_MSC_VER) -/* add a pointer to the section where MSVC stores global constructor pointers */ -/* see http://blogs.msdn.com/vcblog/archive/2006/10/20/crt-initialization.aspx and - http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc */ -#pragma section(".CRT$XCU",read) -#define UTIL_INIT(f) static void __cdecl f##__init(void) {f();}; __declspec(allocate(".CRT$XCU")) void (__cdecl* f##__xcu)(void) = f##__init; -#elif defined(__GNUC__) -#define UTIL_INIT(f) static void f##__init(void) __attribute__((constructor)); static void f##__init(void) {f();} -#else -#error Unsupported compiler: please find out how to implement global initializers in C on it -#endif - -#endif - diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.c b/src/gallium/auxiliary/vl/vl_deint_filter.c index 8fa70e8..9e782e5 100644 --- a/src/gallium/auxiliary/vl/vl_deint_filter.c +++ b/src/gallium/auxiliary/vl/vl_deint_filter.c @@ -47,6 +47,7 @@ #include "util/u_draw.h" #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_format.h" #include "vl_types.h" #include "vl_video_buffer.h" @@ -214,8 +215,9 @@ create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field, ureg_imm4f(shader, -0.02353f, 0, 0, 0)); ureg_MUL(shader, ureg_saturate(ureg_writemask(t_diff, TGSI_WRITEMASK_X)), ureg_src(t_diff), ureg_imm4f(shader, 31.8750f, 0, 0, 0)); - ureg_LRP(shader, ureg_writemask(o_fragment, TGSI_WRITEMASK_X), ureg_src(t_diff), + ureg_LRP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X), ureg_src(t_diff), ureg_src(t_linear), ureg_src(t_weave)); + ureg_MOV(shader, o_fragment, ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X)); ureg_release_temporary(shader, t_tex); ureg_release_temporary(shader, t_comp_top); @@ -253,7 +255,13 @@ vl_deint_filter_init(struct vl_deint_filter *filter, struct pipe_context *pipe, /* TODO: handle other than 4:2:0 subsampling */ memset(&templ, 0, sizeof(templ)); - templ.buffer_format = PIPE_FORMAT_YV12; + templ.buffer_format = pipe->screen->get_video_param + ( + pipe->screen, + PIPE_VIDEO_PROFILE_UNKNOWN, + PIPE_VIDEO_ENTRYPOINT_UNKNOWN, + PIPE_VIDEO_CAP_PREFERED_FORMAT + ); templ.chroma_format = PIPE_VIDEO_CHROMA_FORMAT_420; templ.width = video_width; templ.height = video_height; @@ -271,10 +279,20 @@ vl_deint_filter_init(struct vl_deint_filter *filter, struct pipe_context *pipe, goto error_rs_state; memset(&blend, 0, sizeof blend); - blend.rt[0].colormask = PIPE_MASK_RGBA; - filter->blend = pipe->create_blend_state(pipe, &blend); - if (!filter->blend) - goto error_blend; + blend.rt[0].colormask = PIPE_MASK_R; + filter->blend[0] = pipe->create_blend_state(pipe, &blend); + if (!filter->blend[0]) + goto error_blendR; + + blend.rt[0].colormask = PIPE_MASK_G; + filter->blend[1] = pipe->create_blend_state(pipe, &blend); + if (!filter->blend[1]) + goto error_blendG; + + blend.rt[0].colormask = PIPE_MASK_B; + filter->blend[2] = pipe->create_blend_state(pipe, &blend); + if (!filter->blend[2]) + goto error_blendB; memset(&sampler, 0, sizeof(sampler)); sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; @@ -349,9 +367,15 @@ error_quad: pipe->delete_sampler_state(pipe, filter->sampler); error_sampler: - pipe->delete_blend_state(pipe, filter->blend); + pipe->delete_blend_state(pipe, filter->blend[2]); + +error_blendB: + pipe->delete_blend_state(pipe, filter->blend[1]); + +error_blendG: + pipe->delete_blend_state(pipe, filter->blend[0]); -error_blend: +error_blendR: pipe->delete_rasterizer_state(pipe, filter->rs_state); error_rs_state: @@ -367,7 +391,9 @@ vl_deint_filter_cleanup(struct vl_deint_filter *filter) assert(filter); filter->pipe->delete_sampler_state(filter->pipe, filter->sampler[0]); - filter->pipe->delete_blend_state(filter->pipe, filter->blend); + filter->pipe->delete_blend_state(filter->pipe, filter->blend[0]); + filter->pipe->delete_blend_state(filter->pipe, filter->blend[1]); + filter->pipe->delete_blend_state(filter->pipe, filter->blend[2]); filter->pipe->delete_rasterizer_state(filter->pipe, filter->rs_state); filter->pipe->delete_vertex_elements_state(filter->pipe, filter->ves); pipe_resource_reference(&filter->quad.buffer, NULL); @@ -420,12 +446,14 @@ vl_deint_filter_render(struct vl_deint_filter *filter, struct pipe_sampler_view **next_sv; struct pipe_sampler_view *sampler_views[4]; struct pipe_surface **dst_surfaces; - int j; + const unsigned *plane_order; + int i, j; assert(filter && prevprev && prev && cur && next && field <= 1); /* set up destination and source */ dst_surfaces = filter->video_buffer->get_surfaces(filter->video_buffer); + plane_order = vl_video_buffer_plane_order(filter->video_buffer->buffer_format); cur_sv = cur->get_sampler_view_components(cur); prevprev_sv = prevprev->get_sampler_view_components(prevprev); prev_sv = prev->get_sampler_view_components(prev); @@ -433,7 +461,6 @@ vl_deint_filter_render(struct vl_deint_filter *filter, /* set up pipe state */ filter->pipe->bind_rasterizer_state(filter->pipe, filter->rs_state); - filter->pipe->bind_blend_state(filter->pipe, filter->blend); filter->pipe->set_vertex_buffers(filter->pipe, 0, 1, &filter->quad); filter->pipe->bind_vertex_elements_state(filter->pipe, filter->ves); filter->pipe->bind_vs_state(filter->pipe, filter->vs); @@ -449,12 +476,13 @@ vl_deint_filter_render(struct vl_deint_filter *filter, fb_state.nr_cbufs = 1; /* process each plane separately */ - for (j = 0; j < 3; j++) { - /* select correct YV12 surfaces */ - int k = j == 1 ? 2 : - j == 2 ? 1 : 0; - struct pipe_surface *blit_surf = dst_surfaces[2 * k + field]; - struct pipe_surface *dst_surf = dst_surfaces[2 * k + 1 - field]; + for (i = 0, j = 0; i < VL_NUM_COMPONENTS; ++i) { + struct pipe_surface *blit_surf = dst_surfaces[field]; + struct pipe_surface *dst_surf = dst_surfaces[1 - field]; + int k = plane_order[i]; + + /* bind blend state for this component in the plane */ + filter->pipe->bind_blend_state(filter->pipe, filter->blend[j]); /* update render target state */ viewport.scale[0] = blit_surf->texture->width0; @@ -463,10 +491,10 @@ vl_deint_filter_render(struct vl_deint_filter *filter, fb_state.height = blit_surf->texture->height0; /* update sampler view sources */ - sampler_views[0] = prevprev_sv[j]; - sampler_views[1] = prev_sv[j]; - sampler_views[2] = cur_sv[j]; - sampler_views[3] = next_sv[j]; + sampler_views[0] = prevprev_sv[k]; + sampler_views[1] = prev_sv[k]; + sampler_views[2] = cur_sv[k]; + sampler_views[3] = next_sv[k]; filter->pipe->set_sampler_views(filter->pipe, PIPE_SHADER_FRAGMENT, 0, 4, sampler_views); /* blit current field */ @@ -479,11 +507,16 @@ vl_deint_filter_render(struct vl_deint_filter *filter, /* blit or interpolate other field */ fb_state.cbufs[0] = dst_surf; filter->pipe->set_framebuffer_state(filter->pipe, &fb_state); - if (j > 0 && filter->skip_chroma) { + if (i > 0 && filter->skip_chroma) { util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); } else { filter->pipe->bind_fs_state(filter->pipe, field ? filter->fs_deint_top : filter->fs_deint_bottom); util_draw_arrays(filter->pipe, PIPE_PRIM_QUADS, 0, 4); } + + if (++j >= util_format_get_nr_components(dst_surf->format)) { + dst_surfaces += 2; + j = 0; + } } } diff --git a/src/gallium/auxiliary/vl/vl_deint_filter.h b/src/gallium/auxiliary/vl/vl_deint_filter.h index 3ca378b..49cc96c 100644 --- a/src/gallium/auxiliary/vl/vl_deint_filter.h +++ b/src/gallium/auxiliary/vl/vl_deint_filter.h @@ -38,7 +38,7 @@ struct vl_deint_filter struct pipe_vertex_buffer quad; void *rs_state; - void *blend; + void *blend[3]; void *sampler[4]; void *ves; void *vs; diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c index e8cd24d..462fdcb 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.c +++ b/src/gallium/auxiliary/vl/vl_video_buffer.c @@ -253,14 +253,8 @@ vl_video_buffer_template(struct pipe_resource *templ, templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; templ->usage = usage; - if (plane > 0) { - if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - templ->width0 /= 2; - templ->height0 /= 2; - } else if (tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { - templ->width0 /= 2; - } - } + vl_video_buffer_adjust_size(&templ->width0, &templ->height0, plane, + tmpl->chroma_format, false); } static void diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h index 488c3cc..8a1c077 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.h +++ b/src/gallium/auxiliary/vl/vl_video_buffer.h @@ -48,6 +48,24 @@ struct vl_video_buffer struct pipe_surface *surfaces[VL_MAX_SURFACES]; }; +static inline void +vl_video_buffer_adjust_size(unsigned *width, unsigned *height, unsigned plane, + enum pipe_video_chroma_format chroma_format, + bool interlaced) +{ + if (interlaced) { + *height /= 2; + } + if (plane > 0) { + if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { + *width /= 2; + *height /= 2; + } else if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { + *width /= 2; + } + } +} + /** * get subformats for each plane */ diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp index dca799d..1bf7240 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp @@ -407,7 +407,7 @@ BuildUtil::loadImm(Value *dst, float f) Value * BuildUtil::loadImm(Value *dst, double d) { - return mkOp1v(OP_MOV, TYPE_F64, dst ? dst : getScratch(), mkImm(d)); + return mkOp1v(OP_MOV, TYPE_F64, dst ? dst : getScratch(8), mkImm(d)); } Value * @@ -499,7 +499,7 @@ BuildUtil::DataArray::acquire(ValueMap &m, int i, int c) return v; } else { - return up->getScratch(); + return up->getScratch(eltSize); } } diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h index 8f3bf77..d171f64 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.h @@ -295,7 +295,7 @@ BuildUtil::mkOp3v(operation op, DataType ty, Value *dst, inline LValue * BuildUtil::mkLoadv(DataType ty, Symbol *mem, Value *ptr) { - LValue *dst = getScratch(); + LValue *dst = getScratch(typeSizeof(ty)); mkLoad(ty, dst, mem, ptr); return dst; } diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c index 2e7c790..7180434 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c @@ -195,8 +195,10 @@ nvc0_launch_grid(struct pipe_context *pipe, int ret; ret = !nvc0_compute_state_validate(nvc0); - if (ret) - goto out; + if (ret) { + NOUVEAU_ERR("Failed to launch grid !\n"); + return; + } nvc0_compute_upload_input(nvc0, input); @@ -246,15 +248,11 @@ nvc0_launch_grid(struct pipe_context *pipe, /* rebind all the 3D constant buffers * (looks like binding a CB on COMPUTE clobbers 3D state) */ nvc0->dirty |= NVC0_NEW_CONSTBUF; - for (s = 0; s < 6; s++) { + for (s = 0; s < 5; s++) { for (i = 0; i < NVC0_MAX_PIPE_CONSTBUFS; i++) if (nvc0->constbuf[s][i].u.buf) nvc0->constbuf_dirty[s] |= 1 << i; } memset(nvc0->state.uniform_buffer_bound, 0, sizeof(nvc0->state.uniform_buffer_bound)); - -out: - if (ret) - NOUVEAU_ERR("Failed to launch grid !\n"); } diff --git a/src/gallium/state_trackers/omx/vid_enc.c b/src/gallium/state_trackers/omx/vid_enc.c index aa45089..df22a97 100644 --- a/src/gallium/state_trackers/omx/vid_enc.c +++ b/src/gallium/state_trackers/omx/vid_enc.c @@ -869,6 +869,9 @@ static void enc_ReleaseTasks(struct list_head *head) { struct encode_task *i, *next; + if (!head) + return; + LIST_FOR_EACH_ENTRY_SAFE(i, next, head, list) { pipe_resource_reference(&i->bitstream, NULL); i->buf->destroy(i->buf); diff --git a/src/gallium/state_trackers/va/buffer.c b/src/gallium/state_trackers/va/buffer.c index 8de7935..c2c24d6 100644 --- a/src/gallium/state_trackers/va/buffer.c +++ b/src/gallium/state_trackers/va/buffer.c @@ -40,6 +40,7 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type, unsigned int size, unsigned int num_elements, void *data, VABufferID *buf_id) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) @@ -62,7 +63,10 @@ vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type, if (data) memcpy(buf->data, data, size * num_elements); - *buf_id = handle_table_add(VL_VA_DRIVER(ctx)->htab, buf); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + *buf_id = handle_table_add(drv->htab, buf); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -71,12 +75,16 @@ VAStatus vlVaBufferSetNumElements(VADriverContextP ctx, VABufferID buf_id, unsigned int num_elements) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; @@ -109,22 +117,24 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff) if (!pbuff) return VA_STATUS_ERROR_INVALID_PARAMETER; + pipe_mutex_lock(drv->mutex); buf = handle_table_get(drv->htab, buf_id); - if (!buf) - return VA_STATUS_ERROR_INVALID_BUFFER; - - if (buf->export_refcount > 0) + if (!buf || buf->export_refcount > 0) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (buf->derived_surface.resource) { *pbuff = pipe_buffer_map(drv->pipe, buf->derived_surface.resource, PIPE_TRANSFER_WRITE, &buf->derived_surface.transfer); + pipe_mutex_unlock(drv->mutex); if (!buf->derived_surface.transfer || !*pbuff) return VA_STATUS_ERROR_INVALID_BUFFER; } else { + pipe_mutex_unlock(drv->mutex); *pbuff = buf->data; } @@ -144,20 +154,23 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id) if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); buf = handle_table_get(drv->htab, buf_id); - if (!buf) - return VA_STATUS_ERROR_INVALID_BUFFER; - - if (buf->export_refcount > 0) + if (!buf || buf->export_refcount > 0) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (buf->derived_surface.resource) { - if (!buf->derived_surface.transfer) + if (!buf->derived_surface.transfer) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } pipe_buffer_unmap(drv->pipe, buf->derived_surface.transfer); buf->derived_surface.transfer = NULL; } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -165,18 +178,25 @@ vlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id) VAStatus vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); - if (!buf) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + if (!buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (buf->derived_surface.resource) { - if (buf->export_refcount > 0) + if (buf->export_refcount > 0) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } pipe_resource_reference(&buf->derived_surface.resource, NULL); } @@ -184,6 +204,7 @@ vlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id) FREE(buf->data); FREE(buf); handle_table_remove(VL_VA_DRIVER(ctx)->htab, buf_id); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -192,12 +213,16 @@ VAStatus vlVaBufferInfo(VADriverContextP ctx, VABufferID buf_id, VABufferType *type, unsigned int *size, unsigned int *num_elements) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; @@ -227,7 +252,11 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + drv = VL_VA_DRIVER(ctx); + screen = VL_VA_PSCREEN(ctx); + pipe_mutex_lock(drv->mutex); buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; @@ -256,9 +285,6 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, if (!buf->derived_surface.resource) return VA_STATUS_ERROR_INVALID_BUFFER; - drv = VL_VA_DRIVER(ctx); - screen = VL_VA_PSCREEN(ctx); - if (buf->export_refcount > 0) { if (buf->export_state.mem_type != mem_type) return VA_STATUS_ERROR_INVALID_PARAMETER; @@ -269,7 +295,9 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: { struct winsys_handle whandle; + pipe_mutex_lock(drv->mutex); drv->pipe->flush(drv->pipe, NULL, 0); + pipe_mutex_unlock(drv->mutex); memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_FD; @@ -299,12 +327,16 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id, VAStatus vlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id) { + vlVaDriver *drv; vlVaBuffer *buf; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id); + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + buf = handle_table_get(drv->htab, buf_id); + pipe_mutex_unlock(drv->mutex); if (!buf) return VA_STATUS_ERROR_INVALID_BUFFER; diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c index 192794f..37a0117 100644 --- a/src/gallium/state_trackers/va/context.c +++ b/src/gallium/state_trackers/va/context.c @@ -155,6 +155,7 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx) vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc); vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc); + pipe_mutex_init(drv->mutex); ctx->pDriverData = (void *)drv; ctx->version_major = 0; @@ -262,7 +263,9 @@ vlVaCreateContext(VADriverContextP ctx, VAConfigID config_id, int picture_width, } context->desc.base.profile = config_id; + pipe_mutex_lock(drv->mutex); *context_id = handle_table_add(drv->htab, context); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -277,6 +280,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); if (context->decoder) { @@ -294,6 +298,7 @@ vlVaDestroyContext(VADriverContextP ctx, VAContextID context_id) } FREE(context); handle_table_remove(drv->htab, context_id); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -312,6 +317,7 @@ vlVaTerminate(VADriverContextP ctx) drv->pipe->destroy(drv->pipe); drv->vscreen->destroy(drv->vscreen); handle_table_destroy(drv->htab); + pipe_mutex_destroy(drv->mutex); FREE(drv); return VA_STATUS_SUCCESS; diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c index ccc263f..2c42a98 100644 --- a/src/gallium/state_trackers/va/image.c +++ b/src/gallium/state_trackers/va/image.c @@ -34,6 +34,7 @@ #include "util/u_video.h" #include "vl/vl_winsys.h" +#include "vl/vl_video_buffer.h" #include "va_private.h" @@ -61,15 +62,9 @@ vlVaVideoSurfaceSize(vlVaSurface *p_surf, int component, *width = p_surf->templat.width; *height = p_surf->templat.height; - if (component > 0) { - if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - *width /= 2; - *height /= 2; - } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) - *width /= 2; - } - if (p_surf->templat.interlaced) - *height /= 2; + vl_video_buffer_adjust_size(width, height, component, + p_surf->templat.chroma_format, + p_surf->templat.interlaced); } VAStatus @@ -119,7 +114,9 @@ vlVaCreateImage(VADriverContextP ctx, VAImageFormat *format, int width, int heig img = CALLOC(1, sizeof(VAImage)); if (!img) return VA_STATUS_ERROR_ALLOCATION_FAILED; + pipe_mutex_lock(drv->mutex); img->image_id = handle_table_add(drv->htab, img); + pipe_mutex_unlock(drv->mutex); img->format = *format; img->width = width; @@ -261,6 +258,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) return VA_STATUS_ERROR_ALLOCATION_FAILED; } + pipe_mutex_lock(drv->mutex); img->image_id = handle_table_add(drv->htab, img); img_buf->type = VAImageBufferType; @@ -270,6 +268,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) pipe_resource_reference(&img_buf->derived_surface.resource, surfaces[0]->texture); img->buf = handle_table_add(VL_VA_DRIVER(ctx)->htab, img_buf); + pipe_mutex_unlock(drv->mutex); *image = *img; @@ -279,16 +278,22 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image) VAStatus vlVaDestroyImage(VADriverContextP ctx, VAImageID image) { + vlVaDriver *drv; VAImage *vaimage; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - vaimage = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); - if (!vaimage) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + vaimage = handle_table_get(drv->htab, image); + if (!vaimage) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } handle_table_remove(VL_VA_DRIVER(ctx)->htab, image); + pipe_mutex_unlock(drv->mutex); FREE(vaimage); return vlVaDestroyBuffer(ctx, vaimage->buf); } @@ -321,21 +326,30 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); surf = handle_table_get(drv->htab, surface); - if (!surf || !surf->buffer) + if (!surf || !surf->buffer) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } vaimage = handle_table_get(drv->htab, image); - if (!vaimage) + if (!vaimage) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } img_buf = handle_table_get(drv->htab, vaimage->buf); - if (!img_buf) + if (!img_buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } format = VaFourccToPipeFormat(vaimage->format.fourcc); - if (format == PIPE_FORMAT_NONE) + if (format == PIPE_FORMAT_NONE) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } if (format != surf->buffer->buffer_format) { /* support NV12 to YV12 and IYUV conversion now only */ @@ -344,13 +358,17 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, (format == PIPE_FORMAT_IYUV && surf->buffer->buffer_format == PIPE_FORMAT_NV12)) convert = true; - else + else { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } } views = surf->buffer->get_sampler_view_planes(surf->buffer); - if (!views) + if (!views) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } for (i = 0; i < vaimage->num_planes; i++) { data[i] = img_buf->data + vaimage->offsets[i]; @@ -377,8 +395,10 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, uint8_t *map; map = drv->pipe->transfer_map(drv->pipe, views[i]->texture, 0, PIPE_TRANSFER_READ, &box, &transfer); - if (!map) + if (!map) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } if (i == 1 && convert) { u_copy_nv12_to_yv12(data, pitches, i, j, @@ -393,6 +413,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y, pipe_transfer_unmap(drv->pipe, transfer); } } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -415,28 +436,38 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); surf = handle_table_get(drv->htab, surface); - if (!surf || !surf->buffer) + if (!surf || !surf->buffer) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } vaimage = handle_table_get(drv->htab, image); - if (!vaimage) + if (!vaimage) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } img_buf = handle_table_get(drv->htab, vaimage->buf); - if (!img_buf) + if (!img_buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } if (img_buf->derived_surface.resource) { /* Attempting to transfer derived image to surface */ + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_UNIMPLEMENTED; } format = VaFourccToPipeFormat(vaimage->format.fourcc); - if (format == PIPE_FORMAT_NONE) + if (format == PIPE_FORMAT_NONE) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } if (format != surf->buffer->buffer_format) { struct pipe_video_buffer *tmp_buf; @@ -447,6 +478,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, if (!tmp_buf) { surf->templat.buffer_format = old_surf_format; + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; } @@ -455,8 +487,10 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, } views = surf->buffer->get_sampler_view_planes(surf->buffer); - if (!views) + if (!views) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_OPERATION_FAILED; + } for (i = 0; i < vaimage->num_planes; i++) { data[i] = img_buf->data + vaimage->offsets[i]; @@ -485,6 +519,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image, pitches[i] * views[i]->texture->array_size, 0); } } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/picture.c b/src/gallium/state_trackers/va/picture.c index da9ca5a..89ac024 100644 --- a/src/gallium/state_trackers/va/picture.c +++ b/src/gallium/state_trackers/va/picture.c @@ -50,24 +50,29 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); - if (!context) + if (!context) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_CONTEXT; + } surf = handle_table_get(drv->htab, render_target); + pipe_mutex_unlock(drv->mutex); if (!surf || !surf->buffer) return VA_STATUS_ERROR_INVALID_SURFACE; context->target = surf->buffer; if (!context->decoder) { + /* VPP */ if (context->templat.profile == PIPE_VIDEO_PROFILE_UNKNOWN && - ((context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM && - context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM && - context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM && - context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM) || - context->target->interlaced)) + context->target->buffer_format != PIPE_FORMAT_B8G8R8A8_UNORM && + context->target->buffer_format != PIPE_FORMAT_R8G8B8A8_UNORM && + context->target->buffer_format != PIPE_FORMAT_B8G8R8X8_UNORM && + context->target->buffer_format != PIPE_FORMAT_R8G8B8X8_UNORM && + context->target->buffer_format != PIPE_FORMAT_NV12) return VA_STATUS_ERROR_UNIMPLEMENTED; return VA_STATUS_SUCCESS; @@ -289,14 +294,19 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); - if (!context) + if (!context) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_CONTEXT; + } for (i = 0; i < num_buffers; ++i) { vlVaBuffer *buf = handle_table_get(drv->htab, buffers[i]); - if (!buf) + if (!buf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_BUFFER; + } switch (buf->type) { case VAPictureParameterBufferType: @@ -322,6 +332,7 @@ vlVaRenderPicture(VADriverContextP ctx, VAContextID context_id, VABufferID *buff break; } } + pipe_mutex_unlock(drv->mutex); return vaStatus; } @@ -339,7 +350,9 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id) if (!drv) return VA_STATUS_ERROR_INVALID_CONTEXT; + pipe_mutex_lock(drv->mutex); context = handle_table_get(drv->htab, context_id); + pipe_mutex_unlock(drv->mutex); if (!context) return VA_STATUS_ERROR_INVALID_CONTEXT; diff --git a/src/gallium/state_trackers/va/postproc.c b/src/gallium/state_trackers/va/postproc.c index 15053a9..0cec0c8 100644 --- a/src/gallium/state_trackers/va/postproc.c +++ b/src/gallium/state_trackers/va/postproc.c @@ -27,6 +27,9 @@ #include "util/u_handle_table.h" +#include "vl/vl_defines.h" +#include "vl/vl_video_buffer.h" + #include "va_private.h" static const VARectangle * @@ -44,43 +47,22 @@ vlVaRegionDefault(const VARectangle *region, struct pipe_video_buffer *buf, return def; } -VAStatus -vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +static VAStatus +vlVaPostProcCompositor(vlVaDriver *drv, vlVaContext *context, + const VARectangle *src_region, + const VARectangle *dst_region, + struct pipe_video_buffer *src, + struct pipe_video_buffer *dst, + enum vl_compositor_deinterlace deinterlace) { - VARectangle def_src_region, def_dst_region; - const VARectangle *src_region, *dst_region; + struct pipe_surface **surfaces; struct u_rect src_rect; struct u_rect dst_rect; - vlVaSurface *src_surface; - VAProcPipelineParameterBuffer *pipeline_param; - struct pipe_surface **surfaces; - struct pipe_surface *psurf; - - if (!drv || !context) - return VA_STATUS_ERROR_INVALID_CONTEXT; - - if (!buf || !buf->data) - return VA_STATUS_ERROR_INVALID_BUFFER; - - if (!context->target) - return VA_STATUS_ERROR_INVALID_SURFACE; - - pipeline_param = (VAProcPipelineParameterBuffer *)buf->data; - - src_surface = handle_table_get(drv->htab, pipeline_param->surface); - if (!src_surface || !src_surface->buffer) - return VA_STATUS_ERROR_INVALID_SURFACE; - - surfaces = context->target->get_surfaces(context->target); + surfaces = dst->get_surfaces(dst); if (!surfaces || !surfaces[0]) return VA_STATUS_ERROR_INVALID_SURFACE; - psurf = surfaces[0]; - - src_region = vlVaRegionDefault(pipeline_param->surface_region, src_surface->buffer, &def_src_region); - dst_region = vlVaRegionDefault(pipeline_param->output_region, context->target, &def_dst_region); - src_rect.x0 = src_region->x; src_rect.y0 = src_region->y; src_rect.x1 = src_region->x + src_region->width; @@ -92,9 +74,99 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex dst_rect.y1 = dst_region->y + dst_region->height; vl_compositor_clear_layers(&drv->cstate); - vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src_surface->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE); + vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, src, + &src_rect, NULL, deinterlace); vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect); - vl_compositor_render(&drv->cstate, &drv->compositor, psurf, NULL, false); + vl_compositor_render(&drv->cstate, &drv->compositor, surfaces[0], NULL, false); + + return VA_STATUS_SUCCESS; +} + +static void vlVaGetBox(struct pipe_video_buffer *buf, unsigned idx, + struct pipe_box *box, const VARectangle *region) +{ + unsigned plane = buf->interlaced ? idx / 2: idx; + unsigned x, y, width, height; + + x = abs(region->x); + y = abs(region->y); + width = region->width; + height = region->height; + + vl_video_buffer_adjust_size(&x, &y, plane, buf->chroma_format, + buf->interlaced); + vl_video_buffer_adjust_size(&width, &height, plane, buf->chroma_format, + buf->interlaced); + + box->x = region->x < 0 ? -x : x; + box->y = region->y < 0 ? -y : y; + box->width = width; + box->height = height; +} + +static VAStatus vlVaPostProcBlit(vlVaDriver *drv, vlVaContext *context, + const VARectangle *src_region, + const VARectangle *dst_region, + struct pipe_video_buffer *src, + struct pipe_video_buffer *dst, + enum vl_compositor_deinterlace deinterlace) +{ + struct pipe_surface **src_surfaces; + struct pipe_surface **dst_surfaces; + unsigned i; + + if (src->interlaced != dst->interlaced) + return VA_STATUS_ERROR_INVALID_SURFACE; + + src_surfaces = src->get_surfaces(src); + if (!src_surfaces || !src_surfaces[0]) + return VA_STATUS_ERROR_INVALID_SURFACE; + + dst_surfaces = dst->get_surfaces(dst); + if (!dst_surfaces || !dst_surfaces[0]) + return VA_STATUS_ERROR_INVALID_SURFACE; + + for (i = 0; i < VL_MAX_SURFACES; ++i) { + struct pipe_surface *from = src_surfaces[i]; + struct pipe_blit_info blit; + + if (src->interlaced) { + /* Not 100% accurate, but close enough */ + switch (deinterlace) { + case VL_COMPOSITOR_BOB_TOP: + from = src_surfaces[i & ~1]; + break; + case VL_COMPOSITOR_BOB_BOTTOM: + from = src_surfaces[(i & ~1) + 1]; + break; + default: + break; + } + } + + if (!from || !dst_surfaces[i]) + continue; + + memset(&blit, 0, sizeof(blit)); + blit.src.resource = from->texture; + blit.src.format = from->format; + blit.src.level = 0; + blit.src.box.z = from->u.tex.first_layer; + blit.src.box.depth = 1; + vlVaGetBox(src, i, &blit.src.box, src_region); + + blit.dst.resource = dst_surfaces[i]->texture; + blit.dst.format = dst_surfaces[i]->format; + blit.dst.level = 0; + blit.dst.box.z = dst_surfaces[i]->u.tex.first_layer; + blit.dst.box.depth = 1; + vlVaGetBox(dst, i, &blit.dst.box, dst_region); + + blit.mask = PIPE_MASK_RGBA; + blit.filter = PIPE_TEX_MIPFILTER_LINEAR; + + drv->pipe->blit(drv->pipe, &blit); + } // TODO: figure out why this is necessary for DMA-buf sharing drv->pipe->flush(drv->pipe, NULL, 0); @@ -102,4 +174,75 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex return VA_STATUS_SUCCESS; } +VAStatus +vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf) +{ + enum vl_compositor_deinterlace deinterlace = VL_COMPOSITOR_WEAVE; + VARectangle def_src_region, def_dst_region; + const VARectangle *src_region, *dst_region; + VAProcPipelineParameterBuffer *param; + vlVaSurface *src_surface; + unsigned i; + if (!drv || !context) + return VA_STATUS_ERROR_INVALID_CONTEXT; + + if (!buf || !buf->data) + return VA_STATUS_ERROR_INVALID_BUFFER; + + if (!context->target) + return VA_STATUS_ERROR_INVALID_SURFACE; + + param = buf->data; + + src_surface = handle_table_get(drv->htab, param->surface); + if (!src_surface || !src_surface->buffer) + return VA_STATUS_ERROR_INVALID_SURFACE; + + for (i = 0; i < param->num_filters; i++) { + vlVaBuffer *buf = handle_table_get(drv->htab, param->filters[i]); + VAProcFilterParameterBufferBase *filter; + + if (!buf || buf->type != VAProcFilterParameterBufferType) + return VA_STATUS_ERROR_INVALID_BUFFER; + + filter = buf->data; + switch (filter->type) { + case VAProcFilterDeinterlacing: { + VAProcFilterParameterBufferDeinterlacing *deint = buf->data; + switch (deint->algorithm) { + case VAProcDeinterlacingBob: + if (deint->flags & VA_DEINTERLACING_BOTTOM_FIELD) + deinterlace = VL_COMPOSITOR_BOB_BOTTOM; + else + deinterlace = VL_COMPOSITOR_BOB_TOP; + break; + + case VAProcDeinterlacingWeave: + deinterlace = VL_COMPOSITOR_WEAVE; + break; + + default: + return VA_STATUS_ERROR_UNIMPLEMENTED; + } + + break; + } + + default: + return VA_STATUS_ERROR_UNIMPLEMENTED; + } + } + + src_region = vlVaRegionDefault(param->surface_region, src_surface->buffer, &def_src_region); + dst_region = vlVaRegionDefault(param->output_region, context->target, &def_dst_region); + + if (context->target->buffer_format != PIPE_FORMAT_NV12) + return vlVaPostProcCompositor(drv, context, src_region, dst_region, + src_surface->buffer, context->target, + deinterlace); + else + return vlVaPostProcBlit(drv, context, src_region, dst_region, + src_surface->buffer, context->target, + deinterlace); +} diff --git a/src/gallium/state_trackers/va/subpicture.c b/src/gallium/state_trackers/va/subpicture.c index f146189..f546e56 100644 --- a/src/gallium/state_trackers/va/subpicture.c +++ b/src/gallium/state_trackers/va/subpicture.c @@ -65,22 +65,30 @@ VAStatus vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image, VASubpictureID *subpicture) { + vlVaDriver *drv; vlVaSubpicture *sub; VAImage *img; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); - if (!img) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + img = handle_table_get(drv->htab, image); + if (!img) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } sub = CALLOC(1, sizeof(*sub)); - if (!sub) + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; + } sub->image = img; *subpicture = handle_table_add(VL_VA_DRIVER(ctx)->htab, sub); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -88,17 +96,24 @@ vlVaCreateSubpicture(VADriverContextP ctx, VAImageID image, VAStatus vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture) { + vlVaDriver *drv; vlVaSubpicture *sub; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture); - if (!sub) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + + sub = handle_table_get(drv->htab, subpicture); + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SUBPICTURE; + } FREE(sub); - handle_table_remove(VL_VA_DRIVER(ctx)->htab, subpicture); + handle_table_remove(drv->htab, subpicture); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -106,17 +121,24 @@ vlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture) VAStatus vlVaSubpictureImage(VADriverContextP ctx, VASubpictureID subpicture, VAImageID image) { + vlVaDriver *drv; vlVaSubpicture *sub; VAImage *img; if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - img = handle_table_get(VL_VA_DRIVER(ctx)->htab, image); - if (!img) + drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); + + img = handle_table_get(drv->htab, image); + if (!img) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_IMAGE; + } - sub = handle_table_get(VL_VA_DRIVER(ctx)->htab, subpicture); + sub = handle_table_get(drv->htab, subpicture); + pipe_mutex_unlock(drv->mutex); if (!sub) return VA_STATUS_ERROR_INVALID_SUBPICTURE; @@ -164,15 +186,20 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); sub = handle_table_get(drv->htab, subpicture); - if (!sub) + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SUBPICTURE; + } for (i = 0; i < num_surfaces; i++) { surf = handle_table_get(drv->htab, target_surfaces[i]); - if (!surf) + if (!surf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } } sub->src_rect = src_rect; @@ -191,8 +218,10 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, tex_temp.flags = 0; if (!drv->pipe->screen->is_format_supported( drv->pipe->screen, tex_temp.format, tex_temp.target, - tex_temp.nr_samples, tex_temp.bind)) + tex_temp.nr_samples, tex_temp.bind)) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; + } tex = drv->pipe->screen->resource_create(drv->pipe->screen, &tex_temp); @@ -200,13 +229,16 @@ vlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, u_sampler_view_default_template(&sampler_templ, tex, tex->format); sub->sampler = drv->pipe->create_sampler_view(drv->pipe, tex, &sampler_templ); pipe_resource_reference(&tex, NULL); - if (!sub->sampler) + if (!sub->sampler) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_ALLOCATION_FAILED; + } for (i = 0; i < num_surfaces; i++) { surf = handle_table_get(drv->htab, target_surfaces[i]); util_dynarray_append(&surf->subpics, vlVaSubpicture *, sub); } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -224,15 +256,20 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); sub = handle_table_get(drv->htab, subpicture); - if (!sub) + if (!sub) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SUBPICTURE; + } for (i = 0; i < num_surfaces; i++) { surf = handle_table_get(drv->htab, target_surfaces[i]); - if (!surf) + if (!surf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } array = surf->subpics.data; if (!array) @@ -246,6 +283,7 @@ vlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture, while (surf->subpics.size && util_dynarray_top(&surf->subpics, vlVaSubpicture *) == NULL) (void)util_dynarray_pop(&surf->subpics, vlVaSubpicture *); } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c index 5ddaf04..f23a889 100644 --- a/src/gallium/state_trackers/va/surface.c +++ b/src/gallium/state_trackers/va/surface.c @@ -68,6 +68,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); for (i = 0; i < num_surfaces; ++i) { vlVaSurface *surf = handle_table_get(drv->htab, surface_list[i]); if (surf->buffer) @@ -76,6 +77,7 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur FREE(surf); handle_table_remove(drv->htab, surface_list[i]); } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -236,16 +238,21 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s return VA_STATUS_ERROR_INVALID_CONTEXT; drv = VL_VA_DRIVER(ctx); + pipe_mutex_lock(drv->mutex); surf = handle_table_get(drv->htab, surface_id); - if (!surf) + if (!surf) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_SURFACE; + } screen = drv->pipe->screen; vscreen = drv->vscreen; tex = vscreen->texture_from_drawable(vscreen, draw); - if (!tex) + if (!tex) { + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_DISPLAY; + } dirty_area = vscreen->get_dirty_area(vscreen); @@ -254,6 +261,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s surf_draw = drv->pipe->create_surface(drv->pipe, tex, &surf_templ); if (!surf_draw) { pipe_resource_reference(&tex, NULL); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_ERROR_INVALID_DISPLAY; } @@ -268,8 +276,10 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, true); status = vlVaPutSubpictures(surf, drv, surf_draw, dirty_area, &src_rect, &dst_rect); - if (status) + if (status) { + pipe_mutex_unlock(drv->mutex); return status; + } screen->flush_frontbuffer(screen, tex, 0, 0, vscreen->get_private(vscreen), NULL); @@ -278,6 +288,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s pipe_resource_reference(&tex, NULL); pipe_surface_reference(&surf_draw, NULL); + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; } @@ -599,6 +610,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID)); + pipe_mutex_lock(drv->mutex); for (i = 0; i < num_surfaces; i++) { vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface)); if (!surf) @@ -627,10 +639,12 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, assert(0); } } + pipe_mutex_unlock(drv->mutex); return VA_STATUS_SUCCESS; no_res: + pipe_mutex_unlock(drv->mutex); if (i) vlVaDestroySurfaces(ctx, surfaces, i); @@ -649,7 +663,7 @@ vlVaQueryVideoProcFilters(VADriverContextP ctx, VAContextID context, if (!num_filters || !filters) return VA_STATUS_ERROR_INVALID_PARAMETER; - filters[num++] = VAProcFilterNone; + filters[num++] = VAProcFilterDeinterlacing; *num_filters = num; @@ -674,8 +688,20 @@ vlVaQueryVideoProcFilterCaps(VADriverContextP ctx, VAContextID context, switch (type) { case VAProcFilterNone: break; + case VAProcFilterDeinterlacing: { + VAProcFilterCapDeinterlacing *deint = filter_caps; + + if (*num_filter_caps < 2) { + *num_filter_caps = 2; + return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; + } + + deint[i++].type = VAProcDeinterlacingBob; + deint[i++].type = VAProcDeinterlacingWeave; + break; + } + case VAProcFilterNoiseReduction: - case VAProcFilterDeinterlacing: case VAProcFilterSharpening: case VAProcFilterColorBalance: case VAProcFilterSkinToneEnhancement: diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index bf9d24b..7afd81a 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -44,6 +44,7 @@ #include "vl/vl_csc.h" #include "util/u_dynarray.h" +#include "os/os_thread.h" #define VL_VA_DRIVER(ctx) ((vlVaDriver *)ctx->pDriverData) #define VL_VA_PSCREEN(ctx) (VL_VA_DRIVER(ctx)->vscreen->pscreen) @@ -203,6 +204,7 @@ typedef struct { struct vl_compositor compositor; struct vl_compositor_state cstate; vl_csc_matrix csc; + pipe_mutex mutex; } vlVaDriver; typedef struct { diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c index 55d0d76..ffcedc1 100644 --- a/src/gallium/state_trackers/vdpau/surface.c +++ b/src/gallium/state_trackers/vdpau/surface.c @@ -183,16 +183,9 @@ vlVdpVideoSurfaceSize(vlVdpSurface *p_surf, int component, *width = p_surf->templat.width; *height = p_surf->templat.height; - if (component > 0) { - if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) { - *width /= 2; - *height /= 2; - } else if (p_surf->templat.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) { - *width /= 2; - } - } - if (p_surf->templat.interlaced) - *height /= 2; + vl_video_buffer_adjust_size(width, height, component, + p_surf->templat.chroma_format, + p_surf->templat.interlaced); } /** |