Path: blob/21.2-virgl/src/gallium/auxiliary/vl/vl_mc.c
4565 views
/**************************************************************************1*2* Copyright 2009 Younes Manton.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#include <assert.h>2829#include "pipe/p_context.h"3031#include "util/u_sampler.h"32#include "util/u_draw.h"3334#include "tgsi/tgsi_ureg.h"3536#include "vl_defines.h"37#include "vl_vertex_buffers.h"38#include "vl_mc.h"39#include "vl_idct.h"4041enum VS_OUTPUT42{43VS_O_VPOS = 0,44VS_O_VTOP = 0,45VS_O_VBOTTOM,4647VS_O_FLAGS = VS_O_VTOP,48VS_O_VTEX = VS_O_VBOTTOM49};5051static struct ureg_dst52calc_position(struct vl_mc *r, struct ureg_program *shader, struct ureg_src block_scale)53{54struct ureg_src vrect, vpos;55struct ureg_dst t_vpos;56struct ureg_dst o_vpos;5758vrect = ureg_DECL_vs_input(shader, VS_I_RECT);59vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);6061t_vpos = ureg_DECL_temporary(shader);6263o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);6465/*66* block_scale = (VL_MACROBLOCK_WIDTH, VL_MACROBLOCK_HEIGHT) / (dst.width, dst.height)67*68* t_vpos = (vpos + vrect) * block_scale69* o_vpos.xy = t_vpos70* o_vpos.zw = vpos71*/72ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect);73ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale);74ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos));75ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f));7677return t_vpos;78}7980static struct ureg_dst81calc_line(struct pipe_screen *screen, struct ureg_program *shader)82{83struct ureg_dst tmp;84struct ureg_src pos;8586tmp = ureg_DECL_temporary(shader);8788if (screen->get_param(screen, PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL))89pos = ureg_DECL_system_value(shader, TGSI_SEMANTIC_POSITION, 0);90else91pos = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS,92TGSI_INTERPOLATE_LINEAR);9394/*95* tmp.y = fraction(pos.y / 2) >= 0.5 ? 1 : 096*/97ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), pos, ureg_imm1f(shader, 0.5f));98ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp));99ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp), ureg_imm1f(shader, 0.5f));100101return tmp;102}103104static void *105create_ref_vert_shader(struct vl_mc *r)106{107struct ureg_program *shader;108struct ureg_src mv_scale;109struct ureg_src vmv[2];110struct ureg_dst t_vpos;111struct ureg_dst o_vmv[2];112unsigned i;113114shader = ureg_create(PIPE_SHADER_VERTEX);115if (!shader)116return NULL;117118vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP);119vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM);120121t_vpos = calc_position(r, shader, ureg_imm2f(shader,122(float)VL_MACROBLOCK_WIDTH / r->buffer_width,123(float)VL_MACROBLOCK_HEIGHT / r->buffer_height)124);125126o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP);127o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM);128129/*130* mv_scale.xy = 0.5 / (dst.width, dst.height);131* mv_scale.z = 1.0f / 4.0f132* mv_scale.w = 1.0f / 255.0f133*134* // Apply motion vectors135* o_vmv[0..1].xy = vmv[0..1] * mv_scale + t_vpos136* o_vmv[0..1].zw = vmv[0..1] * mv_scale137*138*/139140mv_scale = ureg_imm4f(shader,1410.5f / r->buffer_width,1420.5f / r->buffer_height,1431.0f / 4.0f,1441.0f / PIPE_VIDEO_MV_WEIGHT_MAX);145146for (i = 0; i < 2; ++i) {147ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos));148ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]);149}150151ureg_release_temporary(shader, t_vpos);152153ureg_END(shader);154155return ureg_create_shader_and_destroy(shader, r->pipe);156}157158static void *159create_ref_frag_shader(struct vl_mc *r)160{161const float y_scale =162r->buffer_height / 2 *163r->macroblock_size / VL_MACROBLOCK_HEIGHT;164165struct ureg_program *shader;166struct ureg_src tc[2], sampler;167struct ureg_dst ref, field;168struct ureg_dst fragment;169unsigned label;170171shader = ureg_create(PIPE_SHADER_FRAGMENT);172if (!shader)173return NULL;174175tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR);176tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR);177178sampler = ureg_DECL_sampler(shader, 0);179ref = ureg_DECL_temporary(shader);180181fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);182183field = calc_line(r->pipe->screen, shader);184185/*186* ref = field.z ? tc[1] : tc[0]187*188* // Adjust tc acording to top/bottom field selection189* if (|ref.z|) {190* ref.y *= y_scale191* ref.y = floor(ref.y)192* ref.y += ref.z193* ref.y /= y_scale194* }195* fragment.xyz = tex(ref, sampler[0])196*/197ureg_CMP(shader, ureg_writemask(ref, TGSI_WRITEMASK_XYZ),198ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),199tc[1], tc[0]);200ureg_CMP(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W),201ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),202tc[1], tc[0]);203204ureg_IF(shader, ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z), &label);205206ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y),207ureg_src(ref), ureg_imm1f(shader, y_scale));208ureg_FLR(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref));209ureg_ADD(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y),210ureg_src(ref), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z));211ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y),212ureg_src(ref), ureg_imm1f(shader, 1.0f / y_scale));213214ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));215ureg_ENDIF(shader);216217ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler);218219ureg_release_temporary(shader, ref);220221ureg_release_temporary(shader, field);222ureg_END(shader);223224return ureg_create_shader_and_destroy(shader, r->pipe);225}226227static void *228create_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, void *callback_priv)229{230struct ureg_program *shader;231232struct ureg_src vrect, vpos;233struct ureg_dst t_vpos, t_vtex;234struct ureg_dst o_vpos, o_flags;235236struct vertex2f scale = {237(float)VL_BLOCK_WIDTH / r->buffer_width * VL_MACROBLOCK_WIDTH / r->macroblock_size,238(float)VL_BLOCK_HEIGHT / r->buffer_height * VL_MACROBLOCK_HEIGHT / r->macroblock_size239};240241unsigned label;242243shader = ureg_create(PIPE_SHADER_VERTEX);244if (!shader)245return NULL;246247vrect = ureg_DECL_vs_input(shader, VS_I_RECT);248vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);249250t_vpos = calc_position(r, shader, ureg_imm2f(shader, scale.x, scale.y));251t_vtex = ureg_DECL_temporary(shader);252253o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);254o_flags = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS);255256/*257* o_vtex.xy = t_vpos258* o_flags.z = intra * 0.5259*260* if(interlaced) {261* t_vtex.xy = vrect.y ? { 0, scale.y } : { -scale.y : 0 }262* t_vtex.z = vpos.y % 2263* t_vtex.y = t_vtex.z ? t_vtex.x : t_vtex.y264* o_vpos.y = t_vtex.y + t_vpos.y265*266* o_flags.w = t_vtex.z ? 0 : 1267* }268*269*/270271vs_callback(callback_priv, r, shader, VS_O_VTEX, t_vpos);272273ureg_MUL(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_Z),274ureg_scalar(vpos, TGSI_SWIZZLE_Z), ureg_imm1f(shader, 0.5f));275ureg_MOV(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), ureg_imm1f(shader, -1.0f));276277if (r->macroblock_size == VL_MACROBLOCK_HEIGHT) { //TODO278ureg_IF(shader, ureg_scalar(vpos, TGSI_SWIZZLE_W), &label);279280ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY),281ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_Y)),282ureg_imm2f(shader, 0.0f, scale.y),283ureg_imm2f(shader, -scale.y, 0.0f));284ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z),285ureg_scalar(vpos, TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.5f));286287ureg_FRC(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), ureg_src(t_vtex));288289ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y),290ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)),291ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_X),292ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Y));293ureg_ADD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_Y),294ureg_src(t_vpos), ureg_src(t_vtex));295296ureg_CMP(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W),297ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)),298ureg_imm1f(shader, 0.0f), ureg_imm1f(shader, 1.0f));299300ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));301ureg_ENDIF(shader);302}303304ureg_release_temporary(shader, t_vtex);305ureg_release_temporary(shader, t_vpos);306307ureg_END(shader);308309return ureg_create_shader_and_destroy(shader, r->pipe);310}311312static void *313create_ycbcr_frag_shader(struct vl_mc *r, float scale, bool invert,314vl_mc_ycbcr_frag_shader fs_callback, void *callback_priv)315{316struct ureg_program *shader;317struct ureg_src flags;318struct ureg_dst tmp;319struct ureg_dst fragment;320unsigned label;321322shader = ureg_create(PIPE_SHADER_FRAGMENT);323if (!shader)324return NULL;325326flags = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS, TGSI_INTERPOLATE_LINEAR);327328fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);329330tmp = calc_line(r->pipe->screen, shader);331332/*333* if (field == tc.w)334* kill();335* else {336* fragment.xyz = tex(tc, sampler) * scale + tc.z337* fragment.w = 1.0f338* }339*/340341ureg_SEQ(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y),342ureg_scalar(flags, TGSI_SWIZZLE_W), ureg_src(tmp));343344ureg_IF(shader, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), &label);345346ureg_KILL(shader);347348ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));349ureg_ELSE(shader, &label);350351fs_callback(callback_priv, r, shader, VS_O_VTEX, tmp);352353if (scale != 1.0f)354ureg_MAD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ),355ureg_src(tmp), ureg_imm1f(shader, scale),356ureg_scalar(flags, TGSI_SWIZZLE_Z));357else358ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ),359ureg_src(tmp), ureg_scalar(flags, TGSI_SWIZZLE_Z));360361ureg_MUL(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_imm1f(shader, invert ? -1.0f : 1.0f));362ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));363364ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));365ureg_ENDIF(shader);366367ureg_release_temporary(shader, tmp);368369ureg_END(shader);370371return ureg_create_shader_and_destroy(shader, r->pipe);372}373374static bool375init_pipe_state(struct vl_mc *r)376{377struct pipe_sampler_state sampler;378struct pipe_blend_state blend;379struct pipe_rasterizer_state rs_state;380unsigned i;381382assert(r);383384memset(&sampler, 0, sizeof(sampler));385sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;386sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;387sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER;388sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;389sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;390sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;391sampler.compare_mode = PIPE_TEX_COMPARE_NONE;392sampler.compare_func = PIPE_FUNC_ALWAYS;393sampler.normalized_coords = 1;394r->sampler_ref = r->pipe->create_sampler_state(r->pipe, &sampler);395if (!r->sampler_ref)396goto error_sampler_ref;397398for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) {399memset(&blend, 0, sizeof blend);400blend.independent_blend_enable = 0;401blend.rt[0].blend_enable = 1;402blend.rt[0].rgb_func = PIPE_BLEND_ADD;403blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;404blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;405blend.rt[0].alpha_func = PIPE_BLEND_ADD;406blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;407blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;408blend.logicop_enable = 0;409blend.logicop_func = PIPE_LOGICOP_CLEAR;410blend.rt[0].colormask = i;411blend.dither = 0;412r->blend_clear[i] = r->pipe->create_blend_state(r->pipe, &blend);413if (!r->blend_clear[i])414goto error_blend;415416blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;417blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;418r->blend_add[i] = r->pipe->create_blend_state(r->pipe, &blend);419if (!r->blend_add[i])420goto error_blend;421422blend.rt[0].rgb_func = PIPE_BLEND_REVERSE_SUBTRACT;423blend.rt[0].alpha_dst_factor = PIPE_BLEND_REVERSE_SUBTRACT;424r->blend_sub[i] = r->pipe->create_blend_state(r->pipe, &blend);425if (!r->blend_sub[i])426goto error_blend;427}428429memset(&rs_state, 0, sizeof(rs_state));430/*rs_state.sprite_coord_enable */431rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;432rs_state.point_quad_rasterization = true;433rs_state.point_size = VL_BLOCK_WIDTH;434rs_state.half_pixel_center = true;435rs_state.bottom_edge_rule = true;436rs_state.depth_clip_near = 1;437rs_state.depth_clip_far = 1;438439r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state);440if (!r->rs_state)441goto error_rs_state;442443return true;444445error_rs_state:446error_blend:447for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) {448if (r->blend_sub[i])449r->pipe->delete_blend_state(r->pipe, r->blend_sub[i]);450451if (r->blend_add[i])452r->pipe->delete_blend_state(r->pipe, r->blend_add[i]);453454if (r->blend_clear[i])455r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]);456}457458r->pipe->delete_sampler_state(r->pipe, r->sampler_ref);459460error_sampler_ref:461return false;462}463464static void465cleanup_pipe_state(struct vl_mc *r)466{467unsigned i;468469assert(r);470471r->pipe->delete_sampler_state(r->pipe, r->sampler_ref);472for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) {473r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]);474r->pipe->delete_blend_state(r->pipe, r->blend_add[i]);475r->pipe->delete_blend_state(r->pipe, r->blend_sub[i]);476}477r->pipe->delete_rasterizer_state(r->pipe, r->rs_state);478}479480bool481vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe,482unsigned buffer_width, unsigned buffer_height,483unsigned macroblock_size, float scale,484vl_mc_ycbcr_vert_shader vs_callback,485vl_mc_ycbcr_frag_shader fs_callback,486void *callback_priv)487{488assert(renderer);489assert(pipe);490491memset(renderer, 0, sizeof(struct vl_mc));492493renderer->pipe = pipe;494renderer->buffer_width = buffer_width;495renderer->buffer_height = buffer_height;496renderer->macroblock_size = macroblock_size;497498if (!init_pipe_state(renderer))499goto error_pipe_state;500501renderer->vs_ref = create_ref_vert_shader(renderer);502if (!renderer->vs_ref)503goto error_vs_ref;504505renderer->vs_ycbcr = create_ycbcr_vert_shader(renderer, vs_callback, callback_priv);506if (!renderer->vs_ycbcr)507goto error_vs_ycbcr;508509renderer->fs_ref = create_ref_frag_shader(renderer);510if (!renderer->fs_ref)511goto error_fs_ref;512513renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale, false, fs_callback, callback_priv);514if (!renderer->fs_ycbcr)515goto error_fs_ycbcr;516517renderer->fs_ycbcr_sub = create_ycbcr_frag_shader(renderer, scale, true, fs_callback, callback_priv);518if (!renderer->fs_ycbcr_sub)519goto error_fs_ycbcr_sub;520521return true;522523error_fs_ycbcr_sub:524renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr);525526error_fs_ycbcr:527renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref);528529error_fs_ref:530renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr);531532error_vs_ycbcr:533renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref);534535error_vs_ref:536cleanup_pipe_state(renderer);537538error_pipe_state:539return false;540}541542void543vl_mc_cleanup(struct vl_mc *renderer)544{545assert(renderer);546547cleanup_pipe_state(renderer);548549renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref);550renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr);551renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref);552renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr);553renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr_sub);554}555556bool557vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer)558{559assert(renderer && buffer);560561buffer->viewport.scale[2] = 1;562buffer->viewport.translate[0] = 0;563buffer->viewport.translate[1] = 0;564buffer->viewport.translate[2] = 0;565buffer->viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;566buffer->viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;567buffer->viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;568buffer->viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;569570buffer->fb_state.nr_cbufs = 1;571buffer->fb_state.zsbuf = NULL;572573return true;574}575576void577vl_mc_cleanup_buffer(struct vl_mc_buffer *buffer)578{579assert(buffer);580}581582void583vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface)584{585assert(buffer && surface);586587buffer->surface_cleared = false;588589buffer->viewport.scale[0] = surface->width;590buffer->viewport.scale[1] = surface->height;591592buffer->fb_state.width = surface->width;593buffer->fb_state.height = surface->height;594buffer->fb_state.cbufs[0] = surface;595}596597static void598prepare_pipe_4_rendering(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned mask)599{600assert(buffer);601602renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);603604if (buffer->surface_cleared)605renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add[mask]);606else607renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear[mask]);608609renderer->pipe->set_framebuffer_state(renderer->pipe, &buffer->fb_state);610renderer->pipe->set_viewport_states(renderer->pipe, 0, 1, &buffer->viewport);611}612613void614vl_mc_render_ref(struct vl_mc *renderer, struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref)615{616assert(buffer && ref);617618prepare_pipe_4_rendering(renderer, buffer, PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B);619620renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ref);621renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref);622623renderer->pipe->set_sampler_views(renderer->pipe, PIPE_SHADER_FRAGMENT,6240, 1, 0, &ref);625renderer->pipe->bind_sampler_states(renderer->pipe, PIPE_SHADER_FRAGMENT,6260, 1, &renderer->sampler_ref);627628util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0,629renderer->buffer_width / VL_MACROBLOCK_WIDTH *630renderer->buffer_height / VL_MACROBLOCK_HEIGHT);631632buffer->surface_cleared = true;633}634635void636vl_mc_render_ycbcr(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned component, unsigned num_instances)637{638unsigned mask = 1 << component;639640assert(buffer);641642if (num_instances == 0)643return;644645prepare_pipe_4_rendering(renderer, buffer, mask);646647renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ycbcr);648renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr);649650util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances);651652if (buffer->surface_cleared) {653renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_sub[mask]);654renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr_sub);655util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances);656}657}658659660