diff options
author | Christian König <[email protected]> | 2011-04-24 19:20:33 +0200 |
---|---|---|
committer | Christian König <[email protected]> | 2011-04-24 19:29:34 +0200 |
commit | 3ea7e2713c836f23d59c4034385609e371a94c8d (patch) | |
tree | 523a78de983e49e031a566873703f5db2edf3d2d | |
parent | b54909910c04313fb45c4e8f39091ad73ec329f3 (diff) |
[g3dvl] start supporting different render target formats
Let's start with NV12, but anything else shouldn't be much of a problem any more.
-rw-r--r-- | src/gallium/auxiliary/vl/vl_compositor.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vl_context.c | 35 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vl_mc.c | 95 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vl_mc.h | 14 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vl_mpeg12_decoder.c | 53 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vl_video_buffer.c | 73 | ||||
-rw-r--r-- | src/gallium/auxiliary/vl/vl_video_buffer.h | 3 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_video_context.h | 7 | ||||
-rw-r--r-- | src/gallium/state_trackers/vdpau/surface.c | 2 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xvmc/surface.c | 2 |
10 files changed, 181 insertions, 105 deletions
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 25f7d5fa1da..e487abf915e 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -506,7 +506,7 @@ vl_compositor_set_buffer_layer(struct pipe_video_compositor *compositor, c->used_layers |= 1 << layer; c->layers[layer].fs = c->fs_video_buffer; - sampler_views = buffer->get_sampler_views(buffer); + sampler_views = buffer->get_sampler_view_components(buffer); for (i = 0; i < 3; ++i) pipe_sampler_view_reference(&c->layers[layer].sampler_views[i], sampler_views[i]); diff --git a/src/gallium/auxiliary/vl/vl_context.c b/src/gallium/auxiliary/vl/vl_context.c index 1240b0b4c32..be28bb507e6 100644 --- a/src/gallium/auxiliary/vl/vl_context.c +++ b/src/gallium/auxiliary/vl/vl_context.c @@ -35,6 +35,18 @@ #include "vl_compositor.h" #include "vl_mpeg12_decoder.h" +const enum pipe_format const_resource_formats_YV12[3] = { + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8_UNORM +}; + +const enum pipe_format const_resource_formats_NV12[3] = { + PIPE_FORMAT_R8_UNORM, + PIPE_FORMAT_R8G8_UNORM, + PIPE_FORMAT_NONE +}; + static void vl_context_destroy(struct pipe_video_context *context) { @@ -202,19 +214,28 @@ vl_context_create_buffer(struct pipe_video_context *context, enum pipe_video_chroma_format chroma_format, unsigned width, unsigned height) { - const enum pipe_format resource_formats[3] = { - PIPE_FORMAT_R8_UNORM, - PIPE_FORMAT_R8_UNORM, - PIPE_FORMAT_R8_UNORM - }; - struct vl_context *ctx = (struct vl_context*)context; struct pipe_video_buffer *result; unsigned buffer_width, buffer_height; + const enum pipe_format *resource_formats; + assert(context); assert(width > 0 && height > 0); - assert(buffer_format == PIPE_FORMAT_YV12); + + switch(buffer_format) { + case PIPE_FORMAT_YV12: + resource_formats = const_resource_formats_YV12; + break; + + case PIPE_FORMAT_NV12: + resource_formats = const_resource_formats_NV12; + break; + + default: + assert(0); + return NULL; + } buffer_width = ctx->pot_buffers ? util_next_power_of_two(width) : width; buffer_height = ctx->pot_buffers ? util_next_power_of_two(height) : height; diff --git a/src/gallium/auxiliary/vl/vl_mc.c b/src/gallium/auxiliary/vl/vl_mc.c index 137a1beaa0d..ecdce6b28bd 100644 --- a/src/gallium/auxiliary/vl/vl_mc.c +++ b/src/gallium/auxiliary/vl/vl_mc.c @@ -368,6 +368,7 @@ init_pipe_state(struct vl_mc *r) struct pipe_sampler_state sampler; struct pipe_blend_state blend; struct pipe_rasterizer_state rs_state; + unsigned i; assert(r); @@ -391,28 +392,30 @@ init_pipe_state(struct vl_mc *r) if (!r->sampler_ycbcr) goto error_sampler_ycbcr; - memset(&blend, 0, sizeof blend); - blend.independent_blend_enable = 0; - blend.rt[0].blend_enable = 1; - blend.rt[0].rgb_func = PIPE_BLEND_ADD; - blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.rt[0].alpha_func = PIPE_BLEND_ADD; - blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.logicop_enable = 0; - blend.logicop_func = PIPE_LOGICOP_CLEAR; - blend.rt[0].colormask = PIPE_MASK_RGBA; - blend.dither = 0; - r->blend_clear = r->pipe->create_blend_state(r->pipe, &blend); - if (!r->blend_clear) - goto error_blend_clear; - - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - r->blend_add = r->pipe->create_blend_state(r->pipe, &blend); - if (!r->blend_add) - goto error_blend_add; + for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { + memset(&blend, 0, sizeof blend); + blend.independent_blend_enable = 0; + blend.rt[0].blend_enable = 1; + blend.rt[0].rgb_func = PIPE_BLEND_ADD; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_func = PIPE_BLEND_ADD; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.logicop_enable = 0; + blend.logicop_func = PIPE_LOGICOP_CLEAR; + blend.rt[0].colormask = i; + blend.dither = 0; + r->blend_clear[i] = r->pipe->create_blend_state(r->pipe, &blend); + if (!r->blend_clear[i]) + goto error_blend; + + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + r->blend_add[i] = r->pipe->create_blend_state(r->pipe, &blend); + if (!r->blend_add[i]) + goto error_blend; + } memset(&rs_state, 0, sizeof(rs_state)); /*rs_state.sprite_coord_enable */ @@ -427,12 +430,15 @@ init_pipe_state(struct vl_mc *r) return true; error_rs_state: - r->pipe->delete_blend_state(r->pipe, r->blend_add); +error_blend: + for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { + if (r->blend_add[i]) + r->pipe->delete_blend_state(r->pipe, r->blend_add[i]); -error_blend_add: - r->pipe->delete_blend_state(r->pipe, r->blend_clear); + if (r->blend_clear[i]) + r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]); + } -error_blend_clear: r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); error_sampler_ref: @@ -445,12 +451,16 @@ error_sampler_ycbcr: static void cleanup_pipe_state(struct vl_mc *r) { + unsigned i; + assert(r); r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); r->pipe->delete_sampler_state(r->pipe, r->sampler_ycbcr); - r->pipe->delete_blend_state(r->pipe, r->blend_clear); - r->pipe->delete_blend_state(r->pipe, r->blend_add); + for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { + r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]); + r->pipe->delete_blend_state(r->pipe, r->blend_add[i]); + } r->pipe->delete_rasterizer_state(r->pipe, r->rs_state); } @@ -520,11 +530,9 @@ vl_mc_cleanup(struct vl_mc *renderer) } bool -vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer, - struct pipe_sampler_view *source) +vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer) { assert(renderer && buffer); - assert(source); buffer->renderer = renderer; @@ -538,8 +546,6 @@ vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer, buffer->fb_state.nr_cbufs = 1; buffer->fb_state.zsbuf = NULL; - pipe_sampler_view_reference(&buffer->source, source); - return true; } @@ -547,8 +553,6 @@ void vl_mc_cleanup_buffer(struct vl_mc_buffer *buffer) { assert(buffer); - - pipe_sampler_view_reference(&buffer->source, NULL); } void @@ -567,7 +571,7 @@ vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface) } static void -prepare_pipe_4_rendering(struct vl_mc_buffer *buffer) +prepare_pipe_4_rendering(struct vl_mc_buffer *buffer, unsigned mask) { struct vl_mc *renderer; @@ -577,11 +581,9 @@ prepare_pipe_4_rendering(struct vl_mc_buffer *buffer) renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state); if (buffer->surface_cleared) - renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add); - else { - renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear); - buffer->surface_cleared = true; - } + renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add[mask]); + else + renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear[mask]); renderer->pipe->set_framebuffer_state(renderer->pipe, &buffer->fb_state); renderer->pipe->set_viewport_state(renderer->pipe, &buffer->viewport); @@ -594,7 +596,7 @@ vl_mc_render_ref(struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref) assert(buffer && ref); - prepare_pipe_4_rendering(buffer); + prepare_pipe_4_rendering(buffer, PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B); renderer = buffer->renderer; @@ -607,10 +609,13 @@ vl_mc_render_ref(struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref) util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, renderer->buffer_width / MACROBLOCK_WIDTH * renderer->buffer_height / MACROBLOCK_HEIGHT); + + buffer->surface_cleared = true; } void -vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, unsigned num_instances) +vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, struct pipe_sampler_view *source, + unsigned component, unsigned num_instances) { struct vl_mc *renderer; @@ -619,14 +624,14 @@ vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, unsigned num_instances) if (num_instances == 0) return; - prepare_pipe_4_rendering(buffer); + prepare_pipe_4_rendering(buffer, 1 << component); renderer = buffer->renderer; renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ycbcr); renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr); - renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &buffer->source); + renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &source); renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ycbcr); util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances); diff --git a/src/gallium/auxiliary/vl/vl_mc.h b/src/gallium/auxiliary/vl/vl_mc.h index bc2b0e7f149..353afa9df62 100644 --- a/src/gallium/auxiliary/vl/vl_mc.h +++ b/src/gallium/auxiliary/vl/vl_mc.h @@ -31,8 +31,11 @@ #include <pipe/p_state.h> #include <pipe/p_video_state.h> +#include "vl_defines.h" #include "vl_types.h" +#define VL_MC_NUM_BLENDERS (1 << VL_MAX_PLANES) + struct pipe_context; struct vl_mc @@ -44,7 +47,8 @@ struct vl_mc void *rs_state; - void *blend_clear, *blend_add; + void *blend_clear[VL_MC_NUM_BLENDERS]; + void *blend_add[VL_MC_NUM_BLENDERS]; void *vs_ref, *vs_ycbcr; void *fs_ref, *fs_ycbcr; void *sampler_ref, *sampler_ycbcr; @@ -58,8 +62,6 @@ struct vl_mc_buffer struct pipe_viewport_state viewport; struct pipe_framebuffer_state fb_state; - - struct pipe_sampler_view *source; }; bool vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, @@ -68,8 +70,7 @@ bool vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, void vl_mc_cleanup(struct vl_mc *renderer); -bool vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer, - struct pipe_sampler_view *source); +bool vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer); void vl_mc_cleanup_buffer(struct vl_mc_buffer *buffer); @@ -77,6 +78,7 @@ void vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface void vl_mc_render_ref(struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref); -void vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, unsigned num_instances); +void vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, struct pipe_sampler_view *source, + unsigned component, unsigned num_instances); #endif /* vl_mc_h */ diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c index 5027db4314e..296f46aba52 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c @@ -97,7 +97,7 @@ init_zscan_buffer(struct vl_mpeg12_buffer *buffer) if (!buffer->zscan_source) goto error_source; - source = buffer->zscan_source->get_sampler_views(buffer->zscan_source); + source = buffer->zscan_source->get_sampler_view_planes(buffer->zscan_source); if (!source) goto error_sampler; @@ -174,11 +174,11 @@ init_idct_buffer(struct vl_mpeg12_buffer *buffer) if (!buffer->idct_intermediate) goto error_intermediate; - idct_source_sv = buffer->idct_source->get_sampler_views(buffer->idct_source); + idct_source_sv = buffer->idct_source->get_sampler_view_planes(buffer->idct_source); if (!idct_source_sv) goto error_source_sv; - idct_intermediate_sv = buffer->idct_intermediate->get_sampler_views(buffer->idct_intermediate); + idct_intermediate_sv = buffer->idct_intermediate->get_sampler_view_planes(buffer->idct_intermediate); if (!idct_intermediate_sv) goto error_intermediate_sv; @@ -231,7 +231,6 @@ init_mc_buffer(struct vl_mpeg12_buffer *buf) { struct vl_mpeg12_decoder *dec; enum pipe_format formats[3]; - struct pipe_sampler_view **mc_source_sv; assert(buf); @@ -247,17 +246,13 @@ init_mc_buffer(struct vl_mpeg12_buffer *buf) if (!buf->mc_source) goto error_mc_source; - mc_source_sv = buf->mc_source->get_sampler_views(buf->mc_source); - if (!mc_source_sv) - goto error_mc_source_sv; - - if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0], mc_source_sv[0])) + if(!vl_mc_init_buffer(&dec->mc_y, &buf->mc[0])) goto error_mc_y; - if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1], mc_source_sv[1])) + if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[1])) goto error_mc_cb; - if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2], mc_source_sv[2])) + if(!vl_mc_init_buffer(&dec->mc_c, &buf->mc[2])) goto error_mc_cr; return true; @@ -269,7 +264,6 @@ error_mc_cb: vl_mc_cleanup_buffer(&buf->mc[0]); error_mc_y: -error_mc_source_sv: buf->mc_source->destroy(buf->mc_source); error_mc_source: @@ -328,7 +322,7 @@ vl_mpeg12_buffer_map(struct pipe_video_decode_buffer *buffer) vl_vb_map(&buf->vertex_stream, dec->pipe); - sampler_views = buf->zscan_source->get_sampler_views(buf->zscan_source); + sampler_views = buf->zscan_source->get_sampler_view_planes(buf->zscan_source); assert(sampler_views); @@ -510,12 +504,13 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer; struct vl_mpeg12_decoder *dec; - struct pipe_sampler_view **sv[2]; + struct pipe_sampler_view **sv[VL_MAX_REF_FRAMES], **mc_source_sv; struct pipe_surface **surfaces; struct pipe_vertex_buffer vb[3]; - unsigned i, j; + unsigned i, j, component; + unsigned nr_components; assert(buf); @@ -523,19 +518,21 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, assert(dec); for (i = 0; i < 2; ++i) - sv[i] = refs[i] ? refs[i]->get_sampler_views(refs[i]) : NULL; - - surfaces = dst->get_surfaces(dst); + sv[i] = refs[i] ? refs[i]->get_sampler_view_planes(refs[i]) : NULL; vb[0] = dec->quads; vb[1] = dec->pos; + surfaces = dst->get_surfaces(dst); + dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv); for (i = 0; i < VL_MAX_PLANES; ++i) { + if (!surfaces[i]) continue; + vl_mc_set_surface(&buf->mc[i], surfaces[i]); - for (j = 0; j < 2; ++j) { - if (sv[j] == NULL) continue; + for (j = 0; j < VL_MAX_REF_FRAMES; ++j) { + if (!sv[j]) continue; vb[2] = vl_vb_get_mv(&buf->vertex_stream, j);; dec->pipe->set_vertex_buffers(dec->pipe, 3, vb); @@ -546,7 +543,7 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_ycbcr); for (i = 0; i < VL_MAX_PLANES; ++i) { - if (num_ycbcr_blocks[i] == 0) continue; + if (!num_ycbcr_blocks[i]) continue; vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, i); dec->pipe->set_vertex_buffers(dec->pipe, 2, vb); @@ -555,8 +552,20 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer, if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], num_ycbcr_blocks[i]); + } + + mc_source_sv = buf->mc_source->get_sampler_view_planes(buf->mc_source); + for (i = 0, component = 0; i < VL_MAX_PLANES; ++i) { + if (!surfaces[i]) continue; - vl_mc_render_ycbcr(&buf->mc[i], num_ycbcr_blocks[i]); + nr_components = util_format_get_nr_components(surfaces[i]->texture->format); + for (j = 0; j < nr_components; ++j, ++component) { + if (!num_ycbcr_blocks[i]) continue; + + vb[1] = vl_vb_get_ycbcr(&buf->vertex_stream, component); + dec->pipe->set_vertex_buffers(dec->pipe, 2, vb); + vl_mc_render_ycbcr(&buf->mc[i], mc_source_sv[component], j, num_ycbcr_blocks[component]); + } } dec->pipe->flush(dec->pipe, fence); diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c index dad8dd2c9ae..dccd7e93945 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.c +++ b/src/gallium/auxiliary/vl/vl_video_buffer.c @@ -38,17 +38,6 @@ #include "vl_video_buffer.h" -static inline void -adjust_swizzle(struct pipe_sampler_view *sv_templ) -{ - if (util_format_get_nr_components(sv_templ->format) == 1) { - sv_templ->swizzle_r = PIPE_SWIZZLE_RED; - sv_templ->swizzle_g = PIPE_SWIZZLE_RED; - sv_templ->swizzle_b = PIPE_SWIZZLE_RED; - sv_templ->swizzle_a = PIPE_SWIZZLE_RED; - } -} - static void vl_video_buffer_destroy(struct pipe_video_buffer *buffer) { @@ -59,13 +48,14 @@ vl_video_buffer_destroy(struct pipe_video_buffer *buffer) for (i = 0; i < VL_MAX_PLANES; ++i) { pipe_surface_reference(&buf->surfaces[i], NULL); - pipe_sampler_view_reference(&buf->sampler_views[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); } } static struct pipe_sampler_view ** -vl_video_buffer_sampler_views(struct pipe_video_buffer *buffer) +vl_video_buffer_sampler_view_planes(struct pipe_video_buffer *buffer) { struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer; struct pipe_sampler_view sv_templ; @@ -77,21 +67,63 @@ vl_video_buffer_sampler_views(struct pipe_video_buffer *buffer) pipe = buf->pipe; for (i = 0; i < buf->num_planes; ++i ) { - if (!buf->sampler_views[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); - adjust_swizzle(&sv_templ); - buf->sampler_views[i] = pipe->create_sampler_view(pipe, buf->resources[i], &sv_templ); - if (!buf->sampler_views[i]) + + 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_views; + return buf->sampler_view_planes; error: for (i = 0; i < buf->num_planes; ++i ) - pipe_sampler_view_reference(&buf->sampler_views[i], NULL); + pipe_sampler_view_reference(&buf->sampler_view_planes[i], NULL); + + return NULL; +} + +static struct pipe_sampler_view ** +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; + unsigned i, j, component; + + assert(buf); + + pipe = buf->pipe; + + for (component = 0, i = 0; i < buf->num_planes; ++i ) { + unsigned nr_components = util_format_get_nr_components(buf->resources[i]->format); + + for (j = 0; j < nr_components; ++j, ++component) { + assert(component < VL_MAX_PLANES); + + if (!buf->sampler_view_components[component]) { + memset(&sv_templ, 0, sizeof(sv_templ)); + u_sampler_view_default_template(&sv_templ, buf->resources[i], buf->resources[i]->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, buf->resources[i], &sv_templ); + if (!buf->sampler_view_components[component]) + goto error; + } + } + } + + return buf->sampler_view_components; + +error: + for (i = 0; i < VL_MAX_PLANES; ++i ) + pipe_sampler_view_reference(&buf->sampler_view_components[i], NULL); return NULL; } @@ -145,7 +177,8 @@ vl_video_buffer_init(struct pipe_video_context *context, buffer = CALLOC_STRUCT(vl_video_buffer); buffer->base.destroy = vl_video_buffer_destroy; - buffer->base.get_sampler_views = vl_video_buffer_sampler_views; + buffer->base.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->pipe = pipe; 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 960acd28060..2dca74f641e 100644 --- a/src/gallium/auxiliary/vl/vl_video_buffer.h +++ b/src/gallium/auxiliary/vl/vl_video_buffer.h @@ -44,7 +44,8 @@ struct vl_video_buffer struct pipe_context *pipe; unsigned num_planes; struct pipe_resource *resources[VL_MAX_PLANES]; - struct pipe_sampler_view *sampler_views[VL_MAX_PLANES]; + struct pipe_sampler_view *sampler_view_planes[VL_MAX_PLANES]; + struct pipe_sampler_view *sampler_view_components[VL_MAX_PLANES]; struct pipe_surface *surfaces[VL_MAX_PLANES]; }; diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h index 7e971641618..88d3ca1f4e4 100644 --- a/src/gallium/include/pipe/p_video_context.h +++ b/src/gallium/include/pipe/p_video_context.h @@ -235,7 +235,12 @@ struct pipe_video_buffer /** * get a individual sampler view for each plane */ - struct pipe_sampler_view **(*get_sampler_views)(struct pipe_video_buffer *buffer); + 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); /** * get a individual surfaces for each plane diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c index cd2125fce63..c30cd07f434 100644 --- a/src/gallium/state_trackers/vdpau/surface.c +++ b/src/gallium/state_trackers/vdpau/surface.c @@ -176,7 +176,7 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface, return VDP_STATUS_NO_IMPLEMENTATION; } - sampler_views = p_surf->video_buffer->get_sampler_views(p_surf->video_buffer); + sampler_views = p_surf->video_buffer->get_sampler_view_planes(p_surf->video_buffer); if (!sampler_views) return VDP_STATUS_RESOURCES; diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index 7429fdfcfb9..cfa15e120d9 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -306,7 +306,7 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac surface_priv->decode_buffer = context_priv->decoder->create_buffer(context_priv->decoder); surface_priv->mv_stride = surface_priv->decode_buffer->get_mv_stream_stride(surface_priv->decode_buffer); - surface_priv->video_buffer = vpipe->create_buffer(vpipe, PIPE_FORMAT_YV12, //TODO + surface_priv->video_buffer = vpipe->create_buffer(vpipe, PIPE_FORMAT_NV12, context_priv->decoder->chroma_format, context_priv->decoder->width, context_priv->decoder->height); |