diff options
author | Ilia Mirkin <[email protected]> | 2013-08-10 13:27:47 -0400 |
---|---|---|
committer | Maarten Lankhorst <[email protected]> | 2013-08-15 15:19:47 +0200 |
commit | b57875bbb3c677eee8930b41b03fbd2544278a6b (patch) | |
tree | 7104f958a9a68c474fc6d5e8626584bbd5804e32 /src/gallium/drivers/nouveau/nouveau_vp3_video.c | |
parent | 940f7cec77316687e2b92c13a2446c88df0ece45 (diff) |
nvc0: refactor video buffer management logic into nouveau_vp3
Signed-off-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nouveau/nouveau_vp3_video.c')
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_vp3_video.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.c b/src/gallium/drivers/nouveau/nouveau_vp3_video.c new file mode 100644 index 00000000000..a55c2e8bc0c --- /dev/null +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.c @@ -0,0 +1,165 @@ +/* + * Copyright 2011-2013 Maarten Lankhorst + * + * 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 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "nouveau_screen.h" +#include "nouveau_context.h" +#include "nouveau_vp3_video.h" + +#include "util/u_video.h" +#include "util/u_format.h" +#include "util/u_sampler.h" + +static struct pipe_sampler_view ** +nouveau_vp3_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer) +{ + struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer; + return buf->sampler_view_planes; +} + +static struct pipe_sampler_view ** +nouveau_vp3_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer) +{ + struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer; + return buf->sampler_view_components; +} + +static struct pipe_surface ** +nouveau_vp3_video_buffer_surfaces(struct pipe_video_buffer *buffer) +{ + struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer; + return buf->surfaces; +} + +static void +nouveau_vp3_video_buffer_destroy(struct pipe_video_buffer *buffer) +{ + struct nouveau_vp3_video_buffer *buf = (struct nouveau_vp3_video_buffer *)buffer; + unsigned i; + + assert(buf); + + for (i = 0; i < VL_NUM_COMPONENTS; ++i) { + pipe_resource_reference(&buf->resources[i], NULL); + pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL); + pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL); + pipe_surface_reference(&buf->surfaces[i * 2], NULL); + pipe_surface_reference(&buf->surfaces[i * 2 + 1], NULL); + } + FREE(buffer); +} + +struct pipe_video_buffer * +nouveau_vp3_video_buffer_create(struct pipe_context *pipe, + const struct pipe_video_buffer *templat, + int flags) +{ + struct nouveau_vp3_video_buffer *buffer; + struct pipe_resource templ; + unsigned i, j, component; + struct pipe_sampler_view sv_templ; + struct pipe_surface surf_templ; + + assert(templat->interlaced); + if (getenv("XVMC_VL") || templat->buffer_format != PIPE_FORMAT_NV12) + return vl_video_buffer_create(pipe, templat); + + assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420); + + buffer = CALLOC_STRUCT(nouveau_vp3_video_buffer); + if (!buffer) + return NULL; + + buffer->base.buffer_format = templat->buffer_format; + buffer->base.context = pipe; + buffer->base.destroy = nouveau_vp3_video_buffer_destroy; + buffer->base.chroma_format = templat->chroma_format; + buffer->base.width = templat->width; + buffer->base.height = templat->height; + buffer->base.get_sampler_view_planes = nouveau_vp3_video_buffer_sampler_view_planes; + buffer->base.get_sampler_view_components = nouveau_vp3_video_buffer_sampler_view_components; + buffer->base.get_surfaces = nouveau_vp3_video_buffer_surfaces; + buffer->base.interlaced = true; + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D_ARRAY; + templ.depth0 = 1; + templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; + templ.format = PIPE_FORMAT_R8_UNORM; + templ.width0 = buffer->base.width; + templ.height0 = (buffer->base.height + 1)/2; + templ.flags = flags; + templ.array_size = 2; + + buffer->resources[0] = pipe->screen->resource_create(pipe->screen, &templ); + if (!buffer->resources[0]) + goto error; + + templ.format = PIPE_FORMAT_R8G8_UNORM; + buffer->num_planes = 2; + templ.width0 = (templ.width0 + 1) / 2; + templ.height0 = (templ.height0 + 1) / 2; + for (i = 1; i < buffer->num_planes; ++i) { + buffer->resources[i] = pipe->screen->resource_create(pipe->screen, &templ); + if (!buffer->resources[i]) + goto error; + } + + memset(&sv_templ, 0, sizeof(sv_templ)); + for (component = 0, i = 0; i < buffer->num_planes; ++i ) { + struct pipe_resource *res = buffer->resources[i]; + unsigned nr_components = util_format_get_nr_components(res->format); + + u_sampler_view_default_template(&sv_templ, res, res->format); + buffer->sampler_view_planes[i] = pipe->create_sampler_view(pipe, res, &sv_templ); + if (!buffer->sampler_view_planes[i]) + goto error; + + for (j = 0; j < nr_components; ++j, ++component) { + sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j; + sv_templ.swizzle_a = PIPE_SWIZZLE_ONE; + + buffer->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ); + if (!buffer->sampler_view_components[component]) + goto error; + } + } + + memset(&surf_templ, 0, sizeof(surf_templ)); + for (j = 0; j < buffer->num_planes; ++j) { + surf_templ.format = buffer->resources[j]->format; + surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 0; + buffer->surfaces[j * 2] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ); + if (!buffer->surfaces[j * 2]) + goto error; + + surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = 1; + buffer->surfaces[j * 2 + 1] = pipe->create_surface(pipe, buffer->resources[j], &surf_templ); + if (!buffer->surfaces[j * 2 + 1]) + goto error; + } + + return &buffer->base; + +error: + nouveau_vp3_video_buffer_destroy(&buffer->base); + return NULL; +} |