From 11395616ddde568531c640a461d70d526bb112ab Mon Sep 17 00:00:00 2001 From: ImJezze Date: Thu, 25 Feb 2016 20:58:49 +0100 Subject: Bloom refactoring - calculation of bloom dimensions is now done only once, when render target is created - reduced blur width for non-vector screens - implemented shadow u/v option for source tile mode --- hlsl/bloom.fx | 22 ++++++++++++------ hlsl/downsample.fx | 21 ++++++----------- hlsl/post.fx | 38 ++++++++++++++++++------------- src/osd/modules/render/d3d/d3dcomm.h | 6 ++++- src/osd/modules/render/d3d/d3dhlsl.cpp | 41 ++++++++++++---------------------- src/osd/modules/render/d3d/d3dhlsl.h | 2 -- src/osd/modules/render/drawd3d.cpp | 30 ++++++++++++++++--------- 7 files changed, 83 insertions(+), 77 deletions(-) diff --git a/hlsl/bloom.fx b/hlsl/bloom.fx index 1ee152adfec..47cc04c47ed 100644 --- a/hlsl/bloom.fx +++ b/hlsl/bloom.fx @@ -202,8 +202,9 @@ float random(float2 seed) uniform float2 ScreenDims; uniform float2 TargetDims; -uniform float2 SourceRect; +uniform float2 SourceDims; +// level dimensions not necessary anymore? uniform float2 Level0Size; uniform float4 Level12Size; uniform float4 Level34Size; @@ -211,6 +212,8 @@ uniform float4 Level56Size; uniform float4 Level78Size; uniform float4 Level9ASize; +uniform bool VectorScreen = false; + VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; @@ -226,12 +229,17 @@ VS_OUTPUT vs_main(VS_INPUT Input) float2 TexCoord = Input.Position.xy / ScreenDims; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - Output.TexCoord0 = TexCoord; - Output.TexCoord12 = TexCoord.xyxy + (0.5f / Level12Size); - Output.TexCoord34 = TexCoord.xyxy + (0.5f / Level34Size); - Output.TexCoord56 = TexCoord.xyxy + (0.5f / Level56Size); - Output.TexCoord78 = TexCoord.xyxy + (0.5f / Level78Size); - Output.TexCoord9A = TexCoord.xyxy + (0.5f / Level9ASize); + Output.TexCoord0 = TexCoord.xy; // + (0.5f / Level0Size); + + TexCoord += VectorScreen + ? 0.5f / TargetDims.xy + : 0.5f / SourceDims.xy; + + Output.TexCoord12 = TexCoord.xyxy; // + (0.5f / Level12Size); + Output.TexCoord34 = TexCoord.xyxy; // + (0.5f / Level34Size); + Output.TexCoord56 = TexCoord.xyxy; // + (0.5f / Level56Size); + Output.TexCoord78 = TexCoord.xyxy; // + (0.5f / Level78Size); + Output.TexCoord9A = TexCoord.xyxy; // + (0.5f / Level9ASize); return Output; } diff --git a/hlsl/downsample.fx b/hlsl/downsample.fx index 3afcdc703dd..fad2ef8341f 100644 --- a/hlsl/downsample.fx +++ b/hlsl/downsample.fx @@ -57,6 +57,8 @@ uniform float2 SourceDims; uniform float2 SourceRect; uniform float2 QuadDims; +uniform int BloomLevel; + uniform bool VectorScreen; static const float2 Coord0Offset = float2(-0.5f, -0.5f); @@ -68,9 +70,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - float2 TargetTexelDims = 1.0f / TargetDims; - float2 ScreenTexelDims = 1.0f / ScreenDims; - float2 SourceTexelDims = 1.0f / SourceDims; + float2 HalfTargetTexelDims = 0.5f / TargetDims; Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; @@ -83,17 +83,10 @@ VS_OUTPUT vs_main(VS_INPUT Input) float2 TexCoord = Input.Position.xy / ScreenDims; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - float2 VectorTexelOffset = ScreenTexelDims * -0.5; - float2 RasterTexelOffset = SourceTexelDims * (0.5f * SourceRect) * (1.0f - (QuadDims / ScreenDims)); - - TexCoord += VectorScreen - ? VectorTexelOffset - : RasterTexelOffset; - - Output.TexCoord01.xy = TexCoord + Coord0Offset * TargetTexelDims; - Output.TexCoord01.zw = TexCoord + Coord1Offset * TargetTexelDims; - Output.TexCoord23.xy = TexCoord + Coord2Offset * TargetTexelDims; - Output.TexCoord23.zw = TexCoord + Coord3Offset * TargetTexelDims; + Output.TexCoord01.xy = TexCoord + Coord0Offset * HalfTargetTexelDims; + Output.TexCoord01.zw = TexCoord + Coord1Offset * HalfTargetTexelDims; + Output.TexCoord23.xy = TexCoord + Coord2Offset * HalfTargetTexelDims; + Output.TexCoord23.zw = TexCoord + Coord3Offset * HalfTargetTexelDims; return Output; } diff --git a/hlsl/post.fx b/hlsl/post.fx index d972926f629..01d83d435ff 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -97,17 +97,14 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy *= 2.0f; // zoom Output.TexCoord = Input.Position.xy / ScreenDims; - Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - Output.SourceCoord = Input.TexCoord; + Output.TexCoord += PrepareBloom + ? 0.0f / TargetDims // use half texel offset (DX9) to do the blur for first bloom layer + : 0.5f / TargetDims; // fix half texel offset correction (DX9) - float2 ScreenCoordOffset = ShadowUVOffset; - ScreenCoordOffset = SwapXY - ? ShadowUVOffset.yx - : ShadowUVOffset.xy; + Output.SourceCoord = Input.TexCoord; Output.ScreenCoord = Input.Position.xy / ScreenDims; - Output.ScreenCoord += ScreenCoordOffset / ScreenDims; Output.Color = Input.Color; @@ -173,22 +170,31 @@ float4 ps_main(PS_INPUT Input) : COLOR float4 BaseColor = tex2D(DiffuseSampler, TexCoord); BaseColor.a = 1.0f; - clip(TexCoord < 0.0f || TexCoord > 1.0f ? -1 : 1); + // keep border + if (!PrepareBloom) + { + // clip border + clip(TexCoord < 0.0f || TexCoord > 1.0f ? -1 : 1); + } // Mask Simulation (may not affect bloom) if (!PrepareBloom && ShadowAlpha > 0.0f) { + float2 shadowUVOffset = ShadowUVOffset; + shadowUVOffset = SwapXY + ? ShadowUVOffset.yx + : ShadowUVOffset.xy; + float2 shadowDims = ShadowDims; shadowDims = SwapXY ? shadowDims.yx : shadowDims.xy; float2 shadowUV = ShadowUV; - // shadowUV = SwapXY - // ? shadowUV.yx - // : shadowUV.xy; - float2 screenCoord = ShadowTileMode == 0 ? ScreenCoord : SourceCoord; + float2 screenCoord = ShadowTileMode == 0 + ? ScreenCoord + shadowUVOffset / ScreenDims + : SourceCoord + shadowUVOffset / SourceDims; screenCoord = SwapXY ? screenCoord.yx : screenCoord.xy; @@ -198,17 +204,17 @@ float4 ps_main(PS_INPUT Input) : COLOR ? shadowCount.yx : shadowCount.xy; - float2 shadowTile = (ShadowTileMode == 0 ? ScreenTexelDims : SourceTexelDims) * shadowCount; + float2 shadowTile = ShadowTileMode == 0 + ? ScreenTexelDims * shadowCount + : SourceTexelDims * shadowCount; shadowTile = SwapXY ? shadowTile.yx : shadowTile.xy; float2 ShadowFrac = frac(screenCoord / shadowTile); + float2 ShadowCoord = (ShadowFrac * shadowUV); ShadowCoord += 0.5f / shadowDims; // half texel offset - // ShadowCoord = SwapXY - // ? ShadowCoord.yx - // : ShadowCoord.xy; float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord); float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha); diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h index 947dbba2362..9c444fd9cf0 100644 --- a/src/osd/modules/render/d3d/d3dcomm.h +++ b/src/osd/modules/render/d3d/d3dcomm.h @@ -292,8 +292,12 @@ public: d3d_render_target *next; d3d_render_target *prev; - surface *bloom_target[11]; + surface *bloom_surface[11]; texture *bloom_texture[11]; + + float bloom_dims[11][2]; + + int bloom_count; }; #endif diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index d862fdcb6a8..5fc5e9a4899 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -60,7 +60,7 @@ static direct3dx9_loadeffect_ptr g_load_effect = NULL; //============================================================ shaders::shaders() : - d3dintf(NULL), machine(NULL), d3d(NULL), num_screens(0), curr_screen(0), curr_frame(0), bloom_count(0), + d3dintf(NULL), machine(NULL), d3d(NULL), num_screens(0), curr_screen(0), curr_frame(0), vecbuf_type(), vecbuf_index(0), vecbuf_count(0), avi_output_file(NULL), avi_frame(0), avi_copy_surface(NULL), avi_copy_texture(NULL), avi_final_target(NULL), avi_final_texture(NULL), black_surface(NULL), black_texture(NULL), render_snap(false), snap_rendered(false), snap_copy_target(NULL), snap_copy_texture(NULL), snap_target(NULL), snap_texture(NULL), snap_width(0), snap_height(0), lines_pending(false), backbuffer(NULL), curr_effect(NULL), default_effect(NULL), prescale_effect(NULL), post_effect(NULL), distortion_effect(NULL), @@ -1444,32 +1444,19 @@ int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info curr_effect = downsample_effect; curr_effect->update_uniforms(); - int bloom_index = 0; - float bloom_width = rt->target_width; - float bloom_height = rt->target_height; - float bloom_size = bloom_width < bloom_height ? bloom_width : bloom_height; - for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) + for (int bloom_index = 0; bloom_index < rt->bloom_count; bloom_index++) { - bloom_dims[bloom_index][0] = (float)(int)bloom_width; - bloom_dims[bloom_index][1] = (float)(int)bloom_height; - - curr_effect->set_vector("TargetDims", 2, bloom_dims[bloom_index]); + curr_effect->set_vector("TargetDims", 2, rt->bloom_dims[bloom_index]); + curr_effect->set_int("BloomLevel", bloom_index + 1); curr_effect->set_texture("DiffuseTexture", bloom_index == 0 ? rt->source_texture[next_index] : rt->bloom_texture[bloom_index - 1]); - // blit(rt->bloom_target[bloom_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->bloom_target[bloom_index], true, poly->get_type(), vertnum, poly->get_count()); - - bloom_width *= 0.5f; - bloom_height *= 0.5f; - - bloom_index++; + // blit(rt->bloom_surface[bloom_index], true, D3DPT_TRIANGLELIST, 0, 2); + blit(rt->bloom_surface[bloom_index], true, poly->get_type(), vertnum, poly->get_count()); } - bloom_count = bloom_index; - return next_index; } @@ -1514,12 +1501,12 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly curr_effect->set_vector("Level78Weight", 2, weight78); curr_effect->set_vector("Level9AWeight", 2, weight9A); - curr_effect->set_vector("Level0Size", 2, bloom_dims[0]); - curr_effect->set_vector("Level12Size", 4, bloom_dims[1]); - curr_effect->set_vector("Level34Size", 4, bloom_dims[3]); - curr_effect->set_vector("Level56Size", 4, bloom_dims[5]); - curr_effect->set_vector("Level78Size", 4, bloom_dims[7]); - curr_effect->set_vector("Level9ASize", 4, bloom_dims[9]); + curr_effect->set_vector("Level0Size", 2, rt->bloom_dims[0]); + curr_effect->set_vector("Level12Size", 4, rt->bloom_dims[1]); + curr_effect->set_vector("Level34Size", 4, rt->bloom_dims[3]); + curr_effect->set_vector("Level56Size", 4, rt->bloom_dims[5]); + curr_effect->set_vector("Level78Size", 4, rt->bloom_dims[7]); + curr_effect->set_vector("Level9ASize", 4, rt->bloom_dims[9]); curr_effect->set_int("BloomBlendMode", options->bloom_blend_mode); curr_effect->set_float("BloomScale", options->bloom_scale); @@ -1528,12 +1515,12 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly curr_effect->set_texture("DiffuseA", rt->target_texture[next_index]); char name[9] = "Diffuse*"; - for (int index = 1; index < bloom_count; index++) + for (int index = 1; index < rt->bloom_count; index++) { name[7] = 'A' + index; curr_effect->set_texture(name, rt->bloom_texture[index - 1]); } - for (int index = bloom_count; index < 11; index++) + for (int index = rt->bloom_count; index < 11; index++) { name[7] = 'A' + index; curr_effect->set_texture(name, black_texture); diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index 4f3a072cf41..5d59aabc6e2 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -380,8 +380,6 @@ private: 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 - float bloom_dims[11][2]; // bloom texture dimensions - int bloom_count; // count of used bloom textures bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader texture_info * shadow_texture; // shadow mask texture for post-processing shader hlsl_options * options; // current options diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index 144de46dfd6..edce723c475 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -2770,10 +2770,10 @@ d3d_render_target::~d3d_render_target() (*d3dintf->texture.release)(bloom_texture[index]); bloom_texture[index] = nullptr; } - if (bloom_target[index] != nullptr) + if (bloom_surface[index] != nullptr) { - (*d3dintf->surface.release)(bloom_target[index]); - bloom_target[index] = nullptr; + (*d3dintf->surface.release)(bloom_surface[index]); + bloom_surface[index] = nullptr; } } @@ -2836,23 +2836,33 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, i (*d3dintf->texture.get_surface_level)(target_texture[index], 0, &target_surface[index]); } - int bloom_index = 0; - float bloom_width = target_width; - float bloom_height = target_height; + bool vector_screen = + d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR; + + // larger blur width for vector screens than raster screens + float scale_factor = vector_screen ? 0.5f : 0.75f; + + float bloom_width = (float)width; + float bloom_height = (float)height; float bloom_size = bloom_width < bloom_height ? bloom_width : bloom_height; - for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) + for (int bloom_index = 0; bloom_index < 11 && bloom_size >= 2.0f; bloom_size *= scale_factor) { - bloom_width *= 0.5f; - bloom_height *= 0.5f; + this->bloom_dims[bloom_index][0] = (int)bloom_width; + this->bloom_dims[bloom_index][1] = (int)bloom_height; result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]); if (result != D3D_OK) { return false; } - (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]); + (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_surface[bloom_index]); + + bloom_width *= scale_factor; + bloom_height *= scale_factor; bloom_index++; + + this->bloom_count = bloom_index; } return true; -- cgit v1.2.3