From 2b0682196df3cfcebadcd67f137f8802aabb27a4 Mon Sep 17 00:00:00 2001 From: Giuseppe Gorgoglione Date: Mon, 4 Jul 2016 09:50:46 +0200 Subject: [PATCH 1/2] Direct3D HLSL: use aviwrite to record avi movies Use common infrastructure in aviwrite.c instead of equivalent local code. In addition: - the target textures used by the HLSL movie recorder are now allocated only when recording is ongoing - removed shaders->begin_frame() and shaders->end_frame() hooks from the main Direct3D rendering loop - set default HLSL movie name to hlsl.avi to match bgfx.avi setting --- src/osd/modules/render/d3d/d3dhlsl.cpp | 474 ++++++++----------------- src/osd/modules/render/d3d/d3dhlsl.h | 30 +- src/osd/modules/render/drawd3d.cpp | 8 +- src/osd/windows/winmain.cpp | 2 +- 4 files changed, 167 insertions(+), 347 deletions(-) diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index f3ef869c87f..e8059b9ead0 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -19,6 +19,7 @@ // MAMEOS headers #include "winmain.h" #include "window.h" +#include "modules/render/aviwrite.h" #include "modules/render/drawd3d.h" #include "d3dcomm.h" #include "strconv.h" @@ -26,11 +27,6 @@ #include "../frontend/mame/ui/slider.h" -//============================================================ -// GLOBALS -//============================================================ - - //============================================================ // PROTOTYPES //============================================================ @@ -38,17 +34,134 @@ static void get_vector(const char *data, int count, float *out, bool report_error); +//============================================================ +// HLSL post-render AVI recorder +//============================================================ + +class movie_recorder +{ +public: + movie_recorder(running_machine& machine, renderer_d3d9 *d3d, int width, int height) + : m_initialized(false), m_d3d(d3d), m_width(width), m_height(height) + , m_sys_texture(nullptr), m_sys_surface(nullptr) + , m_vid_texture(nullptr), m_vid_surface(nullptr) + { + HRESULT result; + + m_avi_writer = std::make_unique(machine, width, height); + + m_frame.allocate(width, height); + if (!m_frame.valid()) + return; + + result = d3d->get_device()->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &m_sys_texture, nullptr); + if (FAILED(result)) + { + osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL AVI dumping (%08lX)\n", result); + return; + } + m_sys_texture->GetSurfaceLevel(0, &m_sys_surface); + + result = d3d->get_device()->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_vid_texture, nullptr); + if (FAILED(result)) + { + osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL AVI dumping (%08lX)\n", result); + return; + } + m_vid_texture->GetSurfaceLevel(0, &m_vid_surface); + + m_initialized = true; + } + + ~movie_recorder() + { + if (m_sys_texture != nullptr) + m_sys_texture->Release(); + + if (m_sys_surface != nullptr) + m_sys_surface->Release(); + + if (m_vid_texture != nullptr) + m_vid_texture->Release(); + + if (m_vid_surface != nullptr) + m_vid_surface->Release(); + } + + void record(std::string name) + { + if (!m_initialized) + return; + + m_avi_writer->record(name); + } + + void save_frame() + { + if (!m_initialized) + return; + + // copy the frame from video memory, where it is not accessible, to system memory + HRESULT result = m_d3d->get_device()->GetRenderTargetData(m_vid_surface, m_sys_surface); + if (FAILED(result)) + return; + + D3DLOCKED_RECT rect; + result = m_sys_surface->LockRect(&rect, nullptr, D3DLOCK_DISCARD); + if (FAILED(result)) + return; + + for (int y = 0; y < m_height; y++) + { + DWORD *src = (DWORD *)((BYTE *)rect.pBits + y * rect.Pitch); + UINT32 *dst = &m_frame.pix32(y); + + for (int x = 0; x < m_width; x++) + { + *dst++ = *src++; + } + } + + result = m_sys_surface->UnlockRect(); + if (FAILED(result)) + osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result); + + m_avi_writer->video_frame(m_frame); + } + + IDirect3DSurface9 * target_surface() { return m_vid_surface; } + +private: + bool m_initialized; + + renderer_d3d9 * m_d3d; + + std::unique_ptr m_avi_writer; + + bitmap_rgb32 m_frame; + int m_width; + int m_height; + IDirect3DTexture9 * m_sys_texture; // texture in system memory + IDirect3DSurface9 * m_sys_surface; // surface in system memory + IDirect3DTexture9 * m_vid_texture; // texture in video memory + IDirect3DSurface9 * m_vid_surface; // surface in video memory +}; + + //============================================================ // shader manager constructor //============================================================ shaders::shaders() : - d3dintf(nullptr), machine(nullptr), d3d(nullptr), post_fx_enable(false), oversampling_enable(false), num_screens(0), curr_screen(0), - shadow_texture(nullptr), options(nullptr), avi_output_file(nullptr), avi_frame(0), avi_copy_surface(nullptr), avi_copy_texture(nullptr), avi_final_target(nullptr), avi_final_texture(nullptr), - black_surface(nullptr), black_texture(nullptr), render_snap(false), snap_rendered(false), snap_copy_target(nullptr), snap_copy_texture(nullptr), snap_target(nullptr), snap_texture(nullptr), - snap_width(0), snap_height(0), initialized(false), backbuffer(nullptr), curr_effect(nullptr), default_effect(nullptr), prescale_effect(nullptr), post_effect(nullptr), - distortion_effect(nullptr), focus_effect(nullptr), phosphor_effect(nullptr), deconverge_effect(nullptr), color_effect(nullptr), ntsc_effect(nullptr), bloom_effect(nullptr), - downsample_effect(nullptr), vector_effect(nullptr), curr_texture(nullptr), curr_render_target(nullptr), curr_poly(nullptr) + d3dintf(nullptr), machine(nullptr), d3d(nullptr), post_fx_enable(false), oversampling_enable(false), + num_screens(0), curr_screen(0), shadow_texture(nullptr), options(nullptr), black_surface(nullptr), + black_texture(nullptr), recording_movie(false),render_snap(false), snap_copy_target(nullptr), + snap_copy_texture(nullptr), snap_target(nullptr), snap_texture(nullptr), snap_width(0), snap_height(0), + initialized(false), backbuffer(nullptr), curr_effect(nullptr), default_effect(nullptr), + prescale_effect(nullptr), post_effect(nullptr), distortion_effect(nullptr), focus_effect(nullptr), + phosphor_effect(nullptr), deconverge_effect(nullptr), color_effect(nullptr), ntsc_effect(nullptr), + bloom_effect(nullptr), downsample_effect(nullptr), vector_effect(nullptr), curr_texture(nullptr), + curr_render_target(nullptr), curr_poly(nullptr) { } @@ -73,15 +186,13 @@ shaders::~shaders() //============================================================ -// shaders::window_save +// shaders::save_snapshot //============================================================ -void shaders::window_save() +void shaders::save_snapshot() { if (!enabled()) - { return; - } HRESULT result = d3d->get_device()->CreateTexture(snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture, nullptr); if (FAILED(result)) @@ -100,88 +211,37 @@ void shaders::window_save() snap_texture->GetSurfaceLevel(0, &snap_target); render_snap = true; - snap_rendered = false; } //============================================================ -// shaders::window_record +// shaders::record_movie //============================================================ -void shaders::window_record() +void shaders::record_movie() { if (!enabled()) + return; + + if (recording_movie) { + recorder.reset(); + recording_movie = false; return; } windows_options &options = downcast(machine->options()); - const char *filename = options.d3d_hlsl_write(); + std::string filename(options.d3d_hlsl_write()); - if (avi_output_file != nullptr) + if (!filename.empty()) { - end_avi_recording(); - } - else if (filename[0] != 0) - { - begin_avi_recording(filename); + recorder = std::make_unique(*machine, d3d, snap_width, snap_height); + recorder->record(filename); + recording_movie = true; } } -//============================================================ -// shaders::avi_update_snap -//============================================================ - -void shaders::avi_update_snap(IDirect3DSurface9 *surface) -{ - if (!enabled()) - { - return; - } - - D3DLOCKED_RECT rect; - - // if we don't have a bitmap, or if it's not the right size, allocate a new one - if (!avi_snap.valid() || snap_width != avi_snap.width() || snap_height != avi_snap.height()) - { - avi_snap.allocate(snap_width, snap_height); - } - - // copy the texture - HRESULT result = d3d->get_device()->GetRenderTargetData(surface, avi_copy_surface); - if (FAILED(result)) - { - return; - } - - // lock the texture - result = avi_copy_surface->LockRect(&rect, nullptr, D3DLOCK_DISCARD); - if (FAILED(result)) - { - return; - } - - // loop over Y - for (int srcy = 0; srcy < snap_height; srcy++) - { - DWORD *src = (DWORD *)((BYTE *)rect.pBits + srcy * rect.Pitch); - UINT32 *dst = &avi_snap.pix32(srcy); - - for (int x = 0; x < snap_width; x++) - { - *dst++ = *src++; - } - } - - // unlock - result = avi_copy_surface->UnlockRect(); - if (FAILED(result)) - osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result); -} - - - //============================================================ // hlsl_render_snapshot //============================================================ @@ -189,39 +249,26 @@ void shaders::avi_update_snap(IDirect3DSurface9 *surface) void shaders::render_snapshot(IDirect3DSurface9 *surface) { if (!enabled()) - { return; - } - D3DLOCKED_RECT rect; - - render_snap = false; - - // if we don't have a bitmap, or if it's not the right size, allocate a new one - if (!avi_snap.valid() || snap_width != avi_snap.width() || snap_height != avi_snap.height()) - { - avi_snap.allocate(snap_width, snap_height); - } + bitmap_rgb32 snapshot(snap_width, snap_height); + if (!snapshot.valid()) + return; // copy the texture HRESULT result = d3d->get_device()->GetRenderTargetData(surface, snap_copy_target); if (FAILED(result)) - { return; - } - // lock the texture + D3DLOCKED_RECT rect; result = snap_copy_target->LockRect(&rect, nullptr, D3DLOCK_DISCARD); if (FAILED(result)) - { return; - } - // loop over Y - for (int srcy = 0; srcy < snap_height; srcy++) + for (int y = 0; y < snap_height; y++) { - DWORD *src = (DWORD *)((BYTE *)rect.pBits + srcy * rect.Pitch); - UINT32 *dst = &avi_snap.pix32(srcy); + DWORD *src = (DWORD *)((BYTE *)rect.pBits + y * rect.Pitch); + UINT32 *dst = &snapshot.pix32(y); for (int x = 0; x < snap_width; x++) { @@ -232,9 +279,7 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface) emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); osd_file::error filerr = machine->video().open_next(file, "png"); if (filerr != osd_file::error::NONE) - { return; - } // add two text entries describing the image std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(emulator_info::get_build_version()); @@ -244,16 +289,13 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface) png_add_text(&pnginfo, "System", text2.c_str()); // now do the actual work - png_error error = png_write_bitmap(file, &pnginfo, avi_snap, 1 << 24, nullptr); + png_error error = png_write_bitmap(file, &pnginfo, snapshot, 1 << 24, nullptr); if (error != PNGERR_NONE) - { osd_printf_error("Error generating PNG for HLSL snapshot: png_error = %d\n", error); - } // free any data allocated png_free(&pnginfo); - // unlock result = snap_copy_target->UnlockRect(); if (FAILED(result)) osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result); @@ -284,141 +326,6 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface) } -//============================================================ -// shaders::record_texture -//============================================================ - -void shaders::record_texture() -{ - if (!enabled()) - { - return; - } - - IDirect3DSurface9 *surface = avi_final_target; - - // ignore if nothing to do - if (avi_output_file == nullptr || surface == nullptr) - { - return; - } - - // get the current time - attotime curtime = machine->time(); - - avi_update_snap(surface); - - // loop until we hit the right time - while (avi_next_frame_time <= curtime) - { - // handle an AVI recording - // write the next frame - avi_file::error avierr = avi_output_file->append_video_frame(avi_snap); - if (avierr != avi_file::error::NONE) - { - end_avi_recording(); - return; - } - - // advance time - avi_next_frame_time += avi_frame_period; - avi_frame++; - } -} - - -//============================================================ -// shaders::end_avi_recording -//============================================================ - -void shaders::end_avi_recording() -{ - if (!enabled()) - { - return; - } - - if (avi_output_file) - { - avi_output_file.reset(); - } - - avi_output_file = nullptr; - avi_frame = 0; -} - - -//============================================================ -// shaders::begin_avi_recording -//============================================================ - -void shaders::begin_avi_recording(const char *name) -{ - if (!enabled()) - { - return; - } - - // stop any existing recording - end_avi_recording(); - - // reset the state - avi_frame = 0; - avi_next_frame_time = machine->time(); - - // build up information about this new movie - avi_file::movie_info info; - info.video_format = 0; - info.video_timescale = 1000 * ((machine->first_screen() != nullptr) ? ATTOSECONDS_TO_HZ(machine->first_screen()->frame_period().m_attoseconds) : screen_device::DEFAULT_FRAME_RATE); - info.video_sampletime = 1000; - info.video_numsamples = 0; - info.video_width = snap_width; - info.video_height = snap_height; - info.video_depth = 24; - - info.audio_format = 0; - info.audio_timescale = machine->sample_rate(); - info.audio_sampletime = 1; - info.audio_numsamples = 0; - info.audio_channels = 2; - info.audio_samplebits = 16; - info.audio_samplerate = machine->sample_rate(); - - // create a new temporary movie file - osd_file::error filerr; - std::string fullpath; - - emu_file tempfile(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - if (name != nullptr) - { - filerr = tempfile.open(name); - } - else - { - filerr = machine->video().open_next(tempfile, "avi"); - } - - // compute the frame time - avi_frame_period = attotime::from_seconds(1000) / info.video_timescale; - - // if we succeeded, make a copy of the name and create the real file over top - if (filerr == osd_file::error::NONE) - { - fullpath = tempfile.fullpath(); - } - - if (filerr == osd_file::error::NONE) - { - // create the file and free the string - avi_file::error avierr = avi_file::create(fullpath, info, avi_output_file); - if (avierr != avi_file::error::NONE) - { - osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr)); - } - } -} - - //============================================================ // remove_cache_target - remove an active cache target //============================================================ @@ -757,29 +664,15 @@ int shaders::create_resources() result = d3d->get_device()->SetRenderTarget(0, black_surface); if (FAILED(result)) osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result); + result = d3d->get_device()->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); if (FAILED(result)) osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result); + result = d3d->get_device()->SetRenderTarget(0, backbuffer); if (FAILED(result)) osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result); - result = d3d->get_device()->CreateTexture(snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &avi_copy_texture, nullptr); - if (FAILED(result)) - { - osd_printf_verbose("Direct3D: Unable to init system-memory target for HLSL AVI dumping (%08lX)\n", result); - return 1; - } - avi_copy_texture->GetSurfaceLevel(0, &avi_copy_surface); - - result = d3d->get_device()->CreateTexture(snap_width, snap_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &avi_final_texture, nullptr); - if (FAILED(result)) - { - osd_printf_verbose("Direct3D: Unable to init video-memory target for HLSL AVI dumping (%08lX)\n", result); - return 1; - } - avi_final_texture->GetSurfaceLevel(0, &avi_final_target); - emu_file file(machine->options().art_path(), OPEN_FLAG_READ); render_load_png(shadow_bitmap, file, nullptr, options->shadow_mask_texture); @@ -947,16 +840,6 @@ void shaders::begin_draw() } -//============================================================ -// shaders::begin_frame -//============================================================ - -void shaders::begin_frame() -{ - record_texture(); -} - - //============================================================ // shaders::blit //============================================================ @@ -1009,24 +892,6 @@ void shaders::blit( } -//============================================================ -// shaders::end_frame -//============================================================ - -void shaders::end_frame() -{ - if (!enabled()) - { - return; - } - - if (render_snap && snap_rendered) - { - render_snapshot(snap_target); - } -} - - //============================================================ // shaders::find_render_target //============================================================ @@ -1400,8 +1265,6 @@ int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *pol curr_effect = vector_effect; curr_effect->update_uniforms(); - // curr_effect->set_float("TimeRatio", options->vector_time_ratio); - // curr_effect->set_float("TimeScale", options->vector_time_scale); curr_effect->set_float("LengthRatio", options->vector_length_ratio); curr_effect->set_float("LengthScale", options->vector_length_scale); curr_effect->set_float("BeamSmooth", options->vector_beam_smooth); @@ -1440,15 +1303,15 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol // we do not clear the backbuffer here because multiple screens might be rendered into blit(backbuffer, false, poly->type(), vertnum, poly->count()); - if (avi_output_file != nullptr) + if (recording_movie) { - blit(avi_final_target, false, poly->type(), vertnum, poly->count()); + blit(recorder->target_surface(), false, poly->type(), vertnum, poly->count()); HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer); if (FAILED(result)) - { osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result); - } + + recorder->save_frame(); } if (render_snap) @@ -1457,11 +1320,11 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer); if (FAILED(result)) - { osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result); - } - snap_rendered = true; + render_snapshot(snap_target); + + render_snap = false; } return next_index; @@ -1875,7 +1738,8 @@ void shaders::delete_resources() return; } - end_avi_recording(); + recording_movie = false; + recorder.reset(); if (options != nullptr) { @@ -1965,30 +1829,6 @@ void shaders::delete_resources() black_texture = nullptr; } - if (avi_copy_texture != nullptr) - { - avi_copy_texture->Release(); - avi_copy_texture = nullptr; - } - - if (avi_copy_surface != nullptr) - { - avi_copy_surface->Release(); - avi_copy_surface = nullptr; - } - - if (avi_final_texture != nullptr) - { - avi_final_texture->Release(); - avi_final_texture = nullptr; - } - - if (avi_final_target != nullptr) - { - avi_final_target->Release(); - avi_final_target = nullptr; - } - shadow_bitmap.reset(); } diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index 130b48c26e5..4200b4a3faf 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -10,7 +10,6 @@ #define __WIN_D3DHLSL__ #include -#include "aviio.h" #include "../frontend/mame/ui/menuitem.h" #include "../frontend/mame/ui/slider.h" #include "modules/lib/osdlib.h" @@ -158,6 +157,7 @@ private: 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 */ @@ -284,9 +284,6 @@ public: d3d_render_target* get_vector_target(render_primitive *prim); bool create_vector_target(render_primitive *prim); - void begin_frame(); - void end_frame(); - void begin_draw(); void end_draw(); @@ -297,13 +294,9 @@ public: bool add_render_target(renderer_d3d9* d3d, render_primitive *prim, texture_info* texture, int source_width, int source_height, int target_width, int target_height); bool add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index); - void window_save(); - void window_record(); - bool recording() const { return avi_output_file != nullptr; } + void save_snapshot(); + void record_movie(); - void avi_update_snap(IDirect3DSurface9 *surface); - void render_snapshot(IDirect3DSurface9 *surface); - void record_texture(); void init_fsfx_quad(); void set_texture(texture_info *info); @@ -326,8 +319,7 @@ private: void blit(IDirect3DSurface9 *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count); void enumerate_screens(); - void end_avi_recording(); - void begin_avi_recording(const char *name); + void render_snapshot(IDirect3DSurface9 *surface); d3d_render_target* find_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index); cache_target * find_cache_target(UINT32 screen_index, int width, int height); @@ -364,21 +356,13 @@ private: texture_info * shadow_texture; // shadow mask texture for post-processing shader hlsl_options * options; // current options - avi_file::ptr avi_output_file; // AVI file - bitmap_rgb32 avi_snap; // AVI snapshot - int avi_frame; // AVI frame - attotime avi_frame_period; // AVI frame period - attotime avi_next_frame_time; // AVI next frame time - IDirect3DSurface9 * avi_copy_surface; // AVI destination surface in system memory - IDirect3DTexture9 * avi_copy_texture; // AVI destination texture in system memory - IDirect3DSurface9 * avi_final_target; // AVI upscaled surface - IDirect3DTexture9 * avi_final_texture; // AVI upscaled texture - 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 - bool snap_rendered; // whether we just rendered our HLSL post-render shot or not 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 diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index 64ac2ca6774..83aab350052 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -142,12 +142,12 @@ void renderer_d3d9::toggle_fsfx() void renderer_d3d9::record() { - get_shaders()->window_record(); + get_shaders()->record_movie(); } void renderer_d3d9::save() { - get_shaders()->window_save(); + get_shaders()->save_snapshot(); } @@ -671,8 +671,6 @@ void renderer_d3d9::begin_frame() if (FAILED(result)) osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result); - m_shaders->begin_frame(); - win->m_primlist->acquire_lock(); // first update any textures @@ -740,8 +738,6 @@ void renderer_d3d9::end_frame() // flush any pending polygons primitive_flush_pending(); - m_shaders->end_frame(); - // finish the scene HRESULT result = m_device->EndScene(); if (FAILED(result)) diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index f4197d31e55..a045159d599 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -160,7 +160,7 @@ const options_entry windows_options::s_option_entries[] = { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" }, { WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enables HLSL post-processing (PS3.0 required)" }, { WINOPTION_HLSL_OVERSAMPLING, "0", OPTION_BOOLEAN, "enables HLSL oversampling" }, - { WINOPTION_HLSL_WRITE, nullptr, OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" }, + { WINOPTION_HLSL_WRITE, "hlsl.avi", OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" }, { WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" }, { WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" }, { WINOPTION_SHADOW_MASK_TILE_MODE, "0", OPTION_INTEGER, "shadow mask tile mode (0 for screen based, 1 for source based)" }, From 85740d73e689ea4f19cdc924ca182a4c55f41b52 Mon Sep 17 00:00:00 2001 From: Giuseppe Gorgoglione Date: Mon, 4 Jul 2016 13:50:10 +0200 Subject: [PATCH 2/2] Remove bgfx_avi_name and hlsl_write options Now the filenames for movies recorded by HLSL and BGFX renderers are automatically generated just like the ones for movies and snapshots recorded by the video core. They are generated according to the "snapname" template (eg. by default //, so you can revert to the old behavior (why?) just setting "snapname bgfx.avi" or "snapname hlsl.avi". The main advantage is that now you can record as many movies as you want during a single gaming session without much hassle (previously you had to move or rename the old movie file by hand before recording a new one). --- src/osd/modules/lib/osdobj_common.cpp | 1 - src/osd/modules/lib/osdobj_common.h | 2 -- src/osd/modules/render/aviwrite.cpp | 34 ++++++++++---------------- src/osd/modules/render/aviwrite.h | 4 +-- src/osd/modules/render/d3d/d3dhlsl.cpp | 16 ++++-------- src/osd/modules/render/drawbgfx.cpp | 2 +- src/osd/windows/winmain.cpp | 1 - src/osd/windows/winmain.h | 2 -- 8 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp index 1587ef63b7f..7659905ec88 100644 --- a/src/osd/modules/lib/osdobj_common.cpp +++ b/src/osd/modules/lib/osdobj_common.cpp @@ -147,7 +147,6 @@ const options_entry osd_options::s_option_entries[] = { OSDOPTION_BGFX_DEBUG, "0", OPTION_BOOLEAN, "enable BGFX debugging statistics" }, { OSDOPTION_BGFX_SCREEN_CHAINS, "default", OPTION_STRING, "comma-delimited list of screen chain JSON names, colon-delimited per-window" }, { OSDOPTION_BGFX_SHADOW_MASK, "slot-mask.png", OPTION_STRING, "shadow mask texture name" }, - { OSDOPTION_BGFX_AVI_NAME, "bgfx.avi", OPTION_STRING, "filename for BGFX output logging" }, // End of list { nullptr } diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h index 7d4238fcbbd..8b7e5c1f117 100644 --- a/src/osd/modules/lib/osdobj_common.h +++ b/src/osd/modules/lib/osdobj_common.h @@ -83,7 +83,6 @@ #define OSDOPTION_BGFX_DEBUG "bgfx_debug" #define OSDOPTION_BGFX_SCREEN_CHAINS "bgfx_screen_chains" #define OSDOPTION_BGFX_SHADOW_MASK "bgfx_shadow_mask" -#define OSDOPTION_BGFX_AVI_NAME "bgfx_avi_name" //============================================================ // TYPE DEFINITIONS @@ -157,7 +156,6 @@ public: bool bgfx_debug() const { return bool_value(OSDOPTION_BGFX_DEBUG); } const char *bgfx_screen_chains() const { return value(OSDOPTION_BGFX_SCREEN_CHAINS); } const char *bgfx_shadow_mask() const { return value(OSDOPTION_BGFX_SHADOW_MASK); } - const char *bgfx_avi_name() const { return value(OSDOPTION_BGFX_AVI_NAME); } private: static const options_entry s_option_entries[]; diff --git a/src/osd/modules/render/aviwrite.cpp b/src/osd/modules/render/aviwrite.cpp index 9ff7c5ab17d..38bc55f1c0c 100644 --- a/src/osd/modules/render/aviwrite.cpp +++ b/src/osd/modules/render/aviwrite.cpp @@ -27,17 +27,14 @@ avi_write::~avi_write() } } -void avi_write::record(std::string name) +void avi_write::record() { if (m_recording) { end_avi_recording(); } - if (name != "") - { - begin_avi_recording(name); - } + begin_avi_recording(); } void avi_write::stop() @@ -46,7 +43,7 @@ void avi_write::stop() end_avi_recording(); } -void avi_write::begin_avi_recording(std::string name) +void avi_write::begin_avi_recording() { // stop any existing recording end_avi_recording(); @@ -73,25 +70,20 @@ void avi_write::begin_avi_recording(std::string name) info.audio_samplebits = 16; info.audio_samplerate = m_machine.sample_rate(); + // compute the frame time + m_frame_period = attotime::from_seconds(1000) / info.video_timescale; + // create a new temporary movie file - osd_file::error filerr; - std::string fullpath; - { - emu_file tempfile(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); - filerr = tempfile.open(name.c_str()); - - // compute the frame time - m_frame_period = attotime::from_seconds(1000) / info.video_timescale; - - // if we succeeded, make a copy of the name and create the real file over top - if (filerr == osd_file::error::NONE) - { - fullpath = tempfile.fullpath(); - } - } + emu_file tempfile(m_machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + + osd_file::error filerr = m_machine.video().open_next(tempfile, "avi"); + // if we succeeded, make a copy of the name and create the real file over top if (filerr == osd_file::error::NONE) { + std::string fullpath = tempfile.fullpath(); + tempfile.close(); + // create the file and free the string avi_file::error avierr = avi_file::create(fullpath, info, m_output_file); if (avierr != avi_file::error::NONE) diff --git a/src/osd/modules/render/aviwrite.h b/src/osd/modules/render/aviwrite.h index ce6325d6815..cfa7779cf15 100644 --- a/src/osd/modules/render/aviwrite.h +++ b/src/osd/modules/render/aviwrite.h @@ -22,7 +22,7 @@ public: avi_write(running_machine& machine, uint32_t width, uint32_t height); ~avi_write(); - void record(std::string name); + void record(); void stop(); void audio_frame(const INT16 *buffer, int samples_this_frame); void video_frame(bitmap_rgb32& snap); @@ -31,7 +31,7 @@ public: bool recording() const { return m_recording; } private: - void begin_avi_recording(std::string name); + void begin_avi_recording(); void end_avi_recording(); running_machine& m_machine; diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index e8059b9ead0..54d63e1029e 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -88,12 +88,12 @@ public: m_vid_surface->Release(); } - void record(std::string name) + void record() { if (!m_initialized) return; - m_avi_writer->record(name); + m_avi_writer->record(); } void save_frame() @@ -230,15 +230,9 @@ void shaders::record_movie() return; } - windows_options &options = downcast(machine->options()); - std::string filename(options.d3d_hlsl_write()); - - if (!filename.empty()) - { - recorder = std::make_unique(*machine, d3d, snap_width, snap_height); - recorder->record(filename); - recording_movie = true; - } + recorder = std::make_unique(*machine, d3d, snap_width, snap_height); + recorder->record(); + recording_movie = true; } diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index dec0110157a..79b7c5d4a70 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -270,7 +270,7 @@ void renderer_bgfx::record() } else { - m_avi_writer->record(m_options.bgfx_avi_name()); + m_avi_writer->record(); m_avi_target = m_targets->create_target("avibuffer", bgfx::TextureFormat::RGBA8, m_width[0], m_height[0], TARGET_STYLE_CUSTOM, false, true, 1, 0); m_avi_texture = bgfx::createTexture2D(m_width[0], m_height[0], 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_BLIT_DST | BGFX_TEXTURE_READ_BACK); } diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index a045159d599..01b1f02d418 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -160,7 +160,6 @@ const options_entry windows_options::s_option_entries[] = { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" }, { WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enables HLSL post-processing (PS3.0 required)" }, { WINOPTION_HLSL_OVERSAMPLING, "0", OPTION_BOOLEAN, "enables HLSL oversampling" }, - { WINOPTION_HLSL_WRITE, "hlsl.avi", OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" }, { WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" }, { WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" }, { WINOPTION_SHADOW_MASK_TILE_MODE, "0", OPTION_INTEGER, "shadow mask tile mode (0 for screen based, 1 for source based)" }, diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h index 0abc85b674a..8b8c4ff18e2 100644 --- a/src/osd/windows/winmain.h +++ b/src/osd/windows/winmain.h @@ -29,7 +29,6 @@ #define WINOPTION_HLSLPATH "hlslpath" #define WINOPTION_HLSL_ENABLE "hlsl_enable" #define WINOPTION_HLSL_OVERSAMPLING "hlsl_oversampling" -#define WINOPTION_HLSL_WRITE "hlsl_write" #define WINOPTION_HLSL_SNAP_WIDTH "hlsl_snap_width" #define WINOPTION_HLSL_SNAP_HEIGHT "hlsl_snap_height" #define WINOPTION_SHADOW_MASK_TILE_MODE "shadow_mask_tile_mode" @@ -130,7 +129,6 @@ public: const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); } bool d3d_hlsl_enable() const { return bool_value(WINOPTION_HLSL_ENABLE); } bool d3d_hlsl_oversampling() const { return bool_value(WINOPTION_HLSL_OVERSAMPLING); } - const char *d3d_hlsl_write() const { return value(WINOPTION_HLSL_WRITE); } int d3d_snap_width() const { return int_value(WINOPTION_HLSL_SNAP_WIDTH); } int d3d_snap_height() const { return int_value(WINOPTION_HLSL_SNAP_HEIGHT); } int screen_shadow_mask_tile_mode() const { return int_value(WINOPTION_SHADOW_MASK_TILE_MODE); }