vl_idct.c revision 020328ca32a3b6548b4c064c4fe115e386752daa
1508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König/**************************************************************************
2508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König *
3508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * Copyright 2010 Christian König
4508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * All Rights Reserved.
5508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König *
6508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * Permission is hereby granted, free of charge, to any person obtaining a
7508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * copy of this software and associated documentation files (the
8508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * "Software"), to deal in the Software without restriction, including
9508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * without limitation the rights to use, copy, modify, merge, publish,
10508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * distribute, sub license, and/or sell copies of the Software, and to
11508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * permit persons to whom the Software is furnished to do so, subject to
12508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * the following conditions:
13508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König *
14508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * The above copyright notice and this permission notice (including the
15508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * next paragraph) shall be included in all copies or substantial portions
16508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * of the Software.
17508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König *
18508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König *
26508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König **************************************************************************/
27508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
28508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include "vl_idct.h"
294abe7382882a451a7750ccc451b8568768d122cbChristian König#include "vl_vertex_buffers.h"
30020328ca32a3b6548b4c064c4fe115e386752daaChristian König#include "vl_ycbcr_buffer.h"
31e87bd8c9578dee384ff03039aa792e1a8dae7f36Christian König#include "vl_defines.h"
32e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König#include "util/u_draw.h"
33508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include <assert.h>
34508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include <pipe/p_context.h>
35508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include <pipe/p_screen.h>
36508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include <util/u_inlines.h>
37508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include <util/u_sampler.h>
38508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include <util/u_format.h>
39508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include <tgsi/tgsi_ureg.h>
40508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König#include "vl_types.h"
41508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
4203c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König#define SCALE_FACTOR_16_TO_9 (32768.0f / 256.0f)
43508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
449c296be7d6fc4cabed97b9d10e24c226b2ee7d08Christian König#define NR_RENDER_TARGETS 4
45a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König
46508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königenum VS_OUTPUT
47508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
48508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   VS_O_VPOS,
49be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   VS_O_L_ADDR0,
50be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   VS_O_L_ADDR1,
51be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   VS_O_R_ADDR0,
52be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   VS_O_R_ADDR1
53508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König};
54508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
55e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian Königstatic const float const_matrix[8][8] = {
56508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.353553f,  0.3535530f },
57508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.4903930f,  0.4157350f,  0.2777850f,  0.0975451f, -0.0975452f, -0.2777850f, -0.415735f, -0.4903930f },
58508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.4619400f,  0.1913420f, -0.1913420f, -0.4619400f, -0.4619400f, -0.1913420f,  0.191342f,  0.4619400f },
59508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.4157350f, -0.0975452f, -0.4903930f, -0.2777850f,  0.2777850f,  0.4903930f,  0.097545f, -0.4157350f },
60508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.3535530f, -0.3535530f, -0.3535530f,  0.3535540f,  0.3535530f, -0.3535540f, -0.353553f,  0.3535530f },
61508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.2777850f, -0.4903930f,  0.0975452f,  0.4157350f, -0.4157350f, -0.0975451f,  0.490393f, -0.2777850f },
62508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.1913420f, -0.4619400f,  0.4619400f, -0.1913420f, -0.1913410f,  0.4619400f, -0.461940f,  0.1913420f },
63508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   {  0.0975451f, -0.2777850f,  0.4157350f, -0.4903930f,  0.4903930f, -0.4157350f,  0.277786f, -0.0975458f }
64508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König};
65508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
66be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königstatic void
67be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königcalc_addr(struct ureg_program *shader, struct ureg_dst addr[2],
68be4de05c1093db27b3fca12b782055ab8a1eba13Christian König          struct ureg_src tc, struct ureg_src start, bool right_side,
69be4de05c1093db27b3fca12b782055ab8a1eba13Christian König          bool transposed, float size)
70be4de05c1093db27b3fca12b782055ab8a1eba13Christian König{
71be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y;
72be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   unsigned sw_start = right_side ? TGSI_SWIZZLE_Y : TGSI_SWIZZLE_X;
73be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
74be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X;
75be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   unsigned sw_tc = right_side ? TGSI_SWIZZLE_X : TGSI_SWIZZLE_Y;
76be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
77be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   /*
78be4de05c1093db27b3fca12b782055ab8a1eba13Christian König    * addr[0..1].(start) = right_side ? start.x : tc.x
79be4de05c1093db27b3fca12b782055ab8a1eba13Christian König    * addr[0..1].(tc) = right_side ? tc.y : start.y
80be4de05c1093db27b3fca12b782055ab8a1eba13Christian König    * addr[0..1].z = tc.z
81be4de05c1093db27b3fca12b782055ab8a1eba13Christian König    * addr[1].(start) += 1.0f / scale
82be4de05c1093db27b3fca12b782055ab8a1eba13Christian König    */
83be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_MOV(shader, ureg_writemask(addr[0], wm_start), ureg_scalar(start, sw_start));
84be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_MOV(shader, ureg_writemask(addr[0], wm_tc), ureg_scalar(tc, sw_tc));
85be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_MOV(shader, ureg_writemask(addr[0], TGSI_WRITEMASK_Z), tc);
86be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
87be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_ADD(shader, ureg_writemask(addr[1], wm_start), ureg_scalar(start, sw_start), ureg_imm1f(shader, 1.0f / size));
88be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_MOV(shader, ureg_writemask(addr[1], wm_tc), ureg_scalar(tc, sw_tc));
89be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_MOV(shader, ureg_writemask(addr[1], TGSI_WRITEMASK_Z), tc);
90be4de05c1093db27b3fca12b782055ab8a1eba13Christian König}
91be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
92508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void *
93310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian Königcreate_vert_shader(struct vl_idct *idct, bool matrix_stage, int color_swizzle)
94508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
95508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   struct ureg_program *shader;
96310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   struct ureg_src vrect, vpos, vblock, eb[4];
97310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   struct ureg_src scale, blocks_xy, t_eb;
98be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_dst t_tex, t_start;
99be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_dst o_vpos, o_l_addr[2], o_r_addr[2];
100310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   unsigned label;
101508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
102508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
103508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   if (!shader)
104508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König      return NULL;
105508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
106be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   t_tex = ureg_DECL_temporary(shader);
107be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   t_start = ureg_DECL_temporary(shader);
108508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
109508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
110508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
111310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   vblock = ureg_swizzle(vrect, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W, TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
112508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
113508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
114be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
115310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   eb[0] = ureg_DECL_vs_input(shader, VS_I_EB_0_0);
116310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   eb[1] = ureg_DECL_vs_input(shader, VS_I_EB_1_0);
117310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   eb[2] = ureg_DECL_vs_input(shader, VS_I_EB_0_1);
118310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   eb[3] = ureg_DECL_vs_input(shader, VS_I_EB_1_1);
119310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
120be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0);
121be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1);
122be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
123be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0);
124be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1);
125508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
126508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   /*
12712836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König    * scale = (BLOCK_WIDTH, BLOCK_HEIGHT) / (dst.width, dst.height)
128310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * blocks_xy = (blocks_x, blocks_y)
12912836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König    *
130310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * ar = vblock.y * blocks.x + vblock.x
131310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * if eb[ar].(color_swizzle)
132310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_vpos.xy = -1
133310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * else
134310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    t_tex = vpos * blocks_xy + vblock
135310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    t_start = t_tex * scale
136310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    t_tex = t_tex + vrect
137310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_vpos.xy = t_tex * scale
138508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König    *
139310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_l_addr = calc_addr(...)
140310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_r_addr = calc_addr(...)
141310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * endif
142310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * o_vpos.zw = vpos
143508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König    *
144508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König    */
145310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
14612836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König   scale = ureg_imm2f(shader,
14722b4acb2069a368e986805d3b43395172ebf9146Christian König      (float)BLOCK_WIDTH / idct->buffer_width,
14822b4acb2069a368e986805d3b43395172ebf9146Christian König      (float)BLOCK_HEIGHT / idct->buffer_height);
14912836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König
150310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   blocks_xy = ureg_imm2f(shader, idct->blocks_x, idct->blocks_y);
151ab130400cf91ab471e265e58193c95f04c7aeedaChristian König
152310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   if (idct->blocks_x > 1 || idct->blocks_y > 1) {
153310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      struct ureg_dst ar = ureg_DECL_address(shader);
154f853ea007816cdad4395b42388e12cd65bb8eb43Christian König
155310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MAD(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X),
156310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König               ureg_scalar(vblock, TGSI_SWIZZLE_Y), blocks_xy, vblock);
157508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
158310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_ARL(shader, ureg_writemask(ar, TGSI_WRITEMASK_X), ureg_src(t_tex));
159310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      t_eb = ureg_src_indirect(eb[0], ureg_src(ar));
160be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   } else {
161310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      t_eb = eb[0];
162be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   }
163be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
164310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_IF(shader, ureg_scalar(t_eb, color_swizzle), &label);
165310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
166310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MOV(shader, o_vpos, ureg_imm1f(shader, -1.0f));
167310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
168310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
169310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_ELSE(shader, &label);
170310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
171310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MAD(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, blocks_xy, vblock);
172310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), ureg_src(t_tex), scale);
173310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
174310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_ADD(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), ureg_src(t_tex), vrect);
175310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
176310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), ureg_src(t_tex), scale);
177310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_Z),
178310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         ureg_scalar(vrect, TGSI_SWIZZLE_X),
179310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         ureg_imm1f(shader, BLOCK_WIDTH / NR_RENDER_TARGETS));
180310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
181310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_tex));
182310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
183310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      if(matrix_stage) {
184310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_l_addr, ureg_src(t_tex), ureg_src(t_start), false, false, idct->buffer_width / 4);
185310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_r_addr, vrect, ureg_imm1f(shader, 0.0f), true, true, BLOCK_WIDTH / 4);
186310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      } else {
187310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_l_addr, vrect, ureg_imm1f(shader, 0.0f), false, false, BLOCK_WIDTH / 4);
188310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_r_addr, ureg_src(t_tex), ureg_src(t_start), true, false, idct->buffer_height / 4);
189310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      }
190310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
191310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
192310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_ENDIF(shader);
193310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
194310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
195310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
196be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, t_tex);
197be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, t_start);
198508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
199508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   ureg_END(shader);
200508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
201508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   return ureg_create_shader_and_destroy(shader, idct->pipe);
202508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
203508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
204508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void
205f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian Königincrement_addr(struct ureg_program *shader, struct ureg_dst daddr[2],
206f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König               struct ureg_src saddr[2], bool right_side, bool transposed,
207f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König               int pos, float size)
208ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König{
209f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y;
210ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X;
211508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
212c8236aaf7056bd8645804e71596d2d6460e62d15Christian König   /*
213c8236aaf7056bd8645804e71596d2d6460e62d15Christian König    * daddr[0..1].(start) = saddr[0..1].(start)
214c8236aaf7056bd8645804e71596d2d6460e62d15Christian König    * daddr[0..1].(tc) = saddr[0..1].(tc)
215f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König    */
216c8236aaf7056bd8645804e71596d2d6460e62d15Christian König
217f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_MOV(shader, ureg_writemask(daddr[0], wm_start), saddr[0]);
218f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_ADD(shader, ureg_writemask(daddr[0], wm_tc), saddr[0], ureg_imm1f(shader, pos / size));
219f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_MOV(shader, ureg_writemask(daddr[1], wm_start), saddr[1]);
220f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_ADD(shader, ureg_writemask(daddr[1], wm_tc), saddr[1], ureg_imm1f(shader, pos / size));
221ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König}
222ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König
223ebab090ed93270b40475151e60dbc7f2b72f1a61Christian Königstatic void
224be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königfetch_four(struct ureg_program *shader, struct ureg_dst m[2], struct ureg_src addr[2], struct ureg_src sampler)
225ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König{
226be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_TEX(shader, m[0], TGSI_TEXTURE_3D, addr[0], sampler);
227be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_TEX(shader, m[1], TGSI_TEXTURE_3D, addr[1], sampler);
228cfe489b89723117e56674c2be7761c201f8d78ffChristian König}
229508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
23012836fbcfad7f317b1f5aa5e46f9946894bf040cChristian Königstatic void
23112836fbcfad7f317b1f5aa5e46f9946894bf040cChristian Königmatrix_mul(struct ureg_program *shader, struct ureg_dst dst, struct ureg_dst l[2], struct ureg_dst r[2])
232cfe489b89723117e56674c2be7761c201f8d78ffChristian König{
233ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   struct ureg_dst tmp;
234cfe489b89723117e56674c2be7761c201f8d78ffChristian König
235ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   tmp = ureg_DECL_temporary(shader);
236508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
237cfe489b89723117e56674c2be7761c201f8d78ffChristian König   /*
238ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König    * tmp.xy = dot4(m[0][0..1], m[1][0..1])
239ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König    * dst = tmp.x + tmp.y
240cfe489b89723117e56674c2be7761c201f8d78ffChristian König    */
241ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_src(l[0]), ureg_src(r[0]));
242ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(l[1]), ureg_src(r[1]));
24374c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   ureg_ADD(shader, dst,
244ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König      ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X),
245ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König      ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y));
246508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
247ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   ureg_release_temporary(shader, tmp);
248508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
249508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
250508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void *
251508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königcreate_matrix_frag_shader(struct vl_idct *idct)
252508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
253508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   struct ureg_program *shader;
254cfe489b89723117e56674c2be7761c201f8d78ffChristian König
255f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   struct ureg_src l_addr[2], r_addr[2];
256cfe489b89723117e56674c2be7761c201f8d78ffChristian König
257f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   struct ureg_dst l[4][2], r[2];
258be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_dst fragment[NR_RENDER_TARGETS];
25912836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König
26074c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   unsigned i, j;
261508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
262508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
263508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   if (!shader)
264508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König      return NULL;
265508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
266be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR);
267be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR);
268be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
269be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR);
270be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR);
271cfe489b89723117e56674c2be7761c201f8d78ffChristian König
272a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König   for (i = 0; i < NR_RENDER_TARGETS; ++i)
273e742a1043dbd56fe11f0490cb74b7a738bab2238Christian König       fragment[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, i);
274e742a1043dbd56fe11f0490cb74b7a738bab2238Christian König
27574c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   for (i = 0; i < 4; ++i) {
276f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      l[i][0] = ureg_DECL_temporary(shader);
277f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      l[i][1] = ureg_DECL_temporary(shader);
278f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   }
2794a8420513d653cd2fccf93a51315120a1a5d0fccChristian König
280f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[0] = ureg_DECL_temporary(shader);
281f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[1] = ureg_DECL_temporary(shader);
282f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König
283f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   for (i = 1; i < 4; ++i) {
284f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      increment_addr(shader, l[i], l_addr, false, false, i, idct->buffer_height);
285f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   }
286f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König
287f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   for (i = 0; i < 4; ++i) {
288f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      struct ureg_src s_addr[2];
289f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[0] = i == 0 ? l_addr[0] : ureg_src(l[i][0]);
290f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[1] = i == 0 ? l_addr[1] : ureg_src(l[i][1]);
291f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      fetch_four(shader, l[i], s_addr, ureg_DECL_sampler(shader, 1));
29274c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   }
293c8236aaf7056bd8645804e71596d2d6460e62d15Christian König
294a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König   for (i = 0; i < NR_RENDER_TARGETS; ++i) {
295f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      if(i > 0)
296f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König         increment_addr(shader, r, r_addr, true, true, i, BLOCK_HEIGHT);
297a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König
298f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      struct ureg_src s_addr[2] = { ureg_src(r[0]), ureg_src(r[1]) };
299f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[0] = i == 0 ? r_addr[0] : ureg_src(r[0]);
300f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[1] = i == 0 ? r_addr[1] : ureg_src(r[1]);
301f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      fetch_four(shader, r, s_addr, ureg_DECL_sampler(shader, 0));
302a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König
30374c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      for (j = 0; j < 4; ++j) {
30474c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König         matrix_mul(shader, ureg_writemask(fragment[i], TGSI_WRITEMASK_X << j), l[j], r);
30574c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      }
306e742a1043dbd56fe11f0490cb74b7a738bab2238Christian König   }
30774c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König
30874c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   for (i = 0; i < 4; ++i) {
30974c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      ureg_release_temporary(shader, l[i][0]);
31074c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      ureg_release_temporary(shader, l[i][1]);
31174c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   }
312f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_release_temporary(shader, r[0]);
313f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_release_temporary(shader, r[1]);
314be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
315be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_END(shader);
316be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
317be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   return ureg_create_shader_and_destroy(shader, idct->pipe);
318be4de05c1093db27b3fca12b782055ab8a1eba13Christian König}
319be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
320be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königstatic void *
321be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königcreate_transpose_frag_shader(struct vl_idct *idct)
322be4de05c1093db27b3fca12b782055ab8a1eba13Christian König{
323be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_program *shader;
324be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
325be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_src l_addr[2], r_addr[2];
326be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
327be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_dst l[2], r[2];
328f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   struct ureg_dst fragment;
329be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
330be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
331be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   if (!shader)
332be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      return NULL;
333be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
334be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR);
335be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR);
336be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
337be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR);
338be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR);
339be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
340f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   l[0] = ureg_DECL_temporary(shader);
341f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   l[1] = ureg_DECL_temporary(shader);
342f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[0] = ureg_DECL_temporary(shader);
343f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[1] = ureg_DECL_temporary(shader);
344f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König
345be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   fetch_four(shader, l, l_addr, ureg_DECL_sampler(shader, 0));
346be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   fetch_four(shader, r, r_addr, ureg_DECL_sampler(shader, 1));
347be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
348be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
349be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
350f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   matrix_mul(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), l, r);
351be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
352be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, l[0]);
353be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, l[1]);
354be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, r[0]);
355be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, r[1]);
356508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
357508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   ureg_END(shader);
358508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
359508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   return ureg_create_shader_and_destroy(shader, idct->pipe);
360508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
361508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
362508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic bool
363310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian Königinit_shaders(struct vl_idct *idct, int color_swizzle)
364508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
365310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   idct->matrix_vs = create_vert_shader(idct, true, color_swizzle);
3668330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->matrix_vs)
3678330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_matrix_vs;
3688330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3695a8078486a013152d150a4524ebfab929eefe6c4Christian König   idct->matrix_fs = create_matrix_frag_shader(idct);
3708330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->matrix_fs)
3718330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_matrix_fs;
372be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
373310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   idct->transpose_vs = create_vert_shader(idct, false, color_swizzle);
3748330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->transpose_vs)
3758330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_transpose_vs;
3768330bc29dda71c41c56b3c1989334823ae8779d4Christian König
37712836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König   idct->transpose_fs = create_transpose_frag_shader(idct);
3788330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->transpose_fs)
3798330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_transpose_fs;
3808330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3818330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return true;
3828330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3838330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_transpose_fs:
3848330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->transpose_vs);
38512836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König
3868330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_transpose_vs:
3878330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_fs_state(idct->pipe, idct->matrix_fs);
3888330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3898330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_matrix_fs:
3908330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->matrix_vs);
3918330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3928330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_matrix_vs:
3938330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return false;
394508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
395508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
396508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void
397508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königcleanup_shaders(struct vl_idct *idct)
398508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
399be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->matrix_vs);
400508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   idct->pipe->delete_fs_state(idct->pipe, idct->matrix_fs);
401be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->transpose_vs);
4028e0c05960daa7a38ab7834e6a9e7e0a7a973ac2dChristian König   idct->pipe->delete_fs_state(idct->pipe, idct->transpose_fs);
403508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
404508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
405508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic bool
4060b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königinit_state(struct vl_idct *idct)
4070b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
4080b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   struct pipe_sampler_state sampler;
4090b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   struct pipe_rasterizer_state rs_state;
4100b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
4110b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4120b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct);
4130b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4148330bc29dda71c41c56b3c1989334823ae8779d4Christian König   memset(&rs_state, 0, sizeof(rs_state));
4158330bc29dda71c41c56b3c1989334823ae8779d4Christian König   rs_state.gl_rasterization_rules = false;
4168330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->rs_state = idct->pipe->create_rasterizer_state(idct->pipe, &rs_state);
4178330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->rs_state)
4188330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_rs_state;
4198330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4205a351e51291922aa295926215fdecccc0baeef51Christian König   for (i = 0; i < 2; ++i) {
4210b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      memset(&sampler, 0, sizeof(sampler));
422be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
423be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
424be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      sampler.wrap_r = PIPE_TEX_WRAP_REPEAT;
4250b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
4260b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
4270b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
4280b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
4290b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.compare_func = PIPE_FUNC_ALWAYS;
4300b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.normalized_coords = 1;
4315a351e51291922aa295926215fdecccc0baeef51Christian König      idct->samplers[i] = idct->pipe->create_sampler_state(idct->pipe, &sampler);
4325a351e51291922aa295926215fdecccc0baeef51Christian König      if (!idct->samplers[i])
4338330bc29dda71c41c56b3c1989334823ae8779d4Christian König         goto error_samplers;
4340b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   }
4350b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4360b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   return true;
4378330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4388330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_samplers:
4395a351e51291922aa295926215fdecccc0baeef51Christian König   for (i = 0; i < 2; ++i)
4405a351e51291922aa295926215fdecccc0baeef51Christian König      if (idct->samplers[i])
4415a351e51291922aa295926215fdecccc0baeef51Christian König         idct->pipe->delete_sampler_state(idct->pipe, idct->samplers[i]);
4428330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4438330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state);
4448330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4458330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_rs_state:
4468330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return false;
4470b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
4480b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4490b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königstatic void
4500b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königcleanup_state(struct vl_idct *idct)
4510b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
4520b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
4530b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4545a351e51291922aa295926215fdecccc0baeef51Christian König   for (i = 0; i < 2; ++i)
4555a351e51291922aa295926215fdecccc0baeef51Christian König      idct->pipe->delete_sampler_state(idct->pipe, idct->samplers[i]);
4560b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4570b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state);
4580b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
4590b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4600b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königstatic bool
461020328ca32a3b6548b4c064c4fe115e386752daaChristian Königinit_intermediate(struct vl_idct *idct, struct vl_idct_buffer *buffer)
462508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
463020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_resource tex_templ, *tex;
464020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_sampler_view sv_templ;
465020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_surface surf_templ;
46621efda86875096333dc0412c0edab1e188f551d8Christian König   unsigned i;
467508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
4680b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && buffer);
4690b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
470020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&tex_templ, 0, sizeof(tex_templ));
471020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.target = PIPE_TEXTURE_3D;
472020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.format = PIPE_FORMAT_R16G16B16A16_SNORM;
473020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.width0 = idct->buffer_width / NR_RENDER_TARGETS;
474020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.height0 = idct->buffer_height / 4;
475020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.depth0 = NR_RENDER_TARGETS;
476020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.array_size = 1;
477020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
478020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.usage = PIPE_USAGE_STATIC;
479020328ca32a3b6548b4c064c4fe115e386752daaChristian König
480020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex = idct->pipe->screen->resource_create(idct->pipe->screen, &tex_templ);
481020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!tex)
482020328ca32a3b6548b4c064c4fe115e386752daaChristian König      goto error_tex;
483020328ca32a3b6548b4c064c4fe115e386752daaChristian König
484020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&sv_templ, 0, sizeof(sv_templ));
485020328ca32a3b6548b4c064c4fe115e386752daaChristian König   u_sampler_view_default_template(&sv_templ, tex, tex->format);
486020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->sampler_views.individual.intermediate =
487020328ca32a3b6548b4c064c4fe115e386752daaChristian König      idct->pipe->create_sampler_view(idct->pipe, tex, &sv_templ);
488020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!buffer->sampler_views.individual.intermediate)
489020328ca32a3b6548b4c064c4fe115e386752daaChristian König         goto error_sampler_view;
490020328ca32a3b6548b4c064c4fe115e386752daaChristian König
491020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[0].width = tex->width0;
492020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[0].height = tex->height0;
493020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[0].nr_cbufs = NR_RENDER_TARGETS;
494020328ca32a3b6548b4c064c4fe115e386752daaChristian König   for(i = 0; i < NR_RENDER_TARGETS; ++i) {
495020328ca32a3b6548b4c064c4fe115e386752daaChristian König      memset(&surf_templ, 0, sizeof(surf_templ));
496020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.format = tex->format;
497020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.u.tex.first_layer = i;
498020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.u.tex.last_layer = i;
499020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
500020328ca32a3b6548b4c064c4fe115e386752daaChristian König      buffer->fb_state[0].cbufs[i] = idct->pipe->create_surface(
501020328ca32a3b6548b4c064c4fe115e386752daaChristian König         idct->pipe, tex, &surf_templ);
502508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
503020328ca32a3b6548b4c064c4fe115e386752daaChristian König      if (!buffer->fb_state[0].cbufs[i])
504020328ca32a3b6548b4c064c4fe115e386752daaChristian König         goto error_surfaces;
505508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   }
506508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
507020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[0].scale[0] = tex->width0;
508020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[0].scale[1] = tex->height0;
5090f07da0a1c87e1c7b53700c33d6b1f8f03c1fe11Christian König
510020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_resource_reference(&tex, NULL);
511508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   return true;
5128330bc29dda71c41c56b3c1989334823ae8779d4Christian König
513020328ca32a3b6548b4c064c4fe115e386752daaChristian Königerror_surfaces:
514020328ca32a3b6548b4c064c4fe115e386752daaChristian König   for(i = 0; i < NR_RENDER_TARGETS; ++i)
515020328ca32a3b6548b4c064c4fe115e386752daaChristian König      pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
516020328ca32a3b6548b4c064c4fe115e386752daaChristian König
517020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, NULL);
518020328ca32a3b6548b4c064c4fe115e386752daaChristian König
519020328ca32a3b6548b4c064c4fe115e386752daaChristian Königerror_sampler_view:
520020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_resource_reference(&tex, NULL);
521020328ca32a3b6548b4c064c4fe115e386752daaChristian König
522020328ca32a3b6548b4c064c4fe115e386752daaChristian Königerror_tex:
5238330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return false;
524508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
525508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
526508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void
527020328ca32a3b6548b4c064c4fe115e386752daaChristian Königcleanup_intermediate(struct vl_idct *idct, struct vl_idct_buffer *buffer)
528508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
529508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   unsigned i;
530508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
5310b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && buffer);
532508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
533020328ca32a3b6548b4c064c4fe115e386752daaChristian König   for(i = 0; i < NR_RENDER_TARGETS; ++i)
534020328ca32a3b6548b4c064c4fe115e386752daaChristian König      pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
535020328ca32a3b6548b4c064c4fe115e386752daaChristian König
536020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, NULL);
537508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
538508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
539020328ca32a3b6548b4c064c4fe115e386752daaChristian Königstruct pipe_sampler_view *
5403dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian Königvl_idct_upload_matrix(struct pipe_context *pipe)
5413dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König{
542e87bd8c9578dee384ff03039aa792e1a8dae7f36Christian König   const float scale = sqrtf(SCALE_FACTOR_16_TO_9);
543e87bd8c9578dee384ff03039aa792e1a8dae7f36Christian König
544020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_resource tex_templ, *matrix;
545020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_sampler_view sv_templ, *sv;
5463dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   struct pipe_transfer *buf_transfer;
5473dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   unsigned i, j, pitch;
5483dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   float *f;
5493dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5503dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   struct pipe_box rect =
5513dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   {
5523dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      0, 0, 0,
5537c4887f5ae642131d7895da5bffda77a6287c6d4Christian König      BLOCK_WIDTH / 4,
5543dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      BLOCK_HEIGHT,
5553dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      1
5563dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   };
5573dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5588330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(pipe);
5598330bc29dda71c41c56b3c1989334823ae8779d4Christian König
560020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&tex_templ, 0, sizeof(tex_templ));
561020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.target = PIPE_TEXTURE_2D;
562020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.format = PIPE_FORMAT_R32G32B32A32_FLOAT;
563020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.last_level = 0;
564020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.width0 = 2;
565020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.height0 = 8;
566020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.depth0 = 1;
567020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.array_size = 1;
568020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.usage = PIPE_USAGE_IMMUTABLE;
569020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.bind = PIPE_BIND_SAMPLER_VIEW;
570020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.flags = 0;
571020328ca32a3b6548b4c064c4fe115e386752daaChristian König
572020328ca32a3b6548b4c064c4fe115e386752daaChristian König   matrix = pipe->screen->resource_create(pipe->screen, &tex_templ);
5738330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!matrix)
5748330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_matrix;
5753dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5763dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   buf_transfer = pipe->get_transfer
5773dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   (
5783dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      pipe, matrix,
579772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
5803dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      &rect
5813dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   );
5828330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!buf_transfer)
5838330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_transfer;
5848330bc29dda71c41c56b3c1989334823ae8779d4Christian König
5853fd53e6c2a05e65872de4292557d7839cbcf7395Christian König   pitch = buf_transfer->stride / sizeof(float);
5863dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5873dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   f = pipe->transfer_map(pipe, buf_transfer);
5888330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!f)
5898330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_map;
5908330bc29dda71c41c56b3c1989334823ae8779d4Christian König
5913dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   for(i = 0; i < BLOCK_HEIGHT; ++i)
5923dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      for(j = 0; j < BLOCK_WIDTH; ++j)
5934a8420513d653cd2fccf93a51315120a1a5d0fccChristian König         // transpose and scale
594e87bd8c9578dee384ff03039aa792e1a8dae7f36Christian König         f[i * pitch + j] = const_matrix[j][i] * scale;
5953dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5963dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   pipe->transfer_unmap(pipe, buf_transfer);
5973dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   pipe->transfer_destroy(pipe, buf_transfer);
5983dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
599020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&sv_templ, 0, sizeof(sv_templ));
600020328ca32a3b6548b4c064c4fe115e386752daaChristian König   u_sampler_view_default_template(&sv_templ, matrix, matrix->format);
601020328ca32a3b6548b4c064c4fe115e386752daaChristian König   sv = pipe->create_sampler_view(pipe, matrix, &sv_templ);
602020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_resource_reference(&matrix, NULL);
603020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!sv)
604020328ca32a3b6548b4c064c4fe115e386752daaChristian König      goto error_map;
605020328ca32a3b6548b4c064c4fe115e386752daaChristian König
606020328ca32a3b6548b4c064c4fe115e386752daaChristian König   return sv;
6078330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6088330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_map:
6098330bc29dda71c41c56b3c1989334823ae8779d4Christian König   pipe->transfer_destroy(pipe, buf_transfer);
6108330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6118330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_transfer:
6128330bc29dda71c41c56b3c1989334823ae8779d4Christian König   pipe_resource_reference(&matrix, NULL);
6138330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6148330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_matrix:
6158330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return NULL;
6163dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König}
6173dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
618c8236aaf7056bd8645804e71596d2d6460e62d15Christian Königbool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
6190b749d6dcb537472771d6fe6e454aafc916ab3feChristian König                  unsigned buffer_width, unsigned buffer_height,
620310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König                  unsigned blocks_x, unsigned blocks_y,
621020328ca32a3b6548b4c064c4fe115e386752daaChristian König                  int color_swizzle, struct pipe_sampler_view *matrix)
622e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König{
6230b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && pipe && matrix);
624e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
625e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König   idct->pipe = pipe;
6260b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->buffer_width = buffer_width;
6270b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->buffer_height = buffer_height;
628310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   idct->blocks_x = blocks_x;
629310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   idct->blocks_y = blocks_y;
630020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&idct->matrix, matrix);
631508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
632310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   if(!init_shaders(idct, color_swizzle))
633508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König      return false;
634508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
6350b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   if(!init_state(idct)) {
6360b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      cleanup_shaders(idct);
637508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König      return false;
638508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   }
639508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
6400b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   return true;
6410b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
6420b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6430b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvoid
6440b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_cleanup(struct vl_idct *idct)
6450b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
6460b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   cleanup_shaders(idct);
6470b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   cleanup_state(idct);
6480b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
649020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&idct->matrix, NULL);
6500b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
6510b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
652020328ca32a3b6548b4c064c4fe115e386752daaChristian Königbool
653020328ca32a3b6548b4c064c4fe115e386752daaChristian Königvl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
654020328ca32a3b6548b4c064c4fe115e386752daaChristian König                    struct pipe_sampler_view *source, struct pipe_surface *destination)
6550b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
6560b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
6570b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6580b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(buffer);
6590b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct);
660020328ca32a3b6548b4c064c4fe115e386752daaChristian König   assert(source);
661020328ca32a3b6548b4c064c4fe115e386752daaChristian König   assert(destination);
6620b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
663020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.matrix, idct->matrix);
664020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.source, source);
665020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.transpose, idct->matrix);
6660b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
667020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!init_intermediate(idct, buffer))
668020328ca32a3b6548b4c064c4fe115e386752daaChristian König      return false;
6690b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6700b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   /* init state */
671020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[1].width = destination->texture->width0;
672020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[1].height = destination->texture->height0;
6730b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   buffer->fb_state[1].nr_cbufs = 1;
674020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_surface_reference(&buffer->fb_state[1].cbufs[0], destination);
675772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König
676020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[1].scale[0] = destination->texture->width0;
677020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[1].scale[1] = destination->texture->height0;
6788330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6790b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   for(i = 0; i < 2; ++i) {
6800b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].scale[2] = 1;
6810b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].scale[3] = 1;
6820b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[0] = 0;
6830b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[1] = 0;
6840b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[2] = 0;
6850b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[3] = 0;
6860b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6870b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->fb_state[i].zsbuf = NULL;
6880b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   }
689508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
690020328ca32a3b6548b4c064c4fe115e386752daaChristian König   return true;
691508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
692508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
69303c5a0ea5cd5b3e5931d6784749f87789a016b98Christian Königvoid
6940b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
695508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
6960b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
6976484898752d733a2442b433fbb78325f9021c698Christian König
6988330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(idct && buffer);
699e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
7008330bc29dda71c41c56b3c1989334823ae8779d4Christian König   for(i = 0; i < NR_RENDER_TARGETS; ++i)
7018330bc29dda71c41c56b3c1989334823ae8779d4Christian König      pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
7020b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
7038330bc29dda71c41c56b3c1989334823ae8779d4Christian König   pipe_surface_reference(&buffer->fb_state[1].cbufs[0], NULL);
704e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
705020328ca32a3b6548b4c064c4fe115e386752daaChristian König   cleanup_intermediate(idct, buffer);
706508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
707508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
70803c5a0ea5cd5b3e5931d6784749f87789a016b98Christian Königvoid
7090b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
7106484898752d733a2442b433fbb78325f9021c698Christian König{
711020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_resource *tex;
712020328ca32a3b6548b4c064c4fe115e386752daaChristian König
7138330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(idct && buffer);
7146484898752d733a2442b433fbb78325f9021c698Christian König
715020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex = buffer->sampler_views.individual.source->texture;
716020328ca32a3b6548b4c064c4fe115e386752daaChristian König
7176484898752d733a2442b433fbb78325f9021c698Christian König   struct pipe_box rect =
7186484898752d733a2442b433fbb78325f9021c698Christian König   {
7196484898752d733a2442b433fbb78325f9021c698Christian König      0, 0, 0,
720020328ca32a3b6548b4c064c4fe115e386752daaChristian König      tex->width0,
721020328ca32a3b6548b4c064c4fe115e386752daaChristian König      tex->height0,
7226484898752d733a2442b433fbb78325f9021c698Christian König      1
7236484898752d733a2442b433fbb78325f9021c698Christian König   };
7246484898752d733a2442b433fbb78325f9021c698Christian König
7250b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   buffer->tex_transfer = idct->pipe->get_transfer
7266484898752d733a2442b433fbb78325f9021c698Christian König   (
727020328ca32a3b6548b4c064c4fe115e386752daaChristian König      idct->pipe, tex,
728772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
7296484898752d733a2442b433fbb78325f9021c698Christian König      &rect
7306484898752d733a2442b433fbb78325f9021c698Christian König   );
7316484898752d733a2442b433fbb78325f9021c698Christian König
7320b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   buffer->texels = idct->pipe->transfer_map(idct->pipe, buffer->tex_transfer);
7336484898752d733a2442b433fbb78325f9021c698Christian König}
7346484898752d733a2442b433fbb78325f9021c698Christian König
7356484898752d733a2442b433fbb78325f9021c698Christian Königvoid
7360b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_add_block(struct vl_idct_buffer *buffer, unsigned x, unsigned y, short *block)
737508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
738508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   unsigned tex_pitch;
739508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   short *texels;
740e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
741508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   unsigned i;
742508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
7430b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(buffer);
7448330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(block);
745e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
7460b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   tex_pitch = buffer->tex_transfer->stride / sizeof(short);
7470b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   texels = buffer->texels + y * tex_pitch * BLOCK_HEIGHT + x * BLOCK_WIDTH;
74803c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König
7499af3c243d958dd5b9802dda321ab980c83cb8cb8Christian König   for (i = 0; i < BLOCK_HEIGHT; ++i)
7509af3c243d958dd5b9802dda321ab980c83cb8cb8Christian König      memcpy(texels + i * tex_pitch, block + i * BLOCK_WIDTH, BLOCK_WIDTH * sizeof(short));
751508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
752508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
75303c5a0ea5cd5b3e5931d6784749f87789a016b98Christian Königvoid
7540b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_unmap_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
7556484898752d733a2442b433fbb78325f9021c698Christian König{
7560b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && buffer);
7576484898752d733a2442b433fbb78325f9021c698Christian König
7580b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->pipe->transfer_unmap(idct->pipe, buffer->tex_transfer);
7590b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->pipe->transfer_destroy(idct->pipe, buffer->tex_transfer);
7606484898752d733a2442b433fbb78325f9021c698Christian König}
7616484898752d733a2442b433fbb78325f9021c698Christian König
7626484898752d733a2442b433fbb78325f9021c698Christian Königvoid
763310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian Königvl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer, unsigned num_instances)
764508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
76557018734023b41ef84f5be560c12dce6ae5f1c58Christian König   unsigned num_verts;
7664abe7382882a451a7750ccc451b8568768d122cbChristian König
7674abe7382882a451a7750ccc451b8568768d122cbChristian König   assert(idct);
768310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   assert(buffer);
7694abe7382882a451a7750ccc451b8568768d122cbChristian König
770310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   if(num_instances > 0) {
771310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      num_verts = idct->blocks_x * idct->blocks_y * 4;
77203c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König
77329840040af128fe3f3542defd9448e1f66c23f03Christian König      idct->pipe->bind_rasterizer_state(idct->pipe, idct->rs_state);
7745a351e51291922aa295926215fdecccc0baeef51Christian König      idct->pipe->bind_fragment_sampler_states(idct->pipe, 2, idct->samplers);
77529840040af128fe3f3542defd9448e1f66c23f03Christian König
77603c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König      /* first stage */
7770b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[0]);
7780b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[0]);
7790b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[0]);
780be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      idct->pipe->bind_vs_state(idct->pipe, idct->matrix_vs);
78113e28cff7655adec0f89aed9c5ee74f8481133abChristian König      idct->pipe->bind_fs_state(idct->pipe, idct->matrix_fs);
782310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      util_draw_arrays_instanced(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts, 0, num_instances);
78303c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König
78403c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König      /* second stage */
7850b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[1]);
7860b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[1]);
7870b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[1]);
788be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      idct->pipe->bind_vs_state(idct->pipe, idct->transpose_vs);
78913e28cff7655adec0f89aed9c5ee74f8481133abChristian König      idct->pipe->bind_fs_state(idct->pipe, idct->transpose_fs);
790310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      util_draw_arrays_instanced(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts, 0, num_instances);
79195febb69cc333dad75c0f2da19dd85f444281ad2Christian König   }
792508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
793