summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2012-12-29 01:05:33 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2012-12-29 01:05:33 +0000
commit8624385a2486de3e59a4459d9a589e6ca363198b (patch)
tree1088fc16f462a27d77dfa223b48b3fe13f11b8b5 /src/osd
parentbecc76adaba421d13537be51dd05f7c65b29a22b (diff)
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]
Diffstat (limited to 'src/osd')
-rw-r--r--src/osd/windows/d3dhlsl.c605
-rw-r--r--src/osd/windows/d3dhlsl.h44
-rw-r--r--src/osd/windows/drawd3d.c151
-rw-r--r--src/osd/windows/drawd3d.h50
4 files changed, 438 insertions, 412 deletions
diff --git a/src/osd/windows/d3dhlsl.c b/src/osd/windows/d3dhlsl.c
index 470c75f484f..28eda4201ab 100644
--- a/src/osd/windows/d3dhlsl.c
+++ b/src/osd/windows/d3dhlsl.c
@@ -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;
}
@@ -575,6 +571,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;
}
@@ -1219,6 +1280,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,60 +1807,89 @@ 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]);
+ options->params_dirty = true;
- 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]);
+ enumerate_screens();
- 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]);
+ return 0;
+}
- 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]);
+//============================================================
+// 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);
- 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]);
+ if (!target->init(d3d, d3dintf, width, height, prescale_x, prescale_y))
+ {
+ global_free(target);
+ return false;
+ }
- 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]);
+ target->next = cachehead;
+ target->prev = NULL;
- 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++;
+ target->screen_index = screen_index;
+ target->ref_count = 1;
- options->params_dirty = true;
+ if (cachehead != NULL)
+ {
+ cachehead->prev = target;
+ }
+ cachehead = target;
- enumerate_screens();
+ return true;
+}
- return 0;
+//============================================================
+// 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;
}
//============================================================
@@ -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)
- 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)
+ if (!add_render_target(d3d, texture, texture->rawwidth, texture->rawheight, hlsl_prescale_x, hlsl_prescale_y))
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();
}
diff --git a/src/osd/windows/d3dhlsl.h b/src/osd/windows/d3dhlsl.h
index 5f7f9896041..efb72f3dfca 100644
--- a/src/osd/windows/d3dhlsl.h
+++ b/src/osd/windows/d3dhlsl.h
@@ -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
diff --git a/src/osd/windows/drawd3d.c b/src/osd/windows/drawd3d.c
index b118f025a57..07b61eac678 100644
--- a/src/osd/windows/drawd3d.c
+++ b/src/osd/windows/drawd3d.c
@@ -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;
+}
diff --git a/src/osd/windows/drawd3d.h b/src/osd/windows/drawd3d.h
index 1bee718737c..dcbb22606fe 100644
--- a/src/osd/windows/drawd3d.h
+++ b/src/osd/windows/drawd3d.h
@@ -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