X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fvl%2Fvl_mc.c;h=4877f5ee6c7f57082b9fc18c1d54c54395a78059;hb=a15cbabb8b546fa063cfb6f528dd67ee0037079b;hp=7474c58250d19cf1b7be87b3ba1ee8761da6c991;hpb=213b9004a6ee033a16af3dcd187aa68b56c39858;p=mesa.git diff --git a/src/gallium/auxiliary/vl/vl_mc.c b/src/gallium/auxiliary/vl/vl_mc.c index 7474c58250d..4877f5ee6c7 100644 --- a/src/gallium/auxiliary/vl/vl_mc.c +++ b/src/gallium/auxiliary/vl/vl_mc.c @@ -27,12 +27,12 @@ #include -#include +#include "pipe/p_context.h" -#include -#include +#include "util/u_sampler.h" +#include "util/u_draw.h" -#include +#include "tgsi/tgsi_ureg.h" #include "vl_defines.h" #include "vl_vertex_buffers.h" @@ -41,8 +41,8 @@ enum VS_OUTPUT { - VS_O_VPOS, - VS_O_VTOP, + VS_O_VPOS = 0, + VS_O_VTOP = 0, VS_O_VBOTTOM, VS_O_FLAGS = VS_O_VTOP, @@ -64,7 +64,7 @@ calc_position(struct vl_mc *r, struct ureg_program *shader, struct ureg_src bloc o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); /* - * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height) + * block_scale = (VL_MACROBLOCK_WIDTH, VL_MACROBLOCK_HEIGHT) / (dst.width, dst.height) * * t_vpos = (vpos + vrect) * block_scale * o_vpos.xy = t_vpos @@ -103,25 +103,23 @@ create_ref_vert_shader(struct vl_mc *r) { struct ureg_program *shader; struct ureg_src mv_scale; - struct ureg_src vrect, vmv[2]; + struct ureg_src vmv[2]; struct ureg_dst t_vpos; - struct ureg_dst o_vpos, o_vmv[2]; + struct ureg_dst o_vmv[2]; unsigned i; shader = ureg_create(TGSI_PROCESSOR_VERTEX); if (!shader) return NULL; - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP); vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM); t_vpos = calc_position(r, shader, ureg_imm2f(shader, - (float)MACROBLOCK_WIDTH / r->buffer_width, - (float)MACROBLOCK_HEIGHT / r->buffer_height) + (float)VL_MACROBLOCK_WIDTH / r->buffer_width, + (float)VL_MACROBLOCK_HEIGHT / r->buffer_height) ); - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); @@ -159,7 +157,7 @@ create_ref_frag_shader(struct vl_mc *r) { const float y_scale = r->buffer_height / 2 * - r->macroblock_size / MACROBLOCK_HEIGHT; + r->macroblock_size / VL_MACROBLOCK_HEIGHT; struct ureg_program *shader; struct ureg_src tc[2], sampler; @@ -233,8 +231,8 @@ create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, v struct ureg_dst o_vpos, o_flags; struct vertex2f scale = { - (float)BLOCK_WIDTH / r->buffer_width * MACROBLOCK_WIDTH / r->macroblock_size, - (float)BLOCK_HEIGHT / r->buffer_height * MACROBLOCK_HEIGHT / r->macroblock_size + (float)VL_BLOCK_WIDTH / r->buffer_width * VL_MACROBLOCK_WIDTH / r->macroblock_size, + (float)VL_BLOCK_HEIGHT / r->buffer_height * VL_MACROBLOCK_HEIGHT / r->macroblock_size }; unsigned label; @@ -273,7 +271,7 @@ create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, v ureg_scalar(vpos, TGSI_SWIZZLE_Z), ureg_imm1f(shader, 0.5f)); ureg_MOV(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), ureg_imm1f(shader, -1.0f)); - if (r->macroblock_size == MACROBLOCK_HEIGHT) { //TODO + if (r->macroblock_size == VL_MACROBLOCK_HEIGHT) { //TODO ureg_IF(shader, ureg_scalar(vpos, TGSI_SWIZZLE_W), &label); ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), @@ -309,7 +307,8 @@ create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, v } static void * -create_ycbcr_frag_shader(struct vl_mc *r, float scale, vl_mc_ycbcr_frag_shader fs_callback, void *callback_priv) +create_ycbcr_frag_shader(struct vl_mc *r, float scale, bool invert, + vl_mc_ycbcr_frag_shader fs_callback, void *callback_priv) { struct ureg_program *shader; struct ureg_src flags; @@ -341,7 +340,7 @@ create_ycbcr_frag_shader(struct vl_mc *r, float scale, vl_mc_ycbcr_frag_shader f ureg_IF(shader, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), &label); - ureg_KILP(shader); + ureg_KILL(shader); ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); ureg_ELSE(shader, &label); @@ -349,13 +348,14 @@ create_ycbcr_frag_shader(struct vl_mc *r, float scale, vl_mc_ycbcr_frag_shader f fs_callback(callback_priv, r, shader, VS_O_VTEX, tmp); if (scale != 1.0f) - ureg_MAD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), + ureg_MAD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_imm1f(shader, scale), ureg_scalar(flags, TGSI_SWIZZLE_Z)); else - ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), + ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_scalar(flags, TGSI_SWIZZLE_Z)); - + + ureg_MUL(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_imm1f(shader, invert ? -1.0f : 1.0f)); ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); @@ -363,6 +363,8 @@ create_ycbcr_frag_shader(struct vl_mc *r, float scale, vl_mc_ycbcr_frag_shader f ureg_release_temporary(shader, tmp); + ureg_END(shader); + return ureg_create_shader_and_destroy(shader, r->pipe); } @@ -413,14 +415,22 @@ init_pipe_state(struct vl_mc *r) r->blend_add[i] = r->pipe->create_blend_state(r->pipe, &blend); if (!r->blend_add[i]) goto error_blend; + + blend.rt[0].rgb_func = PIPE_BLEND_REVERSE_SUBTRACT; + blend.rt[0].alpha_dst_factor = PIPE_BLEND_REVERSE_SUBTRACT; + r->blend_sub[i] = r->pipe->create_blend_state(r->pipe, &blend); + if (!r->blend_sub[i]) + goto error_blend; } memset(&rs_state, 0, sizeof(rs_state)); /*rs_state.sprite_coord_enable */ rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; rs_state.point_quad_rasterization = true; - rs_state.point_size = BLOCK_WIDTH; - rs_state.gl_rasterization_rules = true; + rs_state.point_size = VL_BLOCK_WIDTH; + rs_state.half_pixel_center = true; + rs_state.bottom_edge_rule = true; + rs_state.depth_clip = 1; r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state); if (!r->rs_state) goto error_rs_state; @@ -430,6 +440,9 @@ init_pipe_state(struct vl_mc *r) error_rs_state: error_blend: for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { + if (r->blend_sub[i]) + r->pipe->delete_blend_state(r->pipe, r->blend_sub[i]); + if (r->blend_add[i]) r->pipe->delete_blend_state(r->pipe, r->blend_add[i]); @@ -454,6 +467,7 @@ cleanup_pipe_state(struct vl_mc *r) 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_blend_state(r->pipe, r->blend_sub[i]); } r->pipe->delete_rasterizer_state(r->pipe, r->rs_state); } @@ -491,11 +505,18 @@ vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, if (!renderer->fs_ref) goto error_fs_ref; - renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale, fs_callback, callback_priv); + renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale, false, fs_callback, callback_priv); if (!renderer->fs_ycbcr) goto error_fs_ycbcr; + renderer->fs_ycbcr_sub = create_ycbcr_frag_shader(renderer, scale, true, fs_callback, callback_priv); + if (!renderer->fs_ycbcr_sub) + goto error_fs_ycbcr_sub; + return true; + +error_fs_ycbcr_sub: + renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); error_fs_ycbcr: renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); @@ -524,6 +545,7 @@ vl_mc_cleanup(struct vl_mc *renderer) renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); + renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr_sub); } bool @@ -531,8 +553,6 @@ vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer) { assert(renderer && buffer); - buffer->renderer = renderer; - buffer->viewport.scale[2] = 1; buffer->viewport.scale[3] = 1; buffer->viewport.translate[0] = 0; @@ -568,13 +588,10 @@ vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface) } static void -prepare_pipe_4_rendering(struct vl_mc_buffer *buffer, unsigned mask) +prepare_pipe_4_rendering(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned mask) { - struct vl_mc *renderer; - assert(buffer); - renderer = buffer->renderer; renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state); if (buffer->surface_cleared) @@ -583,19 +600,15 @@ prepare_pipe_4_rendering(struct vl_mc_buffer *buffer, unsigned mask) 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); + renderer->pipe->set_viewport_states(renderer->pipe, 0, 1, &buffer->viewport); } void -vl_mc_render_ref(struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref) +vl_mc_render_ref(struct vl_mc *renderer, struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref) { - struct vl_mc *renderer; - assert(buffer && ref); - prepare_pipe_4_rendering(buffer, PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B); - - renderer = buffer->renderer; + prepare_pipe_4_rendering(renderer, buffer, PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B); renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ref); renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref); @@ -604,28 +617,32 @@ vl_mc_render_ref(struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref) renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ref); util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, - renderer->buffer_width / MACROBLOCK_WIDTH * - renderer->buffer_height / MACROBLOCK_HEIGHT); + renderer->buffer_width / VL_MACROBLOCK_WIDTH * + renderer->buffer_height / VL_MACROBLOCK_HEIGHT); buffer->surface_cleared = true; } void -vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, unsigned component, unsigned num_instances) +vl_mc_render_ycbcr(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned component, unsigned num_instances) { - struct vl_mc *renderer; + unsigned mask = 1 << component; assert(buffer); if (num_instances == 0) return; - prepare_pipe_4_rendering(buffer, 1 << component); - - renderer = buffer->renderer; + prepare_pipe_4_rendering(renderer, buffer, mask); renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ycbcr); renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr); util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances); + + if (buffer->surface_cleared) { + renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_sub[mask]); + renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr_sub); + util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances); + } }