summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/vl
diff options
context:
space:
mode:
authorChristian König <[email protected]>2012-03-03 14:05:54 +0100
committerChristian König <[email protected]>2012-03-09 12:44:04 +0100
commit7236f170e431b18518337f3af12ddde5014721f6 (patch)
tree69c3e494c2c6946477e239e15ac3377fa674473b /src/gallium/auxiliary/vl
parentfb016854bc4327151e9eee3b7b08d0499976631a (diff)
vl/video_buffer: add YUYV and UYVY support
This gets xine working with VDPAU. v2: some minor bugfixes. v3: create the resource with the subsampled format to avoid tilling problems Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/vl')
-rw-r--r--src/gallium/auxiliary/vl/vl_video_buffer.c75
1 files changed, 59 insertions, 16 deletions
diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c
index df21769a5d9..82d7386e644 100644
--- a/src/gallium/auxiliary/vl/vl_video_buffer.c
+++ b/src/gallium/auxiliary/vl/vl_video_buffer.c
@@ -62,6 +62,18 @@ const enum pipe_format const_resource_formats_VUYA[3] = {
PIPE_FORMAT_NONE
};
+const enum pipe_format const_resource_formats_YUYV[3] = {
+ PIPE_FORMAT_R8G8_R8B8_UNORM,
+ PIPE_FORMAT_NONE,
+ PIPE_FORMAT_NONE
+};
+
+const enum pipe_format const_resource_formats_UYVY[3] = {
+ PIPE_FORMAT_G8R8_B8R8_UNORM,
+ PIPE_FORMAT_NONE,
+ PIPE_FORMAT_NONE
+};
+
const unsigned const_resource_plane_order_YUV[3] = {
0,
1,
@@ -90,6 +102,12 @@ vl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
case PIPE_FORMAT_B8G8R8A8_UNORM:
return const_resource_formats_VUYA;
+ case PIPE_FORMAT_YUYV:
+ return const_resource_formats_YUYV;
+
+ case PIPE_FORMAT_UYVY:
+ return const_resource_formats_UYVY;
+
default:
return NULL;
}
@@ -98,13 +116,15 @@ vl_video_buffer_formats(struct pipe_screen *screen, enum pipe_format format)
const unsigned *
vl_video_buffer_plane_order(enum pipe_format format)
{
- switch(format) {
+ switch(format) {
case PIPE_FORMAT_YV12:
return const_resource_plane_order_YVU;
case PIPE_FORMAT_NV12:
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_YUYV:
+ case PIPE_FORMAT_UYVY:
return const_resource_plane_order_YUV;
default:
@@ -112,6 +132,18 @@ vl_video_buffer_plane_order(enum pipe_format format)
}
}
+static enum pipe_format
+vl_video_buffer_surface_format(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ /* a subsampled formats can't work as surface use RGBA instead */
+ if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
+ return PIPE_FORMAT_R8G8B8A8_UNORM;
+
+ return format;
+}
+
boolean
vl_video_buffer_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
@@ -125,10 +157,17 @@ vl_video_buffer_is_format_supported(struct pipe_screen *screen,
return false;
for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
- if (!resource_formats[i])
+ enum pipe_format format = resource_formats[i];
+
+ if (format == PIPE_FORMAT_NONE)
continue;
- if (!screen->is_format_supported(screen, resource_formats[i], PIPE_TEXTURE_2D, 0, PIPE_USAGE_STATIC))
+ /* we at least need to sample from it */
+ if (!screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW))
+ return false;
+
+ format = vl_video_buffer_surface_format(format);
+ if (!screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET))
return false;
}
@@ -262,6 +301,7 @@ vl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
struct pipe_sampler_view sv_templ;
struct pipe_context *pipe;
+ const enum pipe_format *sampler_format;
const unsigned *plane_order;
unsigned i, j, component;
@@ -269,26 +309,30 @@ vl_video_buffer_sampler_view_components(struct pipe_video_buffer *buffer)
pipe = buf->base.context;
+ sampler_format = vl_video_buffer_formats(pipe->screen, buf->base.buffer_format);
plane_order = vl_video_buffer_plane_order(buf->base.buffer_format);
for (component = 0, i = 0; i < buf->num_planes; ++i ) {
struct pipe_resource *res = buf->resources[plane_order[i]];
+ const struct util_format_description *desc = util_format_description(res->format);
unsigned nr_components = util_format_get_nr_components(res->format);
+ if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED)
+ nr_components = 3;
- for (j = 0; j < nr_components; ++j, ++component) {
- assert(component < VL_NUM_COMPONENTS);
+ for (j = 0; j < nr_components && component < VL_NUM_COMPONENTS; ++j, ++component) {
+ if (buf->sampler_view_components[component])
+ continue;
- if (!buf->sampler_view_components[component]) {
- memset(&sv_templ, 0, sizeof(sv_templ));
- u_sampler_view_default_template(&sv_templ, res, res->format);
- sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
- sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
- buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
- if (!buf->sampler_view_components[component])
- goto error;
- }
+ memset(&sv_templ, 0, sizeof(sv_templ));
+ u_sampler_view_default_template(&sv_templ, res, sampler_format[plane_order[i]]);
+ sv_templ.swizzle_r = sv_templ.swizzle_g = sv_templ.swizzle_b = PIPE_SWIZZLE_RED + j;
+ sv_templ.swizzle_a = PIPE_SWIZZLE_ONE;
+ buf->sampler_view_components[component] = pipe->create_sampler_view(pipe, res, &sv_templ);
+ if (!buf->sampler_view_components[component])
+ goto error;
}
}
+ assert(component == VL_NUM_COMPONENTS);
return buf->sampler_view_components;
@@ -323,7 +367,7 @@ vl_video_buffer_surfaces(struct pipe_video_buffer *buffer)
if (!buf->surfaces[surf]) {
memset(&surf_templ, 0, sizeof(surf_templ));
- surf_templ.format = buf->resources[j]->format;
+ surf_templ.format = vl_video_buffer_surface_format(buf->resources[j]->format);
surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
surf_templ.u.tex.first_layer = surf_templ.u.tex.last_layer = i;
buf->surfaces[surf] = pipe->create_surface(pipe, buf->resources[j], &surf_templ);
@@ -406,7 +450,6 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
goto error;
if (resource_formats[1] == PIPE_FORMAT_NONE) {
- assert(tmpl->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444);
assert(resource_formats[2] == PIPE_FORMAT_NONE);
return vl_video_buffer_create_ex2(pipe, tmpl, resources);
}