01234567890123456789012345678901234567890123456789012345678901234567890123456789

hlsl: Added bounds-checking on presets. [MooglyGuy]

hlsl: Cleaned up render target management. May provide better behavior in games
      that use multiple resolutions, e.g. tekken3 and stv. [MooglyGuy]
This commit is contained in:
Ryan Holtz 2012-12-29 01:05:33 +00:00
parent becc76adab
commit 8624385a24
8 changed files with 459 additions and 418 deletions

View File

@ -502,6 +502,7 @@ bool render_texture::get_scaled(UINT32 dwidth, UINT32 dheight, render_texinfo &t
texinfo.width = swidth;
texinfo.height = sheight;
texinfo.palette = palbase;
texinfo.osddata = m_osddata;
texinfo.seqid = ++m_curseq;
return true;
}

View File

@ -233,6 +233,7 @@ struct render_texinfo
UINT32 height; // height of the image
const rgb_t * palette; // palette for PALETTE16 textures, LUTs for RGB15/RGB32
UINT32 seqid; // sequence ID
UINT64 osddata; // aux data to pass to osd
};
@ -441,6 +442,9 @@ public:
// configure the texture bitmap
void set_bitmap(bitmap_t &bitmap, const rectangle &sbounds, texture_format format);
// set any necessary aux data
void set_osd_data(UINT64 data) { m_osddata = data; }
// generic high-quality bitmap scaler
static void hq_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param);
@ -466,6 +470,7 @@ private:
texture_format m_format; // format of the texture data
rgb_t * m_bcglookup; // dynamically allocated B/C/G lookup table
UINT32 m_bcglookup_entries; // number of B/C/G lookup entries allocated
UINT64 m_osddata; // aux data to pass to osd
// scaling state (ARGB32 only)
texture_scaler_func m_scaler; // scaling callback

View File

@ -62,7 +62,7 @@ const device_type SCREEN = &device_creator<screen_device>;
const attotime screen_device::DEFAULT_FRAME_PERIOD(attotime::from_hz(DEFAULT_FRAME_RATE));
UINT32 screen_device::m_id_counter = 0;
//**************************************************************************
// SCREEN DEVICE
@ -103,6 +103,8 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
m_frame_number(0),
m_partial_updates_this_frame(0)
{
m_unique_id = m_id_counter;
m_id_counter++;
memset(m_texture, 0, sizeof(m_texture));
}
@ -288,7 +290,9 @@ void screen_device::device_start()
// allocate raw textures
m_texture[0] = machine().render().texture_alloc();
m_texture[0]->set_osd_data((UINT64)((m_unique_id << 1) | 0));
m_texture[1] = machine().render().texture_alloc();
m_texture[1]->set_osd_data((UINT64)((m_unique_id << 1) | 1));
// configure the default cliparea
render_container::user_settings settings;

View File

@ -291,6 +291,7 @@ private:
bool m_changed; // has this bitmap changed?
INT32 m_last_partial_scan; // scanline of last partial update
bitmap_argb32 m_screen_overlay_bitmap; // screen overlay bitmap
UINT32 m_unique_id; // unique id for this screen_device
// screen timing
attoseconds_t m_frame_period; // attoseconds per frame
@ -333,6 +334,10 @@ private:
bitmap_t & m_bitmap;
};
simple_list<auto_bitmap_item> m_auto_bitmap_list; // list of registered bitmaps
// static data
static UINT32 m_id_counter; // incremented for each constructed screen_device,
// used as a unique identifier during runtime
};
// device type definition

View File

