Merge pull request #1035 from GiuseppeGorgoglione/master

Direct3D HLSL: use aviwrite to record avi movies [GiuseppeGorgoglione]
This commit is contained in:
Vas Crabb 2016-07-07 12:33:47 +10:00 committed by GitHub
commit d68203e283
10 changed files with 180 additions and 380 deletions

View File

@ -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 }

View File

@ -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[];

View File

@ -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)

View File

@ -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;

View File

@ -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<avi_write>(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()
{
if (!m_initialized)
return;
m_avi_writer->record();
}
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<avi_write> 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,31 @@ 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<windows_options &>(machine->options());
const char *filename = options.d3d_hlsl_write();
if (avi_output_file != nullptr)
{
end_avi_recording();
}
else if (filename[0] != 0)
{
begin_avi_recording(filename);
}
recorder = std::make_unique<movie_recorder>(*machine, d3d, snap_width, snap_height);
recorder->record();
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 +243,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 +273,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 +283,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 +320,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 +658,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 +834,6 @@ void shaders::begin_draw()
}
//============================================================
// shaders::begin_frame
//============================================================
void shaders::begin_frame()
{
record_texture();
}
//============================================================
// shaders::blit
//============================================================
@ -1009,24 +886,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 +1259,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 +1297,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 +1314,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 +1732,8 @@ void shaders::delete_resources()
return;
}
end_avi_recording();
recording_movie = false;
recorder.reset();
if (options != nullptr)
{
@ -1965,30 +1823,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();
}

View File

@ -10,7 +10,6 @@
#define __WIN_D3DHLSL__
#include <vector>
#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<movie_recorder> 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

View File

@ -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);
}

View File

@ -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))

View File

@ -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, nullptr, 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)" },

View File

@ -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); }