From 10c49b28752f5f2d822dfb1e2e6a1ec213cc44da Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Thu, 14 Apr 2011 22:31:40 +0200 Subject: [PATCH] [g3dvl] use blending for mc of ref frames --- src/gallium/auxiliary/vl/vl_mpeg12_decoder.c | 67 +++++---- src/gallium/auxiliary/vl/vl_mpeg12_decoder.h | 3 +- src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c | 177 ++++++++++------------- src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h | 30 ++-- src/gallium/auxiliary/vl/vl_types.h | 5 + src/gallium/auxiliary/vl/vl_vertex_buffers.c | 44 +++--- src/gallium/auxiliary/vl/vl_vertex_buffers.h | 10 +- 7 files changed, 171 insertions(+), 165 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c index 669d082..906be37 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c @@ -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) { diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h index 25048e8..c27197f 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h +++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h @@ -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; diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index 0ffb76c..dde7846 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -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->set_fragment_sampler_views(renderer->pipe, 1, &ref); + renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ref); - renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_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); - /* if no reference frame provided use a dummy sampler instead */ - if (!ref[0]) ref[0] = renderer->dummy; - if (!ref[1]) ref[1] = renderer->dummy; + if (empty_num_instances > 0) + util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, + empty_start_instance, empty_num_instances); +} - renderer->pipe->set_fragment_sampler_views(renderer->pipe, 2, ref); +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; - samplers[0] = samplers[1] = renderer->sampler_ref; - renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 2, samplers); + assert(buffer); - 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 (not_empty_num_instances == 0) + return; - if (empty_num_instances > 0) - util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, - empty_start_instance, empty_num_instances); + 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_blend_state(renderer->pipe, 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); - renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr); - - 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); + util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, + not_empty_start_instance, not_empty_num_instances); } diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h index f71bca5..3b5e61d 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h @@ -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 */ diff --git a/src/gallium/auxiliary/vl/vl_types.h b/src/gallium/auxiliary/vl/vl_types.h index a927e82..27bb69d 100644 --- a/src/gallium/auxiliary/vl/vl_types.h +++ b/src/gallium/auxiliary/vl/vl_types.h @@ -43,4 +43,9 @@ struct vertex4f float x, y, z, w; }; +struct vertex4s +{ + short x, y, z, w; +}; + #endif /* vl_types_h */ diff --git a/src/gallium/auxiliary/vl/vl_vertex_buffers.c b/src/gallium/auxiliary/vl/vl_vertex_buffers.c index c834042..4ec1905 100644 --- a/src/gallium/auxiliary/vl/vl_vertex_buffers.c +++ b/src/gallium/auxiliary/vl/vl_vertex_buffers.c @@ -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; - - /* motion vector 0 BOTTOM element */ - vertex_elems[VS_I_MV0_BOTTOM].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 1 TOP element */ - vertex_elems[VS_I_MV1_TOP].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 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); } diff --git a/src/gallium/auxiliary/vl/vl_vertex_buffers.h b/src/gallium/auxiliary/vl/vl_vertex_buffers.h index 58b8418..6cbda7c 100644 --- a/src/gallium/auxiliary/vl/vl_vertex_buffers.h +++ b/src/gallium/auxiliary/vl/vl_vertex_buffers.h @@ -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, -- 2.7.4