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