From 7add54760210313651c8a53a9ff6676512ce3fc8 Mon Sep 17 00:00:00 2001 From: ImJezze Date: Sat, 12 Mar 2016 16:03:28 +0100 Subject: Refactoring of render targes and vector texture coordinates - implemented proper texture coordinates for vector quad primitive - vector screen is now processed in texture coordinates - revered workaround for raster screen, which is again processed in texture coordinates - known issue: cocktail mode for vector screen looks wrong --- hlsl/bloom.fx | 2 +- hlsl/deconverge.fx | 35 ++--- hlsl/distortion.fx | 97 +++++++------- hlsl/downsample.fx | 7 +- hlsl/focus.fx | 14 +- hlsl/phosphor.fx | 2 +- hlsl/post.fx | 99 +++++++------- hlsl/prescale.fx | 2 +- hlsl/primary.fx | 8 +- hlsl/vector.fx | 12 +- src/emu/render.cpp | 52 ++++++-- src/emu/render.h | 2 + src/osd/modules/render/d3d/d3dcomm.h | 7 +- src/osd/modules/render/d3d/d3dhlsl.cpp | 202 ++++++++++++++--------------- src/osd/modules/render/d3d/d3dhlsl.h | 15 ++- src/osd/modules/render/drawd3d.cpp | 230 ++++++++++++++++++--------------- src/osd/modules/render/drawd3d.h | 13 +- 17 files changed, 422 insertions(+), 377 deletions(-) diff --git a/hlsl/bloom.fx b/hlsl/bloom.fx index 47cc04c47ed..a338ff6211e 100644 --- a/hlsl/bloom.fx +++ b/hlsl/bloom.fx @@ -226,7 +226,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; - float2 TexCoord = Input.Position.xy / ScreenDims; + float2 TexCoord = Input.TexCoord; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.TexCoord0 = TexCoord.xy; // + (0.5f / Level0Size); diff --git a/hlsl/deconverge.fx b/hlsl/deconverge.fx index df5bc2e6b49..f1cfa8fb686 100644 --- a/hlsl/deconverge.fx +++ b/hlsl/deconverge.fx @@ -52,12 +52,7 @@ struct PS_INPUT //----------------------------------------------------------------------------- uniform float2 ScreenDims; -uniform float2 SourceDims; -uniform float2 SourceRect; uniform float2 TargetDims; -uniform float2 QuadDims; - -uniform bool SwapXY = false; uniform float3 ConvergeX = float3(0.0f, 0.0f, 0.0f); uniform float3 ConvergeY = float3(0.0f, 0.0f, 0.0f); @@ -72,41 +67,35 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center - Output.Position.xy *= 2.0f; // toom + Output.Position.xy *= 2.0f; // zoom - float2 TexCoord = Input.Position.xy / ScreenDims; + float2 TexCoord = Input.TexCoord; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) - // we have to handle the swap of the coordinates ourself, because we are using screen not texture coordinates - float3 convergeX = SwapXY ? ConvergeY : ConvergeX; - float3 convergeY = SwapXY ? ConvergeX : ConvergeY; - float3 radialConvergeX = SwapXY ? RadialConvergeY : RadialConvergeX; - float3 radialConvergeY = SwapXY ? RadialConvergeX : RadialConvergeY; - // imaginary texel dimensions independed from screen dimension, but ratio - float2 TexelDims = (1.0f / 1024) * (QuadDims / ScreenDims); + float2 TexelDims = (1.0f / 1024); Output.TexCoordX = TexCoord.xxx; Output.TexCoordY = TexCoord.yyy; // center coordinates - Output.TexCoordX -= 0.5f * SourceRect.xxx; - Output.TexCoordY -= 0.5f * SourceRect.yyy; + Output.TexCoordX -= 0.5f; + Output.TexCoordY -= 0.5f; // radial converge offset to "translate" the most outer pixel as thay would be translated by the linar converge with the same amount - float2 radialConvergeOffset = 2.0f / SourceRect; + float2 radialConvergeOffset = 2.0f; // radial converge - Output.TexCoordX *= 1.0f + radialConvergeX * TexelDims.xxx * radialConvergeOffset.xxx; - Output.TexCoordY *= 1.0f + radialConvergeY * TexelDims.yyy * radialConvergeOffset.yyy; + Output.TexCoordX *= 1.0f + RadialConvergeX * TexelDims.xxx * radialConvergeOffset.xxx; + Output.TexCoordY *= 1.0f + RadialConvergeY * TexelDims.yyy * radialConvergeOffset.yyy; // un-center coordinates - Output.TexCoordX += 0.5f * SourceRect.xxx; - Output.TexCoordY += 0.5f * SourceRect.yyy; + Output.TexCoordX += 0.5f; + Output.TexCoordY += 0.5f; // linear converge - Output.TexCoordX += convergeX * TexelDims.xxx; - Output.TexCoordY += convergeY * TexelDims.yyy; + Output.TexCoordX += ConvergeX * TexelDims.xxx; + Output.TexCoordY += ConvergeY * TexelDims.yyy; Output.Color = Input.Color; diff --git a/hlsl/distortion.fx b/hlsl/distortion.fx index 6fd27a99795..0040c76d3b0 100644 --- a/hlsl/distortion.fx +++ b/hlsl/distortion.fx @@ -89,6 +89,8 @@ uniform float2 ScreenDims; // size of the window or fullscreen uniform float2 TargetDims; // size of the target surface uniform float2 QuadDims; // size of the screen quad +uniform bool VectorScreen; + VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; @@ -101,7 +103,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; - Output.TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord = Input.TexCoord; Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) return Output; @@ -117,28 +119,9 @@ uniform float SmoothBorderAmount = 0.0f; uniform float VignettingAmount = 0.0f; uniform float ReflectionAmount = 0.0f; +uniform bool SwapXY = false; uniform int RotationType = 0; // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270° -float2 GetScreenQuadRatio() -{ - float ScreenRatio = ScreenDims.x / ScreenDims.y; - float QuadRatio = QuadDims.x / QuadDims.y; - float ScreenQuadRatio = QuadRatio / ScreenRatio; - - return ScreenQuadRatio > 1.0f - ? float2(1.0, 1.0f / ScreenQuadRatio) - : float2(ScreenQuadRatio, 1.0); -} - -float2 GetQuadRatio() -{ - float QuadRatio = QuadDims.x / QuadDims.y; - - return QuadRatio > 1.0f - ? float2 (1.0f, 1.0f / QuadRatio) - : float2 (QuadRatio, 1.0f); -} - float GetNoiseFactor(float3 n, float random) { // smaller n become more noisy @@ -147,7 +130,7 @@ float GetNoiseFactor(float3 n, float random) float GetVignetteFactor(float2 coord, float amount) { - float2 VignetteCoord = coord / (QuadDims / ScreenDims); + float2 VignetteCoord = coord; float VignetteLength = length(VignetteCoord); float VignetteBlur = (amount * 0.75f) + 0.25; @@ -161,21 +144,42 @@ float GetVignetteFactor(float2 coord, float amount) float GetSpotAddend(float2 coord, float amount) { - float2 QuadRatio = GetQuadRatio(); - - // upper right quadrant - float2 spotOffset = - RotationType == 1 // 90° - ? float2(-0.25f, -0.25f) - : RotationType == 2 // 180° - ? float2(0.25f, -0.25f) - : RotationType == 3 // 270° - ? float2(0.25f, 0.25f) - : float2(-0.25f, 0.25f); - - float2 SpotCoord = coord / (QuadDims / ScreenDims); - SpotCoord += spotOffset * QuadRatio; - SpotCoord *= QuadRatio; + float2 SpotCoord = coord; + + // hack for vector screen + if (VectorScreen) + { + // upper right quadrant + float2 spotOffset = + RotationType == 1 // 90° + ? float2(-0.25f, -0.25f) + : RotationType == 2 // 180° + ? float2(0.25f, -0.25f) + : RotationType == 3 // 270° else 0° + ? float2(0.25f, 0.25f) + : float2(-0.25f, 0.25f); + + // normalized screen canvas ratio + float2 CanvasRatio = SwapXY + ? float2(QuadDims.x / QuadDims.y, 1.0f) + : float2(1.0f, QuadDims.y / QuadDims.x); + + SpotCoord += spotOffset; + SpotCoord *= CanvasRatio; + } + else + { + // upper right quadrant + float2 spotOffset = float2(-0.25f, 0.25f); + + // normalized screen canvas ratio + float2 CanvasRatio = SwapXY + ? float2(1.0f, QuadDims.x / QuadDims.y) + : float2(1.0f, QuadDims.y / QuadDims.x); + + SpotCoord += spotOffset; + SpotCoord *= CanvasRatio; + } float SpotBlur = amount; @@ -193,17 +197,20 @@ float GetSpotAddend(float2 coord, float amount) float GetRoundCornerFactor(float2 coord, float radiusAmount, float smoothAmount) { - float2 ScreenQuadRatio = GetScreenQuadRatio(); - // reduce smooth amount down to radius amount smoothAmount = min(smoothAmount, radiusAmount); - float range = min(QuadDims.x, QuadDims.y) * 0.5; + float2 quadDims = QuadDims; + quadDims = !VectorScreen && SwapXY + ? quadDims.yx + : quadDims.xy; + + float range = min(quadDims.x, quadDims.y) * 0.5; float radius = range * max(radiusAmount, 0.0025f); float smooth = 1.0 / (range * max(smoothAmount, 0.0025f)); // compute box - float box = roundBox(ScreenDims * (coord * 2.0f), ScreenDims * ScreenQuadRatio, radius); + float box = roundBox(quadDims * (coord * 2.0f), quadDims, radius); // apply smooth box *= smooth; @@ -240,20 +247,12 @@ float2 GetDistortedCoords(float2 centerCoord, float amount) float2 GetCoords(float2 coord, float distortionAmount) { - float2 ScreenQuadRatio = GetScreenQuadRatio(); - // center coordinates coord -= 0.5f; - // apply ratio difference between screen and quad - coord /= ScreenQuadRatio; - // distort coordinates coord = GetDistortedCoords(coord, distortionAmount); - // revert ratio difference between screen and quad - coord *= ScreenQuadRatio; - // un-center coordinates coord += 0.5f; diff --git a/hlsl/downsample.fx b/hlsl/downsample.fx index fad2ef8341f..e89407208be 100644 --- a/hlsl/downsample.fx +++ b/hlsl/downsample.fx @@ -53,8 +53,6 @@ struct PS_INPUT uniform float2 ScreenDims; uniform float2 TargetDims; -uniform float2 SourceDims; -uniform float2 SourceRect; uniform float2 QuadDims; uniform int BloomLevel; @@ -71,6 +69,9 @@ VS_OUTPUT vs_main(VS_INPUT Input) VS_OUTPUT Output = (VS_OUTPUT)0; float2 HalfTargetTexelDims = 0.5f / TargetDims; + HalfTargetTexelDims *= VectorScreen + ? (ScreenDims / QuadDims) + : 1.0f; Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; @@ -80,7 +81,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; - float2 TexCoord = Input.Position.xy / ScreenDims; + float2 TexCoord = Input.TexCoord; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.TexCoord01.xy = TexCoord + Coord0Offset * HalfTargetTexelDims; diff --git a/hlsl/focus.fx b/hlsl/focus.fx index 1e2e668911b..138ad0eea6d 100644 --- a/hlsl/focus.fx +++ b/hlsl/focus.fx @@ -51,7 +51,6 @@ struct PS_INPUT uniform float2 ScreenDims; uniform float2 TargetDims; -uniform float2 QuadDims; VS_OUTPUT vs_main(VS_INPUT Input) { @@ -63,11 +62,11 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - float2 TexCoord = Input.Position.xy / ScreenDims; + float2 TexCoord = Input.TexCoord; TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.TexCoord = TexCoord; - + Output.Color = Input.Color; return Output; @@ -79,8 +78,6 @@ VS_OUTPUT vs_main(VS_INPUT Input) uniform float2 Defocus = float2(0.0f, 0.0f); -uniform bool SwapXY = false; - static const float2 Coord1Offset = float2( 0.75f, 0.50f); static const float2 Coord2Offset = float2( 0.25f, 1.00f); static const float2 Coord3Offset = float2(-0.50f, 0.75f); @@ -92,13 +89,10 @@ static const float2 Coord8Offset = float2( 1.00f, -0.25f); float4 ps_main(PS_INPUT Input) : COLOR { - // we have to handle the swap of the coordinates ourself, because we are using screen not texture coordinates - float2 defocus = SwapXY ? Defocus.yx : Defocus.xy; - // imaginary texel dimensions independed from screen dimension, but ratio - float2 TexelDims = (1.0f / 1024) * (QuadDims / ScreenDims); + float2 TexelDims = (1.0f / 1024); - float2 DefocusTexelDims = defocus * TexelDims; + float2 DefocusTexelDims = Defocus * TexelDims; float4 d = tex2D(DiffuseSampler, Input.TexCoord); float3 d1 = tex2D(DiffuseSampler, Input.TexCoord + Coord1Offset * DefocusTexelDims).rgb; diff --git a/hlsl/phosphor.fx b/hlsl/phosphor.fx index 97defea0205..7d665b44749 100644 --- a/hlsl/phosphor.fx +++ b/hlsl/phosphor.fx @@ -79,7 +79,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord = Input.TexCoord; Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.PrevCoord = Output.TexCoord; diff --git a/hlsl/post.fx b/hlsl/post.fx index 01d83d435ff..ce8ccd0c813 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -73,10 +73,10 @@ static const float PHI = 1.618034f; // Scanline & Shadowmask Vertex Shader //----------------------------------------------------------------------------- -uniform float2 ScreenDims; // size of the window or fullscreen -uniform float2 SourceDims; // size of the texture in power-of-two size -uniform float2 SourceRect; // size of the uv rectangle -uniform float2 TargetDims; // size of the target surface +uniform float2 ScreenDims; +uniform float2 SourceDims; +uniform float2 TargetDims; +uniform float2 QuadDims; uniform float2 ShadowDims = float2(32.0f, 32.0f); // size of the shadow texture (extended to power-of-two size) uniform float2 ShadowUVOffset = float2(0.0f, 0.0f); @@ -96,16 +96,16 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = Input.Position.xy / ScreenDims; - + Output.TexCoord = 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) - Output.SourceCoord = Input.TexCoord; - Output.ScreenCoord = Input.Position.xy / ScreenDims; + Output.SourceCoord = Input.TexCoord; + Output.SourceCoord += 0.5f / TargetDims; + Output.Color = Input.Color; return Output; @@ -157,20 +157,55 @@ float2 GetAdjustedCoords(float2 coord, float2 centerOffset) return coord; } -float4 ps_main(PS_INPUT Input) : COLOR +// vector screen has the same quad texture coordinates for every screen orientation, raster screen differs +float2 GetShadowCoord(float2 QuadCoord, float2 SourceCoord) { - float2 ScreenTexelDims = 1.0f / ScreenDims; - float2 SourceTexelDims = 1.0f / SourceDims; + float2 QuadTexel = 1.0f / QuadDims; + float2 SourceTexel = 1.0f / SourceDims; + + float2 canvasCoord = ShadowTileMode == 0 + ? QuadCoord + ShadowUVOffset / QuadDims + : SourceCoord + ShadowUVOffset / SourceDims; + float2 canvasTexelDims = ShadowTileMode == 0 + ? QuadTexel + : SourceTexel; + + float2 shadowDims = ShadowDims; + float2 shadowUV = ShadowUV; + float2 shadowCount = ShadowCount; + + canvasCoord = !VectorScreen && SwapXY + ? canvasCoord.yx + : canvasCoord.xy; + shadowCount = !VectorScreen && SwapXY + ? shadowCount.yx + : shadowCount.xy; + + float2 shadowTile = canvasTexelDims * shadowCount; + + float2 shadowFrac = frac(canvasCoord / shadowTile); + shadowFrac = !VectorScreen && SwapXY + ? shadowFrac.yx + : shadowFrac.xy; + + float2 shadowCoord = (shadowFrac * shadowUV); + shadowCoord += 0.5f / shadowDims; // half texel offset + + return shadowCoord; +} + +float4 ps_main(PS_INPUT Input) : COLOR +{ float2 ScreenCoord = Input.ScreenCoord; float2 TexCoord = GetAdjustedCoords(Input.TexCoord, 0.5f); - float2 SourceCoord = GetAdjustedCoords(Input.SourceCoord, 0.5f * SourceRect); + float2 SourceCoord = GetAdjustedCoords(Input.SourceCoord, 0.5f); // Color float4 BaseColor = tex2D(DiffuseSampler, TexCoord); BaseColor.a = 1.0f; - // keep border + // keep border if (!PrepareBloom) { // clip border @@ -180,41 +215,7 @@ float4 ps_main(PS_INPUT Input) : COLOR // 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; - - float2 screenCoord = ShadowTileMode == 0 - ? ScreenCoord + shadowUVOffset / ScreenDims - : SourceCoord + shadowUVOffset / SourceDims; - screenCoord = SwapXY - ? screenCoord.yx - : screenCoord.xy; - - float2 shadowCount = ShadowCount; - shadowCount = SwapXY - ? shadowCount.yx - : shadowCount.xy; - - 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 + float2 ShadowCoord = GetShadowCoord(ScreenCoord, SourceCoord); float4 ShadowColor = tex2D(ShadowSampler, ShadowCoord); float3 ShadowMaskColor = lerp(1.0f, ShadowColor.rgb, ShadowAlpha); @@ -263,7 +264,7 @@ float4 ps_main(PS_INPUT Input) : COLOR if (!VectorScreen && HumBarAlpha > 0.0f) { float HumBarStep = frac(TimeMilliseconds * HumBarDesync); - float HumBarBrightness = 1.0 - frac(SourceCoord.y / SourceRect.y + HumBarStep) * HumBarAlpha; + float HumBarBrightness = 1.0 - frac(SourceCoord.y + HumBarStep) * HumBarAlpha; BaseColor.rgb *= HumBarBrightness; } } diff --git a/hlsl/prescale.fx b/hlsl/prescale.fx index 419254acd07..2b48a2f9e5a 100644 --- a/hlsl/prescale.fx +++ b/hlsl/prescale.fx @@ -67,7 +67,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy *= 2.0f; // zoom Output.TexCoord = Input.TexCoord; - // Output.TexCoord += 0.5f / targetDims; // half texel offset correction (DX9) + Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) return Output; } diff --git a/hlsl/primary.fx b/hlsl/primary.fx index 2086132a0e7..9f5a3c62faf 100644 --- a/hlsl/primary.fx +++ b/hlsl/primary.fx @@ -67,8 +67,8 @@ VS_OUTPUT vs_screen_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = Input.Position.xy / ScreenDims; - Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) + Output.TexCoord = Input.TexCoord; + // Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.Color = Input.Color; @@ -85,7 +85,7 @@ VS_OUTPUT vs_vector_buffer_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord = Input.TexCoord; Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.Color = Input.Color; @@ -104,6 +104,7 @@ VS_OUTPUT vs_ui_main(VS_INPUT Input) Output.Position.xy *= 2.0f; // zoom Output.TexCoord = Input.TexCoord; + // Output.TexCoord += 0.5f / TargetDims; // half texel offset correction (DX9) Output.Color = Input.Color; @@ -124,7 +125,6 @@ float4 ps_screen_main(PS_INPUT Input) : COLOR float4 ps_vector_buffer_main(PS_INPUT Input) : COLOR { float4 BaseTexel = tex2D(DiffuseSampler, Input.TexCoord); - BaseTexel *= Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f); return BaseTexel; } diff --git a/hlsl/vector.fx b/hlsl/vector.fx index 1e94042ad5e..13aeb943c53 100644 --- a/hlsl/vector.fx +++ b/hlsl/vector.fx @@ -36,6 +36,8 @@ struct PS_INPUT //----------------------------------------------------------------------------- uniform float2 ScreenDims; +uniform float2 QuadDims; + uniform float2 TimeParams; uniform float3 LengthParams; @@ -47,9 +49,9 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; // flip y Output.Position.xy -= 0.5f; // center - Output.Position.xy *= 2.0f; // zoom + Output.Position.xy *= 2.0f * (ScreenDims / QuadDims); // zoom - Output.TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord = Input.TexCoord; Output.Color = Input.Color; @@ -75,7 +77,9 @@ float4 ps_main(PS_INPUT Input) : COLOR lengthModulate = lerp(lengthModulate, 4.0f, minLength * 0.5f); lengthModulate = lerp(1.0f, timeModulate * lengthModulate, LengthParams.y); - float4 outColor = Input.Color * float4(lengthModulate, lengthModulate, lengthModulate, 1.0f); + float4 outColor = float4(lengthModulate, lengthModulate, lengthModulate, 1.0f); + outColor *= Input.Color; + return outColor; } @@ -90,6 +94,6 @@ technique DefaultTechnique Lighting = FALSE; VertexShader = compile vs_2_0 vs_main(); - PixelShader = compile ps_2_0 ps_main(); + PixelShader = compile ps_2_0 ps_main(); } } diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 3de791eab52..0a7fc00c151 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -102,7 +102,7 @@ struct object_transform // GLOBAL VARIABLES //************************************************************************** -// precomputed UV coordinates for various orientations +// precomputed UV coordinates for raster primitive with various orientations static const render_quad_texuv oriented_texcoords[8] = { { { 0,0 }, { 1,0 }, { 0,1 }, { 1,1 } }, // 0 @@ -115,6 +115,12 @@ static const render_quad_texuv oriented_texcoords[8] = { { 1,1 }, { 1,0 }, { 0,1 }, { 0,0 } } // ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y }; +// precomputed UV coordinates for vector primitive +static const render_quad_texuv oriented_vector_texcoords[1] = +{ + { { 0,0 }, { 1,0 }, { 0,1 }, { 1,1 } } +}; + // layer orders static const int layer_order_standard[] = { ITEM_LAYER_SCREEN, ITEM_LAYER_OVERLAY, ITEM_LAYER_BACKDROP, ITEM_LAYER_BEZEL, ITEM_LAYER_CPANEL, ITEM_LAYER_MARQUEE }; static const int layer_order_alternate[] = { ITEM_LAYER_BACKDROP, ITEM_LAYER_SCREEN, ITEM_LAYER_OVERLAY, ITEM_LAYER_BEZEL, ITEM_LAYER_CPANEL, ITEM_LAYER_MARQUEE }; @@ -1756,18 +1762,39 @@ void render_target::add_container_primitives(render_primitive_list &list, const // set the palette prim->texture.palette = curitem->texture()->get_adjusted_palette(container); - // determine UV coordinates and apply clipping + // determine UV coordinates prim->texcoords = oriented_texcoords[finalorient]; + + // apply clipping 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)) | - PRIMFLAG_TEXORIENT(finalorient) | - PRIMFLAG_TEXFORMAT(curitem->texture()->format()); - if (blendmode != -1) - prim->flags |= PRIMFLAG_BLENDMODE(blendmode); - else - prim->flags |= PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags())); + 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 + ? PRIMFLAG_BLENDMODE(blendmode) + : PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags())); + } + else if (curitem->flags() & PRIMFLAG_VECTORBUF_MASK) + { + // adjust the color for brightness/contrast/gamma + prim->color.r = container.apply_brightness_contrast_gamma_fp(prim->color.r); + prim->color.g = container.apply_brightness_contrast_gamma_fp(prim->color.g); + prim->color.b = container.apply_brightness_contrast_gamma_fp(prim->color.b); + + // determine UV coordinates + prim->texcoords = oriented_vector_texcoords[0]; + + // apply clipping + clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); + + // no texture + prim->texture.base = nullptr; + + // set the basic flags + prim->flags = (curitem->flags() & ~PRIMFLAG_BLENDMODE_MASK) + | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); } else { @@ -1776,9 +1803,12 @@ void render_target::add_container_primitives(render_primitive_list &list, const prim->color.g = container.apply_brightness_contrast_gamma_fp(prim->color.g); prim->color.b = container.apply_brightness_contrast_gamma_fp(prim->color.b); - // no texture -- set the basic flags + // no texture prim->texture.base = nullptr; - prim->flags = (curitem->flags() &~ PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); + + // set the basic flags + prim->flags = (curitem->flags() & ~PRIMFLAG_BLENDMODE_MASK) + | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA); // apply clipping clipped = render_clip_quad(&prim->bounds, &cliprect, nullptr); diff --git a/src/emu/render.h b/src/emu/render.h index 6d55c75ada9..09fe68282ef 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -329,6 +329,8 @@ 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; } // reset to prepare for re-use void reset(); diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h index 6240deb3011..3419619df57 100644 --- a/src/osd/modules/render/d3d/d3dcomm.h +++ b/src/osd/modules/render/d3d/d3dcomm.h @@ -77,8 +77,6 @@ public: DWORD get_max_texture_width() { return m_texture_max_width; } DWORD get_max_texture_height() { return m_texture_max_height; } - void compute_texture_size(int texwidth, int texheight, int* p_width, int* p_height); - texture_info * get_default_texture() { return m_default_texture; } texture_info * get_vector_texture() { return m_vector_texture; } @@ -150,6 +148,7 @@ public: private: void prescale(); void compute_size(int texwidth, int texheight); + void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height); d3d_texture_manager * m_texture_manager; // texture manager pointer @@ -245,7 +244,7 @@ public: cache_target() { } ~cache_target(); - bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height); + bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height); surface *last_target; texture *last_texture; @@ -270,7 +269,7 @@ public: d3d_render_target() { } ~d3d_render_target(); - bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int target_width, int target_height); + bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height); int next_index(int index) { return ++index > 1 ? 0 : index; } // real target dimension diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp index c55c679be54..cea0825092b 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.cpp +++ b/src/osd/modules/render/d3d/d3dhlsl.cpp @@ -69,8 +69,8 @@ shaders::shaders() : { master_enable = false; vector_enable = true; - shadow_texture = NULL; - options = NULL; + shadow_texture = nullptr; + options = nullptr; paused = true; lastidx = -1; targethead = nullptr; @@ -553,9 +553,9 @@ void shaders::remove_render_target(texture_info *texture) remove_render_target(find_render_target(texture)); } -void shaders::remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) +void shaders::remove_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index) { - d3d_render_target *target = find_render_target(width, height, screen_index, page_index); + d3d_render_target *target = find_render_target(source_width, source_height, screen_index, page_index); if (target != nullptr) { remove_render_target(target); @@ -1145,9 +1145,9 @@ void shaders::init_effect_info(poly_info *poly) // shaders::find_render_target //============================================================ -d3d_render_target* shaders::find_render_target(texture_info *info) +d3d_render_target* shaders::find_render_target(texture_info *texture) { - UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata; + UINT32 screen_index_data = (UINT32)texture->get_texinfo().osddata; UINT32 screen_index = screen_index_data >> 1; UINT32 page_index = screen_index_data & 1; @@ -1155,8 +1155,8 @@ d3d_render_target* shaders::find_render_target(texture_info *info) while (curr != nullptr && ( curr->screen_index != screen_index || curr->page_index != page_index || - curr->width != info->get_texinfo().width || - curr->height != info->get_texinfo().height)) + curr->width != texture->get_width() || + curr->height != texture->get_height())) { curr = curr->next; } @@ -1169,12 +1169,12 @@ d3d_render_target* shaders::find_render_target(texture_info *info) // shaders::find_render_target //============================================================ -d3d_render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) +d3d_render_target* shaders::find_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index) { d3d_render_target *curr = targethead; while (curr != nullptr && ( - curr->width != width || - curr->height != height || + curr->width != source_width || + curr->height != source_height || curr->screen_index != screen_index || curr->page_index != page_index)) { @@ -1294,8 +1294,7 @@ int shaders::prescale_pass(d3d_render_target *rt, int source_index, poly_info *p curr_effect->set_texture("Diffuse", rt->source_texture[next_index]); next_index = rt->next_index(next_index); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1318,8 +1317,7 @@ int shaders::deconverge_pass(d3d_render_target *rt, int source_index, poly_info curr_effect->set_texture("Diffuse", rt->target_texture[next_index]); next_index = rt->next_index(next_index); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1339,8 +1337,7 @@ int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *po curr_effect->set_texture("Diffuse", rt->target_texture[next_index]); next_index = rt->next_index(next_index); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1362,8 +1359,7 @@ int shaders::phosphor_pass(d3d_render_target *rt, cache_target *ct, int source_i curr_effect->set_bool("Passthrough", false); next_index = rt->next_index(next_index); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); // Pass along our phosphor'd screen curr_effect->update_uniforms(); @@ -1372,8 +1368,7 @@ int shaders::phosphor_pass(d3d_render_target *rt, cache_target *ct, int source_i curr_effect->set_bool("Passthrough", true); // Avoid changing targets due to page flipping - // blit(ct->last_target, true, D3DPT_TRIANGLELIST, 0, 2); - blit(ct->last_target, true, poly->get_type(), vertnum, poly->get_count()); + blit(ct->last_target, true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1421,8 +1416,7 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly, curr_effect->set_bool("PrepareBloom", prepare_bloom); next_index = rt->next_index(next_index); - // blit(prepare_bloom ? rt->source_surface[next_index] : rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(prepare_bloom ? rt->source_surface[next_index] : rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(prepare_bloom ? rt->source_surface[next_index] : rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1449,8 +1443,7 @@ int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info ? rt->source_texture[next_index] : rt->bloom_texture[bloom_index - 1]); - // 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()); + blit(rt->bloom_surface[bloom_index], true, D3DPT_TRIANGLELIST, 0, 2); } return next_index; @@ -1523,8 +1516,7 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly } next_index = rt->next_index(next_index); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1543,36 +1535,12 @@ int shaders::distortion_pass(d3d_render_target *rt, int source_index, poly_info return next_index; } - int screen_count = d3d->window().target()->current_view()->screens().count(); - - // todo: only one screen is supported - if (screen_count > 1) - { - return next_index; - } - - render_bounds bounds = d3d->window().target()->current_view()->bounds(); - render_bounds screen_bounds = d3d->window().target()->current_view()->screen_bounds(); - bool screen_bounds_zoomed = d3d->window().target()->zoom_to_screen(); - bool screen_bounds_differ = - bounds.x0 != screen_bounds.x0 || - bounds.y0 != screen_bounds.y0 || - bounds.x1 != screen_bounds.x1 || - bounds.y1 != screen_bounds.y1; - - // todo: full artworks are not supported - if (screen_bounds_differ && !screen_bounds_zoomed) - { - return next_index; - } - curr_effect = distortion_effect; curr_effect->update_uniforms(); curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]); next_index = rt->next_index(next_index); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1589,7 +1557,6 @@ int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *pol curr_effect->set_vector("TimeParams", 2, time_params); curr_effect->set_vector("LengthParams", 3, length_params); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); return next_index; @@ -1606,8 +1573,7 @@ int shaders::vector_buffer_pass(d3d_render_target *rt, int source_index, poly_in curr_effect->set_texture("Diffuse", rt->target_texture[next_index]); next_index = rt->next_index(next_index); - // blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count()); + blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2); return next_index; } @@ -1677,7 +1643,7 @@ void shaders::render_quad(poly_info *poly, int vertnum) return; } - cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_texinfo().width, curr_texture->get_texinfo().height); + cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_width(), curr_texture->get_height()); int next_index = 0; @@ -1770,7 +1736,9 @@ void shaders::render_quad(poly_info *poly, int vertnum) next_index = distortion_pass(rt, next_index, poly, vertnum); // render on screen + d3d->set_wrap(D3DTADDRESS_MIRROR); next_index = screen_pass(rt, next_index, poly, vertnum); + d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(curr_texture->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP); HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer); if (result != D3D_OK) @@ -1809,27 +1777,16 @@ void shaders::end_draw() //============================================================ // shaders::add_cache_target - register a cache target //============================================================ -bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int screen_index) +bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index) { cache_target* target = (cache_target*)global_alloc_clear(); - if (!target->init(d3d, d3dintf, width, height)) + if (!target->init(d3d, d3dintf, source_width, source_height, target_width, target_height)) { global_free(target); return false; } - if (info != nullptr) - { - target->width = info->get_texinfo().width; - target->height = info->get_texinfo().height; - } - else - { - target->width = d3d->get_width(); - target->height = d3d->get_height(); - } - target->next = cachehead; target->prev = nullptr; @@ -1844,22 +1801,65 @@ bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* info, int width return true; } -d3d_render_target* shaders::get_vector_target() +//============================================================ +// shaders::get_texture_target(render_primitive::prim, texture_info::texture) +//============================================================ +d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_info *texture) +{ + if (!vector_enable) + { + return nullptr; + } + + bool swap_xy = d3d->swap_xy(); + int target_width = swap_xy + ? static_cast(prim->get_quad_height() + 0.5f) + : static_cast(prim->get_quad_width() + 0.5f); + int target_height = swap_xy + ? static_cast(prim->get_quad_width() + 0.5f) + : static_cast(prim->get_quad_height() + 0.5f); + + // find render target and check if the size of the target quad has changed + d3d_render_target *target = find_render_target(texture); + if (target != nullptr && target->target_width == target_width && target->target_height == target_height) + { + return target; + } + + osd_printf_verbose("get_texture_target() - invalid size\n"); + + return nullptr; +} + +d3d_render_target* shaders::get_vector_target(render_primitive *prim) { if (!vector_enable) { return nullptr; } - return find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); + int target_width = static_cast(prim->get_quad_width() + 0.5f); + int target_height = static_cast(prim->get_quad_height() + 0.5f); + + // find render target and check of the size of the target quad has changed + d3d_render_target *target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); + if (target != nullptr && target->target_width == target_width && target->target_height == target_height) + { + return target; + } + + osd_printf_verbose("get_vector_target() - invalid size\n"); + + return nullptr; } void shaders::create_vector_target(render_primitive *prim) { - int width = d3d->get_width(); - int height = d3d->get_height(); + int target_width = static_cast(prim->get_quad_width() + 0.5f); + int target_height = static_cast(prim->get_quad_height() + 0.5f); - if (!add_render_target(d3d, nullptr, width, height, width, height)) + osd_printf_verbose("create_vector_target() - %f, %f; %d, %d\n", prim->get_quad_width(), prim->get_quad_height(), (int)(prim->get_quad_width() + 0.5f), (int)(prim->get_quad_height() + 0.5f)); + if (!add_render_target(d3d, nullptr, d3d->get_width(), d3d->get_height(), target_width, target_height)) { vector_enable = false; } @@ -1870,25 +1870,25 @@ void shaders::create_vector_target(render_primitive *prim) // shaders::add_render_target - register a render target //============================================================ -bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int target_width, int target_height) +bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height) { UINT32 screen_index = 0; UINT32 page_index = 0; - if (info != nullptr) + if (texture != nullptr) { - d3d_render_target *existing_target = find_render_target(info); + d3d_render_target *existing_target = find_render_target(texture); if (existing_target != nullptr) { remove_render_target(existing_target); } - UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata; + UINT32 screen_index_data = (UINT32)texture->get_texinfo().osddata; screen_index = screen_index_data >> 1; page_index = screen_index_data & 1; } else { - d3d_render_target *existing_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); + d3d_render_target *existing_target = find_render_target(source_width, source_height, 0, 0); if (existing_target != nullptr) { remove_render_target(existing_target); @@ -1897,22 +1897,14 @@ bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int widt d3d_render_target* target = (d3d_render_target*)global_alloc_clear(); - if (!target->init(d3d, d3dintf, width, height, target_width, target_height)) + if (!target->init(d3d, d3dintf, source_width, source_height, target_width, target_height)) { global_free(target); return false; } - if (info != nullptr) - { - target->width = info->get_texinfo().width; - target->height = info->get_texinfo().height; - } - else - { - target->width = d3d->get_width(); - target->height = d3d->get_height(); - } + target->screen_index = screen_index; + target->page_index = page_index; HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->target_surface[0]); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); @@ -1921,13 +1913,10 @@ bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int widt result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - target->screen_index = screen_index; - target->page_index = page_index; - - cache_target* cache = find_cache_target(target->screen_index, target->width, target->height); + cache_target* cache = find_cache_target(target->screen_index, source_width, source_height); if (cache == nullptr) { - if (!add_cache_target(d3d, info, target_width, target_height, target->screen_index)) + if (!add_cache_target(d3d, texture, source_width, source_height, target_width, target_height, target->screen_index)) { global_free(target); return false; @@ -1970,7 +1959,16 @@ bool shaders::register_texture(render_primitive *prim, texture_info *texture) enumerate_screens(); - if (!add_render_target(d3d, texture, texture->get_width(), texture->get_height(), d3d->get_width(), d3d->get_height())) + bool swap_xy = d3d->swap_xy(); + int target_width = swap_xy + ? static_cast(prim->get_quad_height() + 0.5f) + : static_cast(prim->get_quad_width() + 0.5f); + int target_height = swap_xy + ? static_cast(prim->get_quad_width() + 0.5f) + : static_cast(prim->get_quad_height() + 0.5f); + + osd_printf_verbose("register_texture() - %f, %f; %d, %d\n", prim->get_quad_width(), prim->get_quad_height(), (int)(prim->get_quad_width() + 0.5f), (int)(prim->get_quad_height() + 0.5f)); + if (!add_render_target(d3d, texture, texture->get_width(), texture->get_height(), target_width, target_height)) { return false; } @@ -2644,8 +2642,9 @@ void uniform::update() if (shadersys->curr_poly != nullptr) { float quaddims[2] = { - shadersys->curr_poly->get_prim_width(), - shadersys->curr_poly->get_prim_height() }; + // round + static_cast(static_cast(shadersys->curr_poly->get_prim_width() + 0.5f)), + static_cast(static_cast(shadersys->curr_poly->get_prim_height() + 0.5f)) }; m_shader->set_vector("QuadDims", 2, quaddims); } break; @@ -2653,12 +2652,7 @@ void uniform::update() case CU_SWAP_XY: { - bool orientation_swap_xy = - (d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; - bool rotation_swap_xy = - (d3d->window().target()->orientation() & ROT90) == ROT90 || - (d3d->window().target()->orientation() & ROT270) == ROT270; - m_shader->set_bool("SwapXY", orientation_swap_xy ^ rotation_swap_xy); + m_shader->set_bool("SwapXY", d3d->swap_xy()); break; } case CU_ORIENTATION_SWAP: diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index 0c3bc095d4c..2ad564c31b1 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -307,7 +307,7 @@ public: void toggle(); bool vector_enabled() { return master_enable && vector_enable; } - d3d_render_target* get_vector_target(); + d3d_render_target* get_vector_target(render_primitive *prim); void create_vector_target(render_primitive *prim); void begin_frame(); @@ -320,8 +320,9 @@ public: void render_quad(poly_info *poly, int vertnum); bool register_texture(render_primitive *prim, texture_info *texture); - bool add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int target_width, int target_height); - bool add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int screen_index); + d3d_render_target* get_texture_target(render_primitive *prim, texture_info *texture); + bool add_render_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height); + bool add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index); void window_save(); void window_record(); @@ -332,10 +333,10 @@ public: void record_texture(); void init_fsfx_quad(void *vertbuf); - void set_texture(texture_info *texture); - d3d_render_target * find_render_target(texture_info *info); + void set_texture(texture_info *info); + d3d_render_target * find_render_target(texture_info *texture); void remove_render_target(texture_info *texture); - void remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index); + void remove_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index); void remove_render_target(d3d_render_target *rt); int create_resources(bool reset); @@ -352,7 +353,7 @@ private: void end_avi_recording(); void begin_avi_recording(const char *name); - d3d_render_target* find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index); + d3d_render_target* find_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index); cache_target * find_cache_target(UINT32 screen_index, int width, int height); void remove_cache_target(cache_target *cache); diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp index 4037c9c0bbe..e927c36458f 100644 --- a/src/osd/modules/render/drawd3d.cpp +++ b/src/osd/modules/render/drawd3d.cpp @@ -420,63 +420,6 @@ d3d_texture_manager::~d3d_texture_manager() { } - -//============================================================ -// d3d_texture_manager::compute_texture_size -//============================================================ - -void d3d_texture_manager::compute_texture_size(int texwidth, int texheight, int* p_width, int* p_height) -{ - int finalheight = texheight; - int finalwidth = texwidth; - - // round width/height up to nearest power of 2 if we need to - if (!(get_texture_caps() & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)) - { - // first the width - if (finalwidth & (finalwidth - 1)) - { - finalwidth |= finalwidth >> 1; - finalwidth |= finalwidth >> 2; - finalwidth |= finalwidth >> 4; - finalwidth |= finalwidth >> 8; - finalwidth++; - } - - // then the height - if (finalheight & (finalheight - 1)) - { - finalheight |= finalheight >> 1; - finalheight |= finalheight >> 2; - finalheight |= finalheight >> 4; - finalheight |= finalheight >> 8; - finalheight++; - } - } - - // round up to square if we need to - if (get_texture_caps() & D3DPTEXTURECAPS_SQUAREONLY) - { - if (finalwidth < finalheight) - finalwidth = finalheight; - else - finalheight = finalwidth; - } - - // adjust the aspect ratio if we need to - while (finalwidth < finalheight && finalheight / finalwidth > get_max_texture_aspect()) - { - finalwidth *= 2; - } - while (finalheight < finalwidth && finalwidth / finalheight > get_max_texture_aspect()) - { - finalheight *= 2; - } - - *p_width = finalwidth; - *p_height = finalheight; -} - void d3d_texture_manager::create_resources() { // experimental: load a PNG to use for vector rendering; it is treated @@ -696,16 +639,12 @@ void d3d_texture_manager::update_textures() { if (m_renderer->get_shaders()->enabled()) { - // create a new texture without prescale, shaders will handle the prescale + // if there isn't one, create a new texture without prescale texture = global_alloc(texture_info(this, &prim->texture, 1, prim->flags)); - if (texture != nullptr) - { - m_renderer->get_shaders()->register_texture(prim, texture); - } } else { - // create a new texture + // if there isn't one, create a new texture texture = global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags)); } } @@ -718,10 +657,21 @@ void d3d_texture_manager::update_textures() texture->get_texinfo().seqid = prim->texture.seqid; } } + + if (m_renderer->get_shaders()->enabled()) + { + if (!m_renderer->get_shaders()->get_texture_target(prim, texture)) + { + if (!m_renderer->get_shaders()->register_texture(prim, texture)) + { + d3dintf->post_fx_available = false; + } + } + } } else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim->flags)) { - if (!m_renderer->get_shaders()->get_vector_target()) + if (!m_renderer->get_shaders()->get_vector_target(prim)) { m_renderer->get_shaders()->create_vector_target(prim); } @@ -754,12 +704,15 @@ void renderer_d3d9::begin_frame() m_shaders->init_fsfx_quad(m_hlsl_buf); } + // loop over line primitives m_line_count = 0; - - // loop over primitives for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next()) + { if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags)) + { m_line_count++; + } + } } void renderer_d3d9::process_primitives() @@ -1444,6 +1397,9 @@ void renderer_d3d9::batch_vectors() m_vectorbatch = mesh_alloc(m_line_count * vector_size); m_batchindex = 0; + float width = 0.0f; + float height = 0.0f; + static int start_index = 0; int line_index = 0; float period = options.screen_vector_time_period(); @@ -1468,6 +1424,14 @@ void renderer_d3d9::batch_vectors() } break; + case render_primitive::QUAD: + if (PRIMFLAG_GET_VECTORBUF(prim->flags)) + { + width = prim->bounds.x1 - prim->bounds.x0; + height = prim->bounds.y1 - prim->bounds.y0; + } + break; + default: // Skip break; @@ -1476,7 +1440,7 @@ void renderer_d3d9::batch_vectors() // now add a polygon entry m_poly[m_numpolys].init(D3DPT_TRIANGLELIST, m_line_count * (options.antialias() ? 8 : 2), vector_size * m_line_count, cached_flags, - m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f); + m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, width, height); m_numpolys++; start_index += (int)((float)line_index * period); @@ -1959,15 +1923,36 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t m_d3dsurface = nullptr; m_d3dfinaltex = nullptr; - // non-screen textures are easy + // determine texture type, required to compute texture size if (!PRIMFLAG_GET_SCREENTEX(flags)) { - // required to compute the size - m_type = TEXTURE_TYPE_PLAIN; + m_type = TEXTURE_TYPE_PLAIN; + } + else + { + if ((m_xprescale == 1 && m_yprescale == 1) || m_renderer->get_shaders()->enabled()) + { + m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN; + } + else + { + if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16) + { + m_type = TEXTURE_TYPE_SURFACE; + } + else + { + m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN; + } + } + } - // compute the size - compute_size(texsource->width, texsource->height); + // compute the size + compute_size(texsource->width, texsource->height); + // non-screen textures are easy + if (!PRIMFLAG_GET_SCREENTEX(flags)) + { assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16); result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex); if (result != D3D_OK) @@ -2030,15 +2015,9 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t m_xprescale = m_yprescale = 1; } - // screen textures with no prescaling are pretty easy and shaders handle prescale itself + // screen textures with no prescaling are pretty easy if (m_xprescale == 1 && m_yprescale == 1) { - // required to compute the size - m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN; - - // compute the size - compute_size(texsource->width, texsource->height); - result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex); if (result == D3D_OK) { @@ -2053,12 +2032,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t // (won't work for YUY textures) if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16) { - // required to compute the size - m_type = TEXTURE_TYPE_SURFACE; - - // compute the size - compute_size(texsource->width, texsource->height); - result = (*d3dintf->device.create_offscreen_plain_surface)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, format, D3DPOOL_DEFAULT, &m_d3dsurface); if (result != D3D_OK) { @@ -2068,12 +2041,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t // otherwise, we allocate a dynamic texture for the source else { - // required to compute the size - m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN; - - // compute the size - compute_size(texsource->width, texsource->height); - result = (*d3dintf->device.create_texture)(m_renderer->get_device(), m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex); if (result != D3D_OK) { @@ -2121,6 +2088,63 @@ error: } +//============================================================ +// texture_info::compute_size_subroutine +//============================================================ + +void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height) +{ + int finalheight = texheight; + int finalwidth = texwidth; + + // round width/height up to nearest power of 2 if we need to + if (!(m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)) + { + // first the width + if (finalwidth & (finalwidth - 1)) + { + finalwidth |= finalwidth >> 1; + finalwidth |= finalwidth >> 2; + finalwidth |= finalwidth >> 4; + finalwidth |= finalwidth >> 8; + finalwidth++; + } + + // then the height + if (finalheight & (finalheight - 1)) + { + finalheight |= finalheight >> 1; + finalheight |= finalheight >> 2; + finalheight |= finalheight >> 4; + finalheight |= finalheight >> 8; + finalheight++; + } + } + + // round up to square if we need to + if (m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_SQUAREONLY) + { + if (finalwidth < finalheight) + finalwidth = finalheight; + else + finalheight = finalwidth; + } + + // adjust the aspect ratio if we need to + while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager->get_max_texture_aspect()) + { + finalwidth *= 2; + } + while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager->get_max_texture_aspect()) + { + finalheight *= 2; + } + + *p_width = finalwidth; + *p_height = finalheight; +} + + //============================================================ // texture_info::compute_size //============================================================ @@ -2156,7 +2180,7 @@ void texture_info::compute_size(int texwidth, int texheight) // take texture size as given when shaders are enabled and we're not creating a surface (UI) texture, still update wrapped textures if (!shaders_enabled || surface_texture || wrap_texture) { - m_texture_manager->compute_texture_size(finalwidth, finalheight, &finalwidth, &finalheight); + compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight); // if we added pixels for the border, and that just barely pushed us over, take it back if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height()) @@ -2167,7 +2191,7 @@ void texture_info::compute_size(int texwidth, int texheight) m_xborderpix = 0; m_yborderpix = 0; - m_texture_manager->compute_texture_size(finalwidth, finalheight, &finalwidth, &finalheight); + compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight); } } @@ -2747,10 +2771,10 @@ cache_target::~cache_target() // cache_target::init - initializes a target cache //============================================================ -bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int target_width, int target_height) +bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height) { - // d3d->get_texture_manager()->compute_texture_size(target_width, target_height, &target_width, &target_height); - + this->width = source_width; + this->height = source_height; this->target_width = target_width; this->target_height = target_height; @@ -2815,21 +2839,19 @@ d3d_render_target::~d3d_render_target() // d3d_render_target::init - initializes a render target //============================================================ -bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int target_width, int target_height) +bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height) { HRESULT result; - // d3d->get_texture_manager()->compute_texture_size(target_width, target_height, &target_width, &target_height); - - this->width = width; - this->height = height; + this->width = source_width; + this->height = source_height; this->target_width = target_width; this->target_height = target_height; for (int index = 0; index < 2; index++) { - result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &source_texture[index]); + result = (*d3dintf->device.create_texture)(d3d->get_device(), source_width, source_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &source_texture[index]); if (result != D3D_OK) { return false; @@ -2850,8 +2872,8 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, i // 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_width = (float)source_width; + float bloom_height = (float)source_height; float bloom_size = bloom_width < bloom_height ? bloom_width : bloom_height; for (int bloom_index = 0; bloom_index < 11 && bloom_size >= 2.0f; bloom_size *= scale_factor) { diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h index 474f9ef8487..de8506ebfbd 100644 --- a/src/osd/modules/render/drawd3d.h +++ b/src/osd/modules/render/drawd3d.h @@ -54,6 +54,17 @@ public: virtual void record() override; virtual void toggle_fsfx() override; + bool swap_xy() + { + // todo: move to osd_window + bool orientation_swap_xy = + (window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; + bool rotation_swap_xy = + (window().target()->orientation() & ROT90) == ROT90 || + (window().target()->orientation() & ROT270) == ROT270; + return orientation_swap_xy ^ rotation_swap_xy; + }; + int initialize(); int device_create(HWND device_HWND); @@ -81,8 +92,6 @@ public: vertex * mesh_alloc(int numverts); - void update_textures(); - void process_primitives(); void primitive_flush_pending(); -- cgit v1.2.3