1 /*
2  * Copyright (C) 2002 Raphael Junqueira
3  * Copyright (C) 2008 David Adam
4  * Copyright (C) 2008 Tony Wasserka
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  */
21 
22 #ifndef __WINE_D3DX9_PRIVATE_H
23 #define __WINE_D3DX9_PRIVATE_H
24 
25 #define NONAMELESSUNION
26 #include "wine/debug.h"
27 #include "wine/heap.h"
28 #include "wine/rbtree.h"
29 
30 #define COBJMACROS
31 #include "d3dx9.h"
32 
33 #define ULONG64_MAX (~(ULONG64)0)
34 
35 struct vec4
36 {
37     float x, y, z, w;
38 };
39 
40 struct volume
41 {
42     UINT width;
43     UINT height;
44     UINT depth;
45 };
46 
47 /* for internal use */
48 enum format_type {
49     FORMAT_ARGB,   /* unsigned */
50     FORMAT_ARGBF16,/* float 16 */
51     FORMAT_ARGBF,  /* float */
52     FORMAT_DXT,
53     FORMAT_INDEX,
54     FORMAT_UNKNOWN
55 };
56 
57 struct pixel_format_desc {
58     D3DFORMAT format;
59     BYTE bits[4];
60     BYTE shift[4];
61     UINT bytes_per_pixel;
62     UINT block_width;
63     UINT block_height;
64     UINT block_byte_count;
65     enum format_type type;
66     void (*from_rgba)(const struct vec4 *src, struct vec4 *dst);
67     void (*to_rgba)(const struct vec4 *src, struct vec4 *dst, const PALETTEENTRY *palette);
68 };
69 
70 struct d3dx_include_from_file
71 {
72     ID3DXInclude ID3DXInclude_iface;
73 };
74 
75 extern CRITICAL_SECTION from_file_mutex DECLSPEC_HIDDEN;
76 extern const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl DECLSPEC_HIDDEN;
77 
78 static inline BOOL is_conversion_from_supported(const struct pixel_format_desc *format)
79 {
80     if (format->type == FORMAT_ARGB || format->type == FORMAT_ARGBF16
81             || format->type == FORMAT_ARGBF)
82         return TRUE;
83     return !!format->to_rgba;
84 }
85 
86 static inline BOOL is_conversion_to_supported(const struct pixel_format_desc *format)
87 {
88     if (format->type == FORMAT_ARGB || format->type == FORMAT_ARGBF16
89             || format->type == FORMAT_ARGBF)
90         return TRUE;
91     return !!format->from_rgba;
92 }
93 
94 HRESULT map_view_of_file(const WCHAR *filename, void **buffer, DWORD *length) DECLSPEC_HIDDEN;
95 HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, void **buffer, DWORD *length) DECLSPEC_HIDDEN;
96 
97 HRESULT write_buffer_to_file(const WCHAR *filename, ID3DXBuffer *buffer) DECLSPEC_HIDDEN;
98 
99 const struct pixel_format_desc *get_format_info(D3DFORMAT format) DECLSPEC_HIDDEN;
100 const struct pixel_format_desc *get_format_info_idx(int idx) DECLSPEC_HIDDEN;
101 
102 void copy_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
103     BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *size,
104     const struct pixel_format_desc *format) DECLSPEC_HIDDEN;
105 void convert_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
106     const struct volume *src_size, const struct pixel_format_desc *src_format,
107     BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size,
108     const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette) DECLSPEC_HIDDEN;
109 void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slice_pitch,
110     const struct volume *src_size, const struct pixel_format_desc *src_format,
111     BYTE *dst, UINT dst_row_pitch, UINT dst_slice_pitch, const struct volume *dst_size,
112     const struct pixel_format_desc *dst_format, D3DCOLOR color_key, const PALETTEENTRY *palette) DECLSPEC_HIDDEN;
113 
114 HRESULT load_texture_from_dds(IDirect3DTexture9 *texture, const void *src_data, const PALETTEENTRY *palette,
115         DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info, unsigned int skip_levels,
116         unsigned int *loaded_miplevels) DECLSPEC_HIDDEN;
117 HRESULT load_cube_texture_from_dds(IDirect3DCubeTexture9 *cube_texture, const void *src_data,
118     const PALETTEENTRY *palette, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
119 HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette,
120     const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key,
121     const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
122 HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, const void *src_data,
123     const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
124 HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture,
125     const PALETTEENTRY *src_palette) DECLSPEC_HIDDEN;
126 
127 unsigned short float_32_to_16(const float in) DECLSPEC_HIDDEN;
128 float float_16_to_32(const unsigned short in) DECLSPEC_HIDDEN;
129 
130 /* debug helpers */
131 const char *debug_d3dxparameter_class(D3DXPARAMETER_CLASS c) DECLSPEC_HIDDEN;
132 const char *debug_d3dxparameter_type(D3DXPARAMETER_TYPE t) DECLSPEC_HIDDEN;
133 const char *debug_d3dxparameter_registerset(D3DXREGISTER_SET r) DECLSPEC_HIDDEN;
134 
135 /* parameter type conversion helpers */
136 static inline BOOL get_bool(D3DXPARAMETER_TYPE type, const void *data)
137 {
138     switch (type)
139     {
140         case D3DXPT_FLOAT:
141         case D3DXPT_INT:
142         case D3DXPT_BOOL:
143             return !!*(DWORD *)data;
144 
145         case D3DXPT_VOID:
146             return *(BOOL *)data;
147 
148         default:
149             return FALSE;
150     }
151 }
152 
153 static inline int get_int(D3DXPARAMETER_TYPE type, const void *data)
154 {
155     switch (type)
156     {
157         case D3DXPT_FLOAT:
158             return (int)(*(float *)data);
159 
160         case D3DXPT_INT:
161         case D3DXPT_VOID:
162             return *(int *)data;
163 
164         case D3DXPT_BOOL:
165             return get_bool(type, data);
166 
167         default:
168             return 0;
169     }
170 }
171 
172 static inline float get_float(D3DXPARAMETER_TYPE type, const void *data)
173 {
174     switch (type)
175     {
176         case D3DXPT_FLOAT:
177         case D3DXPT_VOID:
178             return *(float *)data;
179 
180         case D3DXPT_INT:
181             return (float)(*(int *)data);
182 
183         case D3DXPT_BOOL:
184             return (float)get_bool(type, data);
185 
186         default:
187             return 0.0f;
188     }
189 }
190 
191 static inline void set_number(void *outdata, D3DXPARAMETER_TYPE outtype, const void *indata, D3DXPARAMETER_TYPE intype)
192 {
193     if (outtype == intype)
194     {
195         *(DWORD *)outdata = *(DWORD *)indata;
196         return;
197     }
198 
199     switch (outtype)
200     {
201         case D3DXPT_FLOAT:
202             *(float *)outdata = get_float(intype, indata);
203             break;
204 
205         case D3DXPT_BOOL:
206             *(BOOL *)outdata = get_bool(intype, indata);
207             break;
208 
209         case D3DXPT_INT:
210             *(int *)outdata = get_int(intype, indata);
211             break;
212 
213         default:
214             *(DWORD *)outdata = 0;
215             break;
216     }
217 }
218 
219 static inline BOOL is_param_type_sampler(D3DXPARAMETER_TYPE type)
220 {
221     return type == D3DXPT_SAMPLER
222             || type == D3DXPT_SAMPLER1D || type == D3DXPT_SAMPLER2D
223             || type == D3DXPT_SAMPLER3D || type == D3DXPT_SAMPLERCUBE;
224 }
225 
226 struct d3dx_parameter;
227 
228 enum pres_reg_tables
229 {
230     PRES_REGTAB_IMMED,
231     PRES_REGTAB_CONST,
232     PRES_REGTAB_OCONST,
233     PRES_REGTAB_OBCONST,
234     PRES_REGTAB_OICONST,
235     PRES_REGTAB_TEMP,
236     PRES_REGTAB_COUNT,
237     PRES_REGTAB_FIRST_SHADER = PRES_REGTAB_CONST,
238 };
239 
240 struct d3dx_const_param_eval_output
241 {
242     struct d3dx_parameter *param;
243     enum pres_reg_tables table;
244     enum D3DXPARAMETER_CLASS constant_class;
245     unsigned int register_index;
246     unsigned int register_count;
247     BOOL direct_copy;
248     unsigned int element_count;
249 };
250 
251 struct d3dx_const_tab
252 {
253     unsigned int input_count;
254     D3DXCONSTANT_DESC *inputs;
255     struct d3dx_parameter **inputs_param;
256     unsigned int const_set_count;
257     unsigned int const_set_size;
258     struct d3dx_const_param_eval_output *const_set;
259     const enum pres_reg_tables *regset2table;
260     ULONG64 update_version;
261 };
262 
263 struct d3dx_regstore
264 {
265     void *tables[PRES_REGTAB_COUNT];
266     unsigned int table_sizes[PRES_REGTAB_COUNT]; /* registers count */
267 };
268 
269 struct d3dx_pres_ins;
270 
271 struct d3dx_preshader
272 {
273     struct d3dx_regstore regs;
274 
275     unsigned int ins_count;
276     struct d3dx_pres_ins *ins;
277 
278     struct d3dx_const_tab inputs;
279 };
280 
281 struct d3dx_param_eval
282 {
283     D3DXPARAMETER_TYPE param_type;
284 
285     struct d3dx_preshader pres;
286     struct d3dx_const_tab shader_inputs;
287 
288     ULONG64 *version_counter;
289 };
290 
291 struct param_rb_entry
292 {
293     struct wine_rb_entry entry;
294     char *full_name;
295     struct d3dx_parameter *param;
296 };
297 
298 struct d3dx_shared_data;
299 struct d3dx_top_level_parameter;
300 
301 struct d3dx_parameter
302 {
303     char magic_string[4];
304     struct d3dx_top_level_parameter *top_level_param;
305     struct d3dx_param_eval *param_eval;
306     char *name;
307     void *data;
308     D3DXPARAMETER_CLASS class;
309     D3DXPARAMETER_TYPE  type;
310     UINT rows;
311     UINT columns;
312     UINT element_count;
313     UINT member_count;
314     DWORD flags;
315     UINT bytes;
316     DWORD object_id;
317 
318     struct d3dx_parameter *members;
319     char *semantic;
320 
321     char *full_name;
322     struct wine_rb_entry rb_entry;
323 };
324 
325 struct d3dx_top_level_parameter
326 {
327     struct d3dx_parameter param;
328     UINT annotation_count;
329     struct d3dx_parameter *annotations;
330     ULONG64 update_version;
331     ULONG64 *version_counter;
332     struct d3dx_shared_data *shared_data;
333 };
334 
335 struct d3dx_shared_data
336 {
337     void *data;
338     struct d3dx_top_level_parameter **parameters;
339     unsigned int size, count;
340     ULONG64 update_version;
341 };
342 
343 struct d3dx9_base_effect;
344 
345 static inline BOOL is_top_level_parameter(struct d3dx_parameter *param)
346 {
347     return &param->top_level_param->param == param;
348 }
349 
350 static inline struct d3dx_top_level_parameter
351         *top_level_parameter_from_parameter(struct d3dx_parameter *param)
352 {
353     return CONTAINING_RECORD(param, struct d3dx_top_level_parameter, param);
354 }
355 
356 static inline ULONG64 next_update_version(ULONG64 *version_counter)
357 {
358     return ++*version_counter;
359 }
360 
361 static inline BOOL is_top_level_param_dirty(struct d3dx_top_level_parameter *param, ULONG64 update_version)
362 {
363     struct d3dx_shared_data *shared_data;
364 
365     if ((shared_data = param->shared_data))
366         return update_version < shared_data->update_version;
367     else
368         return update_version < param->update_version;
369 }
370 
371 static inline BOOL is_param_dirty(struct d3dx_parameter *param, ULONG64 update_version)
372 {
373     return is_top_level_param_dirty(param->top_level_param, update_version);
374 }
375 
376 struct d3dx_parameter *get_parameter_by_name(struct d3dx9_base_effect *base,
377         struct d3dx_parameter *parameter, const char *name) DECLSPEC_HIDDEN;
378 
379 #ifdef __REACTOS__
380 #define SET_D3D_STATE_(_manager, _device, _method, ...) ((_manager) ? (_manager)->lpVtbl->_method((_manager), __VA_ARGS__) \
381         : (_device)->lpVtbl->_method((_device), __VA_ARGS__))
382 #define SET_D3D_STATE(_base_effect, _method, ...) SET_D3D_STATE_((_base_effect)->manager, (_base_effect)->device, _method, __VA_ARGS__)
383 #else
384 #define SET_D3D_STATE_(manager, device, method, args...) (manager ? manager->lpVtbl->method(manager, args) \
385         : device->lpVtbl->method(device, args))
386 #define SET_D3D_STATE(base_effect, args...) SET_D3D_STATE_(base_effect->manager, base_effect->device, args)
387 #endif
388 
389 HRESULT d3dx_create_param_eval(struct d3dx9_base_effect *base_effect, void *byte_code,
390         unsigned int byte_code_size, D3DXPARAMETER_TYPE type,
391         struct d3dx_param_eval **peval, ULONG64 *version_counter,
392         const char **skip_constants, unsigned int skip_constants_count) DECLSPEC_HIDDEN;
393 void d3dx_free_param_eval(struct d3dx_param_eval *peval) DECLSPEC_HIDDEN;
394 HRESULT d3dx_evaluate_parameter(struct d3dx_param_eval *peval,
395         const struct d3dx_parameter *param, void *param_value) DECLSPEC_HIDDEN;
396 HRESULT d3dx_param_eval_set_shader_constants(ID3DXEffectStateManager *manager, struct IDirect3DDevice9 *device,
397         struct d3dx_param_eval *peval, BOOL update_all) DECLSPEC_HIDDEN;
398 BOOL is_param_eval_input_dirty(struct d3dx_param_eval *peval, ULONG64 update_version) DECLSPEC_HIDDEN;
399 
400 struct ctab_constant {
401     D3DXCONSTANT_DESC desc;
402     WORD constantinfo_reserved;
403     struct ctab_constant *constants;
404 };
405 
406 const struct ctab_constant *d3dx_shader_get_ctab_constant(ID3DXConstantTable *iface,
407         D3DXHANDLE constant) DECLSPEC_HIDDEN;
408 
409 HRESULT create_dummy_skin(ID3DXSkinInfo **iface) DECLSPEC_HIDDEN;
410 
411 #endif /* __WINE_D3DX9_PRIVATE_H */
412