diff options
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 |
commit | 8624385a2486de3e59a4459d9a589e6ca363198b (patch) | |
tree | 1088fc16f462a27d77dfa223b48b3fe13f11b8b5 /src/osd | |
parent | becc76adaba421d13537be51dd05f7c65b29a22b (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.c | 605 | ||||
-rw-r--r-- | src/osd/windows/d3dhlsl.h | 44 | ||||
-rw-r--r-- | src/osd/windows/drawd3d.c | 151 | ||||
-rw-r--r-- | src/osd/windows/drawd3d.h | 50 |
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 |