1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2009 Younes Manton. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <assert.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pipe/p_context.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "util/u_sampler.h" 33bf215546Sopenharmony_ci#include "util/u_draw.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include "tgsi/tgsi_ureg.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include "vl_defines.h" 38bf215546Sopenharmony_ci#include "vl_vertex_buffers.h" 39bf215546Sopenharmony_ci#include "vl_mc.h" 40bf215546Sopenharmony_ci#include "vl_idct.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cienum VS_OUTPUT 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci VS_O_VPOS = 0, 45bf215546Sopenharmony_ci VS_O_VTOP = 0, 46bf215546Sopenharmony_ci VS_O_VBOTTOM, 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci VS_O_FLAGS = VS_O_VTOP, 49bf215546Sopenharmony_ci VS_O_VTEX = VS_O_VBOTTOM 50bf215546Sopenharmony_ci}; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_cistatic struct ureg_dst 53bf215546Sopenharmony_cicalc_position(struct vl_mc *r, struct ureg_program *shader, struct ureg_src block_scale) 54bf215546Sopenharmony_ci{ 55bf215546Sopenharmony_ci struct ureg_src vrect, vpos; 56bf215546Sopenharmony_ci struct ureg_dst t_vpos; 57bf215546Sopenharmony_ci struct ureg_dst o_vpos; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci vrect = ureg_DECL_vs_input(shader, VS_I_RECT); 60bf215546Sopenharmony_ci vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci t_vpos = ureg_DECL_temporary(shader); 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci /* 67bf215546Sopenharmony_ci * block_scale = (VL_MACROBLOCK_WIDTH, VL_MACROBLOCK_HEIGHT) / (dst.width, dst.height) 68bf215546Sopenharmony_ci * 69bf215546Sopenharmony_ci * t_vpos = (vpos + vrect) * block_scale 70bf215546Sopenharmony_ci * o_vpos.xy = t_vpos 71bf215546Sopenharmony_ci * o_vpos.zw = vpos 72bf215546Sopenharmony_ci */ 73bf215546Sopenharmony_ci ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect); 74bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale); 75bf215546Sopenharmony_ci ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos)); 76bf215546Sopenharmony_ci ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 1.0f)); 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci return t_vpos; 79bf215546Sopenharmony_ci} 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_cistatic struct ureg_dst 82bf215546Sopenharmony_cicalc_line(struct pipe_screen *screen, struct ureg_program *shader) 83bf215546Sopenharmony_ci{ 84bf215546Sopenharmony_ci struct ureg_dst tmp; 85bf215546Sopenharmony_ci struct ureg_src pos; 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci tmp = ureg_DECL_temporary(shader); 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci if (screen->get_param(screen, PIPE_CAP_FS_POSITION_IS_SYSVAL)) 90bf215546Sopenharmony_ci pos = ureg_DECL_system_value(shader, TGSI_SEMANTIC_POSITION, 0); 91bf215546Sopenharmony_ci else 92bf215546Sopenharmony_ci pos = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS, 93bf215546Sopenharmony_ci TGSI_INTERPOLATE_LINEAR); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci /* 96bf215546Sopenharmony_ci * tmp.y = fraction(pos.y / 2) >= 0.5 ? 1 : 0 97bf215546Sopenharmony_ci */ 98bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), pos, ureg_imm1f(shader, 0.5f)); 99bf215546Sopenharmony_ci ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp)); 100bf215546Sopenharmony_ci ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp), ureg_imm1f(shader, 0.5f)); 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci return tmp; 103bf215546Sopenharmony_ci} 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_cistatic void * 106bf215546Sopenharmony_cicreate_ref_vert_shader(struct vl_mc *r) 107bf215546Sopenharmony_ci{ 108bf215546Sopenharmony_ci struct ureg_program *shader; 109bf215546Sopenharmony_ci struct ureg_src mv_scale; 110bf215546Sopenharmony_ci struct ureg_src vmv[2]; 111bf215546Sopenharmony_ci struct ureg_dst t_vpos; 112bf215546Sopenharmony_ci struct ureg_dst o_vmv[2]; 113bf215546Sopenharmony_ci unsigned i; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci shader = ureg_create(PIPE_SHADER_VERTEX); 116bf215546Sopenharmony_ci if (!shader) 117bf215546Sopenharmony_ci return NULL; 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP); 120bf215546Sopenharmony_ci vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM); 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci t_vpos = calc_position(r, shader, ureg_imm2f(shader, 123bf215546Sopenharmony_ci (float)VL_MACROBLOCK_WIDTH / r->buffer_width, 124bf215546Sopenharmony_ci (float)VL_MACROBLOCK_HEIGHT / r->buffer_height) 125bf215546Sopenharmony_ci ); 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); 128bf215546Sopenharmony_ci o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci /* 131bf215546Sopenharmony_ci * mv_scale.xy = 0.5 / (dst.width, dst.height); 132bf215546Sopenharmony_ci * mv_scale.z = 1.0f / 4.0f 133bf215546Sopenharmony_ci * mv_scale.w = 1.0f / 255.0f 134bf215546Sopenharmony_ci * 135bf215546Sopenharmony_ci * // Apply motion vectors 136bf215546Sopenharmony_ci * o_vmv[0..1].xy = vmv[0..1] * mv_scale + t_vpos 137bf215546Sopenharmony_ci * o_vmv[0..1].zw = vmv[0..1] * mv_scale 138bf215546Sopenharmony_ci * 139bf215546Sopenharmony_ci */ 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci mv_scale = ureg_imm4f(shader, 142bf215546Sopenharmony_ci 0.5f / r->buffer_width, 143bf215546Sopenharmony_ci 0.5f / r->buffer_height, 144bf215546Sopenharmony_ci 1.0f / 4.0f, 145bf215546Sopenharmony_ci 1.0f / PIPE_VIDEO_MV_WEIGHT_MAX); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci for (i = 0; i < 2; ++i) { 148bf215546Sopenharmony_ci ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos)); 149bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]); 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci ureg_release_temporary(shader, t_vpos); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci ureg_END(shader); 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(shader, r->pipe); 157bf215546Sopenharmony_ci} 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_cistatic void * 160bf215546Sopenharmony_cicreate_ref_frag_shader(struct vl_mc *r) 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci const float y_scale = 163bf215546Sopenharmony_ci r->buffer_height / 2 * 164bf215546Sopenharmony_ci r->macroblock_size / VL_MACROBLOCK_HEIGHT; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci struct ureg_program *shader; 167bf215546Sopenharmony_ci struct ureg_src tc[2], sampler; 168bf215546Sopenharmony_ci struct ureg_dst ref, field; 169bf215546Sopenharmony_ci struct ureg_dst fragment; 170bf215546Sopenharmony_ci unsigned label; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci shader = ureg_create(PIPE_SHADER_FRAGMENT); 173bf215546Sopenharmony_ci if (!shader) 174bf215546Sopenharmony_ci return NULL; 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); 177bf215546Sopenharmony_ci tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci sampler = ureg_DECL_sampler(shader, 0); 180bf215546Sopenharmony_ci ref = ureg_DECL_temporary(shader); 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci field = calc_line(r->pipe->screen, shader); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci /* 187bf215546Sopenharmony_ci * ref = field.z ? tc[1] : tc[0] 188bf215546Sopenharmony_ci * 189bf215546Sopenharmony_ci * // Adjust tc acording to top/bottom field selection 190bf215546Sopenharmony_ci * if (|ref.z|) { 191bf215546Sopenharmony_ci * ref.y *= y_scale 192bf215546Sopenharmony_ci * ref.y = floor(ref.y) 193bf215546Sopenharmony_ci * ref.y += ref.z 194bf215546Sopenharmony_ci * ref.y /= y_scale 195bf215546Sopenharmony_ci * } 196bf215546Sopenharmony_ci * fragment.xyz = tex(ref, sampler[0]) 197bf215546Sopenharmony_ci */ 198bf215546Sopenharmony_ci ureg_CMP(shader, ureg_writemask(ref, TGSI_WRITEMASK_XYZ), 199bf215546Sopenharmony_ci ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), 200bf215546Sopenharmony_ci tc[1], tc[0]); 201bf215546Sopenharmony_ci ureg_CMP(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), 202bf215546Sopenharmony_ci ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), 203bf215546Sopenharmony_ci tc[1], tc[0]); 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci ureg_IF(shader, ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z), &label); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), 208bf215546Sopenharmony_ci ureg_src(ref), ureg_imm1f(shader, y_scale)); 209bf215546Sopenharmony_ci ureg_FLR(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref)); 210bf215546Sopenharmony_ci ureg_ADD(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), 211bf215546Sopenharmony_ci ureg_src(ref), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z)); 212bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), 213bf215546Sopenharmony_ci ureg_src(ref), ureg_imm1f(shader, 1.0f / y_scale)); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); 216bf215546Sopenharmony_ci ureg_ENDIF(shader); 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler); 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci ureg_release_temporary(shader, ref); 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci ureg_release_temporary(shader, field); 223bf215546Sopenharmony_ci ureg_END(shader); 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(shader, r->pipe); 226bf215546Sopenharmony_ci} 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_cistatic void * 229bf215546Sopenharmony_cicreate_ycbcr_vert_shader(struct vl_mc *r, vl_mc_ycbcr_vert_shader vs_callback, void *callback_priv) 230bf215546Sopenharmony_ci{ 231bf215546Sopenharmony_ci struct ureg_program *shader; 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci struct ureg_src vrect, vpos; 234bf215546Sopenharmony_ci struct ureg_dst t_vpos, t_vtex; 235bf215546Sopenharmony_ci struct ureg_dst o_vpos, o_flags; 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci struct vertex2f scale = { 238bf215546Sopenharmony_ci (float)VL_BLOCK_WIDTH / r->buffer_width * VL_MACROBLOCK_WIDTH / r->macroblock_size, 239bf215546Sopenharmony_ci (float)VL_BLOCK_HEIGHT / r->buffer_height * VL_MACROBLOCK_HEIGHT / r->macroblock_size 240bf215546Sopenharmony_ci }; 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci unsigned label; 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci shader = ureg_create(PIPE_SHADER_VERTEX); 245bf215546Sopenharmony_ci if (!shader) 246bf215546Sopenharmony_ci return NULL; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci vrect = ureg_DECL_vs_input(shader, VS_I_RECT); 249bf215546Sopenharmony_ci vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci t_vpos = calc_position(r, shader, ureg_imm2f(shader, scale.x, scale.y)); 252bf215546Sopenharmony_ci t_vtex = ureg_DECL_temporary(shader); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); 255bf215546Sopenharmony_ci o_flags = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS); 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci /* 258bf215546Sopenharmony_ci * o_vtex.xy = t_vpos 259bf215546Sopenharmony_ci * o_flags.z = intra * 0.5 260bf215546Sopenharmony_ci * 261bf215546Sopenharmony_ci * if(interlaced) { 262bf215546Sopenharmony_ci * t_vtex.xy = vrect.y ? { 0, scale.y } : { -scale.y : 0 } 263bf215546Sopenharmony_ci * t_vtex.z = vpos.y % 2 264bf215546Sopenharmony_ci * t_vtex.y = t_vtex.z ? t_vtex.x : t_vtex.y 265bf215546Sopenharmony_ci * o_vpos.y = t_vtex.y + t_vpos.y 266bf215546Sopenharmony_ci * 267bf215546Sopenharmony_ci * o_flags.w = t_vtex.z ? 0 : 1 268bf215546Sopenharmony_ci * } 269bf215546Sopenharmony_ci * 270bf215546Sopenharmony_ci */ 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci vs_callback(callback_priv, r, shader, VS_O_VTEX, t_vpos); 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_Z), 275bf215546Sopenharmony_ci ureg_scalar(vpos, TGSI_SWIZZLE_Z), ureg_imm1f(shader, 0.5f)); 276bf215546Sopenharmony_ci ureg_MOV(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), ureg_imm1f(shader, -1.0f)); 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci if (r->macroblock_size == VL_MACROBLOCK_HEIGHT) { //TODO 279bf215546Sopenharmony_ci ureg_IF(shader, ureg_scalar(vpos, TGSI_SWIZZLE_W), &label); 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), 282bf215546Sopenharmony_ci ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_Y)), 283bf215546Sopenharmony_ci ureg_imm2f(shader, 0.0f, scale.y), 284bf215546Sopenharmony_ci ureg_imm2f(shader, -scale.y, 0.0f)); 285bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), 286bf215546Sopenharmony_ci ureg_scalar(vpos, TGSI_SWIZZLE_Y), ureg_imm1f(shader, 0.5f)); 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci ureg_FRC(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Z), ureg_src(t_vtex)); 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci ureg_CMP(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), 291bf215546Sopenharmony_ci ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)), 292bf215546Sopenharmony_ci ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_X), 293bf215546Sopenharmony_ci ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Y)); 294bf215546Sopenharmony_ci ureg_ADD(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_Y), 295bf215546Sopenharmony_ci ureg_src(t_vpos), ureg_src(t_vtex)); 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci ureg_CMP(shader, ureg_writemask(o_flags, TGSI_WRITEMASK_W), 298bf215546Sopenharmony_ci ureg_negate(ureg_scalar(ureg_src(t_vtex), TGSI_SWIZZLE_Z)), 299bf215546Sopenharmony_ci ureg_imm1f(shader, 0.0f), ureg_imm1f(shader, 1.0f)); 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); 302bf215546Sopenharmony_ci ureg_ENDIF(shader); 303bf215546Sopenharmony_ci } 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci ureg_release_temporary(shader, t_vtex); 306bf215546Sopenharmony_ci ureg_release_temporary(shader, t_vpos); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci ureg_END(shader); 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(shader, r->pipe); 311bf215546Sopenharmony_ci} 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_cistatic void * 314bf215546Sopenharmony_cicreate_ycbcr_frag_shader(struct vl_mc *r, float scale, bool invert, 315bf215546Sopenharmony_ci vl_mc_ycbcr_frag_shader fs_callback, void *callback_priv) 316bf215546Sopenharmony_ci{ 317bf215546Sopenharmony_ci struct ureg_program *shader; 318bf215546Sopenharmony_ci struct ureg_src flags; 319bf215546Sopenharmony_ci struct ureg_dst tmp; 320bf215546Sopenharmony_ci struct ureg_dst fragment; 321bf215546Sopenharmony_ci unsigned label; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci shader = ureg_create(PIPE_SHADER_FRAGMENT); 324bf215546Sopenharmony_ci if (!shader) 325bf215546Sopenharmony_ci return NULL; 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci flags = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_FLAGS, TGSI_INTERPOLATE_LINEAR); 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci tmp = calc_line(r->pipe->screen, shader); 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci /* 334bf215546Sopenharmony_ci * if (field == tc.w) 335bf215546Sopenharmony_ci * kill(); 336bf215546Sopenharmony_ci * else { 337bf215546Sopenharmony_ci * fragment.xyz = tex(tc, sampler) * scale + tc.z 338bf215546Sopenharmony_ci * fragment.w = 1.0f 339bf215546Sopenharmony_ci * } 340bf215546Sopenharmony_ci */ 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci ureg_SEQ(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), 343bf215546Sopenharmony_ci ureg_scalar(flags, TGSI_SWIZZLE_W), ureg_src(tmp)); 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci ureg_IF(shader, ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y), &label); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci ureg_KILL(shader); 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); 350bf215546Sopenharmony_ci ureg_ELSE(shader, &label); 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci fs_callback(callback_priv, r, shader, VS_O_VTEX, tmp); 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci if (scale != 1.0f) 355bf215546Sopenharmony_ci ureg_MAD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), 356bf215546Sopenharmony_ci ureg_src(tmp), ureg_imm1f(shader, scale), 357bf215546Sopenharmony_ci ureg_scalar(flags, TGSI_SWIZZLE_Z)); 358bf215546Sopenharmony_ci else 359bf215546Sopenharmony_ci ureg_ADD(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XYZ), 360bf215546Sopenharmony_ci ureg_src(tmp), ureg_scalar(flags, TGSI_SWIZZLE_Z)); 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci ureg_MUL(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(tmp), ureg_imm1f(shader, invert ? -1.0f : 1.0f)); 363bf215546Sopenharmony_ci ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f)); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); 366bf215546Sopenharmony_ci ureg_ENDIF(shader); 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci ureg_release_temporary(shader, tmp); 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci ureg_END(shader); 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci return ureg_create_shader_and_destroy(shader, r->pipe); 373bf215546Sopenharmony_ci} 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_cistatic bool 376bf215546Sopenharmony_ciinit_pipe_state(struct vl_mc *r) 377bf215546Sopenharmony_ci{ 378bf215546Sopenharmony_ci struct pipe_sampler_state sampler; 379bf215546Sopenharmony_ci struct pipe_blend_state blend; 380bf215546Sopenharmony_ci struct pipe_rasterizer_state rs_state; 381bf215546Sopenharmony_ci unsigned i; 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci assert(r); 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci memset(&sampler, 0, sizeof(sampler)); 386bf215546Sopenharmony_ci sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 387bf215546Sopenharmony_ci sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 388bf215546Sopenharmony_ci sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER; 389bf215546Sopenharmony_ci sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; 390bf215546Sopenharmony_ci sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 391bf215546Sopenharmony_ci sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; 392bf215546Sopenharmony_ci sampler.compare_mode = PIPE_TEX_COMPARE_NONE; 393bf215546Sopenharmony_ci sampler.compare_func = PIPE_FUNC_ALWAYS; 394bf215546Sopenharmony_ci sampler.normalized_coords = 1; 395bf215546Sopenharmony_ci r->sampler_ref = r->pipe->create_sampler_state(r->pipe, &sampler); 396bf215546Sopenharmony_ci if (!r->sampler_ref) 397bf215546Sopenharmony_ci goto error_sampler_ref; 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { 400bf215546Sopenharmony_ci memset(&blend, 0, sizeof blend); 401bf215546Sopenharmony_ci blend.independent_blend_enable = 0; 402bf215546Sopenharmony_ci blend.rt[0].blend_enable = 1; 403bf215546Sopenharmony_ci blend.rt[0].rgb_func = PIPE_BLEND_ADD; 404bf215546Sopenharmony_ci blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; 405bf215546Sopenharmony_ci blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; 406bf215546Sopenharmony_ci blend.rt[0].alpha_func = PIPE_BLEND_ADD; 407bf215546Sopenharmony_ci blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; 408bf215546Sopenharmony_ci blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; 409bf215546Sopenharmony_ci blend.logicop_enable = 0; 410bf215546Sopenharmony_ci blend.logicop_func = PIPE_LOGICOP_CLEAR; 411bf215546Sopenharmony_ci blend.rt[0].colormask = i; 412bf215546Sopenharmony_ci blend.dither = 0; 413bf215546Sopenharmony_ci r->blend_clear[i] = r->pipe->create_blend_state(r->pipe, &blend); 414bf215546Sopenharmony_ci if (!r->blend_clear[i]) 415bf215546Sopenharmony_ci goto error_blend; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; 418bf215546Sopenharmony_ci blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; 419bf215546Sopenharmony_ci r->blend_add[i] = r->pipe->create_blend_state(r->pipe, &blend); 420bf215546Sopenharmony_ci if (!r->blend_add[i]) 421bf215546Sopenharmony_ci goto error_blend; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci blend.rt[0].rgb_func = PIPE_BLEND_REVERSE_SUBTRACT; 424bf215546Sopenharmony_ci blend.rt[0].alpha_dst_factor = PIPE_BLEND_REVERSE_SUBTRACT; 425bf215546Sopenharmony_ci r->blend_sub[i] = r->pipe->create_blend_state(r->pipe, &blend); 426bf215546Sopenharmony_ci if (!r->blend_sub[i]) 427bf215546Sopenharmony_ci goto error_blend; 428bf215546Sopenharmony_ci } 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci memset(&rs_state, 0, sizeof(rs_state)); 431bf215546Sopenharmony_ci /*rs_state.sprite_coord_enable */ 432bf215546Sopenharmony_ci rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; 433bf215546Sopenharmony_ci rs_state.point_quad_rasterization = true; 434bf215546Sopenharmony_ci rs_state.point_size = VL_BLOCK_WIDTH; 435bf215546Sopenharmony_ci rs_state.half_pixel_center = true; 436bf215546Sopenharmony_ci rs_state.bottom_edge_rule = true; 437bf215546Sopenharmony_ci rs_state.depth_clip_near = 1; 438bf215546Sopenharmony_ci rs_state.depth_clip_far = 1; 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state); 441bf215546Sopenharmony_ci if (!r->rs_state) 442bf215546Sopenharmony_ci goto error_rs_state; 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci return true; 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_cierror_rs_state: 447bf215546Sopenharmony_cierror_blend: 448bf215546Sopenharmony_ci for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { 449bf215546Sopenharmony_ci if (r->blend_sub[i]) 450bf215546Sopenharmony_ci r->pipe->delete_blend_state(r->pipe, r->blend_sub[i]); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci if (r->blend_add[i]) 453bf215546Sopenharmony_ci r->pipe->delete_blend_state(r->pipe, r->blend_add[i]); 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci if (r->blend_clear[i]) 456bf215546Sopenharmony_ci r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]); 457bf215546Sopenharmony_ci } 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_cierror_sampler_ref: 462bf215546Sopenharmony_ci return false; 463bf215546Sopenharmony_ci} 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_cistatic void 466bf215546Sopenharmony_cicleanup_pipe_state(struct vl_mc *r) 467bf215546Sopenharmony_ci{ 468bf215546Sopenharmony_ci unsigned i; 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci assert(r); 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); 473bf215546Sopenharmony_ci for (i = 0; i < VL_MC_NUM_BLENDERS; ++i) { 474bf215546Sopenharmony_ci r->pipe->delete_blend_state(r->pipe, r->blend_clear[i]); 475bf215546Sopenharmony_ci r->pipe->delete_blend_state(r->pipe, r->blend_add[i]); 476bf215546Sopenharmony_ci r->pipe->delete_blend_state(r->pipe, r->blend_sub[i]); 477bf215546Sopenharmony_ci } 478bf215546Sopenharmony_ci r->pipe->delete_rasterizer_state(r->pipe, r->rs_state); 479bf215546Sopenharmony_ci} 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_cibool 482bf215546Sopenharmony_civl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, 483bf215546Sopenharmony_ci unsigned buffer_width, unsigned buffer_height, 484bf215546Sopenharmony_ci unsigned macroblock_size, float scale, 485bf215546Sopenharmony_ci vl_mc_ycbcr_vert_shader vs_callback, 486bf215546Sopenharmony_ci vl_mc_ycbcr_frag_shader fs_callback, 487bf215546Sopenharmony_ci void *callback_priv) 488bf215546Sopenharmony_ci{ 489bf215546Sopenharmony_ci assert(renderer); 490bf215546Sopenharmony_ci assert(pipe); 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci memset(renderer, 0, sizeof(struct vl_mc)); 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci renderer->pipe = pipe; 495bf215546Sopenharmony_ci renderer->buffer_width = buffer_width; 496bf215546Sopenharmony_ci renderer->buffer_height = buffer_height; 497bf215546Sopenharmony_ci renderer->macroblock_size = macroblock_size; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci if (!init_pipe_state(renderer)) 500bf215546Sopenharmony_ci goto error_pipe_state; 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci renderer->vs_ref = create_ref_vert_shader(renderer); 503bf215546Sopenharmony_ci if (!renderer->vs_ref) 504bf215546Sopenharmony_ci goto error_vs_ref; 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci renderer->vs_ycbcr = create_ycbcr_vert_shader(renderer, vs_callback, callback_priv); 507bf215546Sopenharmony_ci if (!renderer->vs_ycbcr) 508bf215546Sopenharmony_ci goto error_vs_ycbcr; 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci renderer->fs_ref = create_ref_frag_shader(renderer); 511bf215546Sopenharmony_ci if (!renderer->fs_ref) 512bf215546Sopenharmony_ci goto error_fs_ref; 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale, false, fs_callback, callback_priv); 515bf215546Sopenharmony_ci if (!renderer->fs_ycbcr) 516bf215546Sopenharmony_ci goto error_fs_ycbcr; 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci renderer->fs_ycbcr_sub = create_ycbcr_frag_shader(renderer, scale, true, fs_callback, callback_priv); 519bf215546Sopenharmony_ci if (!renderer->fs_ycbcr_sub) 520bf215546Sopenharmony_ci goto error_fs_ycbcr_sub; 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci return true; 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_cierror_fs_ycbcr_sub: 525bf215546Sopenharmony_ci renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_cierror_fs_ycbcr: 528bf215546Sopenharmony_ci renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_cierror_fs_ref: 531bf215546Sopenharmony_ci renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_cierror_vs_ycbcr: 534bf215546Sopenharmony_ci renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_cierror_vs_ref: 537bf215546Sopenharmony_ci cleanup_pipe_state(renderer); 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_cierror_pipe_state: 540bf215546Sopenharmony_ci return false; 541bf215546Sopenharmony_ci} 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_civoid 544bf215546Sopenharmony_civl_mc_cleanup(struct vl_mc *renderer) 545bf215546Sopenharmony_ci{ 546bf215546Sopenharmony_ci assert(renderer); 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci cleanup_pipe_state(renderer); 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); 551bf215546Sopenharmony_ci renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); 552bf215546Sopenharmony_ci renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); 553bf215546Sopenharmony_ci renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); 554bf215546Sopenharmony_ci renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr_sub); 555bf215546Sopenharmony_ci} 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_cibool 558bf215546Sopenharmony_civl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer) 559bf215546Sopenharmony_ci{ 560bf215546Sopenharmony_ci assert(renderer && buffer); 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci buffer->viewport.scale[2] = 1; 563bf215546Sopenharmony_ci buffer->viewport.translate[0] = 0; 564bf215546Sopenharmony_ci buffer->viewport.translate[1] = 0; 565bf215546Sopenharmony_ci buffer->viewport.translate[2] = 0; 566bf215546Sopenharmony_ci buffer->viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; 567bf215546Sopenharmony_ci buffer->viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; 568bf215546Sopenharmony_ci buffer->viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; 569bf215546Sopenharmony_ci buffer->viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci buffer->fb_state.nr_cbufs = 1; 572bf215546Sopenharmony_ci buffer->fb_state.zsbuf = NULL; 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci return true; 575bf215546Sopenharmony_ci} 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_civoid 578bf215546Sopenharmony_civl_mc_cleanup_buffer(struct vl_mc_buffer *buffer) 579bf215546Sopenharmony_ci{ 580bf215546Sopenharmony_ci assert(buffer); 581bf215546Sopenharmony_ci} 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_civoid 584bf215546Sopenharmony_civl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface) 585bf215546Sopenharmony_ci{ 586bf215546Sopenharmony_ci assert(buffer && surface); 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci buffer->surface_cleared = false; 589bf215546Sopenharmony_ci 590bf215546Sopenharmony_ci buffer->viewport.scale[0] = surface->width; 591bf215546Sopenharmony_ci buffer->viewport.scale[1] = surface->height; 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci buffer->fb_state.width = surface->width; 594bf215546Sopenharmony_ci buffer->fb_state.height = surface->height; 595bf215546Sopenharmony_ci buffer->fb_state.cbufs[0] = surface; 596bf215546Sopenharmony_ci} 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_cistatic void 599bf215546Sopenharmony_ciprepare_pipe_4_rendering(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned mask) 600bf215546Sopenharmony_ci{ 601bf215546Sopenharmony_ci assert(buffer); 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state); 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci if (buffer->surface_cleared) 606bf215546Sopenharmony_ci renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add[mask]); 607bf215546Sopenharmony_ci else 608bf215546Sopenharmony_ci renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear[mask]); 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci renderer->pipe->set_framebuffer_state(renderer->pipe, &buffer->fb_state); 611bf215546Sopenharmony_ci renderer->pipe->set_viewport_states(renderer->pipe, 0, 1, &buffer->viewport); 612bf215546Sopenharmony_ci} 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_civoid 615bf215546Sopenharmony_civl_mc_render_ref(struct vl_mc *renderer, struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref) 616bf215546Sopenharmony_ci{ 617bf215546Sopenharmony_ci assert(buffer && ref); 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci prepare_pipe_4_rendering(renderer, buffer, PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B); 620bf215546Sopenharmony_ci 621bf215546Sopenharmony_ci renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ref); 622bf215546Sopenharmony_ci renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref); 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci renderer->pipe->set_sampler_views(renderer->pipe, PIPE_SHADER_FRAGMENT, 625bf215546Sopenharmony_ci 0, 1, 0, false, &ref); 626bf215546Sopenharmony_ci renderer->pipe->bind_sampler_states(renderer->pipe, PIPE_SHADER_FRAGMENT, 627bf215546Sopenharmony_ci 0, 1, &renderer->sampler_ref); 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, 630bf215546Sopenharmony_ci renderer->buffer_width / VL_MACROBLOCK_WIDTH * 631bf215546Sopenharmony_ci renderer->buffer_height / VL_MACROBLOCK_HEIGHT); 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci buffer->surface_cleared = true; 634bf215546Sopenharmony_ci} 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_civoid 637bf215546Sopenharmony_civl_mc_render_ycbcr(struct vl_mc *renderer, struct vl_mc_buffer *buffer, unsigned component, unsigned num_instances) 638bf215546Sopenharmony_ci{ 639bf215546Sopenharmony_ci unsigned mask = 1 << component; 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci assert(buffer); 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci if (num_instances == 0) 644bf215546Sopenharmony_ci return; 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci prepare_pipe_4_rendering(renderer, buffer, mask); 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ycbcr); 649bf215546Sopenharmony_ci renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr); 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances); 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci if (buffer->surface_cleared) { 654bf215546Sopenharmony_ci renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_sub[mask]); 655bf215546Sopenharmony_ci renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr_sub); 656bf215546Sopenharmony_ci util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, 0, num_instances); 657bf215546Sopenharmony_ci } 658bf215546Sopenharmony_ci} 659