@ -197,11 +197,11 @@ hlsl_info::hlsl_info()
prescale_force_y = 0;
preset = -1;
shadow_texture = NULL;
registered_targets = 0;
cyclic_target_idx = 0;
options = NULL;
paused = true;
lastidx = -1;
targethead = NULL;
cachehead = NULL;
}
@ -292,7 +292,6 @@ void hlsl_info::avi_update_snap(d3d_surface *surface)
HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->device, surface, avi_copy_surface);
if (result != D3D_OK)
{
printf("Couldn't copy (%08x)\n", (UINT32)result);
return;
}
@ -300,7 +299,6 @@ void hlsl_info::avi_update_snap(d3d_surface *surface)
result = (*d3dintf->surface.lock_rect)(avi_copy_surface, &rect, NULL, D3DLOCK_DISCARD);
if (result != D3D_OK)
{
printf("Couldn't lock (%08x)\n", (UINT32)result);
return;
}
@ -346,7 +344,6 @@ void hlsl_info::render_snapshot(d3d_surface *surface)
HRESULT result = (*d3dintf->device.get_render_target_data)(d3d->device, surface, snap_copy_target);
if (result != D3D_OK)
{
printf("Couldn't copy (%08x)\n", (UINT32)result);
return;
}
@ -354,7 +351,6 @@ void hlsl_info::render_snapshot(d3d_surface *surface)
result = (*d3dintf->surface.lock_rect)(snap_copy_target, &rect, NULL, D3DLOCK_DISCARD);
if (result != D3D_OK)
{
printf("Couldn't lock (%08x)\n", (UINT32)result);
return;
}
@ -574,6 +570,73 @@ void hlsl_info::begin_avi_recording(const char *name)
}
//============================================================
// remove_render_target - remove an active cache target when
// refcount hits zero
//============================================================
void hlsl_info::remove_cache_target(d3d_cache_target *cache)
{
if (cache != NULL)
{
if (cache == cachehead)
{
cachehead= cachehead->next;
}
if (cache->prev != NULL)
{
cache->prev->next = cache->next;
}
if (cache->next != NULL)
{
cache->next->prev = cache->prev;
}
global_free(cache);
}
}
//============================================================
// remove_render_target - remove an active target
//============================================================
void hlsl_info::remove_render_target(d3d_texture_info *texture)
{
d3d_render_target *rt = find_render_target(texture);
if (rt != NULL)
{
if (rt == targethead)
{
targethead = targethead->next;
}
if (rt->prev != NULL)
{
rt->prev->next = rt->next;
}
if (rt->next != NULL)
{
rt->next->prev = rt->prev;
}
d3d_cache_target *cache = find_cache_target(rt->screen_index);
if (cache != NULL)
{
cache->ref_count--;
if (cache->ref_count == 0)
{
remove_cache_target(cache);
}
}
global_free(rt);
}
}
//============================================================
// hlsl_info::set_texture
//============================================================
@ -589,17 +652,14 @@ void hlsl_info::set_texture(d3d_texture_info *texture)
{
if(texture->prev_frame == texture->cur_frame)
{
//printf("Paused\n");
paused = true;
}
else
{
//printf("Not paused\n");
paused = false;
}
texture->prev_frame = texture->cur_frame;
//printf("%08x cur_frame is %d\n", (UINT32)(UINT64)texture, texture->cur_frame);
}
(*d3dintf->effect.set_texture)(effect, "Diffuse", (texture == NULL) ? d3d->default_texture->d3dfinaltex : texture->d3dfinaltex);
@ -627,6 +687,10 @@ void hlsl_info::init(d3d_base *d3dintf, win_window_info *window)
prescale_size_x = 1;
prescale_size_y = 1;
preset = downcast<windows_options &>(window->machine().options()).d3d_hlsl_preset();
if (preset < -1 || preset > 3)
{
preset = -1;
}
snap_width = downcast<windows_options &>(window->machine().options()).d3d_snap_width();
snap_height = downcast<windows_options &>(window->machine().options()).d3d_snap_height();
@ -1022,7 +1086,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, primary_name, &effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load primary.fx\n");
mame_printf_verbose("Direct3D: Unable to load primary.fx\n");
return 1;
}
@ -1030,7 +1094,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, post_name, &post_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load post.fx\n");
mame_printf_verbose("Direct3D: Unable to load post.fx\n");
return 1;
}
@ -1038,7 +1102,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, prescale_name, &prescale_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load prescale.fx\n");
mame_printf_verbose("Direct3D: Unable to load prescale.fx\n");
return 1;
}
@ -1046,7 +1110,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, pincushion_name, &pincushion_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load pincushion.fx\n");
mame_printf_verbose("Direct3D: Unable to load pincushion.fx\n");
return 1;
}
@ -1054,7 +1118,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, phosphor_name, &phosphor_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load phosphor.fx\n");
mame_printf_verbose("Direct3D: Unable to load phosphor.fx\n");
return 1;
}
@ -1062,7 +1126,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, focus_name, &focus_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load focus.fx\n");
mame_printf_verbose("Direct3D: Unable to load focus.fx\n");
return 1;
}
@ -1070,7 +1134,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, deconverge_name, &deconverge_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load deconverge.fx\n");
mame_printf_verbose("Direct3D: Unable to load deconverge.fx\n");
return 1;
}
@ -1078,7 +1142,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, color_name, &color_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load color.fx\n");
mame_printf_verbose("Direct3D: Unable to load color.fx\n");
return 1;
}
@ -1086,7 +1150,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, yiq_encode_name, &yiq_encode_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load yiq_encode.fx\n");
mame_printf_verbose("Direct3D: Unable to load yiq_encode.fx\n");
return 1;
}
@ -1094,7 +1158,7 @@ int hlsl_info::create_resources()
result = (*d3dintf->device.create_effect)(d3d->device, yiq_decode_name, &yiq_decode_effect);
if(result != D3D_OK)
{
printf("Direct3D: Unable to load yiq_decode.fx\n");
mame_printf_verbose("Direct3D: Unable to load yiq_decode.fx\n");
return 1;
}
@ -1148,9 +1212,6 @@ void hlsl_info::begin()
HRESULT result = (*d3dintf->device.get_render_target)(d3d->device, 0, &backbuffer);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
for (int index = 0; index < 9; index++)
screen_encountered[index] = false;
}
@ -1218,6 +1279,40 @@ void hlsl_info::init_effect_info(d3d_poly_info *poly)
}
//============================================================
// hlsl_info::find_render_target
//============================================================
d3d_render_target* hlsl_info::find_render_target(d3d_texture_info *info)
{
d3d_render_target *curr = targethead;
while (curr != NULL && curr->info != info)
{
curr = curr->next;
}
return curr;
}
//============================================================
// hlsl_info::find_cache_target
//============================================================
d3d_cache_target* hlsl_info::find_cache_target(int screen_index)
{
d3d_cache_target *curr = cachehead;
while (curr != NULL && curr->screen_index != screen_index)
{
curr = curr->next;
}
return curr;
}
//============================================================
// hlsl_info::render_quad
//============================================================
@ -1232,16 +1327,12 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
if(PRIMFLAG_GET_SCREENTEX(d3d->last_texture_flags) && poly->texture != NULL)
{
int rawidx = poly->texture->target_index;
int targetidx = rawidx % 9;
int minidx = cyclic_target_idx - (num_screens * 2);
int wrappedidx = (minidx + ((rawidx - minidx) % num_screens) + num_screens) % 9;
//printf("rendering %d %d %d %d %d %d %d %d %d %f %f\n", poly->texture->target_index, rawidx, targetidx, minidx, wrappedidx, poly->texture->rawwidth, poly->texture->rawheight, d3d->width, d3d->height, (float)(poly->texture->ustop - poly->texture->ustart), (float)(poly->texture->vstop - poly->texture->vstart));
screen_encountered[targetidx] = true;
target_in_use[targetidx] = poly->texture;
target_use_count[targetidx] = 60;
d3d_render_target *rt = find_render_target(poly->texture);
if (rt == NULL)
{
return;
}
d3d_cache_target *ct = find_cache_target(rt->screen_index);
if(options->yiq_enable)
{
@ -1267,7 +1358,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.set_float)(curr_effect, "ScanTime", options->yiq_scan_time);
}
HRESULT result = (*d3dintf->device.set_render_target)(d3d->device, 0, target4[targetidx]);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->target[4]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
@ -1289,7 +1380,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
/* Convert our signal from YIQ */
curr_effect = yiq_decode_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Composite", texture4[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Composite", rt->texture[4]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dfinaltex);
if(options->params_dirty)
{
@ -1311,7 +1402,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.set_float)(curr_effect, "ScanTime", options->yiq_scan_time);
}
result = (*d3dintf->device.set_render_target)(d3d->device, 0, target3[targetidx]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->target[3]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
@ -1332,7 +1423,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
curr_effect = color_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", texture3[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->texture[3]);
}
curr_effect = color_effect;
@ -1355,7 +1446,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.set_float)(curr_effect, "Saturation", options->saturation);
}
HRESULT result = (*d3dintf->device.set_render_target)(d3d->device, 0, smalltarget0[targetidx]);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->smalltarget);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
@ -1376,7 +1467,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
/* Pre-scaling pass */
curr_effect = prescale_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", smalltexture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->smalltexture);
if(options->params_dirty)
{
@ -1390,7 +1481,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, prescaletarget0[targetidx]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->prescaletarget);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@ -1408,7 +1499,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
/* Deconverge pass */
curr_effect = deconverge_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", prescaletexture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->prescaletexture);
if(options->params_dirty)
{
@ -1426,7 +1517,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, target2[targetidx]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->target[2]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@ -1450,7 +1541,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
/* Defocus pass 1 */
curr_effect = focus_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", texture2[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->texture[2]);
(*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
(*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
@ -1463,7 +1554,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, target0[targetidx]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->target[0]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@ -1481,7 +1572,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
/* Defocus pass 2 */
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", texture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->texture[0]);
(*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
(*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
@ -1494,7 +1585,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, target1[targetidx]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->target[1]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result);
for (UINT pass = 0; pass < num_passes; pass++)
@ -1513,7 +1604,6 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
// the phosphors are a direct result of the incoming texture, might as well just change the
// input texture.
curr_effect = phosphor_effect;
//printf("num_screens %d\n", num_screens);
if(options->params_dirty)
{
@ -1525,14 +1615,14 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
(*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
(*d3dintf->effect.set_vector)(curr_effect, "Phosphor", 3, options->phosphor);
}
(*d3dintf->effect.set_float)(curr_effect, "TextureWidth", (float)target_width[targetidx]);
(*d3dintf->effect.set_float)(curr_effect, "TextureHeight", (float)target_height[targetidx]);
(*d3dintf->effect.set_float)(curr_effect, "TextureWidth", (float)rt->target_width);
(*d3dintf->effect.set_float)(curr_effect, "TextureHeight", (float)rt->target_height);
(*d3dintf->effect.set_float)(curr_effect, "Passthrough", 0.0f);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? texture1[targetidx] : texture2[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "LastPass", last_texture[wrappedidx]); // Avoid changing targets due to page flipping
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? rt->texture[1] : rt->texture[2]);
(*d3dintf->effect.set_texture)(curr_effect, "LastPass", ct->last_texture);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, target0[targetidx]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, rt->target[0]);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@ -1553,11 +1643,11 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
/* Pass along our phosphor'd screen */
curr_effect = phosphor_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", texture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "LastPass", texture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->texture[0]);
(*d3dintf->effect.set_texture)(curr_effect, "LastPass", rt->texture[0]);
(*d3dintf->effect.set_float)(curr_effect, "Passthrough", 1.0f);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, last_target[wrappedidx]); // Avoid changing targets due to page flipping
result = (*d3dintf->device.set_render_target)(d3d->device, 0, ct->last_target); // Avoid changing targets due to page flipping
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result);
result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
@ -1580,7 +1670,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
{
curr_effect = post_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", texture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->texture[0]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, avi_final_target);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
@ -1603,7 +1693,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
{
curr_effect = post_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", texture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->texture[0]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, snap_target);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
@ -1627,7 +1717,7 @@ void hlsl_info::render_quad(d3d_poly_info *poly, int vertnum)
/* Scanlines and shadow mask */
curr_effect = post_effect;
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", texture0[targetidx]);
(*d3dintf->effect.set_texture)(curr_effect, "Diffuse", rt->texture[0]);
result = (*d3dintf->device.set_render_target)(d3d->device, 0, backbuffer);
if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
@ -1687,153 +1777,7 @@ void hlsl_info::end()
if (!master_enable || !d3dintf->post_fx_available)
return;
d3d_info *d3d = (d3d_info *)window->drawdata;
(*d3dintf->surface.release)(backbuffer);
//printf("registered_targets %d\n", registered_targets);
// Don't check de-registration if we're paused.
if(paused)
{
return;
}
// Unregister any registered targets we didn't traverse in the past frame. A resolution change must
// have occurred.
for(int index = 0; index < 9; index++)
{
if(!screen_encountered[index] && smalltarget0[index] != NULL)
{
if(target_use_count[index] > 0)
{
target_use_count[index]--;
}
else
{
//printf("deregging %d\n", index);
// free all textures
if(target_in_use[index] != NULL)
{
d3d_texture_info *tex = target_in_use[index];
bool found_in_active_list = false;
d3d_texture_info *test_tex = d3d->texlist;
while (test_tex != NULL)
{
if(test_tex == tex)
{
found_in_active_list = true;
break;
}
test_tex = test_tex->next;
}
// only clean up a texture if it won't be cleaned up by drawd3d
if(!found_in_active_list)
{
if (tex->d3dfinaltex != NULL)
{
(*d3dintf->texture.release)(tex->d3dfinaltex);
tex->d3dfinaltex = NULL;
}
if (tex->d3dtex != NULL && tex->d3dtex != tex->d3dfinaltex)
{
(*d3dintf->texture.release)(tex->d3dtex);
tex->d3dtex = NULL;
}
if (tex->d3dsurface != NULL)
{
(*d3dintf->surface.release)(tex->d3dsurface);
}
global_free(tex);
}
}
if (prescaletexture0[index] != NULL)
{
(*d3dintf->texture.release)(prescaletexture0[index]);
prescaletexture0[index] = NULL;
}
if (texture0[index] != NULL)
{
(*d3dintf->texture.release)(texture0[index]);
texture0[index] = NULL;
}
if (texture1[index] != NULL)
{
(*d3dintf->texture.release)(texture1[index]);
texture1[index] = NULL;
}
if (texture2[index] != NULL)
{
(*d3dintf->texture.release)(texture2[index]);
texture2[index] = NULL;
}
if (texture3[index] != NULL)
{
(*d3dintf->texture.release)(texture3[index]);
texture3[index] = NULL;
}
if (texture4[index] != NULL)
{
(*d3dintf->texture.release)(texture4[index]);
texture4[index] = NULL;
}
if (smalltexture0[index] != NULL)
{
(*d3dintf->texture.release)(smalltexture0[index]);
smalltexture0[index] = NULL;
}
if (prescaletarget0[index] != NULL)
{
(*d3dintf->surface.release)(prescaletarget0[index]);
prescaletarget0[index] = NULL;
}
if (target0[index] != NULL)
{
(*d3dintf->surface.release)(target0[index]);
target0[index] = NULL;
}
if (target1[index] != NULL)
{
(*d3dintf->surface.release)(target1[index]);
target1[index] = NULL;
}
if (target2[index] != NULL)
{
(*d3dintf->surface.release)(target2[index]);
target2[index] = NULL;
}
if (target3[index] != NULL)
{
(*d3dintf->surface.release)(target3[index]);
target3[index] = NULL;
}
if (target4[index] != NULL)
{
(*d3dintf->surface.release)(target4[index]);
target4[index] = NULL;
}
if (smalltarget0[index] != NULL)
{
(*d3dintf->surface.release)(smalltarget0[index]);
smalltarget0[index] = NULL;
}
if(last_texture[index] != NULL)
{
(*d3dintf->texture.release)(last_texture[index]);
last_texture[index] = NULL;
}
if(last_target[index] != NULL)
{
(*d3dintf->surface.release)(last_target[index]);
last_target[index] = NULL;
}
target_use_count[index] = 0;
registered_targets--;
}
}
}
}
@ -1848,10 +1792,6 @@ int hlsl_info::register_prescaled_texture(d3d_texture_info *texture, int scwidth
d3d_info *d3d = (d3d_info *)window->drawdata;
//printf("registering prescaled texture, seqid %d\n", texture->texinfo.seqid);
int idx = cyclic_target_idx % 9;
// Find the nearest prescale factor that is over our screen size
int hlsl_prescale_x = prescale_force_x ? prescale_force_x : 1;
if(!prescale_force_x)
@ -1867,54 +1807,8 @@ int hlsl_info::register_prescaled_texture(d3d_texture_info *texture, int scwidth
prescale_size_y = hlsl_prescale_y;
}
HRESULT result = (*d3dintf->device.create_texture)(d3d->device, scwidth * hlsl_prescale_x, scheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture0[idx]);
if (result != D3D_OK)
if (!add_render_target(d3d, texture, scwidth, scheight, hlsl_prescale_x, hlsl_prescale_y))
return 1;
(*d3dintf->texture.get_surface_level)(texture0[idx], 0, &target0[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, scwidth * hlsl_prescale_x, scheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture1[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture1[idx], 0, &target1[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, scwidth * hlsl_prescale_x, scheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture2[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture2[idx], 0, &target2[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, scwidth * hlsl_prescale_x, scheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture3[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture3[idx], 0, &target3[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture4[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture4[idx], 0, &target4[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &smalltexture0[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(smalltexture0[idx], 0, &smalltarget0[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, scwidth * hlsl_prescale_x, scheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescaletexture0[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(prescaletexture0[idx], 0, &prescaletarget0[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, scwidth * hlsl_prescale_x, scheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(last_texture[idx], 0, &last_target[idx]);
texture->target_index = cyclic_target_idx;
target_width[idx] = scwidth * hlsl_prescale_x;
target_height[idx] = scheight * hlsl_prescale_y;
target_use_count[idx] = 60;
target_in_use[idx] = texture;
raw_target_idx[idx] = cyclic_target_idx;
registered_targets++;
cyclic_target_idx++;
options->params_dirty = true;
@ -1923,6 +1817,81 @@ int hlsl_info::register_prescaled_texture(d3d_texture_info *texture, int scwidth
return 0;
}
//============================================================
// hlsl_info::add_cache_target - register a cache target
//============================================================
bool hlsl_info::add_cache_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y, int screen_index)
{
d3d_cache_target* target = (d3d_cache_target*)global_alloc_clear(d3d_cache_target);
if (!target->init(d3d, d3dintf, width, height, prescale_x, prescale_y))
{
global_free(target);
return false;
}
target->next = cachehead;
target->prev = NULL;
target->screen_index = screen_index;
target->ref_count = 1;
if (cachehead != NULL)
{
cachehead->prev = target;
}
cachehead = target;
return true;
}
//============================================================
// hlsl_info::add_render_target - register a render target
//============================================================
bool hlsl_info::add_render_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y)
{
d3d_render_target* target = (d3d_render_target*)global_alloc_clear(d3d_render_target);
if (!target->init(d3d, d3dintf, width, height, prescale_x, prescale_y))
{
global_free(target);
return false;
}
target->info = info;
UINT32 screen_index_data = (UINT32)info->texinfo.osddata;
target->screen_index = screen_index_data >> 1;
target->page_index = screen_index_data & 1;
d3d_cache_target* cache = find_cache_target(target->screen_index);
if (cache == NULL)
{
if (!add_cache_target(d3d, info, width, height, prescale_x, prescale_y, target->screen_index))
{
global_free(target);
return false;
}
}
else
{
cache->ref_count++;
}
target->next = targethead;
target->prev = NULL;
if (targethead != NULL)
{
targethead->prev = target;
}
targethead = target;
return true;
}
//============================================================
// hlsl_info::enumerate_screens
//============================================================
@ -1938,15 +1907,13 @@ void hlsl_info::enumerate_screens()
int hlsl_info::register_texture(d3d_texture_info *texture)
{
enumerate_screens();
if (!master_enable || !d3dintf->post_fx_available)
return 0;
d3d_info *d3d = (d3d_info *)window->drawdata;
//printf("registering unscaled texture, seqid %d\n", texture->texinfo.seqid);
int idx = cyclic_target_idx % 9;
// Find the nearest prescale factor that is over our screen size
int hlsl_prescale_x = prescale_force_x ? prescale_force_x : 1;
if(!prescale_force_x)
@ -1962,59 +1929,11 @@ int hlsl_info::register_texture(d3d_texture_info *texture)
prescale_size_y = hlsl_prescale_y;
}
HRESULT result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth * hlsl_prescale_x, texture->rawheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture0[idx]);
if (result != D3D_OK)
if (!add_render_target(d3d, texture, texture->rawwidth, texture->rawheight, hlsl_prescale_x, hlsl_prescale_y))
return 1;
(*d3dintf->texture.get_surface_level)(texture0[idx], 0, &target0[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth * hlsl_prescale_x, texture->rawheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture1[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture1[idx], 0, &target1[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth * hlsl_prescale_x, texture->rawheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture2[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture2[idx], 0, &target2[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture3[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture3[idx], 0, &target3[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture4[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(texture4[idx], 0, &target4[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &smalltexture0[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(smalltexture0[idx], 0, &smalltarget0[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth * hlsl_prescale_x, texture->rawheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescaletexture0[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(prescaletexture0[idx], 0, &prescaletarget0[idx]);
result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth * hlsl_prescale_x, texture->rawheight * hlsl_prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture[idx]);
if (result != D3D_OK)
return 1;
(*d3dintf->texture.get_surface_level)(last_texture[idx], 0, &last_target[idx]);
texture->target_index = cyclic_target_idx;
target_width[idx] = texture->rawwidth * hlsl_prescale_x;
target_height[idx] = texture->rawheight * hlsl_prescale_y;
target_use_count[idx] = 60;
target_in_use[idx] = texture;
raw_target_idx[idx] = cyclic_target_idx;
registered_targets++;
cyclic_target_idx++;
options->params_dirty = true;
enumerate_screens();
return 0;
}
@ -2136,86 +2055,6 @@ void hlsl_info::delete_resources()
for (int index = 0; index < 9; index++)
{
if (prescaletexture0[index] != NULL)
{
(*d3dintf->texture.release)(prescaletexture0[index]);
prescaletexture0[index] = NULL;
}
if (texture0[index] != NULL)
{
(*d3dintf->texture.release)(texture0[index]);
texture0[index] = NULL;
}
if (texture1[index] != NULL)
{
(*d3dintf->texture.release)(texture1[index]);
texture1[index] = NULL;
}
if (texture2[index] != NULL)
{
(*d3dintf->texture.release)(texture2[index]);
texture2[index] = NULL;
}
if (texture3[index] != NULL)
{
(*d3dintf->texture.release)(texture3[index]);
texture3[index] = NULL;
}
if (texture4[index] != NULL)
{
(*d3dintf->texture.release)(texture4[index]);
texture4[index] = NULL;
}
if (smalltexture0[index] != NULL)
{
(*d3dintf->texture.release)(smalltexture0[index]);
smalltexture0[index] = NULL;
}
if (prescaletarget0[index] != NULL)
{
(*d3dintf->surface.release)(prescaletarget0[index]);
prescaletarget0[index] = NULL;
}
if (target0[index] != NULL)
{
(*d3dintf->surface.release)(target0[index]);
target0[index] = NULL;
}
if (target1[index] != NULL)
{
(*d3dintf->surface.release)(target1[index]);
target1[index] = NULL;
}
if (target2[index] != NULL)
{
(*d3dintf->surface.release)(target2[index]);
target2[index] = NULL;
}
if (target3[index] != NULL)
{
(*d3dintf->surface.release)(target3[index]);
target3[index] = NULL;
}
if (target4[index] != NULL)
{
(*d3dintf->surface.release)(target4[index]);
target4[index] = NULL;
}
if (smalltarget0[index] != NULL)
{
(*d3dintf->surface.release)(smalltarget0[index]);
smalltarget0[index] = NULL;
}
if (last_texture[index] != NULL)
{
(*d3dintf->texture.release)(last_texture[index]);
last_texture[index] = NULL;
}
if (last_target[index] != NULL)
{
(*d3dintf->surface.release)(last_target[index]);
last_target[index] = NULL;
}
}
if (avi_copy_texture != NULL)
@ -2244,8 +2083,6 @@ void hlsl_info::delete_resources()
global_free(options);
registered_targets = 0;
shadow_bitmap.reset();
}

View File

@ -42,14 +42,16 @@
#ifndef __WIN_D3DHLSL__
#define __WIN_D3DHLSL__
#include "aviio.h"
//============================================================
// TYPE DEFINITIONS
//============================================================
class d3d_render_target;
class d3d_cache_target;
class d3d_info;
/* 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
@ -116,6 +118,8 @@ public:
int register_texture(d3d_texture_info *texture);
int register_prescaled_texture(d3d_texture_info *texture, int scwidth, int scheight);
bool add_render_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y);
bool add_cache_target(d3d_info* d3d, d3d_texture_info* info, int width, int height, int prescale_x, int prescale_y, int screen_index);
void window_save();
void window_record();
@ -128,6 +132,7 @@ public:
void frame_complete();
void set_texture(d3d_texture_info *texture);
void remove_render_target(d3d_texture_info *texture);
int create_resources();
void delete_resources();
@ -141,7 +146,9 @@ private:
void end_avi_recording();
void begin_avi_recording(const char *name);
bool screen_encountered[9]; // whether a given screen was encountered this frame
d3d_render_target * find_render_target(d3d_texture_info *info);
d3d_cache_target * find_cache_target(int screen_index);
void remove_cache_target(d3d_cache_target *cache);
d3d_base * d3dintf; // D3D interface
win_window_info * window; // D3D window info
@ -149,6 +156,8 @@ private:
bool master_enable; // overall enable flag
bool paused; // whether or not rendering is currently paused
int num_screens; // number of emulated physical screens
int curr_screen; // current screen for render target operations
int curr_frame; // current frame (0/1) of a screen for render target operations
int lastidx; // index of the last-encountered target
bool write_ini; // enable external ini saving
bool read_ini; // enable external ini loading
@ -159,9 +168,8 @@ private:
int preset; // preset, if relevant
bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader
d3d_texture_info * shadow_texture; // shadow mask texture for post-processing shader
int registered_targets; // number of registered HLSL targets (i.e., screens)
int cyclic_target_idx; // cyclic index of next HLSL target slot
hlsl_options * options; // current uniform state
avi_file * avi_output_file; // AVI file
bitmap_rgb32 avi_snap; // AVI snapshot
int avi_frame; // AVI frame
@ -171,6 +179,7 @@ private:
d3d_texture * avi_copy_texture; // AVI destination texture in system memory
d3d_surface * avi_final_target; // AVI upscaled surface
d3d_texture * avi_final_texture; // AVI upscaled texture
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
d3d_surface * snap_copy_target; // snapshot destination surface in system memory
@ -195,28 +204,9 @@ private:
d3d_effect * yiq_decode_effect; // pointer to the current YIQ decoder effect object
d3d_vertex * fsfx_vertices; // pointer to our full-screen-quad object
// render targets
int raw_target_idx[9]; // Number of targets currently in use
int target_use_count[9]; // Whether or not a target has been used yet
d3d_texture_info * target_in_use[9]; // Target texture that is currently in use
int target_width[9]; // Render target width
int target_height[9]; // Render target height
d3d_surface * last_target[9]; // Render target surface pointer for each screen's previous frame
d3d_texture * last_texture[9]; // Render target texture pointer for each screen's previous frame
d3d_surface * prescaletarget0[9]; // Render target surface pointer (prescale, if necessary)
d3d_surface * target0[9]; // Render target surface pointer (pass 0, if necessary)
d3d_surface * target1[9]; // Render target surface pointer (pass 1, if necessary)
d3d_surface * target2[9]; // Render target surface pointer (pass 2, if necessary)
d3d_surface * target3[9]; // Render target surface pointer (pass 3, if necessary)
d3d_surface * target4[9]; // Render target surface pointer (pass 4, if necessary)
d3d_surface * smalltarget0[9]; // Render target surface pointer (small pass 0, if necessary)
d3d_texture * prescaletexture0[9]; // Render target surface pointer (prescale, if necessary)
d3d_texture * texture0[9]; // Render target texture pointer (pass 0, if necessary)
d3d_texture * texture1[9]; // Render target texture pointer (pass 1, if necessary)
d3d_texture * texture2[9]; // Render target texture pointer (pass 2, if necessary)
d3d_texture * texture3[9]; // Render target texture pointer (pass 3, if necessary)
d3d_texture * texture4[9]; // Render target texture pointer (pass 4, if necessary)
d3d_texture * smalltexture0[9]; // Render target texture pointer (small pass 0, if necessary)
public:
d3d_render_target * targethead;
d3d_cache_target * cachehead;
};
#endif

View File

@ -1719,6 +1719,10 @@ static void primitive_flush_pending(d3d_info *d3d)
}
void texture_destroy(d3d_info *d3d, d3d_texture_info *info)
{
}
//============================================================
// texture_create
//============================================================
@ -2517,14 +2521,34 @@ static d3d_texture_info *texture_find(d3d_info *d3d, const render_primitive *pri
// find a match
for (texture = d3d->texlist; texture != NULL; texture = texture->next)
{
if (texture->hash == texhash &&
texture->texinfo.base == prim->texture.base &&
texture->texinfo.width == prim->texture.width &&
texture->texinfo.height == prim->texture.height &&
((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
{
return texture;
}
}
// nothing found
// nothing found, check if we need to unregister something with hlsl
if (d3d->hlsl != NULL)
{
for (texture = d3d->texlist; texture != NULL; texture = texture->next)
{
// Clear our old texture reference
if (texture->hash == texhash &&
texture->texinfo.base == prim->texture.base &&
((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0 &&
(texture->texinfo.width != prim->texture.width ||
texture->texinfo.height != prim->texture.height))
{
d3d->hlsl->remove_render_target(texture);
break;
}
}
}
return NULL;
}
@ -2551,3 +2575,128 @@ static void texture_update(d3d_info *d3d, const render_primitive *prim)
texture->texinfo.seqid = prim->texture.seqid;
}
}
//============================================================
// d3d_cache_target::~d3d_cache_target
//============================================================
d3d_cache_target::~d3d_cache_target()
{
if (last_texture != NULL)
{
(*d3dintf->texture.release)(last_texture);
last_texture = NULL;
}
if (last_target != NULL)
{
(*d3dintf->surface.release)(last_target);
last_target = NULL;
}
}
//============================================================
// d3d_cache_target::init - initializes a target cache
//============================================================
bool d3d_cache_target::init(d3d_info *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y)
{
HRESULT result = (*d3dintf->device.create_texture)(d3d->device, width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target);
return true;
}
//============================================================
// d3d_render_target::~d3d_render_target
//============================================================
d3d_render_target::~d3d_render_target()
{
for (int index = 0; index < 5; index++)
{
if (texture[index] != NULL)
{
(*d3dintf->texture.release)(texture[index]);
texture[index] = NULL;
}
if (target[index] != NULL)
{
(*d3dintf->surface.release)(target[index]);
target[index] = NULL;
}
}
if (prescaletexture != NULL)
{
(*d3dintf->texture.release)(prescaletexture);
prescaletexture = NULL;
}
if (prescaletarget != NULL)
{
(*d3dintf->surface.release)(prescaletarget);
prescaletarget = NULL;
}
if (smalltexture != NULL)
{
(*d3dintf->texture.release)(smalltexture);
smalltexture = NULL;
}
if (smalltarget != NULL)
{
(*d3dintf->surface.release)(smalltarget);
smalltarget = NULL;
}
}
//============================================================
// d3d_render_target::init - initializes a render target
//============================================================
bool d3d_render_target::init(d3d_info *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y)
{
HRESULT result = (*d3dintf->device.create_texture)(d3d->device, width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture[0]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(texture[0], 0, &target[0]);
result = (*d3dintf->device.create_texture)(d3d->device, width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture[1]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(texture[1], 0, &target[1]);
result = (*d3dintf->device.create_texture)(d3d->device, width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture[2]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(texture[2], 0, &target[2]);
result = (*d3dintf->device.create_texture)(d3d->device, width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture[3]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(texture[3], 0, &target[3]);
result = (*d3dintf->device.create_texture)(d3d->device, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture[4]);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(texture[4], 0, &target[4]);
result = (*d3dintf->device.create_texture)(d3d->device, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &smalltexture);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(smalltexture, 0, &smalltarget);
result = (*d3dintf->device.create_texture)(d3d->device, width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescaletexture);
if (result != D3D_OK)
return false;
(*d3dintf->texture.get_surface_level)(prescaletexture, 0, &prescaletarget);
target_width = width * prescale_x;
target_height = height * prescale_y;
return true;
}

View File

@ -59,6 +59,55 @@
// TYPE DEFINITIONS
//============================================================
class d3d_info;
/* d3d_cache_target is a simple linked list containing only a rednerable target and texture, used for phosphor effects */
class d3d_cache_target
{
public:
// construction/destruction
d3d_cache_target() { }
~d3d_cache_target();
bool init(d3d_info *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y);
d3d_surface *last_target;
d3d_texture *last_texture;
int screen_index;
int ref_count;
d3d_cache_target *next;
d3d_cache_target *prev;
};
/* d3d_render_target is the information about a Direct3D render target chain */
class d3d_render_target
{
public:
// construction/destruction
d3d_render_target() { }
~d3d_render_target();
bool init(d3d_info *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y);
int target_width;
int target_height;
int screen_index;
int page_index;
d3d_surface *prescaletarget;
d3d_texture *prescaletexture;
d3d_surface *smalltarget;
d3d_texture *smalltexture;
d3d_surface *target[5];
d3d_texture *texture[5];
d3d_texture_info *info;
d3d_render_target *next;
d3d_render_target *prev;
};
/* d3d_info is the information about Direct3D for the current screen */
struct d3d_info
{
@ -122,5 +171,6 @@ struct d3d_info
//============================================================
d3d_texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsource, UINT32 flags);
void texture_destroy(d3d_info *d3d, d3d_texture_info *info);
#endif