[g3dvl] use blending for mc of ref frames

This commit is contained in:
Christian König 2011-04-14 22:31:40 +02:00
parent e61a63a651
commit 10c49b2875
7 changed files with 177 additions and 171 deletions

View file

@ -193,6 +193,8 @@ vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer)
{
struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
struct vl_mpeg12_decoder *dec;
unsigned i;
assert(buf);
dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
@ -203,9 +205,8 @@ vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer)
buf->mc_source->destroy(buf->mc_source);
vl_vb_cleanup(&buf->vertex_stream);
vl_mpeg12_mc_cleanup_buffer(&buf->mc[0]);
vl_mpeg12_mc_cleanup_buffer(&buf->mc[1]);
vl_mpeg12_mc_cleanup_buffer(&buf->mc[2]);
for (i = 0; i < VL_MAX_PLANES; ++i)
vl_mc_cleanup_buffer(&buf->mc[i]);
FREE(buf);
}
@ -267,6 +268,7 @@ static void
vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
{
struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
unsigned i;
assert(decoder);
@ -277,14 +279,17 @@ vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
dec->pipe->delete_blend_state(dec->pipe, dec->blend);
dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa);
vl_mpeg12_mc_renderer_cleanup(&dec->mc);
vl_mc_cleanup(&dec->mc);
if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
vl_idct_cleanup(&dec->idct_y);
vl_idct_cleanup(&dec->idct_c);
}
dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[0]);
dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[1]);
dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[2]);
for (i = 0; i < VL_MAX_PLANES; ++i)
dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_eb[i]);
for (i = 0; i < 2; ++i)
dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv[i]);
pipe_resource_reference(&dec->quads.buffer, NULL);
FREE(dec);
@ -409,22 +414,22 @@ vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
if (!mc_source_sv)
goto error_mc_source_sv;
if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[0], mc_source_sv[0]))
if(!vl_mc_init_buffer(&dec->mc, &buffer->mc[0], mc_source_sv[0]))
goto error_mc_y;
if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[1], mc_source_sv[1]))
if(!vl_mc_init_buffer(&dec->mc, &buffer->mc[1], mc_source_sv[1]))
goto error_mc_cb;
if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[2], mc_source_sv[2]))
if(!vl_mc_init_buffer(&dec->mc, &buffer->mc[2], mc_source_sv[2]))
goto error_mc_cr;
return &buffer->base;
error_mc_cr:
vl_mpeg12_mc_cleanup_buffer(&buffer->mc[1]);
vl_mc_cleanup_buffer(&buffer->mc[1]);
error_mc_cb:
vl_mpeg12_mc_cleanup_buffer(&buffer->mc[0]);
vl_mc_cleanup_buffer(&buffer->mc[0]);
error_mc_y:
error_mc_source_sv:
@ -451,20 +456,19 @@ 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_past;
struct pipe_sampler_view **sv_future;
struct pipe_sampler_view **sv[2];
struct pipe_surface **surfaces;
unsigned ne_start, ne_num, e_start, e_num;
unsigned i;
unsigned i, j;
assert(buf);
dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
assert(dec);
sv_past = refs[0] ? refs[0]->get_sampler_views(refs[0]) : NULL;
sv_future = refs[1] ? refs[1]->get_sampler_views(refs[1]) : NULL;
for (i = 0; i < 2; ++i)
sv[i] = refs[i] ? refs[i]->get_sampler_views(refs[i]) : NULL;
surfaces = dst->get_surfaces(dst);
@ -473,20 +477,28 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
dec->pipe->set_vertex_buffers(dec->pipe, 2, buf->vertex_bufs.all);
for (i = 0; i < VL_MAX_PLANES; ++i) {
struct pipe_sampler_view *sv_refs[2];
bool first = true;
vl_mc_set_surface(&dec->mc, surfaces[i]);
for (j = 0; j < 2; ++j) {
if (sv[j] == NULL) continue;
dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv[j]);
vl_mc_render_ref(&buf->mc[i], sv[j][i], first, ne_start, ne_num, e_start, e_num);
first = false;
}
dec->pipe->bind_blend_state(dec->pipe, dec->blend);
dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves[i]);
dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_eb[i]);
if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], ne_num);
sv_refs[0] = sv_past ? sv_past[i] : NULL;
sv_refs[1] = sv_future ? sv_future[i] : NULL;
vl_mc_render_ycbcr(&buf->mc[i], first, ne_start, ne_num);
vl_mpeg12_mc_renderer_flush(&dec->mc, &buf->mc[i], surfaces[i], sv_refs,
ne_start, ne_num, e_start, e_num, fence);
}
dec->pipe->flush(dec->pipe, fence);
}
static void
@ -703,7 +715,10 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
dec->quads = vl_vb_upload_quads(dec->pipe, 2, 2);
for (i = 0; i < VL_MAX_PLANES; ++i)
dec->ves[i] = vl_vb_get_elems_state(dec->pipe, i);
dec->ves_eb[i] = vl_vb_get_elems_state(dec->pipe, i, 0);
for (i = 0; i < 2; ++i)
dec->ves_mv[i] = vl_vb_get_elems_state(dec->pipe, 0, i);
dec->base.width = align(width, MACROBLOCK_WIDTH);
dec->base.height = align(height, MACROBLOCK_HEIGHT);
@ -741,7 +756,7 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
}
}
if (!vl_mpeg12_mc_renderer_init(&dec->mc, dec->pipe, dec->base.width, dec->base.height, mc_scale))
if (!vl_mc_init(&dec->mc, dec->pipe, dec->base.width, dec->base.height, mc_scale))
goto error_mc;
if (!init_pipe_state(dec))
@ -750,7 +765,7 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
return &dec->base;
error_pipe_state:
vl_mpeg12_mc_renderer_cleanup(&dec->mc);
vl_mc_cleanup(&dec->mc);
error_mc:
if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {

View file

@ -52,7 +52,8 @@ struct vl_mpeg12_decoder
enum pipe_format mc_source_format;
struct pipe_vertex_buffer quads;
void *ves[VL_MAX_PLANES];
void *ves_eb[VL_MAX_PLANES];
void *ves_mv[2];
struct vl_idct idct_y, idct_c;
struct vl_mpeg12_mc_renderer mc;

View file

@ -44,10 +44,8 @@ enum VS_OUTPUT
VS_O_LINE,
VS_O_TEX_TOP,
VS_O_TEX_BOTTOM,
VS_O_MV0_TOP,
VS_O_MV0_BOTTOM,
VS_O_MV1_TOP,
VS_O_MV1_BOTTOM
VS_O_MV_TOP,
VS_O_MV_BOTTOM
};
static void *
@ -55,10 +53,10 @@ create_vert_shader(struct vl_mpeg12_mc_renderer *r)
{
struct ureg_program *shader;
struct ureg_src block_scale, mv_scale;
struct ureg_src vrect, vpos, eb, flags, vmv[2][2];
struct ureg_src vrect, vpos, eb, flags, vmv[2];
struct ureg_dst t_vpos, t_vtex, t_vmv;
struct ureg_dst o_vpos, o_line, o_vtex[2], o_vmv[2][2];
unsigned i, j, label;
struct ureg_dst o_vpos, o_line, o_vtex[2], o_vmv[2];
unsigned i, label;
shader = ureg_create(TGSI_PROCESSOR_VERTEX);
if (!shader)
@ -72,19 +70,15 @@ create_vert_shader(struct vl_mpeg12_mc_renderer *r)
vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
eb = ureg_DECL_vs_input(shader, VS_I_EB);
flags = ureg_DECL_vs_input(shader, VS_I_FLAGS);
vmv[0][0] = ureg_DECL_vs_input(shader, VS_I_MV0_TOP);
vmv[0][1] = ureg_DECL_vs_input(shader, VS_I_MV0_BOTTOM);
vmv[1][0] = ureg_DECL_vs_input(shader, VS_I_MV1_TOP);
vmv[1][1] = ureg_DECL_vs_input(shader, VS_I_MV1_BOTTOM);
vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP);
vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM);
o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE);
o_vtex[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX_TOP);
o_vtex[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX_BOTTOM);
o_vmv[0][0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_TOP);
o_vmv[0][1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_BOTTOM);
o_vmv[1][0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_TOP);
o_vmv[1][1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_BOTTOM);
o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_TOP);
o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_BOTTOM);
/*
* block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height)
@ -125,20 +119,21 @@ create_vert_shader(struct vl_mpeg12_mc_renderer *r)
(float)MACROBLOCK_WIDTH / r->buffer_width,
(float)MACROBLOCK_HEIGHT / r->buffer_height);
mv_scale = ureg_imm2f(shader,
mv_scale = ureg_imm4f(shader,
0.5f / r->buffer_width,
0.5f / r->buffer_height);
0.5f / r->buffer_height,
1.0f,
1.0f / 255.0f);
ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect);
ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale);
ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos));
ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
for (i = 0; i < 2; ++i)
for (j = 0; j < 2; ++j) {
ureg_MAD(shader, ureg_writemask(o_vmv[i][j], TGSI_WRITEMASK_XY), mv_scale, vmv[i][j], ureg_src(t_vpos));
ureg_MOV(shader, ureg_writemask(o_vmv[i][j], TGSI_WRITEMASK_Z), ureg_scalar(flags, TGSI_SWIZZLE_Z + i));
}
for (i = 0; i < 2; ++i) {
ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos));
ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_W), mv_scale, vmv[i]);
}
ureg_MOV(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
ureg_CMP(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_Z),
@ -274,24 +269,19 @@ static void *
create_ref_frag_shader(struct vl_mpeg12_mc_renderer *r)
{
struct ureg_program *shader;
struct ureg_src tc[2][2], sampler[2];
struct ureg_dst ref[2], field;
struct ureg_src tc[2], sampler;
struct ureg_dst ref, field;
struct ureg_dst fragment;
unsigned i;
shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
if (!shader)
return NULL;
tc[0][0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_TOP, TGSI_INTERPOLATE_LINEAR);
tc[0][1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_BOTTOM, TGSI_INTERPOLATE_LINEAR);
tc[1][0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_TOP, TGSI_INTERPOLATE_LINEAR);
tc[1][1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_BOTTOM, TGSI_INTERPOLATE_LINEAR);
tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_TOP, TGSI_INTERPOLATE_LINEAR);
tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_BOTTOM, TGSI_INTERPOLATE_LINEAR);
for (i = 0; i < 2; ++i) {
sampler[i] = ureg_DECL_sampler(shader, i);
ref[i] = ureg_DECL_temporary(shader);
}
sampler = ureg_DECL_sampler(shader, 0);
ref = ureg_DECL_temporary(shader);
fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
@ -304,29 +294,12 @@ create_ref_frag_shader(struct vl_mpeg12_mc_renderer *r)
* ref[0..1] = tex(tc[2..3], sampler[0..1])
* result = LRP(info.y, ref[0..1])
*/
ureg_CMP(shader, ureg_writemask(ref[0], TGSI_WRITEMASK_XY),
ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
tc[0][1], tc[0][0]);
ureg_CMP(shader, ureg_writemask(ref[1], TGSI_WRITEMASK_XY),
ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
tc[1][1], tc[1][0]);
ureg_CMP(shader, ref, ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), tc[1], tc[0]);
ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[0]);
ureg_TEX(shader, ref[1], TGSI_TEXTURE_2D, ureg_src(ref[1]), sampler[1]);
ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(ref));
ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler);
ureg_LRP(shader, ref[0],
ureg_scalar(tc[0][0], TGSI_SWIZZLE_Z),
ureg_src(ref[0]), ureg_imm1f(shader, 0.0f));
ureg_LRP(shader, ref[1],
ureg_scalar(tc[1][0], TGSI_SWIZZLE_Z),
ureg_src(ref[1]), ureg_imm1f(shader, 0.0f));
ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(ref[0]), ureg_src(ref[1]));
ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
for (i = 0; i < 2; ++i)
ureg_release_temporary(shader, ref[i]);
ureg_release_temporary(shader, ref);
ureg_release_temporary(shader, field);
ureg_END(shader);
@ -435,11 +408,8 @@ cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
}
bool
vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
struct pipe_context *pipe,
unsigned buffer_width,
unsigned buffer_height,
float scale)
vl_mc_init(struct vl_mpeg12_mc_renderer *renderer, struct pipe_context *pipe,
unsigned buffer_width, unsigned buffer_height, float scale)
{
struct pipe_resource tex_templ, *tex_dummy;
struct pipe_sampler_view sampler_view;
@ -511,7 +481,7 @@ error_pipe_state:
}
void
vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
vl_mc_cleanup(struct vl_mpeg12_mc_renderer *renderer)
{
assert(renderer);
@ -525,19 +495,21 @@ vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
}
bool
vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
struct pipe_sampler_view *source)
vl_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
struct pipe_sampler_view *source)
{
assert(renderer && buffer);
assert(source);
buffer->renderer = renderer;
pipe_sampler_view_reference(&buffer->source, source);
return true;
}
void
vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer)
vl_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer)
{
assert(buffer);
@ -545,17 +517,9 @@ vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer)
}
void
vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
struct pipe_surface *surface, struct pipe_sampler_view *ref[2],
unsigned not_empty_start_instance, unsigned not_empty_num_instances,
unsigned empty_start_instance, unsigned empty_num_instances,
struct pipe_fence_handle **fence)
vl_mc_set_surface(struct vl_mpeg12_mc_renderer *renderer, struct pipe_surface *surface)
{
assert(renderer && buffer);
assert(surface && ref);
if (not_empty_num_instances == 0 && empty_num_instances == 0)
return;
assert(renderer && surface);
renderer->viewport.scale[0] = surface->width;
renderer->viewport.scale[1] = surface->height;
@ -563,46 +527,65 @@ vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mp
renderer->fb_state.width = surface->width;
renderer->fb_state.height = surface->height;
renderer->fb_state.cbufs[0] = surface;
}
void
vl_mc_render_ref(struct vl_mpeg12_mc_buffer *buffer,
struct pipe_sampler_view *ref, bool first,
unsigned not_empty_start_instance, unsigned not_empty_num_instances,
unsigned empty_start_instance, unsigned empty_num_instances)
{
struct vl_mpeg12_mc_renderer *renderer;
assert(buffer && ref);
if (not_empty_num_instances == 0 && empty_num_instances == 0)
return;
renderer = buffer->renderer;
renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
renderer->pipe->set_viewport_state(renderer->pipe, &renderer->viewport);
renderer->pipe->bind_blend_state(renderer->pipe, first ? renderer->blend_clear : renderer->blend_add);
renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs);
renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref);
renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear);
if (ref[0] || ref[1]) {
void *samplers[2];
renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref);
/* if no reference frame provided use a dummy sampler instead */
if (!ref[0]) ref[0] = renderer->dummy;
if (!ref[1]) ref[1] = renderer->dummy;
renderer->pipe->set_fragment_sampler_views(renderer->pipe, 2, ref);
samplers[0] = samplers[1] = renderer->sampler_ref;
renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 2, samplers);
if (not_empty_num_instances > 0)
util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
not_empty_start_instance, not_empty_num_instances);
if (empty_num_instances > 0)
util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
empty_start_instance, empty_num_instances);
renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add);
}
renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &buffer->source);
renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ycbcr);
renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr);
renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &ref);
renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ref);
if (not_empty_num_instances > 0)
util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
not_empty_start_instance, not_empty_num_instances);
renderer->pipe->flush(renderer->pipe, fence);
if (empty_num_instances > 0)
util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
empty_start_instance, empty_num_instances);
}
void
vl_mc_render_ycbcr(struct vl_mpeg12_mc_buffer *buffer, bool first,
unsigned not_empty_start_instance, unsigned not_empty_num_instances)
{
struct vl_mpeg12_mc_renderer *renderer;
assert(buffer);
if (not_empty_num_instances == 0)
return;
renderer = buffer->renderer;
renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
renderer->pipe->set_viewport_state(renderer->pipe, &renderer->viewport);
renderer->pipe->bind_blend_state(renderer->pipe, first ? renderer->blend_clear : renderer->blend_add);
renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs);
renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr);
renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &buffer->source);
renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ycbcr);
util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
not_empty_start_instance, not_empty_num_instances);
}

