Doesn't break nouveau_video, apparently a check already causes it to use vl_video_buffer for vdpau.
Signed-off-by: Maarten Lankhorst <m.b.lankho...@gmail.com> --- src/gallium/auxiliary/vl/vl_mpeg12_decoder.c | 15 +++-- src/gallium/auxiliary/vl/vl_video_buffer.c | 92 +++++++++++++++++++++++++- src/gallium/auxiliary/vl/vl_video_buffer.h | 2 + src/gallium/drivers/nouveau/nouveau_video.c | 37 ---------- src/gallium/drivers/nouveau/nouveau_video.h | 1 - src/gallium/include/pipe/p_video_decoder.h | 17 ++++-- src/gallium/state_trackers/vdpau/surface.c | 55 +++++----------- 7 files changed, 131 insertions(+), 88 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c index 2442d78..32501e0 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c @@ -160,16 +160,18 @@ static bool init_idct_buffer(struct vl_mpeg12_decoder *dec, struct vl_mpeg12_buffer *buffer) { struct pipe_sampler_view **idct_source_sv, **mc_source_sv; + struct vl_video_buffer *mc_source = (struct vl_video_buffer*)dec->mc_source; + struct vl_video_buffer *idct_source = (struct vl_video_buffer*)dec->idct_source; unsigned i; - assert(dec && buffer); + assert(buffer); - idct_source_sv = dec->idct_source->get_sampler_view_planes(dec->idct_source); + idct_source_sv = idct_source->get_sampler_view_planes(&idct_source->base); if (!idct_source_sv) goto error_source_sv; - mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); + mc_source_sv = mc_source->get_sampler_view_planes(&mc_source->base); if (!mc_source_sv) goto error_mc_source_sv; @@ -553,7 +555,8 @@ vl_mpeg12_set_reference_frames(struct pipe_video_decoder *decoder, assert(num_ref_frames <= VL_MAX_REF_FRAMES); for (i = 0; i < num_ref_frames; ++i) { - sv = ref_frames[i]->get_sampler_view_planes(ref_frames[i]); + struct vl_video_buffer *ref = (struct vl_video_buffer *)ref_frames[i]; + sv = ref->get_sampler_view_planes(&ref->base); for (j = 0; j < VL_MAX_PLANES; ++j) pipe_sampler_view_reference(&dec->ref_frames[i][j], sv[j]); } @@ -713,6 +716,7 @@ static void vl_mpeg12_end_frame(struct pipe_video_decoder *decoder) { struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder *)decoder; + struct vl_video_buffer *mc_source; struct pipe_sampler_view **mc_source_sv; struct pipe_vertex_buffer vb[3]; struct vl_mpeg12_buffer *buf; @@ -761,7 +765,8 @@ vl_mpeg12_end_frame(struct pipe_video_decoder *decoder) vl_idct_flush(&buf->idct[i], buf->num_ycbcr_blocks[i]); } - mc_source_sv = dec->mc_source->get_sampler_view_planes(dec->mc_source); + mc_source = (struct vl_video_buffer *)dec->mc_source; + mc_source_sv = mc_source->get_sampler_view_planes(&mc_source->base); for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) { if (!dec->target_surfaces[i]) continue; diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c index 6d714d4..b982477 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.c +++ b/src/gallium/auxiliary/vl/vl_video_buffer.c @@ -35,6 +35,7 @@ #include "util/u_inlines.h" #include "util/u_sampler.h" #include "util/u_memory.h" +#include "util/u_rect.h" #include "vl_video_buffer.h" @@ -151,6 +152,93 @@ error: return NULL; } +static int +vl_video_buffer_reformat(struct vl_video_buffer *buf, enum pipe_format format) +{ + struct pipe_resource templ, *newbuf, *newbuf2 = NULL; + struct pipe_screen *screen = buf->base.context->screen; + unsigned i; + templ = *buf->resources[1]; + if (format == PIPE_FORMAT_NV12) + templ.format = PIPE_FORMAT_R8G8_UNORM; + else if (format == PIPE_FORMAT_YV12) + templ.format = PIPE_FORMAT_R8_UNORM; + else + assert(0); + newbuf = screen->resource_create(screen, &templ); + if (!newbuf) + return -1; + if (templ.format == PIPE_FORMAT_R8_UNORM) { + newbuf2 = screen->resource_create(screen, &templ); + if (!newbuf2) { + pipe_resource_reference(&newbuf, NULL); + return -1; + } + buf->num_planes = 3; + } + else + buf->num_planes = 2; + buf->base.buffer_format = format; + pipe_resource_reference(&buf->resources[1], newbuf); + pipe_resource_reference(&buf->resources[2], newbuf2); + for (i = 1; i < VL_MAX_PLANES; ++i) { + pipe_surface_reference(&buf->surfaces[i], NULL); + pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL); + pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL); + } + return 0; +} + +static int +vl_video_buffer_put_bits(struct pipe_video_buffer *buffer, + enum pipe_format format, + void const *const *source_data, + uint32_t const *source_pitches) +{ + struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer; + struct pipe_sampler_view **sampler_views; + struct pipe_context *pipe = buf->base.context; + unsigned i; + if (buf->base.buffer_format != format) { + if (vl_video_buffer_reformat(buf, format) < 0) + return -1; + } + sampler_views = vl_video_buffer_sampler_view_planes(&buf->base); + if (!sampler_views) + return -1; + for (i = 0; i < buf->num_planes; ++i) { + struct pipe_sampler_view *sv = sampler_views[i ? i ^ 3 : 0]; + struct pipe_box dst_box = { 0, 0, 0, sv->texture->width0, sv->texture->height0, 1 }; + + struct pipe_transfer *transfer; + void *map; + + transfer = pipe->get_transfer(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE, &dst_box); + if (!transfer) + return -1; + + map = pipe->transfer_map(pipe, transfer); + if (map) { + util_copy_rect(map, sv->texture->format, transfer->stride, 0, 0, + dst_box.width, dst_box.height, + source_data[i], source_pitches[i], 0, 0); + + pipe->transfer_unmap(pipe, transfer); + } + pipe->transfer_destroy(pipe, transfer); + } + return 0; +} + +static int +vl_video_buffer_get_bits(struct pipe_video_buffer *buffer, + enum pipe_format format, + void *const *dest_data, + uint32_t const *dest_pitches) +{ + return -1; +} + static struct pipe_sampler_view ** vl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer) { @@ -278,10 +366,12 @@ vl_video_buffer_create_ex(struct pipe_context *pipe, buffer->base.context = pipe; buffer->base.destroy = vl_video_buffer_destroy; - buffer->base.get_sampler_view_planes = vl_video_buffer_sampler_view_planes; + buffer->get_sampler_view_planes = vl_video_buffer_sampler_view_planes; buffer->base.get_sampler_view_components = vl_video_buffer_sampler_view_components; buffer->base.get_surfaces = vl_video_buffer_surfaces; buffer->base.chroma_format = chroma_format; + buffer->base.put_bits = vl_video_buffer_put_bits; + buffer->base.get_bits = vl_video_buffer_get_bits; buffer->base.width = width; buffer->base.height = height; buffer->num_planes = 1; diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h index 8c80b36..de64f69 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.h +++ b/src/gallium/auxiliary/vl/vl_video_buffer.h @@ -41,6 +41,8 @@ struct vl_video_buffer { struct pipe_video_buffer base; + struct pipe_sampler_view **(*get_sampler_view_planes)(struct pipe_video_buffer *buffer); + unsigned num_planes; struct pipe_resource *resources[VL_MAX_PLANES]; struct pipe_sampler_view *sampler_view_planes[VL_MAX_PLANES]; diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c index 162e1aa..fb3c49a 100644 --- a/src/gallium/drivers/nouveau/nouveau_video.c +++ b/src/gallium/drivers/nouveau/nouveau_video.c @@ -650,41 +650,6 @@ vl: } static struct pipe_sampler_view ** -nouveau_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer) -{ - struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer; - struct pipe_sampler_view sv_templ; - struct pipe_context *pipe; - unsigned i; - - assert(buf); - - pipe = buf->base.context; - - for (i = 0; i < buf->num_planes; ++i ) { - if (!buf->sampler_view_planes[i]) { - memset(&sv_templ, 0, sizeof(sv_templ)); - u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->format); - - if (util_format_get_nr_components(buf->resources[i]->format) == 1) - sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = sv_templ.swizzle_a = PIPE_SWIZZLE_RED; - - buf->sampler_view_planes[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ); - if (!buf->sampler_view_planes[i]) - goto error; - } - } - - return buf->sampler_view_planes; - -error: - for (i = 0; i < buf->num_planes; ++i ) - pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL); - - return NULL; -} - -static struct pipe_sampler_view ** nouveau_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer) { struct nouveau_video_buffer *buf = (struct nouveau_video_buffer *)buffer; @@ -765,7 +730,6 @@ nouveau_video_buffer_destroy(struct pipe_video_buffer *buffer) for (i = 0; i < buf->num_planes; ++i) { pipe_surface_reference(&buf->surfaces[i], NULL); - pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL); pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL); pipe_resource_reference(&buf->resources[i], NULL); } @@ -803,7 +767,6 @@ nouveau_video_buffer_create(struct pipe_context *pipe, buffer->base.context = pipe; buffer->base.destroy = nouveau_video_buffer_destroy; - buffer->base.get_sampler_view_planes = nouveau_video_buffer_sampler_view_planes; buffer->base.get_sampler_view_components = nouveau_video_buffer_sampler_view_components; buffer->base.get_surfaces = nouveau_video_buffer_surfaces; buffer->base.chroma_format = chroma_format; diff --git a/src/gallium/drivers/nouveau/nouveau_video.h b/src/gallium/drivers/nouveau/nouveau_video.h index c6875c3..77cbdf9 100644 --- a/src/gallium/drivers/nouveau/nouveau_video.h +++ b/src/gallium/drivers/nouveau/nouveau_video.h @@ -8,7 +8,6 @@ struct nouveau_video_buffer { struct pipe_video_buffer base; unsigned num_planes; struct pipe_resource *resources[2]; - struct pipe_sampler_view *sampler_view_planes[2]; struct pipe_sampler_view *sampler_view_components[3]; struct pipe_surface *surfaces[2]; }; diff --git a/src/gallium/include/pipe/p_video_decoder.h b/src/gallium/include/pipe/p_video_decoder.h index 40b7dcd..5bd6664 100644 --- a/src/gallium/include/pipe/p_video_decoder.h +++ b/src/gallium/include/pipe/p_video_decoder.h @@ -148,11 +148,6 @@ struct pipe_video_buffer void (*destroy)(struct pipe_video_buffer *buffer); /** - * get a individual sampler view for each plane - */ - struct pipe_sampler_view **(*get_sampler_view_planes)(struct pipe_video_buffer *buffer); - - /** * get a individual sampler view for each component */ struct pipe_sampler_view **(*get_sampler_view_components)(struct pipe_video_buffer *buffer); @@ -161,6 +156,18 @@ struct pipe_video_buffer * get a individual surfaces for each plane */ struct pipe_surface **(*get_surfaces)(struct pipe_video_buffer *buffer); + + /** + * write bits to a video buffer + */ + int (*put_bits)(struct pipe_video_buffer *buffer, enum pipe_format format, + void const *const *source_data, uint32_t const *source_pitches); + + /** + * read bits from a video buffer + */ + int (*get_bits)(struct pipe_video_buffer *buffer, enum pipe_format format, + void *const*dest_data, uint32_t const *dest_pitches); }; #ifdef __cplusplus diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c index 77503cf..f5a5d75 100644 --- a/src/gallium/state_trackers/vdpau/surface.c +++ b/src/gallium/state_trackers/vdpau/surface.c @@ -151,6 +151,10 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface, void *const *destination_data, uint32_t const *destination_pitches) { + enum pipe_format pformat = FormatYCBCRToPipe(destination_ycbcr_format); + struct pipe_context *pipe; + int ret; + if (!vlCreateHTAB()) return VDP_STATUS_RESOURCES; @@ -158,11 +162,14 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface, if (!p_surf) return VDP_STATUS_INVALID_HANDLE; - //if (!p_surf->psurface) - // return VDP_STATUS_RESOURCES; + pipe = p_surf->device->context->pipe; + if (!pipe) + return VDP_STATUS_INVALID_HANDLE; - //return VDP_STATUS_OK; - return VDP_STATUS_NO_IMPLEMENTATION; + assert(p_surf->video_buffer); + ret = p_surf->video_buffer->get_bits(p_surf->video_buffer, pformat, + destination_data, destination_pitches); + return ret < 0 ? VDP_STATUS_RESOURCES : VDP_STATUS_OK; } /** @@ -177,8 +184,7 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface, { enum pipe_format pformat = FormatYCBCRToPipe(source_ycbcr_format); struct pipe_context *pipe; - struct pipe_sampler_view **sampler_views; - unsigned i; + int ret; if (!vlCreateHTAB()) return VDP_STATUS_RESOURCES; @@ -191,37 +197,8 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface, if (!pipe) return VDP_STATUS_INVALID_HANDLE; - if (p_surf->video_buffer == NULL || pformat != p_surf->video_buffer->buffer_format) { - assert(0); // TODO Recreate resource - return VDP_STATUS_NO_IMPLEMENTATION; - } - - sampler_views = p_surf->video_buffer->get_sampler_view_planes(p_surf->video_buffer); - if (!sampler_views) - return VDP_STATUS_RESOURCES; - - for (i = 0; i < 3; ++i) { //TODO put nr of planes into util format - struct pipe_sampler_view *sv = sampler_views[i ? i ^ 3 : 0]; - struct pipe_box dst_box = { 0, 0, 0, sv->texture->width0, sv->texture->height0, 1 }; - - struct pipe_transfer *transfer; - void *map; - - transfer = pipe->get_transfer(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE, &dst_box); - if (!transfer) - return VDP_STATUS_RESOURCES; - - map = pipe->transfer_map(pipe, transfer); - if (map) { - util_copy_rect(map, sv->texture->format, transfer->stride, 0, 0, - dst_box.width, dst_box.height, - source_data[i], source_pitches[i], 0, 0); - - pipe->transfer_unmap(pipe, transfer); - } - - pipe->transfer_destroy(pipe, transfer); - } - - return VDP_STATUS_OK; + assert(p_surf->video_buffer); + ret = p_surf->video_buffer->put_bits(p_surf->video_buffer, pformat, + source_data, source_pitches); + return ret < 0 ? VDP_STATUS_RESOURCES : VDP_STATUS_OK; } -- 1.7.7.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev