vl_idct.c revision 59774e5c7a2756c5c430fc74bc80ea75d54f594d
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 *
9359774e5c7a2756c5c430fc74bc80ea75d54f594dChristian Königcreate_vert_shader(struct vl_idct *idct, bool matrix_stage)
94508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
95508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   struct ureg_program *shader;
96794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König   struct ureg_src vrect, vpos, vblock, eb;
97794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König   struct ureg_src scale, blocks_xy;
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
115794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König   eb = ureg_DECL_vs_input(shader, VS_I_EB);
116310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
117be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0);
118be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1);
119be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
120be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0);
121be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1);
122508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
123508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   /*
12412836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König    * scale = (BLOCK_WIDTH, BLOCK_HEIGHT) / (dst.width, dst.height)
125310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * blocks_xy = (blocks_x, blocks_y)
12612836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König    *
127794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König    * if eb.(vblock.y, vblock.x)
128310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_vpos.xy = -1
129310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * else
130310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    t_tex = vpos * blocks_xy + vblock
131310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    t_start = t_tex * scale
132310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    t_tex = t_tex + vrect
133310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_vpos.xy = t_tex * scale
134508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König    *
135310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_l_addr = calc_addr(...)
136310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    *    o_r_addr = calc_addr(...)
137310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * endif
138310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König    * o_vpos.zw = vpos
139508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König    *
140508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König    */
141310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
14212836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König   scale = ureg_imm2f(shader,
14322b4acb2069a368e986805d3b43395172ebf9146Christian König      (float)BLOCK_WIDTH / idct->buffer_width,
14422b4acb2069a368e986805d3b43395172ebf9146Christian König      (float)BLOCK_HEIGHT / idct->buffer_height);
14512836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König
146310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   blocks_xy = ureg_imm2f(shader, idct->blocks_x, idct->blocks_y);
147ab130400cf91ab471e265e58193c95f04c7aeedaChristian König
148310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   if (idct->blocks_x > 1 || idct->blocks_y > 1) {
149794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König      ureg_CMP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY),
150794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König         ureg_negate(ureg_scalar(vblock, TGSI_SWIZZLE_Y)),
151794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König         ureg_swizzle(eb, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_W),
152794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König         ureg_swizzle(eb, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y));
153f853ea007816cdad4395b42388e12cd65bb8eb43Christian König
154794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König      ureg_CMP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X),
155794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König         ureg_negate(ureg_scalar(vblock, TGSI_SWIZZLE_X)),
156794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König         ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_Y),
157794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König         ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X));
158508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
159794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König      eb = ureg_src(t_tex);
160be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   }
161be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
162794cde3f5ef59cf603be284fbc8de33d2cda7d2cChristian König   ureg_IF(shader, ureg_scalar(eb, TGSI_SWIZZLE_X), &label);
163310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
164310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MOV(shader, o_vpos, ureg_imm1f(shader, -1.0f));
165310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
166310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
167310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_ELSE(shader, &label);
168310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
169310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MAD(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, blocks_xy, vblock);
170310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), ureg_src(t_tex), scale);
171310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
172310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_ADD(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), ureg_src(t_tex), vrect);
173310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
174310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), ureg_src(t_tex), scale);
175310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_Z),
176310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         ureg_scalar(vrect, TGSI_SWIZZLE_X),
177310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         ureg_imm1f(shader, BLOCK_WIDTH / NR_RENDER_TARGETS));
178310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
179310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_tex));
180310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
181310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      if(matrix_stage) {
182310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_l_addr, ureg_src(t_tex), ureg_src(t_start), false, false, idct->buffer_width / 4);
183310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_r_addr, vrect, ureg_imm1f(shader, 0.0f), true, true, BLOCK_WIDTH / 4);
184310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      } else {
185310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_l_addr, vrect, ureg_imm1f(shader, 0.0f), false, false, BLOCK_WIDTH / 4);
186310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König         calc_addr(shader, o_r_addr, ureg_src(t_tex), ureg_src(t_start), true, false, idct->buffer_height / 4);
187310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      }
188310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
189310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
190310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_ENDIF(shader);
191310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
192310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
193310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König
194be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, t_tex);
195be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, t_start);
196508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
197508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   ureg_END(shader);
198508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
199508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   return ureg_create_shader_and_destroy(shader, idct->pipe);
200508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
201508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
202508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void
203f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian Königincrement_addr(struct ureg_program *shader, struct ureg_dst daddr[2],
204f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König               struct ureg_src saddr[2], bool right_side, bool transposed,
205f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König               int pos, float size)
206ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König{
207f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y;
208ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X;
209508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
210c8236aaf7056bd8645804e71596d2d6460e62d15Christian König   /*
211c8236aaf7056bd8645804e71596d2d6460e62d15Christian König    * daddr[0..1].(start) = saddr[0..1].(start)
212c8236aaf7056bd8645804e71596d2d6460e62d15Christian König    * daddr[0..1].(tc) = saddr[0..1].(tc)
213f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König    */
214c8236aaf7056bd8645804e71596d2d6460e62d15Christian König
215f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_MOV(shader, ureg_writemask(daddr[0], wm_start), saddr[0]);
216f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_ADD(shader, ureg_writemask(daddr[0], wm_tc), saddr[0], ureg_imm1f(shader, pos / size));
217f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_MOV(shader, ureg_writemask(daddr[1], wm_start), saddr[1]);
218f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_ADD(shader, ureg_writemask(daddr[1], wm_tc), saddr[1], ureg_imm1f(shader, pos / size));
219ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König}
220ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König
221ebab090ed93270b40475151e60dbc7f2b72f1a61Christian Königstatic void
222be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königfetch_four(struct ureg_program *shader, struct ureg_dst m[2], struct ureg_src addr[2], struct ureg_src sampler)
223ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König{
224be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_TEX(shader, m[0], TGSI_TEXTURE_3D, addr[0], sampler);
225be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_TEX(shader, m[1], TGSI_TEXTURE_3D, addr[1], sampler);
226cfe489b89723117e56674c2be7761c201f8d78ffChristian König}
227508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
22812836fbcfad7f317b1f5aa5e46f9946894bf040cChristian Königstatic void
22912836fbcfad7f317b1f5aa5e46f9946894bf040cChristian Königmatrix_mul(struct ureg_program *shader, struct ureg_dst dst, struct ureg_dst l[2], struct ureg_dst r[2])
230cfe489b89723117e56674c2be7761c201f8d78ffChristian König{
231ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   struct ureg_dst tmp;
232cfe489b89723117e56674c2be7761c201f8d78ffChristian König
233ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   tmp = ureg_DECL_temporary(shader);
234508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
235cfe489b89723117e56674c2be7761c201f8d78ffChristian König   /*
236ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König    * tmp.xy = dot4(m[0][0..1], m[1][0..1])
237ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König    * dst = tmp.x + tmp.y
238cfe489b89723117e56674c2be7761c201f8d78ffChristian König    */
239ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_src(l[0]), ureg_src(r[0]));
240ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(l[1]), ureg_src(r[1]));
24174c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   ureg_ADD(shader, dst,
242ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König      ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X),
243ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König      ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y));
244508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
245ebab090ed93270b40475151e60dbc7f2b72f1a61Christian König   ureg_release_temporary(shader, tmp);
246508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
247508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
248508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void *
249508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königcreate_matrix_frag_shader(struct vl_idct *idct)
250508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
251508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   struct ureg_program *shader;
252cfe489b89723117e56674c2be7761c201f8d78ffChristian König
253f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   struct ureg_src l_addr[2], r_addr[2];
254cfe489b89723117e56674c2be7761c201f8d78ffChristian König
255f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   struct ureg_dst l[4][2], r[2];
256be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_dst fragment[NR_RENDER_TARGETS];
25712836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König
25874c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   unsigned i, j;
259508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
260508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
261508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   if (!shader)
262508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König      return NULL;
263508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
264be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR);
265be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR);
266be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
267be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR);
268be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR);
269cfe489b89723117e56674c2be7761c201f8d78ffChristian König
270a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König   for (i = 0; i < NR_RENDER_TARGETS; ++i)
271e742a1043dbd56fe11f0490cb74b7a738bab2238Christian König       fragment[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, i);
272e742a1043dbd56fe11f0490cb74b7a738bab2238Christian König
27374c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   for (i = 0; i < 4; ++i) {
274f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      l[i][0] = ureg_DECL_temporary(shader);
275f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      l[i][1] = ureg_DECL_temporary(shader);
276f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   }
2774a8420513d653cd2fccf93a51315120a1a5d0fccChristian König
278f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[0] = ureg_DECL_temporary(shader);
279f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[1] = ureg_DECL_temporary(shader);
280f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König
281f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   for (i = 1; i < 4; ++i) {
282f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      increment_addr(shader, l[i], l_addr, false, false, i, idct->buffer_height);
283f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   }
284f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König
285f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   for (i = 0; i < 4; ++i) {
286f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      struct ureg_src s_addr[2];
287f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[0] = i == 0 ? l_addr[0] : ureg_src(l[i][0]);
288f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[1] = i == 0 ? l_addr[1] : ureg_src(l[i][1]);
289f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      fetch_four(shader, l[i], s_addr, ureg_DECL_sampler(shader, 1));
29074c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   }
291c8236aaf7056bd8645804e71596d2d6460e62d15Christian König
292a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König   for (i = 0; i < NR_RENDER_TARGETS; ++i) {
293f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      if(i > 0)
294f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König         increment_addr(shader, r, r_addr, true, true, i, BLOCK_HEIGHT);
295a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König
296f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      struct ureg_src s_addr[2] = { ureg_src(r[0]), ureg_src(r[1]) };
297f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[0] = i == 0 ? r_addr[0] : ureg_src(r[0]);
298f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      s_addr[1] = i == 0 ? r_addr[1] : ureg_src(r[1]);
299f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König      fetch_four(shader, r, s_addr, ureg_DECL_sampler(shader, 0));
300a984c67b316ac2ca9aaf6d38a3127cf3d61a249eChristian König
30174c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      for (j = 0; j < 4; ++j) {
30274c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König         matrix_mul(shader, ureg_writemask(fragment[i], TGSI_WRITEMASK_X << j), l[j], r);
30374c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      }
304e742a1043dbd56fe11f0490cb74b7a738bab2238Christian König   }
30574c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König
30674c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   for (i = 0; i < 4; ++i) {
30774c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      ureg_release_temporary(shader, l[i][0]);
30874c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König      ureg_release_temporary(shader, l[i][1]);
30974c71f09f3d321963b738acfb0bfd30b1e1efaebChristian König   }
310f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_release_temporary(shader, r[0]);
311f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   ureg_release_temporary(shader, r[1]);
312be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
313be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_END(shader);
314be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
315be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   return ureg_create_shader_and_destroy(shader, idct->pipe);
316be4de05c1093db27b3fca12b782055ab8a1eba13Christian König}
317be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
318be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königstatic void *
319be4de05c1093db27b3fca12b782055ab8a1eba13Christian Königcreate_transpose_frag_shader(struct vl_idct *idct)
320be4de05c1093db27b3fca12b782055ab8a1eba13Christian König{
321be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_program *shader;
322be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
323be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_src l_addr[2], r_addr[2];
324be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
325be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   struct ureg_dst l[2], r[2];
326f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   struct ureg_dst fragment;
327be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
328be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
329be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   if (!shader)
330be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      return NULL;
331be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
332be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR);
333be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR);
334be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
335be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR);
336be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR);
337be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
338f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   l[0] = ureg_DECL_temporary(shader);
339f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   l[1] = ureg_DECL_temporary(shader);
340f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[0] = ureg_DECL_temporary(shader);
341f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   r[1] = ureg_DECL_temporary(shader);
342f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König
343be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   fetch_four(shader, l, l_addr, ureg_DECL_sampler(shader, 0));
344be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   fetch_four(shader, r, r_addr, ureg_DECL_sampler(shader, 1));
345be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
346be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
347be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
348f780626c35c7c3cac2e9aa7c2ec77ca587d6ab95Christian König   matrix_mul(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), l, r);
349be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
350be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, l[0]);
351be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, l[1]);
352be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, r[0]);
353be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   ureg_release_temporary(shader, r[1]);
354508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
355508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   ureg_END(shader);
356508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
357508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   return ureg_create_shader_and_destroy(shader, idct->pipe);
358508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
359508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
360508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic bool
36159774e5c7a2756c5c430fc74bc80ea75d54f594dChristian Königinit_shaders(struct vl_idct *idct)
362508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
36359774e5c7a2756c5c430fc74bc80ea75d54f594dChristian König   idct->matrix_vs = create_vert_shader(idct, true);
3648330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->matrix_vs)
3658330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_matrix_vs;
3668330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3675a8078486a013152d150a4524ebfab929eefe6c4Christian König   idct->matrix_fs = create_matrix_frag_shader(idct);
3688330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->matrix_fs)
3698330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_matrix_fs;
370be4de05c1093db27b3fca12b782055ab8a1eba13Christian König
37159774e5c7a2756c5c430fc74bc80ea75d54f594dChristian König   idct->transpose_vs = create_vert_shader(idct, false);
3728330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->transpose_vs)
3738330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_transpose_vs;
3748330bc29dda71c41c56b3c1989334823ae8779d4Christian König
37512836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König   idct->transpose_fs = create_transpose_frag_shader(idct);
3768330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->transpose_fs)
3778330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_transpose_fs;
3788330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3798330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return true;
3808330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3818330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_transpose_fs:
3828330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->transpose_vs);
38312836fbcfad7f317b1f5aa5e46f9946894bf040cChristian König
3848330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_transpose_vs:
3858330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_fs_state(idct->pipe, idct->matrix_fs);
3868330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3878330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_matrix_fs:
3888330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->matrix_vs);
3898330bc29dda71c41c56b3c1989334823ae8779d4Christian König
3908330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_matrix_vs:
3918330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return false;
392508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
393508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
394508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void
395508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königcleanup_shaders(struct vl_idct *idct)
396508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
397be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->matrix_vs);
398508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   idct->pipe->delete_fs_state(idct->pipe, idct->matrix_fs);
399be4de05c1093db27b3fca12b782055ab8a1eba13Christian König   idct->pipe->delete_vs_state(idct->pipe, idct->transpose_vs);
4008e0c05960daa7a38ab7834e6a9e7e0a7a973ac2dChristian König   idct->pipe->delete_fs_state(idct->pipe, idct->transpose_fs);
401508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
402508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
403508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic bool
4040b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königinit_state(struct vl_idct *idct)
4050b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
4060b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   struct pipe_sampler_state sampler;
4070b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   struct pipe_rasterizer_state rs_state;
4080b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
4090b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4100b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct);
4110b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4128330bc29dda71c41c56b3c1989334823ae8779d4Christian König   memset(&rs_state, 0, sizeof(rs_state));
4138330bc29dda71c41c56b3c1989334823ae8779d4Christian König   rs_state.gl_rasterization_rules = false;
4148330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->rs_state = idct->pipe->create_rasterizer_state(idct->pipe, &rs_state);
4158330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!idct->rs_state)
4168330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_rs_state;
4178330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4185a351e51291922aa295926215fdecccc0baeef51Christian König   for (i = 0; i < 2; ++i) {
4190b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      memset(&sampler, 0, sizeof(sampler));
420be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
421be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
422be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      sampler.wrap_r = PIPE_TEX_WRAP_REPEAT;
4230b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
4240b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
4250b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
4260b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
4270b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.compare_func = PIPE_FUNC_ALWAYS;
4280b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      sampler.normalized_coords = 1;
4295a351e51291922aa295926215fdecccc0baeef51Christian König      idct->samplers[i] = idct->pipe->create_sampler_state(idct->pipe, &sampler);
4305a351e51291922aa295926215fdecccc0baeef51Christian König      if (!idct->samplers[i])
4318330bc29dda71c41c56b3c1989334823ae8779d4Christian König         goto error_samplers;
4320b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   }
4330b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4340b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   return true;
4358330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4368330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_samplers:
4375a351e51291922aa295926215fdecccc0baeef51Christian König   for (i = 0; i < 2; ++i)
4385a351e51291922aa295926215fdecccc0baeef51Christian König      if (idct->samplers[i])
4395a351e51291922aa295926215fdecccc0baeef51Christian König         idct->pipe->delete_sampler_state(idct->pipe, idct->samplers[i]);
4408330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4418330bc29dda71c41c56b3c1989334823ae8779d4Christian König   idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state);
4428330bc29dda71c41c56b3c1989334823ae8779d4Christian König
4438330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_rs_state:
4448330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return false;
4450b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
4460b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4470b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königstatic void
4480b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königcleanup_state(struct vl_idct *idct)
4490b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
4500b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
4510b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4525a351e51291922aa295926215fdecccc0baeef51Christian König   for (i = 0; i < 2; ++i)
4535a351e51291922aa295926215fdecccc0baeef51Christian König      idct->pipe->delete_sampler_state(idct->pipe, idct->samplers[i]);
4540b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4550b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state);
4560b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
4570b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
4580b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königstatic bool
459020328ca32a3b6548b4c064c4fe115e386752daaChristian Königinit_intermediate(struct vl_idct *idct, struct vl_idct_buffer *buffer)
460508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
461020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_resource tex_templ, *tex;
462020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_sampler_view sv_templ;
463020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_surface surf_templ;
46421efda86875096333dc0412c0edab1e188f551d8Christian König   unsigned i;
465508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
4660b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && buffer);
4670b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
468020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&tex_templ, 0, sizeof(tex_templ));
469020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.target = PIPE_TEXTURE_3D;
470020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.format = PIPE_FORMAT_R16G16B16A16_SNORM;
471020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.width0 = idct->buffer_width / NR_RENDER_TARGETS;
472020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.height0 = idct->buffer_height / 4;
473020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.depth0 = NR_RENDER_TARGETS;
474020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.array_size = 1;
475020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
476020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.usage = PIPE_USAGE_STATIC;
477020328ca32a3b6548b4c064c4fe115e386752daaChristian König
478020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex = idct->pipe->screen->resource_create(idct->pipe->screen, &tex_templ);
479020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!tex)
480020328ca32a3b6548b4c064c4fe115e386752daaChristian König      goto error_tex;
481020328ca32a3b6548b4c064c4fe115e386752daaChristian König
482020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&sv_templ, 0, sizeof(sv_templ));
483020328ca32a3b6548b4c064c4fe115e386752daaChristian König   u_sampler_view_default_template(&sv_templ, tex, tex->format);
484020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->sampler_views.individual.intermediate =
485020328ca32a3b6548b4c064c4fe115e386752daaChristian König      idct->pipe->create_sampler_view(idct->pipe, tex, &sv_templ);
486020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!buffer->sampler_views.individual.intermediate)
487020328ca32a3b6548b4c064c4fe115e386752daaChristian König         goto error_sampler_view;
488020328ca32a3b6548b4c064c4fe115e386752daaChristian König
489020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[0].width = tex->width0;
490020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[0].height = tex->height0;
491020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[0].nr_cbufs = NR_RENDER_TARGETS;
492020328ca32a3b6548b4c064c4fe115e386752daaChristian König   for(i = 0; i < NR_RENDER_TARGETS; ++i) {
493020328ca32a3b6548b4c064c4fe115e386752daaChristian König      memset(&surf_templ, 0, sizeof(surf_templ));
494020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.format = tex->format;
495020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.u.tex.first_layer = i;
496020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.u.tex.last_layer = i;
497020328ca32a3b6548b4c064c4fe115e386752daaChristian König      surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
498020328ca32a3b6548b4c064c4fe115e386752daaChristian König      buffer->fb_state[0].cbufs[i] = idct->pipe->create_surface(
499020328ca32a3b6548b4c064c4fe115e386752daaChristian König         idct->pipe, tex, &surf_templ);
500508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
501020328ca32a3b6548b4c064c4fe115e386752daaChristian König      if (!buffer->fb_state[0].cbufs[i])
502020328ca32a3b6548b4c064c4fe115e386752daaChristian König         goto error_surfaces;
503508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   }
504508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
505020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[0].scale[0] = tex->width0;
506020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[0].scale[1] = tex->height0;
5070f07da0a1c87e1c7b53700c33d6b1f8f03c1fe11Christian König
508020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_resource_reference(&tex, NULL);
509508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   return true;
5108330bc29dda71c41c56b3c1989334823ae8779d4Christian König
511020328ca32a3b6548b4c064c4fe115e386752daaChristian Königerror_surfaces:
512020328ca32a3b6548b4c064c4fe115e386752daaChristian König   for(i = 0; i < NR_RENDER_TARGETS; ++i)
513020328ca32a3b6548b4c064c4fe115e386752daaChristian König      pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
514020328ca32a3b6548b4c064c4fe115e386752daaChristian König
515020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, NULL);
516020328ca32a3b6548b4c064c4fe115e386752daaChristian König
517020328ca32a3b6548b4c064c4fe115e386752daaChristian Königerror_sampler_view:
518020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_resource_reference(&tex, NULL);
519020328ca32a3b6548b4c064c4fe115e386752daaChristian König
520020328ca32a3b6548b4c064c4fe115e386752daaChristian Königerror_tex:
5218330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return false;
522508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
523508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
524508a4a056c3140dc1f90b93acd46c06c30f7094eChristian Königstatic void
525020328ca32a3b6548b4c064c4fe115e386752daaChristian Königcleanup_intermediate(struct vl_idct *idct, struct vl_idct_buffer *buffer)
526508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
527508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   unsigned i;
528508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
5290b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && buffer);
530508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
531020328ca32a3b6548b4c064c4fe115e386752daaChristian König   for(i = 0; i < NR_RENDER_TARGETS; ++i)
532020328ca32a3b6548b4c064c4fe115e386752daaChristian König      pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
533020328ca32a3b6548b4c064c4fe115e386752daaChristian König
534020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.intermediate, NULL);
535508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
536508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
537020328ca32a3b6548b4c064c4fe115e386752daaChristian Königstruct pipe_sampler_view *
5383dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian Königvl_idct_upload_matrix(struct pipe_context *pipe)
5393dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König{
540e87bd8c9578dee384ff03039aa792e1a8dae7f36Christian König   const float scale = sqrtf(SCALE_FACTOR_16_TO_9);
541e87bd8c9578dee384ff03039aa792e1a8dae7f36Christian König
542020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_resource tex_templ, *matrix;
543020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_sampler_view sv_templ, *sv;
5443dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   struct pipe_transfer *buf_transfer;
5453dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   unsigned i, j, pitch;
5463dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   float *f;
5473dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5483dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   struct pipe_box rect =
5493dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   {
5503dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      0, 0, 0,
5517c4887f5ae642131d7895da5bffda77a6287c6d4Christian König      BLOCK_WIDTH / 4,
5523dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      BLOCK_HEIGHT,
5533dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      1
5543dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   };
5553dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5568330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(pipe);
5578330bc29dda71c41c56b3c1989334823ae8779d4Christian König
558020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&tex_templ, 0, sizeof(tex_templ));
559020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.target = PIPE_TEXTURE_2D;
560020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.format = PIPE_FORMAT_R32G32B32A32_FLOAT;
561020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.last_level = 0;
562020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.width0 = 2;
563020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.height0 = 8;
564020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.depth0 = 1;
565020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.array_size = 1;
566020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.usage = PIPE_USAGE_IMMUTABLE;
567020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.bind = PIPE_BIND_SAMPLER_VIEW;
568020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex_templ.flags = 0;
569020328ca32a3b6548b4c064c4fe115e386752daaChristian König
570020328ca32a3b6548b4c064c4fe115e386752daaChristian König   matrix = pipe->screen->resource_create(pipe->screen, &tex_templ);
5718330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!matrix)
5728330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_matrix;
5733dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5743dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   buf_transfer = pipe->get_transfer
5753dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   (
5763dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      pipe, matrix,
577772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
5783dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      &rect
5793dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   );
5808330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!buf_transfer)
5818330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_transfer;
5828330bc29dda71c41c56b3c1989334823ae8779d4Christian König
5833fd53e6c2a05e65872de4292557d7839cbcf7395Christian König   pitch = buf_transfer->stride / sizeof(float);
5843dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5853dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   f = pipe->transfer_map(pipe, buf_transfer);
5868330bc29dda71c41c56b3c1989334823ae8779d4Christian König   if (!f)
5878330bc29dda71c41c56b3c1989334823ae8779d4Christian König      goto error_map;
5888330bc29dda71c41c56b3c1989334823ae8779d4Christian König
5893dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   for(i = 0; i < BLOCK_HEIGHT; ++i)
5903dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König      for(j = 0; j < BLOCK_WIDTH; ++j)
5914a8420513d653cd2fccf93a51315120a1a5d0fccChristian König         // transpose and scale
592e87bd8c9578dee384ff03039aa792e1a8dae7f36Christian König         f[i * pitch + j] = const_matrix[j][i] * scale;
5933dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
5943dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   pipe->transfer_unmap(pipe, buf_transfer);
5953dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König   pipe->transfer_destroy(pipe, buf_transfer);
5963dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
597020328ca32a3b6548b4c064c4fe115e386752daaChristian König   memset(&sv_templ, 0, sizeof(sv_templ));
598020328ca32a3b6548b4c064c4fe115e386752daaChristian König   u_sampler_view_default_template(&sv_templ, matrix, matrix->format);
599020328ca32a3b6548b4c064c4fe115e386752daaChristian König   sv = pipe->create_sampler_view(pipe, matrix, &sv_templ);
600020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_resource_reference(&matrix, NULL);
601020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!sv)
602020328ca32a3b6548b4c064c4fe115e386752daaChristian König      goto error_map;
603020328ca32a3b6548b4c064c4fe115e386752daaChristian König
604020328ca32a3b6548b4c064c4fe115e386752daaChristian König   return sv;
6058330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6068330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_map:
6078330bc29dda71c41c56b3c1989334823ae8779d4Christian König   pipe->transfer_destroy(pipe, buf_transfer);
6088330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6098330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_transfer:
6108330bc29dda71c41c56b3c1989334823ae8779d4Christian König   pipe_resource_reference(&matrix, NULL);
6118330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6128330bc29dda71c41c56b3c1989334823ae8779d4Christian Königerror_matrix:
6138330bc29dda71c41c56b3c1989334823ae8779d4Christian König   return NULL;
6143dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König}
6153dd7bf7d39781f3ef4c0b53732945674c9924cdfChristian König
616c8236aaf7056bd8645804e71596d2d6460e62d15Christian Königbool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
6170b749d6dcb537472771d6fe6e454aafc916ab3feChristian König                  unsigned buffer_width, unsigned buffer_height,
618310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König                  unsigned blocks_x, unsigned blocks_y,
61959774e5c7a2756c5c430fc74bc80ea75d54f594dChristian König                  struct pipe_sampler_view *matrix)
620e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König{
6210b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && pipe && matrix);
622e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
623e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König   idct->pipe = pipe;
6240b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->buffer_width = buffer_width;
6250b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->buffer_height = buffer_height;
626310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   idct->blocks_x = blocks_x;
627310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   idct->blocks_y = blocks_y;
628020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&idct->matrix, matrix);
629508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
63059774e5c7a2756c5c430fc74bc80ea75d54f594dChristian König   if(!init_shaders(idct))
631508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König      return false;
632508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
6330b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   if(!init_state(idct)) {
6340b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      cleanup_shaders(idct);
635508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König      return false;
636508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   }
637508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
6380b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   return true;
6390b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
6400b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6410b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvoid
6420b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_cleanup(struct vl_idct *idct)
6430b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
6440b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   cleanup_shaders(idct);
6450b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   cleanup_state(idct);
6460b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
647020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&idct->matrix, NULL);
6480b749d6dcb537472771d6fe6e454aafc916ab3feChristian König}
6490b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
650020328ca32a3b6548b4c064c4fe115e386752daaChristian Königbool
651020328ca32a3b6548b4c064c4fe115e386752daaChristian Königvl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
652020328ca32a3b6548b4c064c4fe115e386752daaChristian König                    struct pipe_sampler_view *source, struct pipe_surface *destination)
6530b749d6dcb537472771d6fe6e454aafc916ab3feChristian König{
6540b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
6550b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6560b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(buffer);
6570b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct);
658020328ca32a3b6548b4c064c4fe115e386752daaChristian König   assert(source);
659020328ca32a3b6548b4c064c4fe115e386752daaChristian König   assert(destination);
6600b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
661020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.matrix, idct->matrix);
662020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.source, source);
663020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_sampler_view_reference(&buffer->sampler_views.individual.transpose, idct->matrix);
6640b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
665020328ca32a3b6548b4c064c4fe115e386752daaChristian König   if (!init_intermediate(idct, buffer))
666020328ca32a3b6548b4c064c4fe115e386752daaChristian König      return false;
6670b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6680b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   /* init state */
669020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[1].width = destination->texture->width0;
670020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->fb_state[1].height = destination->texture->height0;
6710b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   buffer->fb_state[1].nr_cbufs = 1;
672020328ca32a3b6548b4c064c4fe115e386752daaChristian König   pipe_surface_reference(&buffer->fb_state[1].cbufs[0], destination);
673772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König
674020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[1].scale[0] = destination->texture->width0;
675020328ca32a3b6548b4c064c4fe115e386752daaChristian König   buffer->viewport[1].scale[1] = destination->texture->height0;
6768330bc29dda71c41c56b3c1989334823ae8779d4Christian König
6770b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   for(i = 0; i < 2; ++i) {
6780b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].scale[2] = 1;
6790b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].scale[3] = 1;
6800b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[0] = 0;
6810b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[1] = 0;
6820b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[2] = 0;
6830b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->viewport[i].translate[3] = 0;
6840b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
6850b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      buffer->fb_state[i].zsbuf = NULL;
6860b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   }
687508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
688020328ca32a3b6548b4c064c4fe115e386752daaChristian König   return true;
689508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
690508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
69103c5a0ea5cd5b3e5931d6784749f87789a016b98Christian Königvoid
6920b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
693508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
6940b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   unsigned i;
6956484898752d733a2442b433fbb78325f9021c698Christian König
6968330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(idct && buffer);
697e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
6988330bc29dda71c41c56b3c1989334823ae8779d4Christian König   for(i = 0; i < NR_RENDER_TARGETS; ++i)
6998330bc29dda71c41c56b3c1989334823ae8779d4Christian König      pipe_surface_reference(&buffer->fb_state[0].cbufs[i], NULL);
7000b749d6dcb537472771d6fe6e454aafc916ab3feChristian König
7018330bc29dda71c41c56b3c1989334823ae8779d4Christian König   pipe_surface_reference(&buffer->fb_state[1].cbufs[0], NULL);
702e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
703020328ca32a3b6548b4c064c4fe115e386752daaChristian König   cleanup_intermediate(idct, buffer);
704508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
705508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
70603c5a0ea5cd5b3e5931d6784749f87789a016b98Christian Königvoid
7070b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
7086484898752d733a2442b433fbb78325f9021c698Christian König{
709020328ca32a3b6548b4c064c4fe115e386752daaChristian König   struct pipe_resource *tex;
710020328ca32a3b6548b4c064c4fe115e386752daaChristian König
7118330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(idct && buffer);
7126484898752d733a2442b433fbb78325f9021c698Christian König
713020328ca32a3b6548b4c064c4fe115e386752daaChristian König   tex = buffer->sampler_views.individual.source->texture;
714020328ca32a3b6548b4c064c4fe115e386752daaChristian König
7156484898752d733a2442b433fbb78325f9021c698Christian König   struct pipe_box rect =
7166484898752d733a2442b433fbb78325f9021c698Christian König   {
7176484898752d733a2442b433fbb78325f9021c698Christian König      0, 0, 0,
718020328ca32a3b6548b4c064c4fe115e386752daaChristian König      tex->width0,
719020328ca32a3b6548b4c064c4fe115e386752daaChristian König      tex->height0,
7206484898752d733a2442b433fbb78325f9021c698Christian König      1
7216484898752d733a2442b433fbb78325f9021c698Christian König   };
7226484898752d733a2442b433fbb78325f9021c698Christian König
7230b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   buffer->tex_transfer = idct->pipe->get_transfer
7246484898752d733a2442b433fbb78325f9021c698Christian König   (
725020328ca32a3b6548b4c064c4fe115e386752daaChristian König      idct->pipe, tex,
726772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
7276484898752d733a2442b433fbb78325f9021c698Christian König      &rect
7286484898752d733a2442b433fbb78325f9021c698Christian König   );
7296484898752d733a2442b433fbb78325f9021c698Christian König
7300b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   buffer->texels = idct->pipe->transfer_map(idct->pipe, buffer->tex_transfer);
7316484898752d733a2442b433fbb78325f9021c698Christian König}
7326484898752d733a2442b433fbb78325f9021c698Christian König
7336484898752d733a2442b433fbb78325f9021c698Christian Königvoid
7340b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_add_block(struct vl_idct_buffer *buffer, unsigned x, unsigned y, short *block)
735508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
736508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   unsigned tex_pitch;
737508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   short *texels;
738e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
739508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König   unsigned i;
740508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
7410b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(buffer);
7428330bc29dda71c41c56b3c1989334823ae8779d4Christian König   assert(block);
743e639e1b83ea65985cd84d12dc120d77cab80ba9eChristian König
7440b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   tex_pitch = buffer->tex_transfer->stride / sizeof(short);
7450b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   texels = buffer->texels + y * tex_pitch * BLOCK_HEIGHT + x * BLOCK_WIDTH;
74603c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König
7479af3c243d958dd5b9802dda321ab980c83cb8cb8Christian König   for (i = 0; i < BLOCK_HEIGHT; ++i)
7489af3c243d958dd5b9802dda321ab980c83cb8cb8Christian König      memcpy(texels + i * tex_pitch, block + i * BLOCK_WIDTH, BLOCK_WIDTH * sizeof(short));
749508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
750508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König
75103c5a0ea5cd5b3e5931d6784749f87789a016b98Christian Königvoid
7520b749d6dcb537472771d6fe6e454aafc916ab3feChristian Königvl_idct_unmap_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
7536484898752d733a2442b433fbb78325f9021c698Christian König{
7540b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   assert(idct && buffer);
7556484898752d733a2442b433fbb78325f9021c698Christian König
7560b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->pipe->transfer_unmap(idct->pipe, buffer->tex_transfer);
7570b749d6dcb537472771d6fe6e454aafc916ab3feChristian König   idct->pipe->transfer_destroy(idct->pipe, buffer->tex_transfer);
7586484898752d733a2442b433fbb78325f9021c698Christian König}
7596484898752d733a2442b433fbb78325f9021c698Christian König
7606484898752d733a2442b433fbb78325f9021c698Christian Königvoid
761310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian Königvl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer, unsigned num_instances)
762508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König{
76357018734023b41ef84f5be560c12dce6ae5f1c58Christian König   unsigned num_verts;
7644abe7382882a451a7750ccc451b8568768d122cbChristian König
7654abe7382882a451a7750ccc451b8568768d122cbChristian König   assert(idct);
766310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   assert(buffer);
7674abe7382882a451a7750ccc451b8568768d122cbChristian König
768310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König   if(num_instances > 0) {
769310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      num_verts = idct->blocks_x * idct->blocks_y * 4;
77003c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König
77129840040af128fe3f3542defd9448e1f66c23f03Christian König      idct->pipe->bind_rasterizer_state(idct->pipe, idct->rs_state);
7725a351e51291922aa295926215fdecccc0baeef51Christian König      idct->pipe->bind_fragment_sampler_states(idct->pipe, 2, idct->samplers);
77329840040af128fe3f3542defd9448e1f66c23f03Christian König
77403c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König      /* first stage */
7750b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[0]);
7760b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[0]);
7770b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[0]);
778be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      idct->pipe->bind_vs_state(idct->pipe, idct->matrix_vs);
77913e28cff7655adec0f89aed9c5ee74f8481133abChristian König      idct->pipe->bind_fs_state(idct->pipe, idct->matrix_fs);
780310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      util_draw_arrays_instanced(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts, 0, num_instances);
78103c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König
78203c5a0ea5cd5b3e5931d6784749f87789a016b98Christian König      /* second stage */
7830b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[1]);
7840b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[1]);
7850b749d6dcb537472771d6fe6e454aafc916ab3feChristian König      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[1]);
786be4de05c1093db27b3fca12b782055ab8a1eba13Christian König      idct->pipe->bind_vs_state(idct->pipe, idct->transpose_vs);
78713e28cff7655adec0f89aed9c5ee74f8481133abChristian König      idct->pipe->bind_fs_state(idct->pipe, idct->transpose_fs);
788310eea52ca1e997295c84163066cc5d0fd4f8cf6Christian König      util_draw_arrays_instanced(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts, 0, num_instances);
78995febb69cc333dad75c0f2da19dd85f444281ad2Christian König   }
790508a4a056c3140dc1f90b93acd46c06c30f7094eChristian König}
791