xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/nine/nine_shader.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2011 Joakim Sindholt <[email protected]>
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef _NINE_SHADER_H_
7 #define _NINE_SHADER_H_
8 
9 #include "d3d9types.h"
10 #include "d3d9caps.h"
11 #include "nine_defines.h"
12 #include "nine_helpers.h"
13 #include "nine_state.h"
14 #include "pipe/p_state.h" /* PIPE_MAX_ATTRIBS */
15 #include "util/u_memory.h"
16 #include "tgsi/tgsi_ureg.h"
17 
18 struct NineDevice9;
19 struct NineVertexDeclaration9;
20 struct ureg_program;
21 
22 struct nine_lconstf /* NOTE: both pointers should be FREE'd by the user */
23 {
24     struct nine_range *ranges; /* single MALLOC, but next-pointers valid */
25     float *data;
26 };
27 
28 struct nine_shader_constant_combination;
29 
30 struct nine_shader_info
31 {
32     unsigned type; /* in, PIPE_SHADER_x */
33 
34     uint8_t version; /* (major << 4) | minor */
35 
36     const DWORD *byte_code; /* in, pointer to shader tokens */
37     DWORD        byte_size; /* out, size of data at byte_code */
38 
39     void *cso; /* out, pipe cso for bind_vs,fs_state */
40 
41     uint16_t input_map[PIPE_MAX_ATTRIBS]; /* VS input -> NINE_DECLUSAGE_x */
42     uint8_t num_inputs; /* there may be unused inputs (NINE_DECLUSAGE_NONE) */
43 
44     bool position_t; /* out, true if VP writes pre-transformed position */
45     bool point_size; /* out, true if VP writes point size */
46     float point_size_min;
47     float point_size_max;
48 
49     uint32_t sampler_ps1xtypes; /* 2 bits per sampler */
50     uint16_t sampler_mask; /* out, which samplers are being used */
51     uint16_t sampler_mask_shadow; /* in, which samplers use depth compare */
52     uint8_t rt_mask; /* out, which render targets are being written */
53 
54     uint8_t fog_enable;
55     uint8_t fog_mode;
56     uint8_t zfog;
57     uint8_t force_color_in_centroid;
58     uint8_t color_flatshade;
59     uint8_t projected; /* ps 1.1 to 1.3 */
60     uint16_t fetch4;
61     uint8_t alpha_test_emulation;
62     uint8_t clip_plane_emulation;
63     bool emulate_features;
64 
65     unsigned const_i_base; /* in vec4 (16 byte) units */
66     unsigned const_b_base; /* in vec4 (16 byte) units */
67     unsigned const_used_size;
68 
69     bool int_slots_used[NINE_MAX_CONST_I];
70     bool bool_slots_used[NINE_MAX_CONST_B];
71 
72     unsigned const_float_slots;
73     unsigned const_int_slots;
74     unsigned const_bool_slots;
75 
76     unsigned *const_ranges;
77 
78     struct nine_lconstf lconstf; /* out, NOTE: members to be free'd by user */
79     uint8_t bumpenvmat_needed;
80 
81     struct {
82         struct nine_shader_constant_combination* c_combination;
83         bool (*int_const_added)[NINE_MAX_CONST_I];
84         bool (*bool_const_added)[NINE_MAX_CONST_B];
85     } add_constants_defs;
86 
87     bool swvp_on;
88 
89     bool process_vertices;
90     struct NineVertexDeclaration9 *vdecl_out;
91     struct pipe_stream_output_info so;
92 };
93 
94 struct nine_vs_output_info
95 {
96     BYTE output_semantic;
97     int output_semantic_index;
98     int mask;
99     int output_index;
100 };
101 
102 void *
103 nine_create_shader_with_so_and_destroy(struct ureg_program *p,
104                                        struct pipe_context *pipe,
105                                        const struct pipe_stream_output_info *so);
106 
107 HRESULT
108 nine_translate_shader(struct NineDevice9 *device,
109                       struct nine_shader_info *,
110                       struct pipe_context *);
111 
112 
113 struct nine_shader_variant
114 {
115     struct nine_shader_variant *next;
116     void *cso;
117     unsigned *const_ranges;
118     unsigned const_used_size;
119     uint64_t key;
120 };
121 
122 static inline void *
nine_shader_variant_get(struct nine_shader_variant * list,unsigned ** const_ranges,unsigned * const_used_size,uint64_t key)123 nine_shader_variant_get(struct nine_shader_variant *list,
124                         unsigned **const_ranges,
125                         unsigned *const_used_size,
126                         uint64_t key)
127 {
128     while (list->key != key && list->next)
129         list = list->next;
130     if (list->key == key) {
131         *const_ranges = list->const_ranges;
132         *const_used_size = list->const_used_size;
133         return list->cso;
134     }
135     return NULL;
136 }
137 
138 static inline bool
nine_shader_variant_add(struct nine_shader_variant * list,uint64_t key,void * cso,unsigned * const_ranges,unsigned const_used_size)139 nine_shader_variant_add(struct nine_shader_variant *list,
140                         uint64_t key, void *cso,
141                         unsigned *const_ranges,
142                         unsigned const_used_size)
143 {
144     while (list->next) {
145         assert(list->key != key);
146         list = list->next;
147     }
148     list->next = MALLOC_STRUCT(nine_shader_variant);
149     if (!list->next)
150         return false;
151     list->next->next = NULL;
152     list->next->key = key;
153     list->next->cso = cso;
154     list->next->const_ranges = const_ranges;
155     list->next->const_used_size = const_used_size;
156     return true;
157 }
158 
159 static inline void
nine_shader_variants_free(struct nine_shader_variant * list)160 nine_shader_variants_free(struct nine_shader_variant *list)
161 {
162     while (list->next) {
163         struct nine_shader_variant *ptr = list->next;
164         list->next = ptr->next;
165         FREE(ptr);
166     }
167 }
168 
169 struct nine_shader_variant_so
170 {
171     struct nine_shader_variant_so *next;
172     struct NineVertexDeclaration9 *vdecl;
173     struct pipe_stream_output_info so;
174     void *cso;
175 };
176 
177 static inline void *
nine_shader_variant_so_get(struct nine_shader_variant_so * list,struct NineVertexDeclaration9 * vdecl,struct pipe_stream_output_info * so)178 nine_shader_variant_so_get(struct nine_shader_variant_so *list,
179                            struct NineVertexDeclaration9 *vdecl,
180                            struct pipe_stream_output_info *so)
181 {
182     while (list->vdecl != vdecl && list->next)
183         list = list->next;
184     if (list->vdecl == vdecl) {
185         *so = list->so;
186         return list->cso;
187     }
188     return NULL;
189 }
190 
191 static inline bool
nine_shader_variant_so_add(struct nine_shader_variant_so * list,struct NineVertexDeclaration9 * vdecl,struct pipe_stream_output_info * so,void * cso)192 nine_shader_variant_so_add(struct nine_shader_variant_so *list,
193                            struct NineVertexDeclaration9 *vdecl,
194                            struct pipe_stream_output_info *so, void *cso)
195 {
196     if (list->vdecl == NULL) { /* first shader */
197         list->next = NULL;
198         nine_bind(&list->vdecl, vdecl);
199         list->so = *so;
200         list->cso = cso;
201         return true;
202     }
203     while (list->next) {
204         assert(list->vdecl != vdecl);
205         list = list->next;
206     }
207     list->next = MALLOC_STRUCT(nine_shader_variant_so);
208     if (!list->next)
209         return false;
210     list->next->next = NULL;
211     nine_bind(&list->vdecl, vdecl);
212     list->next->so = *so;
213     list->next->cso = cso;
214     return true;
215 }
216 
217 static inline void
nine_shader_variants_so_free(struct nine_shader_variant_so * list)218 nine_shader_variants_so_free(struct nine_shader_variant_so *list)
219 {
220     while (list->next) {
221         struct nine_shader_variant_so *ptr = list->next;
222         list->next = ptr->next;
223         nine_bind(&ptr->vdecl, NULL);
224         FREE(ptr);
225     }
226     if (list->vdecl)
227         nine_bind(&list->vdecl, NULL);
228 }
229 
230 struct nine_shader_constant_combination
231 {
232     struct nine_shader_constant_combination *next;
233     int const_i[NINE_MAX_CONST_I][4];
234     BOOL const_b[NINE_MAX_CONST_B];
235 };
236 
237 #define NINE_MAX_CONSTANT_COMBINATION_VARIANTS 32
238 
239 static inline uint8_t
nine_shader_constant_combination_key(struct nine_shader_constant_combination ** list,bool * int_slots_used,bool * bool_slots_used,int * const_i,BOOL * const_b)240 nine_shader_constant_combination_key(struct nine_shader_constant_combination **list,
241                                      bool *int_slots_used,
242                                      bool *bool_slots_used,
243                                      int *const_i,
244                                      BOOL *const_b)
245 {
246     int i;
247     uint8_t index = 0;
248     bool match;
249     struct nine_shader_constant_combination **next_allocate = list, *current = *list;
250 
251     assert(int_slots_used);
252     assert(bool_slots_used);
253     assert(const_i);
254     assert(const_b);
255 
256     while (current) {
257         index++; /* start at 1. 0 is for the variant without constant replacement */
258         match = true;
259         for (i = 0; i < NINE_MAX_CONST_I; ++i) {
260             if (int_slots_used[i])
261                 match &= !memcmp(const_i + 4*i, current->const_i[i], sizeof(current->const_i[0]));
262         }
263         for (i = 0; i < NINE_MAX_CONST_B; ++i) {
264             if (bool_slots_used[i])
265                 match &= const_b[i] == current->const_b[i];
266         }
267         if (match)
268             return index;
269         next_allocate = &current->next;
270         current = current->next;
271     }
272 
273     if (index < NINE_MAX_CONSTANT_COMBINATION_VARIANTS) {
274         *next_allocate = MALLOC_STRUCT(nine_shader_constant_combination);
275         current = *next_allocate;
276         index++;
277         current->next = NULL;
278         memcpy(current->const_i, const_i, sizeof(current->const_i));
279         memcpy(current->const_b, const_b, sizeof(current->const_b));
280         return index;
281     }
282 
283     return 0; /* Too many variants, revert to no replacement */
284 }
285 
286 static inline struct nine_shader_constant_combination *
nine_shader_constant_combination_get(struct nine_shader_constant_combination * list,uint8_t index)287 nine_shader_constant_combination_get(struct nine_shader_constant_combination *list, uint8_t index)
288 {
289     if (index == 0)
290         return NULL;
291     while (index) {
292         assert(list != NULL);
293         index--;
294         if (index == 0)
295             return list;
296         list = list->next;
297     }
298     assert(false);
299     return NULL;
300 }
301 
302 static inline void
nine_shader_constant_combination_free(struct nine_shader_constant_combination * list)303 nine_shader_constant_combination_free(struct nine_shader_constant_combination *list)
304 {
305     if (!list)
306         return;
307 
308     while (list->next) {
309         struct nine_shader_constant_combination *ptr = list->next;
310         list->next = ptr->next;
311         FREE(ptr);
312     }
313 
314     FREE(list);
315 }
316 
317 /* Returns corresponding opposite test */
318 static inline unsigned
pipe_comp_to_tgsi_opposite(BYTE flags)319 pipe_comp_to_tgsi_opposite(BYTE flags)
320 {
321     switch (flags) {
322     case PIPE_FUNC_GREATER: return TGSI_OPCODE_SLE;
323     case PIPE_FUNC_EQUAL: return TGSI_OPCODE_SNE;
324     case PIPE_FUNC_GEQUAL: return TGSI_OPCODE_SLT;
325     case PIPE_FUNC_LESS: return TGSI_OPCODE_SGE;
326     case PIPE_FUNC_NOTEQUAL: return TGSI_OPCODE_SEQ;
327     case PIPE_FUNC_LEQUAL: return TGSI_OPCODE_SGT;
328     default:
329         assert(!"invalid comparison flags");
330         return TGSI_OPCODE_SGT;
331     }
332 }
333 
334 #endif /* _NINE_SHADER_H_ */
335