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