diff --git a/bgfx/effects/hlsl/distortion.json b/bgfx/effects/hlsl/distortion.json index c459d70a6c..b3b9b5a581 100644 --- a/bgfx/effects/hlsl/distortion.json +++ b/bgfx/effects/hlsl/distortion.json @@ -28,7 +28,9 @@ { "name": "s_tex", "type": "int", "values": [ 0.0 ] }, { "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }, { "name": "u_screen_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_screen_count", "type": "vec4", "values": [ 1.0, 0.0, 0.0, 0.0 ] }, { "name": "u_target_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, + { "name": "u_target_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, { "name": "u_quad_dims", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, { "name": "u_distortion", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] }, { "name": "u_cubic_distortion", "type": "vec4", "values": [ 0.20, 0.0, 0.0, 0.0 ] }, diff --git a/bgfx/effects/hlsl/post.json b/bgfx/effects/hlsl/post.json index 1fb934a36c..db08baa4d8 100644 --- a/bgfx/effects/hlsl/post.json +++ b/bgfx/effects/hlsl/post.json @@ -29,6 +29,8 @@ { "name": "s_shadow", "type": "int", "values": [ 1.0 ] }, { "name": "u_swap_xy", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }, { "name": "u_source_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] }, + { "name": "u_target_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] }, + { "name": "u_target_scale", "type": "vec4", "values": [ 1.0, 1.0, 0.0, 0.0 ] }, { "name": "u_quad_dims", "type": "vec4", "values": [ 256.0, 256.0, 0.0, 0.0 ] }, { "name": "u_humbar_hertz_rate", "type": "vec4", "values": [ 0.001, 0.0, 0.0, 0.0 ] }, { "name": "u_humbar_alpha", "type": "vec4", "values": [ 0.0, 0.0, 0.0, 0.0 ] }, diff --git a/bgfx/shaders/dx11/chains/hlsl/fs_distortion.bin b/bgfx/shaders/dx11/chains/hlsl/fs_distortion.bin index 41f4aef5d2..0407e658a5 100644 Binary files a/bgfx/shaders/dx11/chains/hlsl/fs_distortion.bin and b/bgfx/shaders/dx11/chains/hlsl/fs_distortion.bin differ diff --git a/bgfx/shaders/dx11/chains/hlsl/fs_post.bin b/bgfx/shaders/dx11/chains/hlsl/fs_post.bin index b22fb024fb..60b08cf304 100644 Binary files a/bgfx/shaders/dx11/chains/hlsl/fs_post.bin and b/bgfx/shaders/dx11/chains/hlsl/fs_post.bin differ diff --git a/bgfx/shaders/dx9/chains/hlsl/fs_distortion.bin b/bgfx/shaders/dx9/chains/hlsl/fs_distortion.bin index 445bad83f4..54217cd112 100644 Binary files a/bgfx/shaders/dx9/chains/hlsl/fs_distortion.bin and b/bgfx/shaders/dx9/chains/hlsl/fs_distortion.bin differ diff --git a/bgfx/shaders/dx9/chains/hlsl/fs_post.bin b/bgfx/shaders/dx9/chains/hlsl/fs_post.bin index 8cc13a336d..31377efe8c 100644 Binary files a/bgfx/shaders/dx9/chains/hlsl/fs_post.bin and b/bgfx/shaders/dx9/chains/hlsl/fs_post.bin differ diff --git a/bgfx/shaders/gles/chains/hlsl/fs_distortion.bin b/bgfx/shaders/gles/chains/hlsl/fs_distortion.bin index fa2f788eec..a1f750c9aa 100644 Binary files a/bgfx/shaders/gles/chains/hlsl/fs_distortion.bin and b/bgfx/shaders/gles/chains/hlsl/fs_distortion.bin differ diff --git a/bgfx/shaders/gles/chains/hlsl/fs_post.bin b/bgfx/shaders/gles/chains/hlsl/fs_post.bin index a48adbecf4..3f4b0d6397 100644 Binary files a/bgfx/shaders/gles/chains/hlsl/fs_post.bin and b/bgfx/shaders/gles/chains/hlsl/fs_post.bin differ diff --git a/bgfx/shaders/glsl/chains/hlsl/fs_distortion.bin b/bgfx/shaders/glsl/chains/hlsl/fs_distortion.bin index 15f466dbc5..bb7ab27910 100644 Binary files a/bgfx/shaders/glsl/chains/hlsl/fs_distortion.bin and b/bgfx/shaders/glsl/chains/hlsl/fs_distortion.bin differ diff --git a/bgfx/shaders/glsl/chains/hlsl/fs_post.bin b/bgfx/shaders/glsl/chains/hlsl/fs_post.bin index 2bfa4c7145..887cf531e2 100644 Binary files a/bgfx/shaders/glsl/chains/hlsl/fs_post.bin and b/bgfx/shaders/glsl/chains/hlsl/fs_post.bin differ diff --git a/bgfx/shaders/metal/chains/hlsl/fs_distortion.bin b/bgfx/shaders/metal/chains/hlsl/fs_distortion.bin index 2ea407b319..d33db30a83 100644 Binary files a/bgfx/shaders/metal/chains/hlsl/fs_distortion.bin and b/bgfx/shaders/metal/chains/hlsl/fs_distortion.bin differ diff --git a/bgfx/shaders/metal/chains/hlsl/fs_post.bin b/bgfx/shaders/metal/chains/hlsl/fs_post.bin index ab0fc156fd..b6c6bd79b8 100644 Binary files a/bgfx/shaders/metal/chains/hlsl/fs_post.bin and b/bgfx/shaders/metal/chains/hlsl/fs_post.bin differ diff --git a/hlsl/distortion.fx b/hlsl/distortion.fx index 3b7a9d592e..c7128bccfe 100644 --- a/hlsl/distortion.fx +++ b/hlsl/distortion.fx @@ -86,7 +86,9 @@ float roundBox(float2 p, float2 b, float r) //----------------------------------------------------------------------------- uniform float2 ScreenDims; // size of the window or fullscreen +uniform int ScreenCount; uniform float2 TargetDims; // size of the target surface +uniform float2 TargetScale; uniform float2 QuadDims; // size of the screen quad VS_OUTPUT vs_main(VS_INPUT Input) @@ -170,7 +172,7 @@ float GetSpotAddend(float2 coord, float amount) return saturate(SigmoidSpot); } -float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount) +float GetBoundsFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount) { // reduce smooth amount down to radius amount smoothAmount = min(smoothAmount, radiusAmount); @@ -216,7 +218,7 @@ float2 GetDistortedCoords(float2 centerCoord, float amount, float amountCube) return centerCoord; } -float2 GetCoords(float2 coord, float distortionAmount, float cubicDistortionAmount) +float2 GetTextureCoords(float2 coord, float distortionAmount, float cubicDistortionAmount) { // center coordinates coord -= 0.5f; @@ -230,35 +232,61 @@ float2 GetCoords(float2 coord, float distortionAmount, float cubicDistortionAmou return coord; } +float2 GetQuadCoords(float2 coord, float distortionAmount, float cubicDistortionAmount) +{ + // center coordinates + coord -= 0.5f; + + // keep coords inside of the quad bounds of a single screen + if (ScreenCount == 1) + { + // base-target dimensions (without oversampling) + float2 BaseTargetDims = TargetDims / TargetScale; + + // apply base-target/quad difference + coord *= BaseTargetDims / (SwapXY ? QuadDims.yx : QuadDims.xy); + } + + // distort coordinates + coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount); + + return coord; +} + float4 ps_main(PS_INPUT Input) : COLOR { + // image distortion float distortionAmount = DistortionAmount; float cubicDistortionAmount = CubicDistortionAmount > 0.0f ? CubicDistortionAmount * 1.1f // cubic distortion need to be a little higher to compensate the quartic distortion : CubicDistortionAmount * 1.2f; // negativ values even more + // corner distortion at least by the amount of the image distorition + float distortCornerAmount = max(DistortCornerAmount, DistortionAmount + CubicDistortionAmount); + + float roundCornerAmount = RoundCornerAmount * 0.5f; + float smoothBorderAmount = SmoothBorderAmount * 0.5f; + float2 TexelDims = 1.0f / TargetDims; - // Screen Curvature - float2 TexCoord = GetCoords(Input.TexCoord, distortionAmount, cubicDistortionAmount); + // base-target dimensions (without oversampling) + float2 BaseTargetDims = TargetDims / TargetScale; - // Corner Curvature - float2 CornerCoord = GetCoords(Input.TexCoord, DistortCornerAmount, 0.0f); + // Screen Texture Curvature + float2 BaseCoord = GetTextureCoords(Input.TexCoord, distortionAmount, cubicDistortionAmount); + + // Screen Quad Curvature + float2 QuadCoord = GetQuadCoords(Input.TexCoord, distortCornerAmount, 0.0f); // clip border - clip(TexCoord < 0.0f - TexelDims || TexCoord > 1.0f + TexelDims ? -1 : 1); - - float2 TexCoordCentered = TexCoord; - TexCoordCentered -= 0.5f; - float2 CornerCoordCentered = CornerCoord; - CornerCoordCentered -= 0.5f; + clip(BaseCoord < 0.0f - TexelDims || BaseCoord > 1.0f + TexelDims ? -1 : 1); // Color - float4 BaseColor = tex2D(DiffuseSampler, TexCoord); + float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); BaseColor.a = 1.0f; // Vignetting Simulation - float2 VignetteCoord = CornerCoordCentered; + float2 VignetteCoord = QuadCoord; float VignetteFactor = GetVignetteFactor(VignetteCoord, VignettingAmount); BaseColor.rgb *= VignetteFactor; @@ -266,20 +294,23 @@ float4 ps_main(PS_INPUT Input) : COLOR // Light Reflection Simulation float3 LightColor = float3(1.0f, 0.90f, 0.80f); // color temperature 5.000 Kelvin - float2 SpotCoord = CornerCoordCentered; - float2 NoiseCoord = CornerCoordCentered; + float2 SpotCoord = QuadCoord; + float2 NoiseCoord = QuadCoord; float SpotAddend = GetSpotAddend(SpotCoord, ReflectionAmount); float NoiseFactor = GetNoiseFactor(SpotAddend, random(NoiseCoord)); BaseColor.rgb += SpotAddend * NoiseFactor * LightColor; // Round Corners Simulation - float2 RoundCornerCoord = CornerCoordCentered; - float2 RoundCornerBounds = SwapXY - ? QuadDims.yx - : QuadDims.xy; + float2 RoundCornerCoord = QuadCoord; + float2 RoundCornerBounds = ScreenCount == 1 + ? QuadDims // align corners to quad bounds of a single screen + : BaseTargetDims; // align corners to target bounds of multiple screens + RoundCornerBounds = SwapXY + ? RoundCornerBounds.yx + : RoundCornerBounds.xy; - float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerBounds, RoundCornerAmount * 0.5f, SmoothBorderAmount * 0.5f); + float roundCornerFactor = GetBoundsFactor(RoundCornerCoord, RoundCornerBounds, roundCornerAmount, smoothBorderAmount); BaseColor.rgb *= roundCornerFactor; return BaseColor; diff --git a/hlsl/post.fx b/hlsl/post.fx index 717c919d8a..e6dda5a947 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -76,6 +76,7 @@ static const float HalfPI = PI * 0.5f; uniform float2 ScreenDims; uniform float2 SourceDims; uniform float2 TargetDims; +uniform float2 TargetScale; uniform float2 QuadDims; uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size) @@ -158,17 +159,20 @@ float2 GetAdjustedCoords(float2 coord) return coord; } -float2 GetShadowCoord(float2 QuadCoord, float2 SourceCoord) +float2 GetShadowCoord(float2 TargetCoord, float2 SourceCoord) { - float2 QuadTexel = 1.0f / QuadDims; - float2 SourceTexel = 1.0f / SourceDims; + // base-target dimensions (without oversampling) + float2 BaseTargetDims = TargetDims / TargetScale; + BaseTargetDims = SwapXY + ? BaseTargetDims.yx + : BaseTargetDims.xy; float2 canvasCoord = ShadowTileMode == 0 - ? QuadCoord + ShadowUVOffset / QuadDims + ? TargetCoord + ShadowUVOffset / BaseTargetDims : SourceCoord + ShadowUVOffset / SourceDims; float2 canvasTexelDims = ShadowTileMode == 0 - ? QuadTexel - : SourceTexel; + ? 1.0f / BaseTargetDims + : 1.0f / SourceDims; float2 shadowDims = ShadowDims; float2 shadowUV = ShadowUV; @@ -204,15 +208,15 @@ float2 GetShadowCoord(float2 QuadCoord, float2 SourceCoord) float4 ps_main(PS_INPUT Input) : COLOR { float2 ScreenCoord = Input.ScreenCoord; - float2 TexCoord = GetAdjustedCoords(Input.TexCoord); + float2 BaseCoord = GetAdjustedCoords(Input.TexCoord); float2 SourceCoord = GetAdjustedCoords(Input.SourceCoord); // Color - float4 BaseColor = tex2D(DiffuseSampler, TexCoord); + float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); BaseColor.a = 1.0f; // clip border - clip(TexCoord < 0.0f || TexCoord > 1.0f ? -1 : 1); + clip(BaseCoord < 0.0f || BaseCoord > 1.0f ? -1 : 1); // Mask Simulation (may not affect bloom) if (!PrepareBloom && ShadowAlpha > 0.0f) diff --git a/hlsl/prescale.fx b/hlsl/prescale.fx index 2b48a2f9e5..3f52c20b46 100644 --- a/hlsl/prescale.fx +++ b/hlsl/prescale.fx @@ -40,7 +40,6 @@ struct VS_INPUT float4 Position : POSITION; float4 Color : COLOR0; float2 TexCoord : TEXCOORD0; - float2 Unused : TEXCOORD1; }; struct PS_INPUT diff --git a/hlsl/primary.fx b/hlsl/primary.fx index 939d37e97d..839ebbf8bf 100644 --- a/hlsl/primary.fx +++ b/hlsl/primary.fx @@ -53,7 +53,6 @@ static const float Epsilon = 1.0e-7f; uniform float2 ScreenDims; uniform float2 TargetDims; -uniform float2 QuadDims; VS_OUTPUT vs_screen_main(VS_INPUT Input) { diff --git a/hlsl/vector.fx b/hlsl/vector.fx index 686b617bbd..7de585fd3a 100644 --- a/hlsl/vector.fx +++ b/hlsl/vector.fx @@ -46,7 +46,7 @@ float roundBox(float2 p, float2 b, float r) //----------------------------------------------------------------------------- uniform float2 ScreenDims; -uniform float2 QuadDims; +uniform float2 TargetDims; VS_OUTPUT vs_main(VS_INPUT Input) { @@ -76,7 +76,7 @@ uniform float LengthRatio; // Size at which fade is maximum uniform float LengthScale; // How much length affects the vector's fade uniform float BeamSmooth; -float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount) +float GetBoundsFactor(float2 coord, float2 bounds, float radiusAmount, float smoothAmount) { // reduce smooth amount down to radius amount smoothAmount = min(smoothAmount, radiusAmount); @@ -100,7 +100,7 @@ float GetRoundCornerFactor(float2 coord, float2 bounds, float radiusAmount, floa float4 ps_main(PS_INPUT Input) : COLOR { - float2 lineSize = Input.SizeInfo / max(QuadDims.x, QuadDims.y); // normalize + float2 lineSize = Input.SizeInfo / max(TargetDims.x, TargetDims.y); // normalize float lineLength = lineSize.x; float lineLengthRatio = LengthRatio; @@ -113,7 +113,7 @@ float4 ps_main(PS_INPUT Input) : COLOR float4 outColor = float4(timeLengthModulate, timeLengthModulate, timeLengthModulate, 1.0f); outColor *= Input.Color; - float RoundCornerFactor = GetRoundCornerFactor(Input.TexCoord - 0.5f, Input.SizeInfo, 1.0f, BeamSmooth); + float RoundCornerFactor = GetBoundsFactor(Input.TexCoord - 0.5f, Input.SizeInfo, 1.0f, BeamSmooth); outColor.rgb *= RoundCornerFactor; return outColor; diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 7e2ad4c2ca..0e28f3c049 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -1402,6 +1402,7 @@ render_primitive_list &render_target::get_primitives() { render_primitive *prim = list.alloc(render_primitive::QUAD); set_render_bounds_xy(&prim->bounds, 0.0f, 0.0f, (float)m_width, (float)m_height); + prim->full_bounds = prim->bounds; set_render_color(&prim->color, 1.0f, 1.0f, 1.0f, 1.0f); prim->texture.base = nullptr; prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); @@ -1411,6 +1412,7 @@ render_primitive_list &render_target::get_primitives() { prim = list.alloc(render_primitive::QUAD); set_render_bounds_xy(&prim->bounds, 1.0f, 1.0f, (float)(m_width - 1), (float)(m_height - 1)); + prim->full_bounds = prim->bounds; set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); prim->texture.base = nullptr; prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); @@ -1855,6 +1857,9 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->color.b = container_xform.color.b * curitem.color().b; prim->color.a = container_xform.color.a * curitem.color().a; + // copy unclipped bounds + prim->full_bounds = prim->bounds; + // now switch off the type bool clipped = true; switch (curitem.type()) @@ -1917,7 +1922,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); // apply the final orientation from the quad flags and then build up the final flags - prim->flags = (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) + prim->flags |= (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | PRIMFLAG_TEXORIENT(finalorient) | PRIMFLAG_TEXFORMAT(curitem.texture()->format()); prim->flags |= blendmode != -1 @@ -1977,7 +1982,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); // apply the final orientation from the quad flags and then build up the final flags - prim->flags = (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) + prim->flags |= (curitem.flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) | PRIMFLAG_TEXORIENT(finalorient); prim->flags |= blendmode != -1 ? PRIMFLAG_BLENDMODE(blendmode) @@ -1986,7 +1991,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const else { // set the basic flags - prim->flags = (curitem.flags() & ~PRIMFLAG_BLENDMODE_MASK) + prim->flags |= (curitem.flags() & ~PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); // apply clipping @@ -2008,22 +2013,23 @@ void render_target::add_container_primitives(render_primitive_list &list, const // allocate a primitive render_primitive *prim = list.alloc(render_primitive::QUAD); set_render_bounds_wh(&prim->bounds, xform.xoffs, xform.yoffs, xform.xscale, xform.yscale); + prim->full_bounds = prim->bounds; prim->color = container_xform.color; width = render_round_nearest(prim->bounds.x1) - render_round_nearest(prim->bounds.x0); height = render_round_nearest(prim->bounds.y1) - render_round_nearest(prim->bounds.y0); container.overlay()->get_scaled( - (container_xform.orientation & ORIENTATION_SWAP_XY) ? height : width, - (container_xform.orientation & ORIENTATION_SWAP_XY) ? width : height, prim->texture, list); + (container_xform.orientation & ORIENTATION_SWAP_XY) ? height : width, + (container_xform.orientation & ORIENTATION_SWAP_XY) ? width : height, prim->texture, list); // determine UV coordinates prim->texcoords = oriented_texcoords[container_xform.orientation]; // set the flags and add it to the list - prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation) | - PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY) | - PRIMFLAG_TEXFORMAT(container.overlay()->format()) | - PRIMFLAG_TEXSHADE(1); + prim->flags = PRIMFLAG_TEXORIENT(container_xform.orientation) + | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY) + | PRIMFLAG_TEXFORMAT(container.overlay()->format()) + | PRIMFLAG_TEXSHADE(1); list.append_or_return(*prim, false); } @@ -2057,6 +2063,7 @@ void render_target::add_element_primitives(render_primitive_list &list, const ob INT32 width = render_round_nearest(xform.xscale); INT32 height = render_round_nearest(xform.yscale); set_render_bounds_wh(&prim->bounds, render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), (float) width, (float) height); + prim->full_bounds = prim->bounds; if (xform.orientation & ORIENTATION_SWAP_XY) std::swap(width, height); width = std::min(width, m_maxtexwidth); @@ -2511,6 +2518,7 @@ void render_target::add_clear_extents(render_primitive_list &list) { render_primitive *prim = list.alloc(render_primitive::QUAD); set_render_bounds_xy(&prim->bounds, (float)x0, (float)y0, (float)x1, (float)y1); + prim->full_bounds = prim->bounds; set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); prim->texture.base = nullptr; prim->flags = PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); diff --git a/src/emu/render.h b/src/emu/render.h index 069ae534a3..d0f8a29b0c 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -203,7 +203,7 @@ struct render_color // render_texuv - floating point set of UV texture coordinates struct render_texuv { - float u; // U coodinate (0.0-1.0) + float u; // U coordinate (0.0-1.0) float v; // V coordinate (0.0-1.0) }; @@ -345,8 +345,10 @@ public: // getters render_primitive *next() const { return m_next; } bool packable(const INT32 pack_size) const { return (flags & PRIMFLAG_PACKABLE) && texture.base != nullptr && texture.width <= pack_size && texture.height <= pack_size; } - float get_quad_width() const { return bounds.x1 - bounds.x0; } - float get_quad_height() const { return bounds.y1 - bounds.y0; } + float get_quad_width() const { return abs(bounds.x1 - bounds.x0); } + float get_quad_height() const { return abs(bounds.y1 - bounds.y0); } + float get_full_quad_width() const { return abs(full_bounds.x1 - full_bounds.x0); } + float get_full_quad_height() const { return abs(full_bounds.y1 - full_bounds.y0); } // reset to prepare for re-use void reset(); @@ -354,6 +356,7 @@ public: // public state primitive_type type; // type of primitive render_bounds bounds; // bounds or positions + render_bounds full_bounds; // bounds or positions (unclipped) render_color color; // RGBA values UINT32 flags; // flags float width; // width (for line primitives) @@ -602,8 +605,8 @@ private: user_settings m_user; // user settings bitmap_argb32 * m_overlaybitmap; // overlay bitmap render_texture * m_overlaytexture; // overlay texture - std::unique_ptr m_palclient; // client to the screen palette - std::vector m_bcglookup; // copy of screen palette with bcg adjustment + std::unique_ptr m_palclient; // client to the screen palette + std::vector m_bcglookup; // copy of screen palette with bcg adjustment rgb_t m_bcglookup256[0x400]; // lookup table for brightness/contrast/gamma }; diff --git a/src/osd/modules/render/bgfx/chain.cpp b/src/osd/modules/render/bgfx/chain.cpp index 5806c3ce04..352bb6f918 100644 --- a/src/osd/modules/render/bgfx/chain.cpp +++ b/src/osd/modules/render/bgfx/chain.cpp @@ -77,9 +77,9 @@ void bgfx_chain::process(render_primitive* prim, int view, int screen, texture_m screen_device_iterator screen_iterator(window.machine().root_device()); screen_device* screen_device = screen_iterator.byindex(screen); - int current_view = view; - uint16_t screen_width(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f)); - uint16_t screen_height(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f)); + uint16_t screen_count(window.target()->current_view()->screens().count()); + uint16_t screen_width(floor(prim->get_quad_width() + 0.5f)); + uint16_t screen_height(floor(prim->get_quad_height() + 0.5f)); uint32_t rotation_type = (window.target()->orientation() & ROT90) == ROT90 ? 1 : (window.target()->orientation() & ROT180) == ROT180 ? 2 : @@ -101,11 +101,12 @@ void bgfx_chain::process(render_primitive* prim, int view, int screen, texture_m screen_offset_y = -screen_container.yoffset(); } + int current_view = view; for (bgfx_chain_entry* entry : m_entries) { if (!entry->skip()) { - entry->submit(current_view, prim, textures, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, blend, screen); + entry->submit(current_view, prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, blend, screen); current_view++; } } diff --git a/src/osd/modules/render/bgfx/chainentry.cpp b/src/osd/modules/render/bgfx/chainentry.cpp index ec802e8369..ab18b4029f 100644 --- a/src/osd/modules/render/bgfx/chainentry.cpp +++ b/src/osd/modules/render/bgfx/chainentry.cpp @@ -55,7 +55,7 @@ bgfx_chain_entry::~bgfx_chain_entry() delete m_clear; } -void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen) +void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen) { bgfx::setViewSeq(view, true); @@ -73,7 +73,7 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager& put_screen_buffer(prim, &buffer); bgfx::setVertexBuffer(&buffer); - setup_auto_uniforms(prim, textures, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, screen); + setup_auto_uniforms(prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, screen); for (bgfx_entry_uniform* uniform : m_uniforms) { @@ -137,6 +137,16 @@ void bgfx_chain_entry::setup_screenoffset_uniforms(float screen_offset_x, float } } +void bgfx_chain_entry::setup_screencount_uniforms(uint16_t screen_count) +{ + bgfx_uniform* u_screen_count = m_effect->uniform("u_screen_count"); + if (u_screen_count != nullptr) + { + float values[1] = { float(screen_count) }; + u_screen_count->set(values, sizeof(float)); + } +} + void bgfx_chain_entry::setup_sourcesize_uniform(render_primitive* prim) const { bgfx_uniform* source_dims = m_effect->uniform("u_source_dims"); @@ -161,6 +171,20 @@ void bgfx_chain_entry::setup_targetsize_uniform(int32_t screen) const } } +void bgfx_chain_entry::setup_targetscale_uniform(int32_t screen) const +{ + bgfx_uniform* target_scale = m_effect->uniform("u_target_scale"); + if (target_scale != nullptr) + { + bgfx_target* output = m_targets.target(screen, m_output); + if (output != nullptr) + { + float values[2] = { float(output->scale()), float(output->scale()) }; + target_scale->set(values, sizeof(float) * 2); + } + } +} + void bgfx_chain_entry::setup_rotationtype_uniform(uint32_t rotation_type) const { bgfx_uniform* rotation_type_uniform = m_effect->uniform("u_rotation_type"); @@ -201,13 +225,15 @@ void bgfx_chain_entry::setup_screenindex_uniform(int32_t screen) const } } -void bgfx_chain_entry::setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen) +void bgfx_chain_entry::setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen) { setup_screensize_uniforms(textures, screen_width, screen_height, screen); setup_screenscale_uniforms(screen_scale_x, screen_scale_y); setup_screenoffset_uniforms(screen_offset_x, screen_offset_y); + setup_screencount_uniforms(screen_count); setup_sourcesize_uniform(prim); setup_targetsize_uniform(screen); + setup_targetscale_uniform(screen); setup_rotationtype_uniform(rotation_type); setup_swapxy_uniform(swap_xy); setup_quaddims_uniform(prim); diff --git a/src/osd/modules/render/bgfx/chainentry.h b/src/osd/modules/render/bgfx/chainentry.h index 4f4bede532..64130c5c93 100644 --- a/src/osd/modules/render/bgfx/chainentry.h +++ b/src/osd/modules/render/bgfx/chainentry.h @@ -37,7 +37,7 @@ public: bgfx_chain_entry(std::string name, bgfx_effect* effect, clear_state* clear, std::vector suppressors, std::vector inputs, std::vector uniforms, target_manager& targets, std::string output); ~bgfx_chain_entry(); - void submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen); + void submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen); // Getters std::string name() const { return m_name; } @@ -45,12 +45,14 @@ public: bool skip(); private: - void setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen); + void setup_auto_uniforms(render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, int32_t screen); void setup_screensize_uniforms(texture_manager& textures, uint16_t screen_width, uint16_t screen_height, int32_t screen); void setup_screenscale_uniforms(float screen_scale_x, float screen_scale_y); void setup_screenoffset_uniforms(float screen_offset_x, float screen_offset_y); + void setup_screencount_uniforms(uint16_t screen_count); void setup_sourcesize_uniform(render_primitive* prim) const; void setup_targetsize_uniform(int32_t screen) const; + void setup_targetscale_uniform(int32_t screen) const; void setup_rotationtype_uniform(uint32_t rotation_type) const; void setup_swapxy_uniform(bool swap_xy) const; void setup_quaddims_uniform(render_primitive* prim) const; diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp index 444d3c0534..b58e555862 100644 --- a/src/osd/modules/render/bgfx/chainmanager.cpp +++ b/src/osd/modules/render/bgfx/chainmanager.cpp @@ -435,8 +435,8 @@ uint32_t chain_manager::handle_screen_chains(uint32_t view, render_primitive *st continue; } - uint16_t screen_width(floor((prim->bounds.x1 - prim->bounds.x0) + 0.5f)); - uint16_t screen_height(floor((prim->bounds.y1 - prim->bounds.y0) + 0.5f)); + uint16_t screen_width(floor(prim->get_full_quad_width() + 0.5f)); + uint16_t screen_height(floor(prim->get_full_quad_height() + 0.5f)); if (window.swap_xy()) { std::swap(screen_width, screen_height); diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc index 449294978b..dda16f150e 100644 --- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc +++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_distortion.sc @@ -11,7 +11,9 @@ $input v_color0, v_texcoord0 // Autos uniform vec4 u_swap_xy; uniform vec4 u_screen_dims; +uniform vec4 u_screen_count; uniform vec4 u_target_dims; +uniform vec4 u_target_scale; uniform vec4 u_quad_dims; // User-supplied @@ -97,7 +99,7 @@ float GetSpotAddend(vec2 coord, float amount) return saturate(SigmoidSpot); } -float GetRoundCornerFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothAmount) +float GetBoundsFactor(vec2 coord, vec2 bounds, float radiusAmount, float smoothAmount) { // reduce smooth amount down to radius amount smoothAmount = min(smoothAmount, radiusAmount); @@ -141,7 +143,7 @@ vec2 GetDistortedCoords(vec2 centerCoord, float amount, float amountCube) return centerCoord; } -vec2 GetCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount) +vec2 GetTextureCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount) { // center coordinates coord -= 0.5; @@ -155,6 +157,27 @@ vec2 GetCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount) return coord; } +vec2 GetQuadCoords(vec2 coord, float distortionAmount, float cubicDistortionAmount) +{ + // center coordinates + coord -= 0.5; + + // keep coords inside of the quad bounds of a single screen + if (u_screen_count.x > 0.0 && u_screen_count.x < 2.0) + { + // base-target dimensions (without oversampling) + vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy; + + // apply base-target/quad difference + coord *= BaseTargetDims / ((u_swap_xy.x > 0.0) ? u_quad_dims.yx : u_quad_dims.xy); + } + + // distort coordinates + coord = GetDistortedCoords(coord, distortionAmount, cubicDistortionAmount); + + return coord; +} + // Shader void main() @@ -164,18 +187,22 @@ void main() ? u_cubic_distortion.x * 1.1 // cubic distortion need to be a little higher to compensate the quartic distortion : u_cubic_distortion.x * 1.2; // negativ values even more + // corner distortion at least by the amount of the image distorition + float distortCornerAmount = max(u_distort_corner.x, u_distortion.x + u_cubic_distortion.x); + + float roundCornerAmount = u_round_corner.x * 0.5; + float smoothBorderAmount = u_smooth_border.x * 0.5; + vec2 TexelDims = vec2(1.0 / u_target_dims.x, 1.0 / u_target_dims.y); - // Screen Curvature - vec2 BaseCoord = GetCoords(v_texcoord0, distortionAmount, cubicDistortionAmount); + // base-target dimensions (without oversampling) + vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy; - // Corner Curvature - vec2 CornerCoord = GetCoords(v_texcoord0, u_distort_corner.x, 0.0); + // Screen Texture Curvature + vec2 BaseCoord = GetTextureCoords(v_texcoord0, distortionAmount, cubicDistortionAmount); - vec2 BaseCoordCentered = BaseCoord; - BaseCoordCentered -= 0.5; - vec2 CornerCoordCentered = CornerCoord; - CornerCoordCentered -= 0.5; + // Screen Quad Curvature + vec2 QuadCoord = GetQuadCoords(v_texcoord0, distortCornerAmount, 0.0); // Color vec4 BaseColor = texture2D(s_tex, BaseCoord); @@ -188,7 +215,7 @@ void main() else { // Vignetting Simulation - vec2 VignetteCoord = CornerCoordCentered; + vec2 VignetteCoord = QuadCoord; float VignetteFactor = GetVignetteFactor(VignetteCoord, u_vignetting.x); BaseColor.rgb *= VignetteFactor; @@ -196,20 +223,23 @@ void main() // Light Reflection Simulation vec4 LightColor = vec4(1.0, 0.90, 0.80, 1.0); // color temperature 5.000 Kelvin - vec2 SpotCoord = CornerCoordCentered; - vec2 NoiseCoord = CornerCoordCentered; + vec2 SpotCoord = QuadCoord; + vec2 NoiseCoord = QuadCoord; float SpotAddend = GetSpotAddend(SpotCoord, u_reflection.x); float NoiseFactor = GetNoiseFactor(SpotAddend, rand(NoiseCoord)); BaseColor += SpotAddend * NoiseFactor * LightColor; // Round Corners Simulation - vec2 RoundCornerCoord = CornerCoordCentered; - vec2 RoundCornerBounds = (u_swap_xy.x > 0.0) - ? u_quad_dims.yx - : u_quad_dims.xy; + vec2 RoundCornerCoord = QuadCoord; + vec2 RoundCornerBounds = (u_screen_count.x > 0.0 && u_screen_count.x < 2.0) + ? u_quad_dims.xy // align corners to screen quad bounds + : BaseTargetDims; // align corners to target texture bounds + RoundCornerBounds = (u_swap_xy.x > 0.0) + ? RoundCornerBounds.yx + : RoundCornerBounds.xy; - float roundCornerFactor = GetRoundCornerFactor(RoundCornerCoord, RoundCornerBounds, u_round_corner.x * 0.5f, u_smooth_border.x * 0.5f); + float roundCornerFactor = GetBoundsFactor(RoundCornerCoord, RoundCornerBounds, roundCornerAmount, smoothBorderAmount); BaseColor.rgb *= roundCornerFactor; gl_FragColor = BaseColor; diff --git a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_post.sc b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_post.sc index 63800bb61d..beba1f1743 100644 --- a/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_post.sc +++ b/src/osd/modules/render/bgfx/shaders/chains/hlsl/fs_post.sc @@ -11,6 +11,8 @@ $input v_color0, v_texcoord0 // Autos uniform vec4 u_swap_xy; uniform vec4 u_source_dims; // size of the guest machine +uniform vec4 u_target_dims; +uniform vec4 u_target_scale; uniform vec4 u_quad_dims; uniform vec4 u_screen_scale; uniform vec4 u_screen_offset; @@ -63,13 +65,19 @@ vec2 GetAdjustedCoords(vec2 coord) return coord; } -vec2 GetShadowCoord(vec2 QuadCoord, vec2 SourceCoord) +vec2 GetShadowCoord(vec2 TargetCoord, vec2 SourceCoord) { + // base-target dimensions (remove oversampling) + vec2 BaseTargetDims = u_target_dims.xy / u_target_scale.xy; + BaseTargetDims = u_swap_xy.x > 0.0 + ? BaseTargetDims.yx + : BaseTargetDims.xy; + vec2 canvasCoord = u_shadow_tile_mode.x == 0.0 - ? QuadCoord + u_shadow_uv_offset.xy / u_quad_dims.xy + ? TargetCoord + u_shadow_uv_offset.xy / BaseTargetDims : SourceCoord + u_shadow_uv_offset.xy / u_source_dims.xy; vec2 canvasTexelDims = u_shadow_tile_mode.x == 0.0 - ? vec2(1.0, 1.0) / u_quad_dims.xy + ? vec2(1.0, 1.0) / BaseTargetDims : vec2(1.0, 1.0) / u_source_dims.xy; vec2 shadowUV = u_shadow_uv.xy; diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index 105313cb30..837e599b90 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -787,7 +787,9 @@ int shaders::create_resources() { effects[i]->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS); effects[i]->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS); + effects[i]->add_uniform("TargetScale", uniform::UT_FLOAT, uniform::CU_TARGET_SCALE); effects[i]->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); + effects[i]->add_uniform("ScreenCount", uniform::UT_INT, uniform::CU_SCREEN_COUNT); effects[i]->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS); effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY); effects[i]->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN); @@ -1018,9 +1020,9 @@ rgb_t shaders::apply_color_convolution(rgb_t color) { // this function uses the same algorithm as the color convolution shader pass - float r = static_cast(color.r()) / 255.0f; - float g = static_cast(color.g()) / 255.0f; - float b = static_cast(color.b()) / 255.0f; + float r = float(color.r()) / 255.0f; + float g = float(color.g()) / 255.0f; + float b = float(color.b()) / 255.0f; float *rRatio = options->red_ratio; float *gRatio = options->grn_ratio; @@ -1049,9 +1051,9 @@ rgb_t shaders::apply_color_convolution(rgb_t color) b = chroma[2] * saturation + luma; return rgb_t( - std::max(0, std::min(255, static_cast(r * 255.0f))), - std::max(0, std::min(255, static_cast(g * 255.0f))), - std::max(0, std::min(255, static_cast(b * 255.0f)))); + std::max(0, std::min(255, int(r * 255.0f))), + std::max(0, std::min(255, int(g * 255.0f))), + std::max(0, std::min(255, int(b * 255.0f)))); } int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum) @@ -1161,6 +1163,8 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly, { int next_index = source_index; + auto win = d3d->assert_window(); + screen_device_iterator screen_iterator(machine->root_device()); screen_device *screen = screen_iterator.byindex(curr_screen); render_container &screen_container = screen->container(); @@ -1177,9 +1181,9 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly, : rgb_t(0, 0, 0); back_color_rgb = apply_color_convolution(back_color_rgb); float back_color[3] = { - static_cast(back_color_rgb.r()) / 255.0f, - static_cast(back_color_rgb.g()) / 255.0f, - static_cast(back_color_rgb.b()) / 255.0f }; + float(back_color_rgb.r()) / 255.0f, + float(back_color_rgb.g()) / 255.0f, + float(back_color_rgb.b()) / 255.0f }; curr_effect = post_effect; curr_effect->update_uniforms(); @@ -1582,8 +1586,8 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_i auto win = d3d->assert_window(); - int target_width = int(prim->get_quad_width() + 0.5f); - int target_height = int(prim->get_quad_height() + 0.5f); + int target_width = int(prim->get_full_quad_width() + 0.5f); + int target_height = int(prim->get_full_quad_height() + 0.5f); target_width *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1; if (win->swap_xy()) @@ -1618,11 +1622,10 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim) auto win = d3d->assert_window(); - // source and target size are the same for vector targets int source_width = int(prim->get_quad_width() + 0.5f); int source_height = int(prim->get_quad_height() + 0.5f); - int target_width = source_width; - int target_height = source_height; + int target_width = int(prim->get_full_quad_width() + 0.5f); + int target_height = int(prim->get_full_quad_height() + 0.5f); target_width *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1; if (win->swap_xy()) @@ -1658,11 +1661,10 @@ bool shaders::create_vector_target(render_primitive *prim) auto win = d3d->assert_window(); - // source and target size are the same for vector targets int source_width = int(prim->get_quad_width() + 0.5f); int source_height = int(prim->get_quad_height() + 0.5f); - int target_width = source_width; - int target_height = source_height; + int target_width = int(prim->get_full_quad_width() + 0.5f); + int target_height = int(prim->get_full_quad_height() + 0.5f); target_width *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1; if (win->swap_xy()) @@ -1748,8 +1750,8 @@ bool shaders::register_texture(render_primitive *prim, texture_info *texture) int source_width = texture->get_width(); int source_height = texture->get_height(); - int target_width = int(prim->get_quad_width() + 0.5f); - int target_height = int(prim->get_quad_height() + 0.5f); + int target_width = int(prim->get_full_quad_width() + 0.5f); + int target_height = int(prim->get_full_quad_height() + 0.5f); target_width *= oversampling_enable ? 2 : 1; target_height *= oversampling_enable ? 2 : 1; if (win->swap_xy()) @@ -2339,6 +2341,12 @@ void uniform::update() m_shader->set_vector("ScreenDims", 2, &screendims.c.x); break; } + case CU_SCREEN_COUNT: + { + int screen_count = win->target()->current_view()->screens().count(); + m_shader->set_int("ScreenCount", screen_count); + break; + } case CU_SOURCE_DIMS: { if (vector_screen) @@ -2347,8 +2355,8 @@ void uniform::update() { // vector screen has no source texture, so take the source dimensions of the render target float sourcedims[2] = { - static_cast(shadersys->curr_render_target->width), - static_cast(shadersys->curr_render_target->height) }; + float(shadersys->curr_render_target->width), + float(shadersys->curr_render_target->height) }; m_shader->set_vector("SourceDims", 2, sourcedims); } } @@ -2367,20 +2375,30 @@ void uniform::update() if (shadersys->curr_render_target) { float targetdims[2] = { - static_cast(shadersys->curr_render_target->target_width), - static_cast(shadersys->curr_render_target->target_height) }; + float(shadersys->curr_render_target->target_width), + float(shadersys->curr_render_target->target_height) }; m_shader->set_vector("TargetDims", 2, targetdims); } break; } + case CU_TARGET_SCALE: + { + if (shadersys->curr_render_target) + { + float targetscale[2] = { + shadersys->oversampling_enable ? 2.0f : 1.0f, + shadersys->oversampling_enable ? 2.0f : 1.0f }; + m_shader->set_vector("TargetScale", 2, targetscale); + } + break; + } case CU_QUAD_DIMS: { if (shadersys->curr_poly) { float quaddims[2] = { - // round - static_cast(static_cast(shadersys->curr_poly->prim_width() + 0.5f)), - static_cast(static_cast(shadersys->curr_poly->prim_height() + 0.5f)) }; + floor(shadersys->curr_poly->prim_width() + 0.5f), + floor(shadersys->curr_poly->prim_height() + 0.5f) }; m_shader->set_vector("QuadDims", 2, quaddims); } break; @@ -2497,7 +2515,7 @@ void uniform::update() break; case CU_POST_SHADOW_COUNT: { - float shadowcount[2] = { static_cast(options->shadow_mask_count_x), static_cast(options->shadow_mask_count_y) }; + float shadowcount[2] = { float(options->shadow_mask_count_x), float(options->shadow_mask_count_y) }; m_shader->set_vector("ShadowCount", 2, shadowcount); break; } diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index 8256421c4a..cd99f4dd7b 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -42,8 +42,10 @@ public: enum { CU_SCREEN_DIMS = 0, + CU_SCREEN_COUNT, CU_SOURCE_DIMS, CU_TARGET_DIMS, + CU_TARGET_SCALE, CU_QUAD_DIMS, CU_SWAP_XY, diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index 61371a0518..aca3fb779c 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -1423,6 +1423,8 @@ void renderer_d3d9::batch_vectors(int vector_count) float quad_width = 0.0f; float quad_height = 0.0f; + float target_width = 0.0f; + float target_height = 0.0f; int vertex_count = vector_count * 6; int triangle_count = vector_count * 2; @@ -1445,8 +1447,10 @@ void renderer_d3d9::batch_vectors(int vector_count) case render_primitive::QUAD: if (PRIMFLAG_GET_VECTORBUF(prim.flags)) { - quad_width = prim.bounds.x1 - prim.bounds.x0; - quad_height = prim.bounds.y1 - prim.bounds.y0; + quad_width = prim.get_quad_width(); + quad_height = prim.get_quad_height(); + target_width = prim.get_full_quad_width(); + target_height = prim.get_full_quad_height(); } break; @@ -1476,18 +1480,18 @@ void renderer_d3d9::batch_vectors(int vector_count) ((rotation_0 || rotation_90) && orientation_swap_xy) || ((rotation_180 || rotation_90) && !orientation_swap_xy); - float screen_width = static_cast(this->get_width()); - float screen_height = static_cast(this->get_height()); + float screen_width = float(this->get_width()); + float screen_height = float(this->get_height()); float half_screen_width = screen_width * 0.5f; float half_screen_height = screen_height * 0.5f; float screen_swap_x_factor = 1.0f / screen_width * screen_height; float screen_swap_y_factor = 1.0f / screen_height * screen_width; - float screen_quad_ratio_x = screen_width / quad_width; - float screen_quad_ratio_y = screen_height / quad_height; + float screen_target_ratio_x = screen_width / target_width; + float screen_target_ratio_y = screen_height / target_height; if (swap_xy) { - std::swap(screen_quad_ratio_x, screen_quad_ratio_y); + std::swap(screen_target_ratio_x, screen_target_ratio_y); } for (int batchindex = 0; batchindex < m_batchindex; batchindex++) @@ -1513,9 +1517,9 @@ void renderer_d3d9::batch_vectors(int vector_count) m_vectorbatch[batchindex].x -= half_screen_width; m_vectorbatch[batchindex].y -= half_screen_height; - // correct screen/quad ratio (vectors are created in screen coordinates and have to be adjusted for texture corrdinates of the quad) - m_vectorbatch[batchindex].x *= screen_quad_ratio_x; - m_vectorbatch[batchindex].y *= screen_quad_ratio_y; + // correct screen/target ratio (vectors are created in screen coordinates and have to be adjusted for texture corrdinates of the target) + m_vectorbatch[batchindex].x *= screen_target_ratio_x; + m_vectorbatch[batchindex].y *= screen_target_ratio_y; // un-center m_vectorbatch[batchindex].x += half_screen_width; @@ -1668,10 +1672,10 @@ void renderer_d3d9::draw_line(const render_primitive &prim) vertex[0].u0 = start.c.x; vertex[0].v0 = start.c.y; - vertex[2].u0 = stop.c.x; - vertex[2].v0 = start.c.y; vertex[1].u0 = start.c.x; vertex[1].v0 = stop.c.y; + vertex[2].u0 = stop.c.x; + vertex[2].v0 = start.c.y; vertex[3].u0 = stop.c.x; vertex[3].v0 = stop.c.y; @@ -1703,7 +1707,6 @@ void renderer_d3d9::draw_line(const render_primitive &prim) void renderer_d3d9::draw_quad(const render_primitive &prim) { texture_info *texture = m_texture_manager->find_texinfo(&prim.texture, prim.flags); - if (texture == nullptr) { texture = get_default_texture(); @@ -1712,7 +1715,9 @@ void renderer_d3d9::draw_quad(const render_primitive &prim) // get a pointer to the vertex buffer vertex *vertex = mesh_alloc(4); if (vertex == nullptr) + { return; + } // fill in the vertexes clockwise vertex[0].x = prim.bounds.x0; @@ -1723,8 +1728,8 @@ void renderer_d3d9::draw_quad(const render_primitive &prim) vertex[2].y = prim.bounds.y1; vertex[3].x = prim.bounds.x1; vertex[3].y = prim.bounds.y1; - float width = prim.bounds.x1 - prim.bounds.x0; - float height = prim.bounds.y1 - prim.bounds.y0; + float quad_width = prim.get_quad_width(); + float quad_height = prim.get_quad_height(); // set the texture coordinates if (texture != nullptr) @@ -1761,7 +1766,7 @@ void renderer_d3d9::draw_quad(const render_primitive &prim) } // now add a polygon entry - m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, D3DTOP_MODULATE, width, height); + m_poly[m_numpolys].init(D3DPT_TRIANGLESTRIP, 2, 4, prim.flags, texture, D3DTOP_MODULATE, quad_width, quad_height); m_numpolys++; }