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"
21 struct exa_context
*exa
;
23 struct cso_hash
*vs_hash
;
24 struct cso_hash
*fs_hash
;
33 * CONST[0] = (0, 0, 0, 1)
36 static const char over_op
[] =
37 "SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n"
38 "MUL TEMP[3], TEMP[0], TEMP[3]\n"
39 "ADD TEMP[0], TEMP[3], TEMP[0]\n";
43 create_preamble(struct ureg_program
*ureg
)
49 src_in_mask(struct ureg_program
*ureg
,
54 /* MUL dst, src, mask.wwww */
55 ureg_MUL(ureg
, dst
, src
,
56 ureg_scalar(mask
, TGSI_SWIZZLE_W
));
60 create_vs(struct pipe_context
*pipe
,
63 struct ureg_program
*ureg
;
67 ureg
= ureg_create(TGSI_PROCESSOR_VERTEX
);
71 if ((vs_traits
& VS_COMPOSITE
)) {
72 src
= ureg_DECL_vs_input(ureg
,
73 TGSI_SEMANTIC_POSITION
, 1);
74 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 1);
75 ureg_MOV(ureg
, dst
, src
);
77 if ((vs_traits
& VS_MASK
)) {
78 src
= ureg_DECL_vs_input(ureg
,
79 TGSI_SEMANTIC_POSITION
, 2);
80 dst
= ureg_DECL_output(ureg
, TGSI_SEMANTIC_POSITION
, 2);
81 ureg_MOV(ureg
, dst
, src
);
86 return ureg_create_shader_and_destroy(ureg
, pipe
);
90 create_fs(struct pipe_context
*pipe
,
93 struct ureg_program
*ureg
;
94 struct ureg_src dst_sampler
, src_sampler
, mask_sampler
;
95 struct ureg_src dst_pos
, src_pos
, mask_pos
;
96 struct ureg_src src
, mask
;
99 ureg
= ureg_create(TGSI_PROCESSOR_FRAGMENT
);
103 #if 0 /* unused right now */
104 dst_sampler
= ureg_DECL_sampler(ureg
);
105 dst_pos
= ureg_DECL_fs_input(ureg
,
106 TGSI_SEMANTIC_POSITION
,
108 TGSI_INTERPOLATE_PERSPECTIVE
);
111 src_sampler
= ureg_DECL_sampler(ureg
);
112 src_pos
= ureg_DECL_fs_input(ureg
,
113 TGSI_SEMANTIC_POSITION
,
115 TGSI_INTERPOLATE_PERSPECTIVE
);
117 out
= ureg_DECL_output(ureg
,
121 if ((fs_traits
& FS_MASK
)) {
122 mask_sampler
= ureg_DECL_sampler(ureg
);
123 mask_pos
= ureg_DECL_fs_input(ureg
,
124 TGSI_SEMANTIC_POSITION
,
126 TGSI_INTERPOLATE_PERSPECTIVE
);
129 if ((fs_traits
& FS_MASK
)) {
130 ureg_TEX(ureg
, ureg_dst(mask
),
131 TGSI_TEXTURE_2D
, mask_pos
, mask_sampler
);
133 src_in_mask(ureg
, out
, src
, mask
);
136 TGSI_TEXTURE_2D
, src_pos
, src_sampler
);
141 return ureg_create_shader_and_destroy(ureg
, pipe
);
144 struct xorg_shaders
* xorg_shaders_create(struct exa_context
*exa
)
146 struct xorg_shaders
*sc
= CALLOC_STRUCT(xorg_shaders
);
149 sc
->vs_hash
= cso_hash_create();
150 sc
->fs_hash
= cso_hash_create();
156 cache_destroy(struct cso_context
*cso
,
157 struct cso_hash
*hash
,
160 struct cso_hash_iter iter
= cso_hash_first_node(hash
);
161 while (!cso_hash_iter_is_null(iter
)) {
162 void *shader
= (void *)cso_hash_iter_data(iter
);
163 if (processor
== PIPE_SHADER_FRAGMENT
) {
164 cso_delete_fragment_shader(cso
, shader
);
165 } else if (processor
== PIPE_SHADER_VERTEX
) {
166 cso_delete_vertex_shader(cso
, shader
);
168 iter
= cso_hash_erase(hash
, iter
);
170 cso_hash_delete(hash
);
173 void xorg_shaders_destroy(struct xorg_shaders
*sc
)
175 cache_destroy(sc
->exa
->cso
, sc
->vs_hash
,
177 cache_destroy(sc
->exa
->cso
, sc
->fs_hash
,
178 PIPE_SHADER_FRAGMENT
);
184 shader_from_cache(struct pipe_context
*pipe
,
186 struct cso_hash
*hash
,
191 struct cso_hash_iter iter
= cso_hash_find(hash
, key
);
193 if (cso_hash_iter_is_null(iter
)) {
194 if (type
== PIPE_SHADER_VERTEX
)
195 shader
= create_vs(pipe
, key
);
197 shader
= create_fs(pipe
, key
);
198 cso_hash_insert(hash
, key
, shader
);
200 shader
= (void *)cso_hash_iter_data(iter
);
205 struct xorg_shader
xorg_shaders_get(struct xorg_shaders
*sc
,
209 struct xorg_shader shader
= {0};
212 vs
= shader_from_cache(sc
->exa
->ctx
, PIPE_SHADER_VERTEX
,
213 sc
->vs_hash
, vs_traits
);
214 fs
= shader_from_cache(sc
->exa
->ctx
, PIPE_SHADER_FRAGMENT
,
215 sc
->fs_hash
, fs_traits
);
217 debug_assert(vs
&& fs
);