1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 //============================================================
4 //
5 //  drawd3d.c - Win32 Direct3D HLSL-specific header
6 //
7 //============================================================
8 
9 #ifndef __WIN_D3DHLSL__
10 #define __WIN_D3DHLSL__
11 
12 #include <vector>
13 #include "../frontend/mame/ui/menuitem.h"
14 #include "../frontend/mame/ui/slider.h"
15 #include "modules/lib/osdlib.h"
16 
17 //============================================================
18 //  TYPE DEFINITIONS
19 //============================================================
20 
21 // Typedefs for dynamically loaded functions
22 typedef HRESULT (WINAPI *d3dx_create_effect_from_file_fn)(LPDIRECT3DDEVICE9, LPCTSTR, const D3DXMACRO *, LPD3DXINCLUDE, DWORD, LPD3DXEFFECTPOOL, LPD3DXEFFECT *, LPD3DXBUFFER *);
23 
24 struct slider_state;
25 
26 class effect;
27 class shaders;
28 
29 class uniform
30 {
31 public:
32 	typedef enum
33 	{
34 		UT_VEC4,
35 		UT_VEC3,
36 		UT_VEC2,
37 		UT_FLOAT,
38 		UT_INT,
39 		UT_BOOL,
40 		UT_MATRIX,
41 		UT_SAMPLER
42 	} uniform_type;
43 
44 	enum
45 	{
46 		CU_SCREEN_DIMS = 0,
47 		CU_SCREEN_COUNT,
48 		CU_SOURCE_DIMS,
49 		CU_TARGET_DIMS,
50 		CU_TARGET_SCALE,
51 		CU_QUAD_DIMS,
52 
53 		CU_SWAP_XY,
54 		CU_VECTOR_SCREEN,
55 
56 		CU_NTSC_CCFREQ,
57 		CU_NTSC_A,
58 		CU_NTSC_B,
59 		CU_NTSC_O,
60 		CU_NTSC_P,
61 		CU_NTSC_NOTCH,
62 		CU_NTSC_YFREQ,
63 		CU_NTSC_IFREQ,
64 		CU_NTSC_QFREQ,
65 		CU_NTSC_HTIME,
66 		CU_NTSC_ENABLE,
67 
68 		CU_COLOR_RED_RATIOS,
69 		CU_COLOR_GRN_RATIOS,
70 		CU_COLOR_BLU_RATIOS,
71 		CU_COLOR_OFFSET,
72 		CU_COLOR_SCALE,
73 		CU_COLOR_SATURATION,
74 
75 		CU_CONVERGE_LINEAR_X,
76 		CU_CONVERGE_LINEAR_Y,
77 		CU_CONVERGE_RADIAL_X,
78 		CU_CONVERGE_RADIAL_Y,
79 
80 		CU_FOCUS_SIZE,
81 
82 		CU_PHOSPHOR_LIFE,
83 
84 		CU_POST_VIGNETTING,
85 		CU_POST_DISTORTION,
86 		CU_POST_CUBIC_DISTORTION,
87 		CU_POST_DISTORT_CORNER,
88 		CU_POST_ROUND_CORNER,
89 		CU_POST_SMOOTH_BORDER,
90 		CU_POST_REFLECTION,
91 		CU_POST_SHADOW_ALPHA,
92 		CU_POST_SHADOW_COUNT,
93 		CU_POST_SHADOW_UV,
94 		CU_POST_SHADOW_UV_OFFSET,
95 		CU_POST_SHADOW_DIMS,
96 		CU_POST_SCANLINE_ALPHA,
97 		CU_POST_SCANLINE_SCALE,
98 		CU_POST_SCANLINE_HEIGHT,
99 		CU_POST_SCANLINE_VARIATION,
100 		CU_POST_SCANLINE_BRIGHT_SCALE,
101 		CU_POST_SCANLINE_BRIGHT_OFFSET,
102 		CU_POST_POWER,
103 		CU_POST_FLOOR,
104 		CU_CHROMA_MODE,
105 		CU_CHROMA_A,
106 		CU_CHROMA_B,
107 		CU_CHROMA_C,
108 		CU_CHROMA_CONVERSION_GAIN,
109 		CU_CHROMA_Y_GAIN,
110 		CU_LUT_ENABLE,
111 		CU_UI_LUT_ENABLE,
112 
113 		CU_COUNT
114 	};
115 
116 	uniform(effect *shader, const char *name, uniform_type type, int id);
117 
118 	void        update();
119 
120 protected:
121 	uniform_type m_type;
122 	int         m_id;
123 
124 	effect      *m_shader;
125 	D3DXHANDLE  m_handle;
126 };
127 
128 class effect
129 {
130 	friend class uniform;
131 
132 public:
133 	effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, const char *path);
134 	~effect();
135 
136 	void        begin(UINT *passes, DWORD flags);
137 	void        begin_pass(UINT pass);
138 
139 	void        end();
140 	void        end_pass();
141 
142 	void        set_technique(const char *name);
143 
144 	void        set_vector(D3DXHANDLE param, int count, float *vector);
145 	void        set_float(D3DXHANDLE param, float value);
146 	void        set_int(D3DXHANDLE param, int value);
147 	void        set_bool(D3DXHANDLE param, bool value);
148 	void        set_matrix(D3DXHANDLE param, D3DXMATRIX *matrix);
149 	void        set_texture(D3DXHANDLE param, IDirect3DTexture9 *tex);
150 
151 	void        add_uniform(const char *name, uniform::uniform_type type, int id);
152 	void        update_uniforms();
153 
154 	D3DXHANDLE  get_parameter(D3DXHANDLE param, const char *name);
155 
get_shaders()156 	shaders*    get_shaders() { return m_shaders; }
157 
is_valid()158 	bool        is_valid() { return m_valid; }
159 
160 private:
161 	std::vector<std::unique_ptr<uniform>> m_uniform_list;
162 
163 	ID3DXEffect *m_effect;
164 	shaders     *m_shaders;
165 
166 	bool        m_valid;
167 };
168 
169 class d3d_render_target;
170 class cache_target;
171 class renderer_d3d9;
172 class movie_recorder;
173 
174 /* hlsl_options is the information about runtime-mutable Direct3D HLSL options */
175 /* in the future this will be moved into an OSD/emu shared buffer */
176 struct hlsl_options
177 {
178 	bool                    params_init;
179 	bool                    params_dirty;
180 	int                     shadow_mask_tile_mode;
181 	float                   shadow_mask_alpha;
182 	char                    shadow_mask_texture[1024];
183 	int                     shadow_mask_count_x;
184 	int                     shadow_mask_count_y;
185 	float                   shadow_mask_u_size;
186 	float                   shadow_mask_v_size;
187 	float                   shadow_mask_u_offset;
188 	float                   shadow_mask_v_offset;
189 	float                   distortion;
190 	float                   cubic_distortion;
191 	float                   distort_corner;
192 	float                   round_corner;
193 	float                   smooth_border;
194 	float                   reflection;
195 	float                   vignetting;
196 	float                   scanline_alpha;
197 	float                   scanline_scale;
198 	float                   scanline_height;
199 	float                   scanline_variation;
200 	float                   scanline_bright_scale;
201 	float                   scanline_bright_offset;
202 	float                   scanline_jitter;
203 	float                   hum_bar_alpha;
204 	float                   defocus[2];
205 	float                   converge_x[3];
206 	float                   converge_y[3];
207 	float                   radial_converge_x[3];
208 	float                   radial_converge_y[3];
209 	float                   red_ratio[3];
210 	float                   grn_ratio[3];
211 	float                   blu_ratio[3];
212 	float                   offset[3];
213 	float                   scale[3];
214 	float                   power[3];
215 	float                   floor[3];
216 	float                   phosphor[3];
217 	float                   saturation;
218 	int                     chroma_mode;
219 	float                   chroma_a[2];
220 	float                   chroma_b[2];
221 	float                   chroma_c[2];
222 	float                   chroma_conversion_gain[3];
223 	float                   chroma_y_gain[3];
224 
225 	// NTSC
226 	int                     yiq_enable;
227 	float                   yiq_jitter;
228 	float                   yiq_cc;
229 	float                   yiq_a;
230 	float                   yiq_b;
231 	float                   yiq_o;
232 	float                   yiq_p;
233 	float                   yiq_n;
234 	float                   yiq_y;
235 	float                   yiq_i;
236 	float                   yiq_q;
237 	float                   yiq_scan_time;
238 	int                     yiq_phase_count;
239 
240 	// Vectors
241 	float                   vector_beam_smooth;
242 	float                   vector_length_scale;
243 	float                   vector_length_ratio;
244 
245 	// Bloom
246 	int                     bloom_blend_mode;
247 	float                   bloom_scale;
248 	float                   bloom_overdrive[3];
249 	float                   bloom_level0_weight;
250 	float                   bloom_level1_weight;
251 	float                   bloom_level2_weight;
252 	float                   bloom_level3_weight;
253 	float                   bloom_level4_weight;
254 	float                   bloom_level5_weight;
255 	float                   bloom_level6_weight;
256 	float                   bloom_level7_weight;
257 	float                   bloom_level8_weight;
258 
259 	// Final
260 	char lut_texture[1024];
261 	int lut_enable;
262 	char ui_lut_texture[1024];
263 	int ui_lut_enable;
264 };
265 
266 struct slider_desc
267 {
268 	const char *                name;
269 	int                         minval;
270 	int                         defval;
271 	int                         maxval;
272 	int                         step;
273 	int                         slider_type;
274 	int                         screen_type;
275 	int                         id;
276 	float                       scale;
277 	const char *                format;
278 	std::vector<const char *>   strings;
279 };
280 
281 class slider
282 {
283 public:
slider(slider_desc * desc,void * value,bool * dirty)284 	slider(slider_desc *desc, void *value, bool *dirty) : m_desc(desc), m_value(value) { }
285 
286 	int32_t update(std::string *str, int32_t newval);
287 
288 private:
289 	slider_desc *   m_desc;
290 	void *          m_value;
291 };
292 
293 class shaders : public slider_changed_notifier
294 {
295 	friend class effect;
296 	friend class uniform;
297 
298 public:
299 	// construction/destruction
300 	shaders();
301 	~shaders();
302 
303 	bool init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer);
304 
enabled()305 	bool enabled() { return post_fx_enable && d3dintf->post_fx_available; }
toggle()306 	void toggle() { post_fx_enable = initialized && !post_fx_enable; }
307 
308 	void begin_draw();
309 	void end_draw();
310 
311 	void render_quad(poly_info *poly, int vertnum);
312 
313 	bool create_vector_target(render_primitive *prim, int screen);
314 	d3d_render_target* get_vector_target(render_primitive *prim, int screen);
315 	bool create_texture_target(render_primitive *prim, int width, int height, int screen);
316 	d3d_render_target* get_texture_target(render_primitive *prim, int width, int height, int screen);
317 	bool add_render_target(renderer_d3d9* d3d, render_primitive *prim, int source_width, int source_height, int source_screen, int target_width, int target_height);
318 
319 	void save_snapshot();
320 	void record_movie();
321 	void record_audio(const int16_t *buffer, int samples_this_frame);
322 
323 	void init_fsfx_quad();
324 
325 	void set_texture(texture_info *info);
326 	void remove_render_target(int source_width, int source_height, uint32_t screen_index);
327 	void remove_render_target(d3d_render_target *rt);
328 
329 	int create_resources();
330 	void delete_resources();
331 
332 	// slider-related functions
333 	virtual int32_t slider_changed(running_machine &machine, void *arg, int /*id*/, std::string *str, int32_t newval) override;
334 	std::unique_ptr<slider_state> slider_alloc(int id, const char *title, int32_t minval, int32_t defval, int32_t maxval, int32_t incval, void *arg);
335 	void init_slider_list();
get_slider_list()336 	std::vector<ui::menu_item> get_slider_list() { return m_sliders; }
337 	void *get_slider_option(int id, int index = 0);
338 
339 private:
340 	void                    blit(IDirect3DSurface9 *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, uint32_t prim_index, uint32_t prim_count);
341 	void                    enumerate_screens();
342 
343 	void                    render_snapshot(IDirect3DSurface9 *surface);
344 	// Time since last call, only updates once per render of all screens
delta_time()345 	double                  delta_time() { return delta_t; }
346 	d3d_render_target*      find_render_target(int source_width, int source_height, uint32_t screen_index);
347 
348 	rgb_t                   apply_color_convolution(rgb_t color);
349 
350 	// Shader passes
351 	int                     ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
352 	int                     color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
353 	int                     prescale_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
354 	int                     deconverge_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
355 	int                     scanline_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
356 	int                     defocus_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
357 	int                     phosphor_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
358 	int                     post_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom);
359 	int                     downsample_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
360 	int                     bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
361 	int                     chroma_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
362 	int                     distortion_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
363 	int                     vector_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
364 	int                     vector_buffer_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
365 	int                     screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
366 	void                    ui_pass(poly_info *poly, int vertnum);
367 
368 	d3d_base *              d3dintf;                    // D3D interface
369 
370 	running_machine *       machine;
371 	renderer_d3d9 *         d3d;                        // D3D renderer
372 
373 	bool                    post_fx_enable;             // overall enable flag
374 	bool                    oversampling_enable;        // oversampling enable flag
375 	int                     num_screens;                // number of emulated physical screens
376 	int                     curr_screen;                // current screen for render target operations
377 	double                  acc_t;                      // accumulated machine time
378 	double                  delta_t;                    // data for delta_time
379 	bitmap_argb32           shadow_bitmap;              // shadow mask bitmap for post-processing shader
380 	texture_info *          shadow_texture;             // shadow mask texture for post-processing shader
381 	bitmap_argb32           lut_bitmap;
382 	texture_info *          lut_texture;
383 	bitmap_argb32           ui_lut_bitmap;
384 	texture_info *          ui_lut_texture;
385 	hlsl_options *          options;                    // current options
386 
387 	IDirect3DSurface9 *     black_surface;              // black dummy surface
388 	IDirect3DTexture9 *     black_texture;              // black dummy texture
389 
390 	bool                    recording_movie;            // ongoing movie recording
391 	std::unique_ptr<movie_recorder> recorder;           // HLSL post-render movie recorder
392 
393 	bool                    render_snap;                // whether or not to take HLSL post-render snapshot
394 	IDirect3DSurface9 *     snap_copy_target;           // snapshot destination surface in system memory
395 	IDirect3DTexture9 *     snap_copy_texture;          // snapshot destination surface in system memory
396 	IDirect3DSurface9 *     snap_target;                // snapshot upscaled surface
397 	IDirect3DTexture9 *     snap_texture;               // snapshot upscaled texture
398 	int                     snap_width;                 // snapshot width
399 	int                     snap_height;                // snapshot height
400 
401 	bool                    initialized;                // whether or not we're initialized
402 
403 	// HLSL effects
404 	IDirect3DSurface9 *     backbuffer;                 // pointer to our device's backbuffer
405 	effect *                curr_effect;                // pointer to the currently active effect object
406 	effect *                default_effect;             // pointer to the primary-effect object
407 	effect *                prescale_effect;            // pointer to the prescale-effect object
408 	effect *                post_effect;                // pointer to the post-effect object
409 	effect *                distortion_effect;          // pointer to the distortion-effect object
410 	effect *                scanline_effect;
411 	effect *                focus_effect;               // pointer to the focus-effect object
412 	effect *                phosphor_effect;            // pointer to the phosphor-effect object
413 	effect *                deconverge_effect;          // pointer to the deconvergence-effect object
414 	effect *                color_effect;               // pointer to the color-effect object
415 	effect *                ntsc_effect;                // pointer to the NTSC effect object
416 	effect *                bloom_effect;               // pointer to the bloom composite effect
417 	effect *                downsample_effect;          // pointer to the bloom downsample effect
418 	effect *                vector_effect;              // pointer to the vector-effect object
419 	effect *                chroma_effect;
420 
421 	texture_info *          curr_texture;
422 	d3d_render_target *     curr_render_target;
423 	poly_info *             curr_poly;
424 
425 	std::vector<std::unique_ptr<d3d_render_target>> m_render_target_list;
426 
427 	std::vector<slider*>    internal_sliders;
428 	std::vector<ui::menu_item> m_sliders;
429 	std::vector<std::unique_ptr<slider_state>> m_core_sliders;
430 
431 	static slider_desc      s_sliders[];
432 	static hlsl_options     last_options;               // last used options
433 	static char             last_system_name[16];       // last used system
434 
435 	osd::dynamic_module::ptr d3dx9_dll;
436 	d3dx_create_effect_from_file_fn d3dx_create_effect_from_file_ptr;
437 };
438 
439 #endif
440