2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23 #ifndef _NINE_SHADER_H_
24 #define _NINE_SHADER_H_
26 #include "d3d9types.h"
28 #include "nine_defines.h"
29 #include "nine_helpers.h"
30 #include "nine_state.h"
31 #include "pipe/p_state.h" /* PIPE_MAX_ATTRIBS */
32 #include "util/u_memory.h"
35 struct NineVertexDeclaration9
;
38 struct nine_lconstf
/* NOTE: both pointers should be FREE'd by the user */
40 struct nine_range
*ranges
; /* single MALLOC, but next-pointers valid */
44 struct nine_shader_constant_combination
;
46 struct nine_shader_info
48 unsigned type
; /* in, PIPE_SHADER_x */
50 uint8_t version
; /* (major << 4) | minor */
52 const DWORD
*byte_code
; /* in, pointer to shader tokens */
53 DWORD byte_size
; /* out, size of data at byte_code */
55 void *cso
; /* out, pipe cso for bind_vs,fs_state */
57 uint16_t input_map
[PIPE_MAX_ATTRIBS
]; /* VS input -> NINE_DECLUSAGE_x */
58 uint8_t num_inputs
; /* there may be unused inputs (NINE_DECLUSAGE_NONE) */
60 boolean position_t
; /* out, true if VP writes pre-transformed position */
61 boolean point_size
; /* out, true if VP writes point size */
65 uint32_t sampler_ps1xtypes
; /* 2 bits per sampler */
66 uint16_t sampler_mask
; /* out, which samplers are being used */
67 uint16_t sampler_mask_shadow
; /* in, which samplers use depth compare */
68 uint8_t rt_mask
; /* out, which render targets are being written */
72 uint8_t force_color_in_centroid
;
73 uint8_t projected
; /* ps 1.1 to 1.3 */
75 unsigned const_i_base
; /* in vec4 (16 byte) units */
76 unsigned const_b_base
; /* in vec4 (16 byte) units */
77 unsigned const_used_size
;
79 boolean int_slots_used
[NINE_MAX_CONST_I
];
80 boolean bool_slots_used
[NINE_MAX_CONST_B
];
82 unsigned const_float_slots
;
83 unsigned const_int_slots
;
84 unsigned const_bool_slots
;
86 unsigned *const_ranges
;
88 struct nine_lconstf lconstf
; /* out, NOTE: members to be free'd by user */
89 uint8_t bumpenvmat_needed
;
92 struct nine_shader_constant_combination
* c_combination
;
93 boolean (*int_const_added
)[NINE_MAX_CONST_I
];
94 boolean (*bool_const_added
)[NINE_MAX_CONST_B
];
99 boolean process_vertices
;
100 struct NineVertexDeclaration9
*vdecl_out
;
101 struct pipe_stream_output_info so
;
104 struct nine_vs_output_info
106 BYTE output_semantic
;
107 int output_semantic_index
;
113 nine_create_shader_with_so_and_destroy(struct ureg_program
*p
,
114 struct pipe_context
*pipe
,
115 const struct pipe_stream_output_info
*so
);
118 nine_translate_shader(struct NineDevice9
*device
,
119 struct nine_shader_info
*,
120 struct pipe_context
*);
123 struct nine_shader_variant
125 struct nine_shader_variant
*next
;
127 unsigned *const_ranges
;
128 unsigned const_used_size
;
133 nine_shader_variant_get(struct nine_shader_variant
*list
,
134 unsigned **const_ranges
,
135 unsigned *const_used_size
,
138 while (list
->key
!= key
&& list
->next
)
140 if (list
->key
== key
) {
141 *const_ranges
= list
->const_ranges
;
142 *const_used_size
= list
->const_used_size
;
148 static inline boolean
149 nine_shader_variant_add(struct nine_shader_variant
*list
,
150 uint64_t key
, void *cso
,
151 unsigned *const_ranges
,
152 unsigned const_used_size
)
155 assert(list
->key
!= key
);
158 list
->next
= MALLOC_STRUCT(nine_shader_variant
);
161 list
->next
->next
= NULL
;
162 list
->next
->key
= key
;
163 list
->next
->cso
= cso
;
164 list
->next
->const_ranges
= const_ranges
;
165 list
->next
->const_used_size
= const_used_size
;
170 nine_shader_variants_free(struct nine_shader_variant
*list
)
173 struct nine_shader_variant
*ptr
= list
->next
;
174 list
->next
= ptr
->next
;
179 struct nine_shader_variant_so
181 struct nine_shader_variant_so
*next
;
182 struct NineVertexDeclaration9
*vdecl
;
183 struct pipe_stream_output_info so
;
188 nine_shader_variant_so_get(struct nine_shader_variant_so
*list
,
189 struct NineVertexDeclaration9
*vdecl
,
190 struct pipe_stream_output_info
*so
)
192 while (list
->vdecl
!= vdecl
&& list
->next
)
194 if (list
->vdecl
== vdecl
) {
201 static inline boolean
202 nine_shader_variant_so_add(struct nine_shader_variant_so
*list
,
203 struct NineVertexDeclaration9
*vdecl
,
204 struct pipe_stream_output_info
*so
, void *cso
)
206 if (list
->vdecl
== NULL
) { /* first shader */
208 nine_bind(&list
->vdecl
, vdecl
);
214 assert(list
->vdecl
!= vdecl
);
217 list
->next
= MALLOC_STRUCT(nine_shader_variant_so
);
220 list
->next
->next
= NULL
;
221 nine_bind(&list
->vdecl
, vdecl
);
222 list
->next
->so
= *so
;
223 list
->next
->cso
= cso
;
228 nine_shader_variants_so_free(struct nine_shader_variant_so
*list
)
231 struct nine_shader_variant_so
*ptr
= list
->next
;
232 list
->next
= ptr
->next
;
233 nine_bind(&ptr
->vdecl
, NULL
);
237 nine_bind(&list
->vdecl
, NULL
);
240 struct nine_shader_constant_combination
242 struct nine_shader_constant_combination
*next
;
243 int const_i
[NINE_MAX_CONST_I
][4];
244 BOOL const_b
[NINE_MAX_CONST_B
];
247 #define NINE_MAX_CONSTANT_COMBINATION_VARIANTS 32
249 static inline uint8_t
250 nine_shader_constant_combination_key(struct nine_shader_constant_combination
**list
,
251 boolean
*int_slots_used
,
252 boolean
*bool_slots_used
,
259 struct nine_shader_constant_combination
**next_allocate
= list
, *current
= *list
;
261 assert(int_slots_used
);
262 assert(bool_slots_used
);
267 index
++; /* start at 1. 0 is for the variant without constant replacement */
269 for (i
= 0; i
< NINE_MAX_CONST_I
; ++i
) {
270 if (int_slots_used
[i
])
271 match
&= !memcmp(const_i
+ 4*i
, current
->const_i
[i
], sizeof(current
->const_i
[0]));
273 for (i
= 0; i
< NINE_MAX_CONST_B
; ++i
) {
274 if (bool_slots_used
[i
])
275 match
&= const_b
[i
] == current
->const_b
[i
];
279 next_allocate
= ¤t
->next
;
280 current
= current
->next
;
283 if (index
< NINE_MAX_CONSTANT_COMBINATION_VARIANTS
) {
284 *next_allocate
= MALLOC_STRUCT(nine_shader_constant_combination
);
285 current
= *next_allocate
;
287 current
->next
= NULL
;
288 memcpy(current
->const_i
, const_i
, sizeof(current
->const_i
));
289 memcpy(current
->const_b
, const_b
, sizeof(current
->const_b
));
293 return 0; /* Too many variants, revert to no replacement */
296 static inline struct nine_shader_constant_combination
*
297 nine_shader_constant_combination_get(struct nine_shader_constant_combination
*list
, uint8_t index
)
302 assert(list
!= NULL
);
313 nine_shader_constant_combination_free(struct nine_shader_constant_combination
*list
)
319 struct nine_shader_constant_combination
*ptr
= list
->next
;
320 list
->next
= ptr
->next
;
327 #endif /* _NINE_SHADER_H_ */