1 #include "xorg_exa_tgsi.h"
3 /*### stupidity defined in X11/extensions/XI.h */
6 #include "pipe/p_format.h"
7 #include "pipe/p_context.h"
8 #include "pipe/p_state.h"
9 #include "pipe/p_inlines.h"
10 #include "pipe/p_shader_tokens.h"
12 #include "util/u_memory.h"
13 #include "util/u_simple_shaders.h"
15 #include "tgsi/tgsi_ureg.h"
17 #include "cso_cache/cso_context.h"
18 #include "cso_cache/cso_hash.h"
22 * IN[1] = src tex coord | solid fill color
23 * IN[2] = mask tex coord
24 * IN[3] = dst tex coord
25 * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
26 * CONST[1] = (-1, -1, 0, 0)
29 * OUT[1] = src tex coord | solid fill color
30 * OUT[2] = mask tex coord
31 * OUT[3] = dst tex coord
38 * IN[0] = pos src | solid fill color
41 * CONST[0] = (0, 0, 0, 1)
47 struct exa_context
*exa
;
49 struct cso_hash
*vs_hash
;
50 struct cso_hash
*fs_hash
;
53 static const char over_op
[] =
54 "SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n"
55 "MUL TEMP[3], TEMP[0], TEMP[3]\n"
56 "ADD TEMP[0], TEMP[3], TEMP[0]\n";
60 create_preamble(struct ureg_program
*ureg
)
66 src_in_mask(struct ureg_program
*ureg
,
71 /* MUL dst, src, mask.wwww */
72 ureg_MUL(ureg
, dst
, src
,
73 ureg_scalar(mask
, TGSI_SWIZZLE_W
));
76 static struct ureg_src
77 vs_normalize_coords(struct ureg_program
*ureg
, struct ureg_src coords
,
78 struct ureg_src const0
, struct ureg_src const1
)
80 struct ureg_dst tmp
= ureg_DECL_temporary(ureg
);
82 ureg_MUL(ureg
, tmp
, coords
, const0
);
83 ureg_ADD(ureg
, tmp
, ureg_src(tmp
), const1
);
85 ureg_release_temporary(ureg
, tmp
);
90 linear_gradient(struct ureg_program
*ureg
,
93 struct ureg_src sampler
,
94 struct ureg_src coords
,
95 struct ureg_src const0124
,
96 struct ureg_src matrow0
,
97 struct ureg_src matrow1
,
98 struct ureg_src matrow2
)
100 struct ureg_dst temp0
= ureg_DECL_temporary(ureg
);
101 struct ureg_dst temp1
= ureg_DECL_temporary(ureg
);
102 struct ureg_dst temp2
= ureg_DECL_temporary(ureg
);
103 struct ureg_dst temp3
= ureg_DECL_temporary(ureg
);
104 struct ureg_dst temp4
= ureg_DECL_temporary(ureg
);
105 struct ureg_dst temp5
= ureg_DECL_temporary(ureg
);
108 ureg_writemask(temp0
, TGSI_WRITEMASK_XY
), pos
);
110 ureg_writemask(temp0
, TGSI_WRITEMASK_Z
),
111 ureg_scalar(const0124
, TGSI_SWIZZLE_Y
));
113 ureg_DP3(ureg
, temp1
, matrow0
, ureg_src(temp0
));
114 ureg_DP3(ureg
, temp2
, matrow1
, ureg_src(temp0
));
115 ureg_DP3(ureg
, temp3
, matrow2
, ureg_src(temp0
));
116 ureg_RCP(ureg
, temp3
, ureg_src(temp3
));
117 ureg_MUL(ureg
, temp1
, ureg_src(temp1
), ureg_src(temp3
));
118 ureg_MUL(ureg
, temp2
, ureg_src(temp2
), ureg_src(temp3
));
120 ureg_MOV(ureg
, ureg_writemask(temp4
, TGSI_WRITEMASK_X
),
122 ureg_MOV(ureg
, ureg_writemask(temp4
, TGSI_WRITEMASK_Y
),
125 ureg_MUL(ureg
, temp0
,
126 ureg_scalar(coords
, TGSI_SWIZZLE_Y
),
127 ureg_scalar(ureg_src(temp4
), TGSI_SWIZZLE_Y
));
128 ureg_MAD(ureg
, temp1
,
129 ureg_scalar(coords
, TGSI_SWIZZLE_X
),
130 ureg_scalar(ureg_src(temp4
), TGSI_SWIZZLE_X
),
133 ureg_MUL(ureg
, temp2
,
135 ureg_scalar(coords
, TGSI_SWIZZLE_Z
));
138 TGSI_TEXTURE_1D
, ureg_src(temp2
), sampler
);
140 ureg_release_temporary(ureg
, temp0
);
141 ureg_release_temporary(ureg
, temp1
);
142 ureg_release_temporary(ureg
, temp2
);
143 ureg_release_temporary(ureg
, temp3
);
144 ureg_release_temporary(ureg
, temp4
);
145 ureg_release_temporary(ureg
, temp5
);
150 radial_gradient(struct ureg_program
*ureg
,
153 struct ureg_src sampler
,
154 struct ureg_src coords
,
155 struct ureg_src const0124
,
156 struct ureg_src matrow0
,
157 struct ureg_src matrow1
,
158 struct ureg_src matrow2
)
160 struct ureg_dst temp0
= ureg_DECL_temporary(ureg
);
161 struct ureg_dst temp1
= ureg_DECL_temporary(ureg
);
162 struct ureg_dst temp2
= ureg_DECL_temporary(ureg
);
163 struct ureg_dst temp3
= ureg_DECL_temporary(ureg
);
164 struct ureg_dst temp4
= ureg_DECL_temporary(ureg
);
165 struct ureg_dst temp5
= ureg_DECL_temporary(ureg
);
168 ureg_writemask(temp0
, TGSI_WRITEMASK_XY
),
171 ureg_writemask(temp0
, TGSI_WRITEMASK_Z
),
172 ureg_scalar(const0124
, TGSI_SWIZZLE_Y
));
174 ureg_DP3(ureg
, temp1
, matrow0
, ureg_src(temp0
));
175 ureg_DP3(ureg
, temp2
, matrow1
, ureg_src(temp0
));
176 ureg_DP3(ureg
, temp3
, matrow2
, ureg_src(temp0
));
177 ureg_RCP(ureg
, temp3
, ureg_src(temp3
));
178 ureg_MUL(ureg
, temp1
, ureg_src(temp1
), ureg_src(temp3
));
179 ureg_MUL(ureg
, temp2
, ureg_src(temp2
), ureg_src(temp3
));
181 ureg_MOV(ureg
, ureg_writemask(temp5
, TGSI_WRITEMASK_X
),
183 ureg_MOV(ureg
, ureg_writemask(temp5
, TGSI_WRITEMASK_Y
),
186 ureg_MUL(ureg
, temp0
, ureg_scalar(coords
, TGSI_SWIZZLE_Y
),
187 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
));
188 ureg_MAD(ureg
, temp1
,
189 ureg_scalar(coords
, TGSI_SWIZZLE_X
),
190 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
),
192 ureg_ADD(ureg
, temp1
,
193 ureg_src(temp1
), ureg_src(temp1
));
194 ureg_MUL(ureg
, temp3
,
195 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
),
196 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
));
197 ureg_MAD(ureg
, temp4
,
198 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
),
199 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
),
201 ureg_MOV(ureg
, temp4
, ureg_negate(ureg_src(temp4
)));
202 ureg_MUL(ureg
, temp2
,
203 ureg_scalar(coords
, TGSI_SWIZZLE_Z
),
205 ureg_MUL(ureg
, temp0
,
206 ureg_scalar(const0124
, TGSI_SWIZZLE_W
),
208 ureg_MUL(ureg
, temp3
,
209 ureg_src(temp1
), ureg_src(temp1
));
210 ureg_SUB(ureg
, temp2
,
211 ureg_src(temp3
), ureg_src(temp0
));
212 ureg_RSQ(ureg
, temp2
, ureg_abs(ureg_src(temp2
)));
213 ureg_RCP(ureg
, temp2
, ureg_src(temp2
));
214 ureg_SUB(ureg
, temp1
,
215 ureg_src(temp2
), ureg_src(temp1
));
216 ureg_ADD(ureg
, temp0
,
217 ureg_scalar(coords
, TGSI_SWIZZLE_Z
),
218 ureg_scalar(coords
, TGSI_SWIZZLE_Z
));
219 ureg_RCP(ureg
, temp0
, ureg_src(temp0
));
220 ureg_MUL(ureg
, temp2
,
221 ureg_src(temp1
), ureg_src(temp0
));
222 ureg_TEX(ureg
, out
, TGSI_TEXTURE_1D
,
223 ureg_src(temp2
), sampler
);
225 ureg_release_temporary(ureg
, temp0
);
226 ureg_release_temporary(ureg
, temp1
);
227 ureg_release_temporary(ureg
, temp2
);
228 ureg_release_temporary(ureg
, temp3
);
229 ureg_release_temporary(ureg
, temp4
);
230 ureg_release_temporary(ureg
, temp5
);
234 create_vs(struct pipe_context
*pipe
,
237 struct ureg_program
*ureg
;
240 struct ureg_src const0
, const1
;
241 boolean is_fill
= vs_traits
& VS_FILL
;
242 boolean is_composite
= vs_traits
& VS_COMPOSITE
;
243 boolean has_mask
= vs_traits
& VS_MASK
;
245 ureg
= ureg_create(TGSI_PROCESSOR_VERTEX
);
249 const0
= ureg_DECL_constant(ureg
);
250 const1
= ureg_DECL_constant(ureg
);
252 /* it has to be either a fill or a composite op */
253 debug_assert(is_fill
^ is_composite
);
255 src
= ureg_DECL_vs_input(ureg
,
256 TGSI_SEMANTIC_POSITION
, 0);
257 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 0);
258 src
= vs_normalize_coords(ureg
, src
,
260 ureg_MOV(ureg
, dst
, src
);
264 src
= ureg_DECL_vs_input(ureg
,
265 TGSI_SEMANTIC_GENERIC
, 1);
266 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_GENERIC
, 1);
267 ureg_MOV(ureg
, dst
, src
);
270 src
= ureg_DECL_vs_input(ureg
,
271 TGSI_SEMANTIC_COLOR
, 1);
272 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_COLOR
, 1);
273 ureg_MOV(ureg
, dst
, src
);
277 src
= ureg_DECL_vs_input(ureg
,
278 TGSI_SEMANTIC_GENERIC
, 2);
279 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 2);
280 ureg_MOV(ureg
, dst
, src
);
285 return ureg_create_shader_and_destroy(ureg
, pipe
);
289 create_fs(struct pipe_context
*pipe
,
292 struct ureg_program
*ureg
;
293 struct ureg_src
/*dst_sampler,*/ src_sampler
, mask_sampler
;
294 struct ureg_src
/*dst_pos,*/ src_pos
, mask_pos
;
295 struct ureg_src src
, mask
;
297 boolean is_fill
= fs_traits
& VS_FILL
;
298 boolean is_composite
= fs_traits
& VS_COMPOSITE
;
299 /*boolean has_mask = fs_traits & VS_MASK;*/
301 ureg
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
305 /* it has to be either a fill or a composite op */
306 debug_assert(is_fill
^ is_composite
);
308 out
= ureg_DECL_output(ureg
,
313 src_sampler
= ureg_DECL_sampler(ureg
, 0);
314 src_pos
= ureg_DECL_fs_input(ureg
,
315 TGSI_SEMANTIC_POSITION
,
317 TGSI_INTERPOLATE_PERSPECTIVE
);
320 src_pos
= ureg_DECL_fs_input(ureg
,
323 TGSI_INTERPOLATE_PERSPECTIVE
);
326 if ((fs_traits
& FS_MASK
)) {
327 mask_sampler
= ureg_DECL_sampler(ureg
, 1);
328 mask_pos
= ureg_DECL_fs_input(ureg
,
329 TGSI_SEMANTIC_POSITION
,
331 TGSI_INTERPOLATE_PERSPECTIVE
);
334 #if 0 /* unused right now */
335 dst_sampler
= ureg_DECL_sampler(ureg
, 2);
336 dst_pos
= ureg_DECL_fs_input(ureg
,
337 TGSI_SEMANTIC_POSITION
,
339 TGSI_INTERPOLATE_PERSPECTIVE
);
342 if ((fs_traits
& FS_MASK
)) {
343 ureg_TEX(ureg
, ureg_dst(mask
),
344 TGSI_TEXTURE_2D
, mask_pos
, mask_sampler
);
346 src_in_mask(ureg
, out
, src
, mask
);
349 TGSI_TEXTURE_2D
, src_pos
, src_sampler
);
354 return ureg_create_shader_and_destroy(ureg
, pipe
);
357 struct xorg_shaders
* xorg_shaders_create(struct exa_context
*exa
)
359 struct xorg_shaders
*sc
= CALLOC_STRUCT(xorg_shaders
);
362 sc
->vs_hash
= cso_hash_create();
363 sc
->fs_hash
= cso_hash_create();
369 cache_destroy(struct cso_context
*cso
,
370 struct cso_hash
*hash
,
373 struct cso_hash_iter iter
= cso_hash_first_node(hash
);
374 while (!cso_hash_iter_is_null(iter
)) {
375 void *shader
= (void *)cso_hash_iter_data(iter
);
376 if (processor
== PIPE_SHADER_FRAGMENT
) {
377 cso_delete_fragment_shader(cso
, shader
);
378 } else if (processor
== PIPE_SHADER_VERTEX
) {
379 cso_delete_vertex_shader(cso
, shader
);
381 iter
= cso_hash_erase(hash
, iter
);
383 cso_hash_delete(hash
);
386 void xorg_shaders_destroy(struct xorg_shaders
*sc
)
388 cache_destroy(sc
->exa
->cso
, sc
->vs_hash
,
390 cache_destroy(sc
->exa
->cso
, sc
->fs_hash
,
391 PIPE_SHADER_FRAGMENT
);
397 shader_from_cache(struct pipe_context
*pipe
,
399 struct cso_hash
*hash
,
404 struct cso_hash_iter iter
= cso_hash_find(hash
, key
);
406 if (cso_hash_iter_is_null(iter
)) {
407 if (type
== PIPE_SHADER_VERTEX
)
408 shader
= create_vs(pipe
, key
);
410 shader
= create_fs(pipe
, key
);
411 cso_hash_insert(hash
, key
, shader
);
413 shader
= (void *)cso_hash_iter_data(iter
);
418 struct xorg_shader
xorg_shaders_get(struct xorg_shaders
*sc
,
422 struct xorg_shader shader
= {0};
425 vs
= shader_from_cache(sc
->exa
->ctx
, PIPE_SHADER_VERTEX
,
426 sc
->vs_hash
, vs_traits
);
427 fs
= shader_from_cache(sc
->exa
->ctx
, PIPE_SHADER_FRAGMENT
,
428 sc
->fs_hash
, fs_traits
);
430 debug_assert(vs
&& fs
);