View file

@ -55,26 +55,28 @@ struct vl_mpeg12_mc_renderer
struct vl_mpeg12_mc_buffer
{
struct vl_mpeg12_mc_renderer *renderer;
struct pipe_sampler_view *source;
};
bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
struct pipe_context *pipe,
unsigned picture_width,
unsigned picture_height,
float scale);
bool vl_mc_init(struct vl_mpeg12_mc_renderer *renderer, struct pipe_context *pipe,
unsigned picture_width, unsigned picture_height, float scale);
void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
void vl_mc_cleanup(struct vl_mpeg12_mc_renderer *renderer);
bool vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
struct pipe_sampler_view *source);
bool vl_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
struct pipe_sampler_view *source);
void vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer);
void vl_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer);
void vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
struct pipe_surface *surface, struct pipe_sampler_view *ref[2],
unsigned not_empty_start_instance, unsigned not_empty_num_instances,
unsigned empty_start_instance, unsigned empty_num_instances,
struct pipe_fence_handle **fence);
void vl_mc_set_surface(struct vl_mpeg12_mc_renderer *renderer, struct pipe_surface *surface);
void vl_mc_render_ref(struct vl_mpeg12_mc_buffer *buffer,
struct pipe_sampler_view *ref, bool first,
unsigned not_empty_start_instance, unsigned not_empty_num_instances,
unsigned empty_start_instance, unsigned empty_num_instances);
void vl_mc_render_ycbcr(struct vl_mpeg12_mc_buffer *buffer, bool first,
unsigned not_empty_start_instance, unsigned not_empty_num_instances);
#endif /* vl_mpeg12_mc_renderer_h */

