Path: blob/21.2-virgl/src/gallium/auxiliary/vl/vl_compositor_gfx.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_compiler.h"30#include "pipe/p_context.h"3132#include "util/u_memory.h"33#include "util/u_draw.h"34#include "util/u_surface.h"35#include "util/u_upload_mgr.h"3637#include "tgsi/tgsi_ureg.h"3839#include "vl_csc.h"40#include "vl_types.h"4142#include "vl_compositor_gfx.h"4344enum VS_OUTPUT45{46VS_O_VPOS = 0,47VS_O_COLOR = 0,48VS_O_VTEX = 0,49VS_O_VTOP,50VS_O_VBOTTOM,51};5253void *54create_vert_shader(struct vl_compositor *c)55{56struct ureg_program *shader;57struct ureg_src vpos, vtex, color;58struct ureg_dst tmp;59struct ureg_dst o_vpos, o_vtex, o_color;60struct ureg_dst o_vtop, o_vbottom;6162shader = ureg_create(PIPE_SHADER_VERTEX);63if (!shader)64return false;6566vpos = ureg_DECL_vs_input(shader, 0);67vtex = ureg_DECL_vs_input(shader, 1);68color = ureg_DECL_vs_input(shader, 2);69tmp = ureg_DECL_temporary(shader);70o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);71o_color = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, VS_O_COLOR);72o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX);73o_vtop = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP);74o_vbottom = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM);7576/*77* o_vpos = vpos78* o_vtex = vtex79* o_color = color80*/81ureg_MOV(shader, o_vpos, vpos);82ureg_MOV(shader, o_vtex, vtex);83ureg_MOV(shader, o_color, color);8485/*86* tmp.x = vtex.w / 287* tmp.y = vtex.w / 488*89* o_vtop.x = vtex.x90* o_vtop.y = vtex.y * tmp.x + 0.25f91* o_vtop.z = vtex.y * tmp.y + 0.25f92* o_vtop.w = 1 / tmp.x93*94* o_vbottom.x = vtex.x95* o_vbottom.y = vtex.y * tmp.x - 0.25f96* o_vbottom.z = vtex.y * tmp.y - 0.25f97* o_vbottom.w = 1 / tmp.y98*/99ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X),100ureg_scalar(vtex, TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.5f));101ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y),102ureg_scalar(vtex, TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.25f));103104ureg_MOV(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_X), vtex);105ureg_MAD(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_Y), ureg_scalar(vtex, TGSI_SWIZZLE_Y),106ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(shader, 0.25f));107ureg_MAD(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_Z), ureg_scalar(vtex, TGSI_SWIZZLE_Y),108ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.25f));109ureg_RCP(shader, ureg_writemask(o_vtop, TGSI_WRITEMASK_W),110ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X));111112ureg_MOV(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_X), vtex);113ureg_MAD(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_Y), ureg_scalar(vtex, TGSI_SWIZZLE_Y),114ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X), ureg_imm1f(shader, -0.25f));115ureg_MAD(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_Z), ureg_scalar(vtex, TGSI_SWIZZLE_Y),116ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), ureg_imm1f(shader, -0.25f));117ureg_RCP(shader, ureg_writemask(o_vbottom, TGSI_WRITEMASK_W),118ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y));119120ureg_END(shader);121122return ureg_create_shader_and_destroy(shader, c->pipe);123}124125static void126create_frag_shader_weave(struct ureg_program *shader, struct ureg_dst fragment)127{128struct ureg_src i_tc[2];129struct ureg_src sampler[3];130struct ureg_dst t_tc[2];131struct ureg_dst t_texel[2];132unsigned i, j;133134i_tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR);135i_tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR);136137for (i = 0; i < 3; ++i) {138sampler[i] = ureg_DECL_sampler(shader, i);139ureg_DECL_sampler_view(shader, i, TGSI_TEXTURE_2D_ARRAY,140TGSI_RETURN_TYPE_FLOAT,141TGSI_RETURN_TYPE_FLOAT,142TGSI_RETURN_TYPE_FLOAT,143TGSI_RETURN_TYPE_FLOAT);144}145146for (i = 0; i < 2; ++i) {147t_tc[i] = ureg_DECL_temporary(shader);148t_texel[i] = ureg_DECL_temporary(shader);149}150151/* calculate the texture offsets152* t_tc.x = i_tc.x153* t_tc.y = (round(i_tc.y - 0.5) + 0.5) / height * 2154*/155for (i = 0; i < 2; ++i) {156ureg_MOV(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_X), i_tc[i]);157ureg_ADD(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_YZ),158i_tc[i], ureg_imm1f(shader, -0.5f));159ureg_ROUND(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_YZ), ureg_src(t_tc[i]));160ureg_MOV(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_W),161ureg_imm1f(shader, i ? 1.0f : 0.0f));162ureg_ADD(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_YZ),163ureg_src(t_tc[i]), ureg_imm1f(shader, 0.5f));164ureg_MUL(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_Y),165ureg_src(t_tc[i]), ureg_scalar(i_tc[0], TGSI_SWIZZLE_W));166ureg_MUL(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_Z),167ureg_src(t_tc[i]), ureg_scalar(i_tc[1], TGSI_SWIZZLE_W));168}169170/* fetch the texels171* texel[0..1].x = tex(t_tc[0..1][0])172* texel[0..1].y = tex(t_tc[0..1][1])173* texel[0..1].z = tex(t_tc[0..1][2])174*/175for (i = 0; i < 2; ++i)176for (j = 0; j < 3; ++j) {177struct ureg_src src = ureg_swizzle(ureg_src(t_tc[i]),178TGSI_SWIZZLE_X, j ? TGSI_SWIZZLE_Z : TGSI_SWIZZLE_Y, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);179180ureg_TEX(shader, ureg_writemask(t_texel[i], TGSI_WRITEMASK_X << j),181TGSI_TEXTURE_2D_ARRAY, src, sampler[j]);182}183184/* calculate linear interpolation factor185* factor = |round(i_tc.y) - i_tc.y| * 2186*/187ureg_ROUND(shader, ureg_writemask(t_tc[0], TGSI_WRITEMASK_YZ), i_tc[0]);188ureg_ADD(shader, ureg_writemask(t_tc[0], TGSI_WRITEMASK_YZ),189ureg_src(t_tc[0]), ureg_negate(i_tc[0]));190ureg_MUL(shader, ureg_writemask(t_tc[0], TGSI_WRITEMASK_YZ),191ureg_abs(ureg_src(t_tc[0])), ureg_imm1f(shader, 2.0f));192ureg_LRP(shader, fragment, ureg_swizzle(ureg_src(t_tc[0]),193TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z),194ureg_src(t_texel[0]), ureg_src(t_texel[1]));195196for (i = 0; i < 2; ++i) {197ureg_release_temporary(shader, t_texel[i]);198ureg_release_temporary(shader, t_tc[i]);199}200}201202static void203create_frag_shader_csc(struct ureg_program *shader, struct ureg_dst texel,204struct ureg_dst fragment)205{206struct ureg_src csc[3];207struct ureg_src lumakey;208struct ureg_dst temp[2];209unsigned i;210211for (i = 0; i < 3; ++i)212csc[i] = ureg_DECL_constant(shader, i);213214lumakey = ureg_DECL_constant(shader, 3);215216for (i = 0; i < 2; ++i)217temp[i] = ureg_DECL_temporary(shader);218219ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W),220ureg_imm1f(shader, 1.0f));221222for (i = 0; i < 3; ++i)223ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i],224ureg_src(texel));225226ureg_MOV(shader, ureg_writemask(temp[0], TGSI_WRITEMASK_W),227ureg_scalar(ureg_src(texel), TGSI_SWIZZLE_Z));228ureg_SLE(shader, ureg_writemask(temp[1], TGSI_WRITEMASK_W),229ureg_src(temp[0]), ureg_scalar(lumakey, TGSI_SWIZZLE_X));230ureg_SGT(shader, ureg_writemask(temp[0], TGSI_WRITEMASK_W),231ureg_src(temp[0]), ureg_scalar(lumakey, TGSI_SWIZZLE_Y));232ureg_MAX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W),233ureg_src(temp[0]), ureg_src(temp[1]));234235for (i = 0; i < 2; ++i)236ureg_release_temporary(shader, temp[i]);237}238239static void240create_frag_shader_yuv(struct ureg_program *shader, struct ureg_dst texel)241{242struct ureg_src tc;243struct ureg_src sampler[3];244unsigned i;245246tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);247for (i = 0; i < 3; ++i) {248sampler[i] = ureg_DECL_sampler(shader, i);249ureg_DECL_sampler_view(shader, i, TGSI_TEXTURE_2D_ARRAY,250TGSI_RETURN_TYPE_FLOAT,251TGSI_RETURN_TYPE_FLOAT,252TGSI_RETURN_TYPE_FLOAT,253TGSI_RETURN_TYPE_FLOAT);254}255256/*257* texel.xyz = tex(tc, sampler[i])258*/259for (i = 0; i < 3; ++i)260ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D_ARRAY, tc, sampler[i]);261}262263void *264create_frag_shader_video_buffer(struct vl_compositor *c)265{266struct ureg_program *shader;267struct ureg_dst texel;268struct ureg_dst fragment;269270shader = ureg_create(PIPE_SHADER_FRAGMENT);271if (!shader)272return false;273274texel = ureg_DECL_temporary(shader);275fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);276277create_frag_shader_yuv(shader, texel);278create_frag_shader_csc(shader, texel, fragment);279280ureg_release_temporary(shader, texel);281ureg_END(shader);282283return ureg_create_shader_and_destroy(shader, c->pipe);284}285286void *287create_frag_shader_weave_rgb(struct vl_compositor *c)288{289struct ureg_program *shader;290struct ureg_dst texel, fragment;291292shader = ureg_create(PIPE_SHADER_FRAGMENT);293if (!shader)294return false;295296texel = ureg_DECL_temporary(shader);297fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);298299create_frag_shader_weave(shader, texel);300create_frag_shader_csc(shader, texel, fragment);301302ureg_release_temporary(shader, texel);303304ureg_END(shader);305306return ureg_create_shader_and_destroy(shader, c->pipe);307}308309void *310create_frag_shader_deint_yuv(struct vl_compositor *c, bool y, bool w)311{312struct ureg_program *shader;313struct ureg_dst texel, fragment;314315shader = ureg_create(PIPE_SHADER_FRAGMENT);316if (!shader)317return false;318319texel = ureg_DECL_temporary(shader);320fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);321322if (w)323create_frag_shader_weave(shader, texel);324else325create_frag_shader_yuv(shader, texel);326327if (y)328ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), ureg_src(texel));329else330ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XY),331ureg_swizzle(ureg_src(texel), TGSI_SWIZZLE_Y,332TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W));333334ureg_release_temporary(shader, texel);335336ureg_END(shader);337338return ureg_create_shader_and_destroy(shader, c->pipe);339}340341void *342create_frag_shader_palette(struct vl_compositor *c, bool include_cc)343{344struct ureg_program *shader;345struct ureg_src csc[3];346struct ureg_src tc;347struct ureg_src sampler;348struct ureg_src palette;349struct ureg_dst texel;350struct ureg_dst fragment;351unsigned i;352353shader = ureg_create(PIPE_SHADER_FRAGMENT);354if (!shader)355return false;356357for (i = 0; include_cc && i < 3; ++i)358csc[i] = ureg_DECL_constant(shader, i);359360tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);361sampler = ureg_DECL_sampler(shader, 0);362ureg_DECL_sampler_view(shader, 0, TGSI_TEXTURE_2D,363TGSI_RETURN_TYPE_FLOAT,364TGSI_RETURN_TYPE_FLOAT,365TGSI_RETURN_TYPE_FLOAT,366TGSI_RETURN_TYPE_FLOAT);367palette = ureg_DECL_sampler(shader, 1);368ureg_DECL_sampler_view(shader, 1, TGSI_TEXTURE_1D,369TGSI_RETURN_TYPE_FLOAT,370TGSI_RETURN_TYPE_FLOAT,371TGSI_RETURN_TYPE_FLOAT,372TGSI_RETURN_TYPE_FLOAT);373374texel = ureg_DECL_temporary(shader);375fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);376377/*378* texel = tex(tc, sampler)379* fragment.xyz = tex(texel, palette) * csc380* fragment.a = texel.a381*/382ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);383ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(texel));384385if (include_cc) {386ureg_TEX(shader, texel, TGSI_TEXTURE_1D, ureg_src(texel), palette);387for (i = 0; i < 3; ++i)388ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel));389} else {390ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ),391TGSI_TEXTURE_1D, ureg_src(texel), palette);392}393394ureg_release_temporary(shader, texel);395ureg_END(shader);396397return ureg_create_shader_and_destroy(shader, c->pipe);398}399400void *401create_frag_shader_rgba(struct vl_compositor *c)402{403struct ureg_program *shader;404struct ureg_src tc, color, sampler;405struct ureg_dst texel, fragment;406407shader = ureg_create(PIPE_SHADER_FRAGMENT);408if (!shader)409return false;410411tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);412color = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_COLOR, VS_O_COLOR, TGSI_INTERPOLATE_LINEAR);413sampler = ureg_DECL_sampler(shader, 0);414ureg_DECL_sampler_view(shader, 0, TGSI_TEXTURE_2D,415TGSI_RETURN_TYPE_FLOAT,416TGSI_RETURN_TYPE_FLOAT,417TGSI_RETURN_TYPE_FLOAT,418TGSI_RETURN_TYPE_FLOAT);419texel = ureg_DECL_temporary(shader);420fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);421422/*423* fragment = tex(tc, sampler)424*/425ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);426ureg_MUL(shader, fragment, ureg_src(texel), color);427ureg_END(shader);428429return ureg_create_shader_and_destroy(shader, c->pipe);430}431432void *433create_frag_shader_rgb_yuv(struct vl_compositor *c, bool y)434{435struct ureg_program *shader;436struct ureg_src tc, sampler;437struct ureg_dst texel, fragment;438439struct ureg_src csc[3];440unsigned i;441442shader = ureg_create(PIPE_SHADER_FRAGMENT);443if (!shader)444return false;445446for (i = 0; i < 3; ++i)447csc[i] = ureg_DECL_constant(shader, i);448449sampler = ureg_DECL_sampler(shader, 0);450tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);451texel = ureg_DECL_temporary(shader);452fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);453454ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);455456if (y) {457ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), csc[0], ureg_src(texel));458} else {459for (i = 0; i < 2; ++i)460ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i + 1], ureg_src(texel));461}462463ureg_release_temporary(shader, texel);464ureg_END(shader);465466return ureg_create_shader_and_destroy(shader, c->pipe);467}468469static void470gen_rect_verts(struct vertex2f *vb, struct vl_compositor_layer *layer)471{472struct vertex2f tl, tr, br, bl;473474assert(vb && layer);475476switch (layer->rotate) {477default:478case VL_COMPOSITOR_ROTATE_0:479tl = layer->dst.tl;480tr.x = layer->dst.br.x;481tr.y = layer->dst.tl.y;482br = layer->dst.br;483bl.x = layer->dst.tl.x;484bl.y = layer->dst.br.y;485break;486case VL_COMPOSITOR_ROTATE_90:487tl.x = layer->dst.br.x;488tl.y = layer->dst.tl.y;489tr = layer->dst.br;490br.x = layer->dst.tl.x;491br.y = layer->dst.br.y;492bl = layer->dst.tl;493break;494case VL_COMPOSITOR_ROTATE_180:495tl = layer->dst.br;496tr.x = layer->dst.tl.x;497tr.y = layer->dst.br.y;498br = layer->dst.tl;499bl.x = layer->dst.br.x;500bl.y = layer->dst.tl.y;501break;502case VL_COMPOSITOR_ROTATE_270:503tl.x = layer->dst.tl.x;504tl.y = layer->dst.br.y;505tr = layer->dst.tl;506br.x = layer->dst.br.x;507br.y = layer->dst.tl.y;508bl = layer->dst.br;509break;510}511512vb[ 0].x = tl.x;513vb[ 0].y = tl.y;514vb[ 1].x = layer->src.tl.x;515vb[ 1].y = layer->src.tl.y;516vb[ 2] = layer->zw;517vb[ 3].x = layer->colors[0].x;518vb[ 3].y = layer->colors[0].y;519vb[ 4].x = layer->colors[0].z;520vb[ 4].y = layer->colors[0].w;521522vb[ 5].x = tr.x;523vb[ 5].y = tr.y;524vb[ 6].x = layer->src.br.x;525vb[ 6].y = layer->src.tl.y;526vb[ 7] = layer->zw;527vb[ 8].x = layer->colors[1].x;528vb[ 8].y = layer->colors[1].y;529vb[ 9].x = layer->colors[1].z;530vb[ 9].y = layer->colors[1].w;531532vb[10].x = br.x;533vb[10].y = br.y;534vb[11].x = layer->src.br.x;535vb[11].y = layer->src.br.y;536vb[12] = layer->zw;537vb[13].x = layer->colors[2].x;538vb[13].y = layer->colors[2].y;539vb[14].x = layer->colors[2].z;540vb[14].y = layer->colors[2].w;541542vb[15].x = bl.x;543vb[15].y = bl.y;544vb[16].x = layer->src.tl.x;545vb[16].y = layer->src.br.y;546vb[17] = layer->zw;547vb[18].x = layer->colors[3].x;548vb[18].y = layer->colors[3].y;549vb[19].x = layer->colors[3].z;550vb[19].y = layer->colors[3].w;551}552553static inline struct u_rect554calc_drawn_area(struct vl_compositor_state *s, struct vl_compositor_layer *layer)555{556struct vertex2f tl, br;557struct u_rect result;558559assert(s && layer);560561// rotate562switch (layer->rotate) {563default:564case VL_COMPOSITOR_ROTATE_0:565tl = layer->dst.tl;566br = layer->dst.br;567break;568case VL_COMPOSITOR_ROTATE_90:569tl.x = layer->dst.br.x;570tl.y = layer->dst.tl.y;571br.x = layer->dst.tl.x;572br.y = layer->dst.br.y;573break;574case VL_COMPOSITOR_ROTATE_180:575tl = layer->dst.br;576br = layer->dst.tl;577break;578case VL_COMPOSITOR_ROTATE_270:579tl.x = layer->dst.tl.x;580tl.y = layer->dst.br.y;581br.x = layer->dst.br.x;582br.y = layer->dst.tl.y;583break;584}585586// scale587result.x0 = tl.x * layer->viewport.scale[0] + layer->viewport.translate[0];588result.y0 = tl.y * layer->viewport.scale[1] + layer->viewport.translate[1];589result.x1 = br.x * layer->viewport.scale[0] + layer->viewport.translate[0];590result.y1 = br.y * layer->viewport.scale[1] + layer->viewport.translate[1];591592// and clip593result.x0 = MAX2(result.x0, s->scissor.minx);594result.y0 = MAX2(result.y0, s->scissor.miny);595result.x1 = MIN2(result.x1, s->scissor.maxx);596result.y1 = MIN2(result.y1, s->scissor.maxy);597return result;598}599600static void601gen_vertex_data(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty)602{603struct vertex2f *vb;604unsigned i;605606assert(c);607608/* Allocate new memory for vertices. */609u_upload_alloc(c->pipe->stream_uploader, 0,610c->vertex_buf.stride * VL_COMPOSITOR_MAX_LAYERS * 4, /* size */6114, /* alignment */612&c->vertex_buf.buffer_offset, &c->vertex_buf.buffer.resource,613(void **)&vb);614615for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) {616if (s->used_layers & (1 << i)) {617struct vl_compositor_layer *layer = &s->layers[i];618gen_rect_verts(vb, layer);619vb += 20;620621if (!layer->viewport_valid) {622layer->viewport.scale[0] = c->fb_state.width;623layer->viewport.scale[1] = c->fb_state.height;624layer->viewport.translate[0] = 0;625layer->viewport.translate[1] = 0;626}627628if (dirty && layer->clearing) {629struct u_rect drawn = calc_drawn_area(s, layer);630if (631dirty->x0 >= drawn.x0 &&632dirty->y0 >= drawn.y0 &&633dirty->x1 <= drawn.x1 &&634dirty->y1 <= drawn.y1) {635636// We clear the dirty area anyway, no need for clear_render_target637dirty->x0 = dirty->y0 = VL_COMPOSITOR_MAX_DIRTY;638dirty->x1 = dirty->y1 = VL_COMPOSITOR_MIN_DIRTY;639}640}641}642}643644u_upload_unmap(c->pipe->stream_uploader);645}646647static void648draw_layers(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rect *dirty)649{650unsigned vb_index, i;651652assert(c);653654for (i = 0, vb_index = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {655if (s->used_layers & (1 << i)) {656struct vl_compositor_layer *layer = &s->layers[i];657struct pipe_sampler_view **samplers = &layer->sampler_views[0];658unsigned num_sampler_views = !samplers[1] ? 1 : !samplers[2] ? 2 : 3;659void *blend = layer->blend ? layer->blend : i ? c->blend_add : c->blend_clear;660661c->pipe->bind_blend_state(c->pipe, blend);662c->pipe->set_viewport_states(c->pipe, 0, 1, &layer->viewport);663c->pipe->bind_fs_state(c->pipe, layer->fs);664c->pipe->bind_sampler_states(c->pipe, PIPE_SHADER_FRAGMENT, 0,665num_sampler_views, layer->samplers);666c->pipe->set_sampler_views(c->pipe, PIPE_SHADER_FRAGMENT, 0,667num_sampler_views, 0, samplers);668669util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, vb_index * 4, 4);670vb_index++;671672if (dirty) {673// Remember the currently drawn area as dirty for the next draw command674struct u_rect drawn = calc_drawn_area(s, layer);675dirty->x0 = MIN2(drawn.x0, dirty->x0);676dirty->y0 = MIN2(drawn.y0, dirty->y0);677dirty->x1 = MAX2(drawn.x1, dirty->x1);678dirty->y1 = MAX2(drawn.y1, dirty->y1);679}680}681}682}683684void685vl_compositor_gfx_render(struct vl_compositor_state *s,686struct vl_compositor *c,687struct pipe_surface *dst_surface,688struct u_rect *dirty_area,689bool clear_dirty)690{691assert(c);692assert(dst_surface);693694c->fb_state.width = dst_surface->width;695c->fb_state.height = dst_surface->height;696c->fb_state.cbufs[0] = dst_surface;697698if (!s->scissor_valid) {699s->scissor.minx = 0;700s->scissor.miny = 0;701s->scissor.maxx = dst_surface->width;702s->scissor.maxy = dst_surface->height;703}704c->pipe->set_scissor_states(c->pipe, 0, 1, &s->scissor);705706gen_vertex_data(c, s, dirty_area);707708if (clear_dirty && dirty_area &&709(dirty_area->x0 < dirty_area->x1 || dirty_area->y0 < dirty_area->y1)) {710711c->pipe->clear_render_target(c->pipe, dst_surface, &s->clear_color,7120, 0, dst_surface->width, dst_surface->height, false);713dirty_area->x0 = dirty_area->y0 = VL_COMPOSITOR_MAX_DIRTY;714dirty_area->x1 = dirty_area->y1 = VL_COMPOSITOR_MIN_DIRTY;715}716717c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);718c->pipe->bind_vs_state(c->pipe, c->vs);719c->pipe->set_vertex_buffers(c->pipe, 0, 1, 0, false, &c->vertex_buf);720c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state);721pipe_set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, s->shader_params);722c->pipe->bind_rasterizer_state(c->pipe, c->rast);723724draw_layers(c, s, dirty_area);725}726727728