// license:BSD-3-Clause // copyright-holders:Aaron Giles //============================================================ // // drawd3d.c - Win32 Direct3D HLSL-specific header // //============================================================ #ifndef __WIN_D3DHLSL__ #define __WIN_D3DHLSL__ #include #include "../frontend/mame/ui/menuitem.h" #include "../frontend/mame/ui/slider.h" #include "modules/lib/osdlib.h" //============================================================ // TYPE DEFINITIONS //============================================================ // Typedefs for dynamically loaded functions typedef HRESULT (WINAPI *d3dx_create_effect_from_file_fn)(LPDIRECT3DDEVICE9, LPCTSTR, const D3DXMACRO *, LPD3DXINCLUDE, DWORD, LPD3DXEFFECTPOOL, LPD3DXEFFECT *, LPD3DXBUFFER *); struct slider_state; class effect; class shaders; class uniform { public: typedef enum { UT_VEC4, UT_VEC3, UT_VEC2, UT_FLOAT, UT_INT, UT_BOOL, UT_MATRIX, UT_SAMPLER } uniform_type; enum { CU_SCREEN_DIMS = 0, CU_SCREEN_COUNT, CU_SOURCE_DIMS, CU_TARGET_DIMS, CU_TARGET_SCALE, CU_QUAD_DIMS, CU_SWAP_XY, CU_VECTOR_SCREEN, CU_NTSC_CCFREQ, CU_NTSC_A, CU_NTSC_B, CU_NTSC_O, CU_NTSC_P, CU_NTSC_NOTCH, CU_NTSC_YFREQ, CU_NTSC_IFREQ, CU_NTSC_QFREQ, CU_NTSC_HTIME, CU_NTSC_ENABLE, CU_COLOR_RED_RATIOS, CU_COLOR_GRN_RATIOS, CU_COLOR_BLU_RATIOS, CU_COLOR_OFFSET, CU_COLOR_SCALE, CU_COLOR_SATURATION, CU_CONVERGE_LINEAR_X, CU_CONVERGE_LINEAR_Y, CU_CONVERGE_RADIAL_X, CU_CONVERGE_RADIAL_Y, CU_FOCUS_SIZE, CU_PHOSPHOR_LIFE, CU_POST_VIGNETTING, CU_POST_DISTORTION, CU_POST_CUBIC_DISTORTION, CU_POST_DISTORT_CORNER, CU_POST_ROUND_CORNER, CU_POST_SMOOTH_BORDER, CU_POST_REFLECTION, CU_POST_SHADOW_ALPHA, CU_POST_SHADOW_COUNT, CU_POST_SHADOW_UV, CU_POST_SHADOW_UV_OFFSET, CU_POST_SHADOW_DIMS, CU_POST_SCANLINE_ALPHA, CU_POST_SCANLINE_SCALE, CU_POST_SCANLINE_HEIGHT, CU_POST_SCANLINE_VARIATION, CU_POST_SCANLINE_BRIGHT_SCALE, CU_POST_SCANLINE_BRIGHT_OFFSET, CU_POST_POWER, CU_POST_FLOOR, CU_CHROMA_MODE, CU_CHROMA_A, CU_CHROMA_B, CU_CHROMA_C, CU_CHROMA_CONVERSION_GAIN, CU_CHROMA_Y_GAIN, CU_LUT_ENABLE, CU_UI_LUT_ENABLE, CU_COUNT }; uniform(effect *shader, const char *name, uniform_type type, int id); void update(); protected: uniform_type m_type; int m_id; effect *m_shader; D3DXHANDLE m_handle; }; class effect { friend class uniform; public: effect(shaders *shadersys, IDirect3DDevice9 *dev, const char *name, const char *path); ~effect(); void begin(UINT *passes, DWORD flags); void begin_pass(UINT pass); void end(); void end_pass(); void set_technique(const char *name); void set_vector(D3DXHANDLE param, int count, float *vector); void set_float(D3DXHANDLE param, float value); void set_int(D3DXHANDLE param, int value); void set_bool(D3DXHANDLE param, bool value); void set_matrix(D3DXHANDLE param, D3DXMATRIX *matrix); void set_texture(D3DXHANDLE param, IDirect3DTexture9 *tex); void add_uniform(const char *name, uniform::uniform_type type, int id); void update_uniforms(); D3DXHANDLE get_parameter(D3DXHANDLE param, const char *name); shaders* get_shaders() { return m_shaders; } bool is_valid() { return m_valid; } private: std::vector> m_uniform_list; ID3DXEffect *m_effect; shaders *m_shaders; bool m_valid; }; class d3d_render_target; class cache_target; class renderer_d3d9; class movie_recorder; /* hlsl_options is the information about runtime-mutable Direct3D HLSL options */ /* in the future this will be moved into an OSD/emu shared buffer */ struct hlsl_options { bool params_init; bool params_dirty; int shadow_mask_tile_mode; float shadow_mask_alpha; char shadow_mask_texture[1024]; int shadow_mask_count_x; int shadow_mask_count_y; float shadow_mask_u_size; float shadow_mask_v_size; float shadow_mask_u_offset; float shadow_mask_v_offset; float distortion; float cubic_distortion; float distort_corner; float round_corner; float smooth_border; float reflection; float vignetting; float scanline_alpha; float scanline_scale; float scanline_height; float scanline_variation; float scanline_bright_scale; float scanline_bright_offset; float scanline_jitter; float hum_bar_alpha; float defocus[2]; float converge_x[3]; float converge_y[3]; float radial_converge_x[3]; float radial_converge_y[3]; float red_ratio[3]; float grn_ratio[3]; float blu_ratio[3]; float offset[3]; float scale[3]; float power[3]; float floor[3]; float phosphor[3]; float saturation; int chroma_mode; float chroma_a[2]; float chroma_b[2]; float chroma_c[2]; float chroma_conversion_gain[3]; float chroma_y_gain[3]; // NTSC int yiq_enable; float yiq_jitter; float yiq_cc; float yiq_a; float yiq_b; float yiq_o; float yiq_p; float yiq_n; float yiq_y; float yiq_i; float yiq_q; float yiq_scan_time; int yiq_phase_count; // Vectors float vector_beam_smooth; float vector_length_scale; float vector_length_ratio; // Bloom int bloom_blend_mode; float bloom_scale; float bloom_overdrive[3]; float bloom_level0_weight; float bloom_level1_weight; float bloom_level2_weight; float bloom_level3_weight; float bloom_level4_weight; float bloom_level5_weight; float bloom_level6_weight; float bloom_level7_weight; float bloom_level8_weight; // Final char lut_texture[1024]; int lut_enable; char ui_lut_texture[1024]; int ui_lut_enable; }; struct slider_desc { const char * name; int minval; int defval; int maxval; int step; int slider_type; int screen_type; int id; float scale; const char * format; std::vector strings; }; class slider { public: slider(slider_desc *desc, void *value, bool *dirty) : m_desc(desc), m_value(value) { } int32_t update(std::string *str, int32_t newval); private: slider_desc * m_desc; void * m_value; }; class shaders { friend class effect; friend class uniform; public: // construction/destruction shaders(); ~shaders(); bool init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer); bool enabled() { return post_fx_enable && d3dintf->post_fx_available; } void toggle() { post_fx_enable = initialized && !post_fx_enable; } void begin_draw(); void end_draw(); void render_quad(poly_info *poly, int vertnum); bool create_vector_target(render_primitive *prim, int screen); d3d_render_target* get_vector_target(render_primitive *prim, int screen); bool create_texture_target(render_primitive *prim, int width, int height, int screen); d3d_render_target* get_texture_target(render_primitive *prim, int width, int height, int screen); 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); void save_snapshot(); void record_movie(); void record_audio(const int16_t *buffer, int samples_this_frame); void init_fsfx_quad(); void set_texture(texture_info *info); void remove_render_target(int source_width, int source_height, uint32_t screen_index); void remove_render_target(d3d_render_target *rt); int create_resources(); void delete_resources(); // slider-related functions std::unique_ptr slider_alloc(std::string &&title, int32_t minval, int32_t defval, int32_t maxval, int32_t incval, slider *arg); void init_slider_list(); std::vector get_slider_list() { return m_sliders; } void *get_slider_option(int id, int index = 0); private: void blit(IDirect3DSurface9 *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, uint32_t prim_index, uint32_t prim_count); void enumerate_screens(); void render_snapshot(IDirect3DSurface9 *surface); // Time since last call, only updates once per render of all screens double delta_time() { return delta_t; } d3d_render_target* find_render_target(int source_width, int source_height, uint32_t screen_index); rgb_t apply_color_convolution(rgb_t color); // Shader passes int ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int prescale_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int deconverge_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int scanline_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int defocus_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int phosphor_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int post_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom); int downsample_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int chroma_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int distortion_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int vector_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int vector_buffer_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); int screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum); void ui_pass(poly_info *poly, int vertnum); d3d_base * d3dintf; // D3D interface running_machine * machine; renderer_d3d9 * d3d; // D3D renderer bool post_fx_enable; // overall enable flag bool oversampling_enable; // oversampling enable flag int num_screens; // number of emulated physical screens int curr_screen; // current screen for render target operations double acc_t; // accumulated machine time double delta_t; // data for delta_time bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader texture_info * shadow_texture; // shadow mask texture for post-processing shader bitmap_argb32 lut_bitmap; texture_info * lut_texture; bitmap_argb32 ui_lut_bitmap; texture_info * ui_lut_texture; hlsl_options * options; // current options IDirect3DSurface9 * black_surface; // black dummy surface IDirect3DTexture9 * black_texture; // black dummy texture bool recording_movie; // ongoing movie recording std::unique_ptr recorder; // HLSL post-render movie recorder bool render_snap; // whether or not to take HLSL post-render snapshot IDirect3DSurface9 * snap_copy_target; // snapshot destination surface in system memory IDirect3DTexture9 * snap_copy_texture; // snapshot destination surface in system memory IDirect3DSurface9 * snap_target; // snapshot upscaled surface IDirect3DTexture9 * snap_texture; // snapshot upscaled texture int snap_width; // snapshot width int snap_height; // snapshot height bool initialized; // whether or not we're initialized // HLSL effects IDirect3DSurface9 * backbuffer; // pointer to our device's backbuffer effect * curr_effect; // pointer to the currently active effect object effect * default_effect; // pointer to the primary-effect object effect * prescale_effect; // pointer to the prescale-effect object effect * post_effect; // pointer to the post-effect object effect * distortion_effect; // pointer to the distortion-effect object effect * scanline_effect; effect * focus_effect; // pointer to the focus-effect object effect * phosphor_effect; // pointer to the phosphor-effect object effect * deconverge_effect; // pointer to the deconvergence-effect object effect * color_effect; // pointer to the color-effect object effect * ntsc_effect; // pointer to the NTSC effect object effect * bloom_effect; // pointer to the bloom composite effect effect * downsample_effect; // pointer to the bloom downsample effect effect * vector_effect; // pointer to the vector-effect object effect * chroma_effect; texture_info * curr_texture; d3d_render_target * curr_render_target; poly_info * curr_poly; std::vector> m_render_target_list; std::vector internal_sliders; std::vector m_sliders; std::vector> m_core_sliders; static slider_desc s_sliders[]; static hlsl_options last_options; // last used options static char last_system_name[16]; // last used system osd::dynamic_module::ptr d3dx9_dll; d3dx_create_effect_from_file_fn d3dx_create_effect_from_file_ptr; }; #endif