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 xorg_renderer
*r
;
49 struct cso_hash
*vs_hash
;
50 struct cso_hash
*fs_hash
;
54 src_in_mask(struct ureg_program
*ureg
,
58 boolean component_alpha
)
60 if (component_alpha
) {
61 ureg_MUL(ureg
, dst
, src
, mask
);
64 ureg_MUL(ureg
, dst
, src
,
65 ureg_scalar(mask
, TGSI_SWIZZLE_W
));
69 static struct ureg_src
70 vs_normalize_coords(struct ureg_program
*ureg
, struct ureg_src coords
,
71 struct ureg_src const0
, struct ureg_src const1
)
73 struct ureg_dst tmp
= ureg_DECL_temporary(ureg
);
75 ureg_MAD(ureg
, tmp
, coords
, const0
, const1
);
77 ureg_release_temporary(ureg
, tmp
);
82 linear_gradient(struct ureg_program
*ureg
,
85 struct ureg_src sampler
,
86 struct ureg_src coords
,
87 struct ureg_src const0124
,
88 struct ureg_src matrow0
,
89 struct ureg_src matrow1
,
90 struct ureg_src matrow2
)
92 struct ureg_dst temp0
= ureg_DECL_temporary(ureg
);
93 struct ureg_dst temp1
= ureg_DECL_temporary(ureg
);
94 struct ureg_dst temp2
= ureg_DECL_temporary(ureg
);
95 struct ureg_dst temp3
= ureg_DECL_temporary(ureg
);
96 struct ureg_dst temp4
= ureg_DECL_temporary(ureg
);
97 struct ureg_dst temp5
= ureg_DECL_temporary(ureg
);
100 ureg_writemask(temp0
, TGSI_WRITEMASK_XY
), pos
);
102 ureg_writemask(temp0
, TGSI_WRITEMASK_Z
),
103 ureg_scalar(const0124
, TGSI_SWIZZLE_Y
));
105 ureg_DP3(ureg
, temp1
, matrow0
, ureg_src(temp0
));
106 ureg_DP3(ureg
, temp2
, matrow1
, ureg_src(temp0
));
107 ureg_DP3(ureg
, temp3
, matrow2
, ureg_src(temp0
));
108 ureg_RCP(ureg
, temp3
, ureg_src(temp3
));
109 ureg_MUL(ureg
, temp1
, ureg_src(temp1
), ureg_src(temp3
));
110 ureg_MUL(ureg
, temp2
, ureg_src(temp2
), ureg_src(temp3
));
112 ureg_MOV(ureg
, ureg_writemask(temp4
, TGSI_WRITEMASK_X
),
114 ureg_MOV(ureg
, ureg_writemask(temp4
, TGSI_WRITEMASK_Y
),
117 ureg_MUL(ureg
, temp0
,
118 ureg_scalar(coords
, TGSI_SWIZZLE_Y
),
119 ureg_scalar(ureg_src(temp4
), TGSI_SWIZZLE_Y
));
120 ureg_MAD(ureg
, temp1
,
121 ureg_scalar(coords
, TGSI_SWIZZLE_X
),
122 ureg_scalar(ureg_src(temp4
), TGSI_SWIZZLE_X
),
125 ureg_MUL(ureg
, temp2
,
127 ureg_scalar(coords
, TGSI_SWIZZLE_Z
));
130 TGSI_TEXTURE_1D
, ureg_src(temp2
), sampler
);
132 ureg_release_temporary(ureg
, temp0
);
133 ureg_release_temporary(ureg
, temp1
);
134 ureg_release_temporary(ureg
, temp2
);
135 ureg_release_temporary(ureg
, temp3
);
136 ureg_release_temporary(ureg
, temp4
);
137 ureg_release_temporary(ureg
, temp5
);
142 radial_gradient(struct ureg_program
*ureg
,
145 struct ureg_src sampler
,
146 struct ureg_src coords
,
147 struct ureg_src const0124
,
148 struct ureg_src matrow0
,
149 struct ureg_src matrow1
,
150 struct ureg_src matrow2
)
152 struct ureg_dst temp0
= ureg_DECL_temporary(ureg
);
153 struct ureg_dst temp1
= ureg_DECL_temporary(ureg
);
154 struct ureg_dst temp2
= ureg_DECL_temporary(ureg
);
155 struct ureg_dst temp3
= ureg_DECL_temporary(ureg
);
156 struct ureg_dst temp4
= ureg_DECL_temporary(ureg
);
157 struct ureg_dst temp5
= ureg_DECL_temporary(ureg
);
160 ureg_writemask(temp0
, TGSI_WRITEMASK_XY
),
163 ureg_writemask(temp0
, TGSI_WRITEMASK_Z
),
164 ureg_scalar(const0124
, TGSI_SWIZZLE_Y
));
166 ureg_DP3(ureg
, temp1
, matrow0
, ureg_src(temp0
));
167 ureg_DP3(ureg
, temp2
, matrow1
, ureg_src(temp0
));
168 ureg_DP3(ureg
, temp3
, matrow2
, ureg_src(temp0
));
169 ureg_RCP(ureg
, temp3
, ureg_src(temp3
));
170 ureg_MUL(ureg
, temp1
, ureg_src(temp1
), ureg_src(temp3
));
171 ureg_MUL(ureg
, temp2
, ureg_src(temp2
), ureg_src(temp3
));
173 ureg_MOV(ureg
, ureg_writemask(temp5
, TGSI_WRITEMASK_X
),
175 ureg_MOV(ureg
, ureg_writemask(temp5
, TGSI_WRITEMASK_Y
),
178 ureg_MUL(ureg
, temp0
, ureg_scalar(coords
, TGSI_SWIZZLE_Y
),
179 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
));
180 ureg_MAD(ureg
, temp1
,
181 ureg_scalar(coords
, TGSI_SWIZZLE_X
),
182 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
),
184 ureg_ADD(ureg
, temp1
,
185 ureg_src(temp1
), ureg_src(temp1
));
186 ureg_MUL(ureg
, temp3
,
187 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
),
188 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_Y
));
189 ureg_MAD(ureg
, temp4
,
190 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
),
191 ureg_scalar(ureg_src(temp5
), TGSI_SWIZZLE_X
),
193 ureg_MOV(ureg
, temp4
, ureg_negate(ureg_src(temp4
)));
194 ureg_MUL(ureg
, temp2
,
195 ureg_scalar(coords
, TGSI_SWIZZLE_Z
),
197 ureg_MUL(ureg
, temp0
,
198 ureg_scalar(const0124
, TGSI_SWIZZLE_W
),
200 ureg_MUL(ureg
, temp3
,
201 ureg_src(temp1
), ureg_src(temp1
));
202 ureg_SUB(ureg
, temp2
,
203 ureg_src(temp3
), ureg_src(temp0
));
204 ureg_RSQ(ureg
, temp2
, ureg_abs(ureg_src(temp2
)));
205 ureg_RCP(ureg
, temp2
, ureg_src(temp2
));
206 ureg_SUB(ureg
, temp1
,
207 ureg_src(temp2
), ureg_src(temp1
));
208 ureg_ADD(ureg
, temp0
,
209 ureg_scalar(coords
, TGSI_SWIZZLE_Z
),
210 ureg_scalar(coords
, TGSI_SWIZZLE_Z
));
211 ureg_RCP(ureg
, temp0
, ureg_src(temp0
));
212 ureg_MUL(ureg
, temp2
,
213 ureg_src(temp1
), ureg_src(temp0
));
214 ureg_TEX(ureg
, out
, TGSI_TEXTURE_1D
,
215 ureg_src(temp2
), sampler
);
217 ureg_release_temporary(ureg
, temp0
);
218 ureg_release_temporary(ureg
, temp1
);
219 ureg_release_temporary(ureg
, temp2
);
220 ureg_release_temporary(ureg
, temp3
);
221 ureg_release_temporary(ureg
, temp4
);
222 ureg_release_temporary(ureg
, temp5
);
226 create_vs(struct pipe_context
*pipe
,
229 struct ureg_program
*ureg
;
232 struct ureg_src const0
, const1
;
233 boolean is_fill
= vs_traits
& VS_FILL
;
234 boolean is_composite
= vs_traits
& VS_COMPOSITE
;
235 boolean has_mask
= vs_traits
& VS_MASK
;
236 unsigned input_slot
= 0;
238 ureg
= ureg_create(TGSI_PROCESSOR_VERTEX
);
242 const0
= ureg_DECL_constant(ureg
, 0);
243 const1
= ureg_DECL_constant(ureg
, 1);
245 /* it has to be either a fill or a composite op */
246 debug_assert(is_fill
^ is_composite
);
248 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
249 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 0);
250 src
= vs_normalize_coords(ureg
, src
,
252 ureg_MOV(ureg
, dst
, src
);
255 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
256 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_GENERIC
, 0);
257 ureg_MOV(ureg
, dst
, src
);
261 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
262 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_COLOR
, 0);
263 ureg_MOV(ureg
, dst
, src
);
267 src
= ureg_DECL_vs_input(ureg
, input_slot
++);
268 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_GENERIC
, 1);
269 ureg_MOV(ureg
, dst
, src
);
274 return ureg_create_shader_and_destroy(ureg
, pipe
);
278 create_fs(struct pipe_context
*pipe
,
281 struct ureg_program
*ureg
;
282 struct ureg_src
/*dst_sampler,*/ src_sampler
, mask_sampler
;
283 struct ureg_src
/*dst_pos,*/ src_input
, mask_pos
;
284 struct ureg_dst src
, mask
;
286 boolean has_mask
= fs_traits
& FS_MASK
;
287 boolean is_fill
= fs_traits
& FS_FILL
;
288 boolean is_composite
= fs_traits
& FS_COMPOSITE
;
289 boolean is_solid
= fs_traits
& FS_SOLID_FILL
;
290 boolean is_lingrad
= fs_traits
& FS_LINGRAD_FILL
;
291 boolean is_radgrad
= fs_traits
& FS_RADGRAD_FILL
;
292 boolean is_comp_alpha
= fs_traits
& FS_COMPONENT_ALPHA
;
294 ureg
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
298 /* it has to be either a fill or a composite op */
299 debug_assert(is_fill
^ is_composite
);
301 out
= ureg_DECL_output(ureg
,
306 src_sampler
= ureg_DECL_sampler(ureg
, 0);
307 src_input
= ureg_DECL_fs_input(ureg
,
308 TGSI_SEMANTIC_GENERIC
,
310 TGSI_INTERPOLATE_PERSPECTIVE
);
312 debug_assert(is_fill
);
314 src_input
= ureg_DECL_fs_input(ureg
,
317 TGSI_INTERPOLATE_PERSPECTIVE
);
319 src_input
= ureg_DECL_fs_input(ureg
,
320 TGSI_SEMANTIC_POSITION
,
322 TGSI_INTERPOLATE_PERSPECTIVE
);
326 mask_sampler
= ureg_DECL_sampler(ureg
, 1);
327 mask_pos
= ureg_DECL_fs_input(ureg
,
328 TGSI_SEMANTIC_GENERIC
,
330 TGSI_INTERPOLATE_PERSPECTIVE
);
333 #if 0 /* unused right now */
334 dst_sampler
= ureg_DECL_sampler(ureg
, 2);
335 dst_pos
= ureg_DECL_fs_input(ureg
,
336 TGSI_SEMANTIC_POSITION
,
338 TGSI_INTERPOLATE_PERSPECTIVE
);
343 src
= ureg_DECL_temporary(ureg
);
347 TGSI_TEXTURE_2D
, src_input
, src_sampler
);
348 } else if (is_fill
) {
351 src
= ureg_dst(src_input
);
353 ureg_MOV(ureg
, out
, src_input
);
354 } else if (is_lingrad
|| is_radgrad
) {
355 struct ureg_src coords
, const0124
,
356 matrow0
, matrow1
, matrow2
;
359 src
= ureg_DECL_temporary(ureg
);
363 coords
= ureg_DECL_constant(ureg
, 0);
364 const0124
= ureg_DECL_constant(ureg
, 1);
365 matrow0
= ureg_DECL_constant(ureg
, 2);
366 matrow1
= ureg_DECL_constant(ureg
, 3);
367 matrow2
= ureg_DECL_constant(ureg
, 4);
370 linear_gradient(ureg
, src
,
371 src_input
, src_sampler
,
373 matrow0
, matrow1
, matrow2
);
374 } else if (is_radgrad
) {
375 radial_gradient(ureg
, src
,
376 src_input
, src_sampler
,
378 matrow0
, matrow1
, matrow2
);
381 debug_assert(!"Unknown fill type!");
385 mask
= ureg_DECL_temporary(ureg
);
387 TGSI_TEXTURE_2D
, mask_pos
, mask_sampler
);
389 src_in_mask(ureg
, out
, ureg_src(src
), ureg_src(mask
), is_comp_alpha
);
390 ureg_release_temporary(ureg
, mask
);
395 return ureg_create_shader_and_destroy(ureg
, pipe
);
398 struct xorg_shaders
* xorg_shaders_create(struct xorg_renderer
*r
)
400 struct xorg_shaders
*sc
= CALLOC_STRUCT(xorg_shaders
);
403 sc
->vs_hash
= cso_hash_create();
404 sc
->fs_hash
= cso_hash_create();
410 cache_destroy(struct cso_context
*cso
,
411 struct cso_hash
*hash
,
414 struct cso_hash_iter iter
= cso_hash_first_node(hash
);
415 while (!cso_hash_iter_is_null(iter
)) {
416 void *shader
= (void *)cso_hash_iter_data(iter
);
417 if (processor
== PIPE_SHADER_FRAGMENT
) {
418 cso_delete_fragment_shader(cso
, shader
);
419 } else if (processor
== PIPE_SHADER_VERTEX
) {
420 cso_delete_vertex_shader(cso
, shader
);
422 iter
= cso_hash_erase(hash
, iter
);
424 cso_hash_delete(hash
);
427 void xorg_shaders_destroy(struct xorg_shaders
*sc
)
429 cache_destroy(sc
->r
->cso
, sc
->vs_hash
,
431 cache_destroy(sc
->r
->cso
, sc
->fs_hash
,
432 PIPE_SHADER_FRAGMENT
);
438 shader_from_cache(struct pipe_context
*pipe
,
440 struct cso_hash
*hash
,
445 struct cso_hash_iter iter
= cso_hash_find(hash
, key
);
447 if (cso_hash_iter_is_null(iter
)) {
448 if (type
== PIPE_SHADER_VERTEX
)
449 shader
= create_vs(pipe
, key
);
451 shader
= create_fs(pipe
, key
);
452 cso_hash_insert(hash
, key
, shader
);
454 shader
= (void *)cso_hash_iter_data(iter
);
459 struct xorg_shader
xorg_shaders_get(struct xorg_shaders
*sc
,
463 struct xorg_shader shader
= { NULL
, NULL
};
466 vs
= shader_from_cache(sc
->r
->pipe
, PIPE_SHADER_VERTEX
,
467 sc
->vs_hash
, vs_traits
);
468 fs
= shader_from_cache(sc
->r
->pipe
, PIPE_SHADER_FRAGMENT
,
469 sc
->fs_hash
, fs_traits
);
471 debug_assert(vs
&& fs
);