View file

@ -43,4 +43,9 @@ struct vertex4f
float x, y, z, w;
};
struct vertex4s
{
short x, y, z, w;
};
#endif /* vl_types_h */

View file

@ -33,11 +33,11 @@
struct vl_vertex_stream
{
struct vertex2s pos;
uint8_t eb[3][2][2];
uint8_t dct_type_field;
uint8_t mb_type_intra;
uint8_t mv_wheights[2];
struct vertex2s mv[4];
uint8_t dummy[2];
uint8_t eb[3][2][2];
struct vertex4s mv[4];
};
/* vertices for a quad covering a block */
@ -130,7 +130,7 @@ vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements
}
void *
vl_vb_get_elems_state(struct pipe_context *pipe, int component)
vl_vb_get_elems_state(struct pipe_context *pipe, int component, int motionvector)
{
struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
@ -140,25 +140,19 @@ vl_vb_get_elems_state(struct pipe_context *pipe, int component)
/* Position element */
vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED;
/* empty block element of selected component */
vertex_elems[VS_I_EB].src_offset = 4 + component * 4;
vertex_elems[VS_I_EB].src_format = PIPE_FORMAT_R8G8B8A8_USCALED;
/* flags */
vertex_elems[VS_I_FLAGS].src_offset = 16;
vertex_elems[VS_I_FLAGS].src_format = PIPE_FORMAT_R8G8B8A8_UNORM;
/* motion vector 0 TOP element */
vertex_elems[VS_I_MV0_TOP].src_format = PIPE_FORMAT_R16G16_SSCALED;
/* empty block element of selected component */
vertex_elems[VS_I_EB].src_offset = 8 + component * 4;
vertex_elems[VS_I_EB].src_format = PIPE_FORMAT_R8G8B8A8_USCALED;
/* motion vector 0 BOTTOM element */
vertex_elems[VS_I_MV0_BOTTOM].src_format = PIPE_FORMAT_R16G16_SSCALED;
/* motion vector TOP element */
vertex_elems[VS_I_MV_TOP].src_offset = 20 + motionvector * 16;
vertex_elems[VS_I_MV_TOP].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED;
/* motion vector 1 TOP element */
vertex_elems[VS_I_MV1_TOP].src_format = PIPE_FORMAT_R16G16_SSCALED;
/* motion vector 1 BOTTOM element */
vertex_elems[VS_I_MV1_BOTTOM].src_format = PIPE_FORMAT_R16G16_SSCALED;
/* motion vector BOTTOM element */
vertex_elems[VS_I_MV_BOTTOM].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED;
vl_vb_element_helper(&vertex_elems[VS_I_VPOS], NUM_VS_INPUTS - 1, 1);
@ -209,33 +203,43 @@ vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
}
static void
get_motion_vectors(struct pipe_mpeg12_macroblock *mb, struct vertex2s mv[4])
get_motion_vectors(struct pipe_mpeg12_macroblock *mb, struct vertex4s mv[4])
{
if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
mv[0].x = mv[1].x = mb->mv[0].top.x;
mv[0].y = mv[1].y = mb->mv[0].top.y;
mv[0].z = 0; mv[1].z = 1;
mv[2].x = mv[3].x = mb->mv[1].top.x;
mv[2].y = mv[3].y = mb->mv[1].top.y;
mv[2].z = 0; mv[3].z = 1;
} else {
mv[0].x = mb->mv[0].top.x;
mv[0].y = mb->mv[0].top.y - (mb->mv[0].top.y % 4);
mv[0].z = mb->mv[0].top.field_select;
mv[1].x = mb->mv[0].bottom.x;
mv[1].y = mb->mv[0].bottom.y - (mb->mv[0].bottom.y % 4);
mv[1].z = mb->mv[0].bottom.field_select;
if (mb->mv[0].top.field_select) mv[0].y += 2;
if (!mb->mv[0].bottom.field_select) mv[1].y -= 2;
mv[2].x = mb->mv[1].top.x;
mv[2].y = mb->mv[1].top.y - (mb->mv[1].top.y % 4);
mv[2].z = mb->mv[1].top.field_select;
mv[3].x = mb->mv[1].bottom.x;
mv[3].y = mb->mv[1].bottom.y - (mb->mv[1].bottom.y % 4);
mv[3].z = mb->mv[1].bottom.field_select;
if (mb->mv[1].top.field_select) mv[2].y += 2;
if (!mb->mv[1].bottom.field_select) mv[3].y -= 2;
}
mv[0].w = mv[1].w = mb->mv[0].wheight;
mv[2].w = mv[3].w = mb->mv[1].wheight;
}
void
@ -265,8 +269,6 @@ vl_vb_add_block(struct vl_vertex_buffer *buffer, struct pipe_mpeg12_macroblock *
stream->dct_type_field = mb->dct_type == PIPE_MPEG12_DCT_TYPE_FIELD;
stream->mb_type_intra = !mb->dct_intra;
stream->mv_wheights[0] = mb->mv[0].wheight;
stream->mv_wheights[1] = mb->mv[1].wheight;
get_motion_vectors(mb, stream->mv);
}

View file

@ -42,12 +42,10 @@ enum VS_INPUT
{
VS_I_RECT,
VS_I_VPOS,
VS_I_EB,
VS_I_FLAGS,
VS_I_MV0_TOP,
VS_I_MV0_BOTTOM,
VS_I_MV1_TOP,
VS_I_MV1_BOTTOM,
VS_I_EB,
VS_I_MV_TOP,
VS_I_MV_BOTTOM,
NUM_VS_INPUTS
};
@ -66,7 +64,7 @@ struct vl_vertex_buffer
struct pipe_vertex_buffer vl_vb_upload_quads(struct pipe_context *pipe,
unsigned blocks_x, unsigned blocks_y);
void *vl_vb_get_elems_state(struct pipe_context *pipe, int component);
void *vl_vb_get_elems_state(struct pipe_context *pipe, int component, int motionvector);
struct pipe_vertex_buffer vl_vb_init(struct vl_vertex_buffer *buffer,
struct pipe_context *pipe,