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