diff options
-rw-r--r-- | hlsl/bloom.fx | 34 | ||||
-rw-r--r-- | hlsl/downsample.fx | 28 | ||||
-rw-r--r-- | hlsl/post.fx | 78 | ||||
-rw-r--r-- | hlsl/primary.fx | 11 | ||||
-rw-r--r-- | hlsl/simple.fx | 93 | ||||
-rw-r--r-- | src/osd/modules/render/d3d/d3dcomm.h | 3 | ||||
-rw-r--r-- | src/osd/modules/render/d3d/d3dhlsl.c | 1112 | ||||
-rw-r--r-- | src/osd/modules/render/d3d/d3dhlsl.h | 25 | ||||
-rw-r--r-- | src/osd/modules/render/drawd3d.c | 162 | ||||
-rw-r--r-- | src/osd/modules/render/drawd3d.h | 11 |
10 files changed, 621 insertions, 936 deletions
diff --git a/hlsl/bloom.fx b/hlsl/bloom.fx index f6a0c9d57d1..9ed97bbd936 100644 --- a/hlsl/bloom.fx +++ b/hlsl/bloom.fx @@ -177,7 +177,7 @@ struct PS_INPUT uniform float2 ScreenDims; -uniform float2 Prescale = float2(8.0f, 8.0f); +uniform float2 Prescale = float2(1.0f, 1.0f); uniform float4 Level01Size; uniform float4 Level23Size; @@ -192,10 +192,6 @@ VS_OUTPUT vs_main(VS_INPUT Input) { VS_OUTPUT Output = (VS_OUTPUT)0; - float2 ScreenDimsTexel = 1.0f / ScreenDims; - - float2 HalfPrescale = Prescale * 0.5f; - Output.Position = float4(Input.Position.xyz, 1.0f); Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; @@ -204,26 +200,14 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; - // Vector graphics is not prescaled it has the size of the screen - if (PrepareVector) - { - Output.TexCoord01 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level01Size; - Output.TexCoord23 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level23Size; - Output.TexCoord45 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level45Size; - Output.TexCoord67 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level67Size; - Output.TexCoord89 = Input.Position.xyxy / ScreenDims.xyxy + 1.0f / Level89Size; - Output.TexCoordA = Input.Position.xy / ScreenDims.xy + 1.0f / LevelASize; - } - else - { - Output.TexCoord01 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level01Size; - Output.TexCoord23 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level23Size; - Output.TexCoord45 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level45Size; - Output.TexCoord67 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level67Size; - Output.TexCoord89 = Input.Position.xyxy / ScreenDims.xyxy + HalfPrescale.xyxy / Level89Size; - Output.TexCoordA = Input.Position.xy / ScreenDims.xy + HalfPrescale.xy / LevelASize; - } - + float2 TexCoord = Input.Position.xy / ScreenDims; + Output.TexCoord01 = TexCoord.xyxy + Prescale.xyxy / Level01Size; + Output.TexCoord23 = TexCoord.xyxy + Prescale.xyxy / Level23Size; + Output.TexCoord45 = TexCoord.xyxy + Prescale.xyxy / Level45Size; + Output.TexCoord67 = TexCoord.xyxy + Prescale.xyxy / Level67Size; + Output.TexCoord89 = TexCoord.xyxy + Prescale.xyxy / Level89Size; + Output.TexCoordA = TexCoord.xy + Prescale.xy / LevelASize; + return Output; } diff --git a/hlsl/downsample.fx b/hlsl/downsample.fx index b7579fc24ed..18eaa8313c0 100644 --- a/hlsl/downsample.fx +++ b/hlsl/downsample.fx @@ -50,11 +50,7 @@ struct PS_INPUT uniform float2 ScreenDims; uniform float2 TargetSize; -uniform float2 Prescale = float2(8.0f, 8.0f); - -uniform float BloomRescale; - -uniform bool PrepareVector = false; +uniform float2 Prescale = float2(1.0f, 1.0f); VS_OUTPUT vs_main(VS_INPUT Input) { @@ -71,22 +67,10 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Color = Input.Color; float2 TexCoord = Input.Position.xy / ScreenDims; - - // Vector graphics is not prescaled it has the size of the screen - if (PrepareVector) - { - Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize; - Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize; - Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize; - Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize; - } - else - { - Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize * Prescale; - Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize * Prescale; - Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize * Prescale; - Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize * Prescale; - } + Output.TexCoord01.xy = TexCoord + float2(-0.5f, -0.5f) * TargetTexelSize * Prescale; + Output.TexCoord01.zw = TexCoord + float2( 0.5f, -0.5f) * TargetTexelSize * Prescale; + Output.TexCoord23.xy = TexCoord + float2(-0.5f, 0.5f) * TargetTexelSize * Prescale; + Output.TexCoord23.zw = TexCoord + float2( 0.5f, 0.5f) * TargetTexelSize * Prescale; return Output; } @@ -102,7 +86,7 @@ float4 ps_main(PS_INPUT Input) : COLOR float4 texel2 = tex2D(DiffuseSampler, Input.TexCoord23.xy); float4 texel3 = tex2D(DiffuseSampler, Input.TexCoord23.zw); - float4 outTexel = (texel0 + texel1 + texel2 + texel3) / 4.0 * BloomRescale; + float4 outTexel = (texel0 + texel1 + texel2 + texel3) / 4.0; return float4(outTexel.rgb, 1.0f); } diff --git a/hlsl/post.fx b/hlsl/post.fx index 78e4b648ddf..b9a75fd5fa6 100644 --- a/hlsl/post.fx +++ b/hlsl/post.fx @@ -66,11 +66,13 @@ bool xor(bool a, bool b) //----------------------------------------------------------------------------- uniform float2 ScreenDims; // size of the window or fullscreen -uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f); +uniform float2 ScreenRatio = float2(1.0f, 3.0f / 4.0f); // normalized screen ratio (defalt ratio of 4:3) 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 target + 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); @@ -78,7 +80,9 @@ uniform float2 Prescale = float2(8.0f, 8.0f); uniform bool OrientationSwapXY = false; // false landscape, true portrait for default screen orientation uniform bool RotationSwapXY = false; // swapped default screen orientation due to screen rotation + uniform bool PrepareBloom = false; // disables some effects for rendering bloom textures +uniform bool PrepareVector = false; VS_OUTPUT vs_main(VS_INPUT Input) { @@ -106,7 +110,7 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy -= 0.5f; // center Output.Position.xy *= 2.0f; // zoom - Output.TexCoord = Input.TexCoord; + Output.TexCoord = PrepareVector ? (Input.Position.xy / ScreenDims) : Input.TexCoord; Output.Color = Input.Color; @@ -140,7 +144,7 @@ static const float Epsilon = 1.0e-7f; static const float PI = 3.1415927f; static const float E = 2.7182817f; static const float Gelfond = 23.140692f; // e^pi (Gelfond constant) -static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond–Schneider constant) +static const float GelfondSchneider = 2.6651442f; // 2^sqrt(2) (Gelfond-Schneider constant) float nextPowerOfTwo(float n) { @@ -212,9 +216,13 @@ float RoundBox(float2 p, float2 b, float r) float GetRoundCornerFactor(float2 coord, float amount) { - float2 SourceArea = 1.0f / SourceRect; - float2 SourceRes = SourceDims * SourceRect; - float2 SourceRatio = float2(1.0f, SourceRes.y / SourceRes.x); + // hint: vector target area is always quadratic + float2 UsedSourceRect = PrepareVector + ? float2(1.0f, 1.0f) + : SourceRect; + float2 SourceArea = 1.0f / UsedSourceRect; + float2 SourceDimsArea = SourceDims * UsedSourceRect; + float2 SourceRatio = float2(1.0f, SourceDimsArea.y / SourceDimsArea.x); float2 SourceTexelDims = 1.0f / SourceDims; // base on the default ratio of 4:3 @@ -248,24 +256,24 @@ float4 ps_main(PS_INPUT Input) : COLOR float2 ScreenTexelDims = 1.0f / ScreenDims; float2 SourceTexelDims = 1.0f / SourceDims; - float2 SourceArea = 1.0f / SourceRect; - float2 HalfSourceRect = SourceRect * 0.5f; + // hint: vector target area is always quadratic + float2 UsedSourceRect = PrepareVector + ? float2(1.0f, 1.0f) + : SourceRect; + float UsedCurvatureAmount = CurvatureAmount * 0.25f; // reduced curvature + + float2 SourceArea = 1.0f / UsedSourceRect; + float2 DoubleSourceArea = SourceArea * 2.0f; + float SquareSourceAreaLength = pow(length(SourceArea), 2.0f); + float2 HalfSourceRect = UsedSourceRect * 0.5f; // Screen Curvature - float2 CurvatureUnitCoord = - Input.TexCoord - * SourceArea * 2.0f - - 1.0f; - float2 CurvatureCurve = - CurvatureUnitCoord - * pow(length(CurvatureUnitCoord), 2.0f) - / pow(length(SourceArea), 2.0f) - * CurvatureAmount * 0.25f; // reduced curvature - float2 CurvatureZoom = - 1.0f - - SourceArea * 2.0f - / pow(length(SourceArea), 2.0f) - * CurvatureAmount * 0.25f; // reduced curvature + float2 CurvatureUnitCoord = (Input.TexCoord * DoubleSourceArea) - 1.0f; + float2 CurvatureFactor = (1.0 / SquareSourceAreaLength) * UsedCurvatureAmount; + float2 CurvatureCurve = CurvatureUnitCoord * pow(length(CurvatureUnitCoord), 2.0f) * CurvatureFactor; + float2 CurvatureZoom = 1.0f - (DoubleSourceArea * CurvatureFactor); + + // todo: vector cuverture requires a correction on y-axis if screen and target size differ and y > x float2 ScreenCoord = Input.ScreenCoord / ScreenDims; ScreenCoord -= HalfSourceRect; @@ -278,11 +286,26 @@ float4 ps_main(PS_INPUT Input) : COLOR BaseCoord *= CurvatureZoom; // zoom BaseCoord += HalfSourceRect; BaseCoord += CurvatureCurve; // distortion + + float2 CurvatureCorrection = 1.0f; + + // vector cuverture correction + if (PrepareVector) + { + float ScreenRatio = ScreenDims.x / ScreenDims.y; + float TargetRatio = TargetDims.x / TargetDims.y; + + // hint: vector cuverture requires a correction on the x-axis by the amount that screen and target size differ + CurvatureCorrection.x += + (ScreenRatio / TargetRatio - 1.0f) + * (1.0f + SquareSourceAreaLength * UsedCurvatureAmount); + } + // the floowing coordinates are used for effects float2 BaseCoordCentered = Input.TexCoord; BaseCoordCentered -= HalfSourceRect; - BaseCoordCentered *= CurvatureZoom; // zoom - BaseCoordCentered += CurvatureCurve; // distortion + BaseCoordCentered *= CurvatureZoom * CurvatureCorrection; // zoom + BaseCoordCentered += CurvatureCurve * CurvatureCorrection; // distortion float2 BaseAreaCoord = BaseCoord; BaseAreaCoord *= SourceArea; @@ -302,6 +325,7 @@ float4 ps_main(PS_INPUT Input) : COLOR float4 BaseColor = tex2D(DiffuseSampler, BaseCoord); BaseColor.a = 1.0f; + // BaseColor.rgb = 1.0f; // Vignetting Simulation (may affect bloom) float2 VignetteCoord = BaseAreaCoordCentered; @@ -368,7 +392,7 @@ float4 ps_main(PS_INPUT Input) : COLOR // todo: there is an offset which can be noticed at lower prescale in high-resolution float2 ScanlinePrescaleOffset = 0.0f; - float InnerSine = BaseCoordCentered.y * ScanlineScale * SourceDims.y; + float InnerSine = BaseCoord.y * ScanlineScale * SourceDims.y; float ScanJitter = ScanlineOffset * SourceDims.y; float ScanBrightMod = sin(InnerSine * PI + ScanJitter + ScanlinePrescaleOffset); float3 ScanColor = lerp(1.0f, (pow(ScanBrightMod * ScanBrightMod, ScanlineHeight) * ScanlineBrightScale + 1.0f + ScanlineBrightOffset) * 0.5f, ScanlineAlpha); @@ -377,7 +401,9 @@ float4 ps_main(PS_INPUT Input) : COLOR } // Output - float4 Output = BaseColor * Input.Color; + float4 Output = PrepareVector + ? BaseColor * (Input.Color + float4(1.0f, 1.0f, 1.0f, 0.0f)) + : BaseColor * Input.Color; Output.a = 1.0f; // Light Reflection Simulation (may not affect bloom) diff --git a/hlsl/primary.fx b/hlsl/primary.fx index fd53bf572e8..ed73750185d 100644 --- a/hlsl/primary.fx +++ b/hlsl/primary.fx @@ -47,8 +47,7 @@ struct PS_INPUT //----------------------------------------------------------------------------- uniform float2 ScreenDims; -uniform float PostPass; -uniform float FixedAlpha; +uniform bool PostPass; uniform float Brighten; VS_OUTPUT vs_main(VS_INPUT Input) @@ -59,9 +58,11 @@ VS_OUTPUT vs_main(VS_INPUT Input) Output.Position.xy /= ScreenDims; Output.Position.y = 1.0f - Output.Position.y; Output.Position.xy -= 0.5f; - Output.Position *= float4(2.0f, 2.0f, 1.0f, 1.0f); + Output.Position.xy *= 2.0f; + + Output.TexCoord = PostPass ? (Input.Position.xy / ScreenDims) : Input.TexCoord; + Output.Color = Input.Color; - Output.TexCoord = lerp(Input.TexCoord, Input.Position.xy / ScreenDims, PostPass); return Output; } @@ -86,8 +87,6 @@ technique TestTechnique { Lighting = FALSE; - //Sampler[0] = <DiffuseSampler>; - VertexShader = compile vs_2_0 vs_main(); PixelShader = compile ps_2_0 ps_main(); } diff --git a/hlsl/simple.fx b/hlsl/simple.fx deleted file mode 100644 index e26ca3fbb36..00000000000 --- a/hlsl/simple.fx +++ /dev/null @@ -1,93 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ryan Holtz,ImJezze -//----------------------------------------------------------------------------- -// Effect File Variables -//----------------------------------------------------------------------------- - -texture DiffuseTexture; - -sampler DiffuseSampler = sampler_state -{ - Texture = <DiffuseTexture>; - MipFilter = LINEAR; - MinFilter = LINEAR; - MagFilter = LINEAR; - AddressU = CLAMP; - AddressV = CLAMP; - AddressW = CLAMP; -}; - -//----------------------------------------------------------------------------- -// Vertex Definitions -//----------------------------------------------------------------------------- - -struct VS_OUTPUT -{ - float4 Position : POSITION; - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; -}; - -struct VS_INPUT -{ - float3 Position : POSITION; - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; -}; - -struct PS_INPUT -{ - float4 Color : COLOR0; - float2 TexCoord : TEXCOORD0; -}; - -//----------------------------------------------------------------------------- -// Simple Vertex Shader -//----------------------------------------------------------------------------- - -uniform float2 ScreenDims; - -VS_OUTPUT vs_main(VS_INPUT Input) -{ - VS_OUTPUT Output = (VS_OUTPUT)0; - - Output.Position = float4(Input.Position.xyz, 1.0f); - 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.TexCoord = Input.Position.xy / ScreenDims; - - Output.Color = Input.Color; - - return Output; -} - -//----------------------------------------------------------------------------- -// Simple Pixel Shader -//----------------------------------------------------------------------------- - -float4 ps_main(PS_INPUT Input) : COLOR -{ - float4 texel = tex2D(DiffuseSampler, Input.TexCoord); - - return float4(texel.rgb, 1.0f); -} - -//----------------------------------------------------------------------------- -// Simple Effect -//----------------------------------------------------------------------------- - -technique TestTechnique -{ - pass Pass0 - { - Lighting = FALSE; - - Sampler[0] = <DiffuseSampler>; - - VertexShader = compile vs_2_0 vs_main(); - PixelShader = compile ps_2_0 ps_main(); - } -} diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h index 58a51eaf1cf..daaa4bde9ac 100644 --- a/src/osd/modules/render/d3d/d3dcomm.h +++ b/src/osd/modules/render/d3d/d3dcomm.h @@ -146,10 +146,11 @@ public: vec2f & get_uvstop() { return m_stop; } vec2f & get_rawdims() { return m_rawdims; } + static void compute_size_subroutine(texture_manager* texture_manager, int texwidth, int texheight, int* p_width, int* p_height); + private: void prescale(); void compute_size(int texwidth, int texheight); - void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height); texture_manager * m_texture_manager; // texture manager pointer diff --git a/src/osd/modules/render/d3d/d3dhlsl.c b/src/osd/modules/render/d3d/d3dhlsl.c index 1f244bf2184..db1448c6552 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.c +++ b/src/osd/modules/render/d3d/d3dhlsl.c @@ -45,7 +45,6 @@ #include "strconv.h" - //============================================================ // GLOBALS //============================================================ @@ -151,6 +150,7 @@ hlsl_options shaders::s_hlsl_presets[4] = }, }; + //============================================================ // PROTOTYPES //============================================================ @@ -165,6 +165,7 @@ static void get_vector(const char *data, int count, float *out, int report_error typedef HRESULT (WINAPI *direct3dx9_loadeffect_ptr)(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, const D3DXMACRO *pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT *ppEffect, LPD3DXBUFFER *ppCompilationErrors); static direct3dx9_loadeffect_ptr g_load_effect = NULL; + //============================================================ // shader manager constructor //============================================================ @@ -188,7 +189,6 @@ shaders::shaders() } - //============================================================ // shaders destructor //============================================================ @@ -214,7 +214,6 @@ shaders::~shaders() } - //============================================================ // shaders::window_save //============================================================ @@ -222,7 +221,9 @@ shaders::~shaders() void shaders::window_save() { if (!master_enable || !d3dintf->post_fx_available) + { return; + } HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), snap_width, snap_height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &snap_copy_texture); if (result != D3D_OK) @@ -245,7 +246,6 @@ void shaders::window_save() } - //============================================================ // shaders::window_record //============================================================ @@ -253,15 +253,21 @@ void shaders::window_save() void shaders::window_record() { if (!master_enable || !d3dintf->post_fx_available) + { return; + } windows_options &options = downcast<windows_options &>(machine->options()); const char *filename = options.d3d_hlsl_write(); if (avi_output_file != NULL) + { end_avi_recording(); + } else if (filename[0] != 0) + { begin_avi_recording(filename); + } } @@ -272,7 +278,9 @@ void shaders::window_record() void shaders::avi_update_snap(surface *surface) { if (!master_enable || !d3dintf->post_fx_available) + { return; + } D3DLOCKED_RECT rect; @@ -302,13 +310,18 @@ void shaders::avi_update_snap(surface *surface) DWORD *src = (DWORD *)((BYTE *)rect.pBits + srcy * rect.Pitch); UINT32 *dst = &avi_snap.pix32(srcy); - for(int x = 0; x < snap_width; x++) + for (int x = 0; x < snap_width; x++) + { *dst++ = *src++; + } } // unlock result = (*d3dintf->surface.unlock_rect)(avi_copy_surface); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result); + if (result != D3D_OK) + { + osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result); + } } @@ -320,7 +333,9 @@ void shaders::avi_update_snap(surface *surface) void shaders::render_snapshot(surface *surface) { if (!master_enable || !d3dintf->post_fx_available) + { return; + } D3DLOCKED_RECT rect; @@ -346,9 +361,9 @@ void shaders::render_snapshot(surface *surface) return; } - for(int cy = 0; cy < 2; cy++) + for (int cy = 0; cy < 2; cy++) { - for(int cx = 0; cx < 2; cx++) + for (int cx = 0; cx < 2; cx++) { // loop over Y for (int srcy = 0; srcy < snap_height / 2; srcy++) @@ -358,8 +373,10 @@ void shaders::render_snapshot(surface *surface) DWORD *src = (DWORD *)((BYTE *)rect.pBits + toty * rect.Pitch + totx * 4); UINT32 *dst = &avi_snap.pix32(srcy); - for(int x = 0; x < snap_width / 2; x++) + for (int x = 0; x < snap_width / 2; x++) + { *dst++ = *src++; + } } int idx = cy * 2 + cx; @@ -367,7 +384,9 @@ void shaders::render_snapshot(surface *surface) emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); file_error filerr = open_next(d3d, file, NULL, "png", idx); if (filerr != FILERR_NONE) + { return; + } // add two text entries describing the image std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(build_version); @@ -379,7 +398,9 @@ void shaders::render_snapshot(surface *surface) // now do the actual work png_error error = png_write_bitmap(file, &pnginfo, avi_snap, 1 << 24, NULL); if (error != PNGERR_NONE) + { osd_printf_error("Error generating PNG for HLSL snapshot: png_error = %d\n", error); + } // free any data allocated png_free(&pnginfo); @@ -390,25 +411,25 @@ void shaders::render_snapshot(surface *surface) result = (*d3dintf->surface.unlock_rect)(snap_copy_target); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result); - if(snap_texture != NULL) + if (snap_texture != NULL) { (*d3dintf->texture.release)(snap_texture); snap_texture = NULL; } - if(snap_target != NULL) + if (snap_target != NULL) { (*d3dintf->surface.release)(snap_target); snap_target = NULL; } - if(snap_copy_texture != NULL) + if (snap_copy_texture != NULL) { (*d3dintf->texture.release)(snap_copy_texture); snap_copy_texture = NULL; } - if(snap_copy_target != NULL) + if (snap_copy_target != NULL) { (*d3dintf->surface.release)(snap_copy_target); snap_copy_target = NULL; @@ -423,13 +444,17 @@ void shaders::render_snapshot(surface *surface) void shaders::record_texture() { if (!master_enable || !d3dintf->post_fx_available) + { return; + } surface *surface = avi_final_target; // ignore if nothing to do if (avi_output_file == NULL || surface == NULL) + { return; + } // get the current time attotime curtime = machine->time(); @@ -462,10 +487,14 @@ void shaders::record_texture() void shaders::end_avi_recording() { if (!master_enable || !d3dintf->post_fx_available) + { return; + } if (avi_output_file != NULL) + { avi_close(avi_output_file); + } avi_output_file = NULL; avi_frame = 0; @@ -511,7 +540,9 @@ void shaders::toggle() void shaders::begin_avi_recording(const char *name) { if (!master_enable || !d3dintf->post_fx_available) + { return; + } // stop any existing recording end_avi_recording(); @@ -668,20 +699,27 @@ void shaders::remove_render_target(render_target *rt) void shaders::set_texture(texture_info *texture) { if (!master_enable || !d3dintf->post_fx_available) + { return; + } - if(texture != NULL) + if (texture != NULL) { paused = texture->paused(); texture->advance_frame(); } + // set initial texture to use texture_info *default_texture = d3d->get_default_texture(); default_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex()); if (options->yiq_enable) + { yiq_encode_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex()); + } else + { color_effect->set_texture("Diffuse", (texture == NULL) ? default_texture->get_finaltex() : texture->get_finaltex()); + } } @@ -692,7 +730,9 @@ void shaders::set_texture(texture_info *texture) void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *renderer) { if (!d3dintf->post_fx_available) + { return; + } g_load_effect = (direct3dx9_loadeffect_ptr)GetProcAddress(d3dintf->libhandle, "D3DXCreateEffectFromFileW"); if (g_load_effect == NULL) @@ -729,7 +769,7 @@ void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *rende prescale_force_x = winoptions.d3d_hlsl_prescale_x(); prescale_force_y = winoptions.d3d_hlsl_prescale_y(); - if(preset == -1) + if (preset == -1) { options->shadow_mask_alpha = winoptions.screen_shadow_mask_alpha(); options->shadow_mask_count_x = winoptions.screen_shadow_mask_count_x(); @@ -802,7 +842,6 @@ void shaders::init(base *d3dintf, running_machine *machine, d3d::renderer *rende } - //============================================================ // shaders::init_fsfx_quad //============================================================ @@ -813,12 +852,16 @@ void shaders::init_fsfx_quad(void *vertbuf) // that are guaranteed to be at a fixed position so as to simply use D3DPT_TRIANGLELIST, 0, 2 // instead of having to do bookkeeping about a specific screen quad if (!master_enable || !d3dintf->post_fx_available) + { return; + } // get a pointer to the vertex buffer fsfx_vertices = (vertex *)vertbuf; if (fsfx_vertices == NULL) + { return; + } // fill in the vertexes clockwise fsfx_vertices[0].x = 0.0f; @@ -875,7 +918,6 @@ void shaders::init_fsfx_quad(void *vertbuf) } - //============================================================ // shaders::create_resources //============================================================ @@ -883,10 +925,15 @@ void shaders::init_fsfx_quad(void *vertbuf) int shaders::create_resources(bool reset) { if (!master_enable || !d3dintf->post_fx_available) + { return 0; + } HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result); + if (result != D3D_OK) + { + osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result); + } result = (*d3dintf->device.create_texture)(d3d->get_device(), 4, 4, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &black_texture); if (result != D3D_OK) @@ -941,7 +988,6 @@ int shaders::create_resources(bool reset) const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir(); default_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir); - simple_effect = new effect(this, d3d->get_device(), "simple.fx", fx_dir); post_effect = new effect(this, d3d->get_device(), "post.fx", fx_dir); prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir); phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir); @@ -954,19 +1000,21 @@ int shaders::create_resources(bool reset) downsample_effect = new effect(this, d3d->get_device(), "downsample.fx", fx_dir); vector_effect = new effect(this, d3d->get_device(), "vector.fx", fx_dir); - if (!default_effect->is_valid()) return 1; - if (!simple_effect->is_valid()) return 1; - if (!post_effect->is_valid()) return 1; - if (!prescale_effect->is_valid()) return 1; - if (!phosphor_effect->is_valid()) return 1; - if (!focus_effect->is_valid()) return 1; - if (!deconverge_effect->is_valid()) return 1; - if (!color_effect->is_valid()) return 1; - if (!yiq_encode_effect->is_valid()) return 1; - if (!yiq_decode_effect->is_valid()) return 1; - if (!bloom_effect->is_valid()) return 1; - if (!downsample_effect->is_valid()) return 1; - if (!vector_effect->is_valid()) return 1; + if (!default_effect->is_valid() || + !post_effect->is_valid() || + !prescale_effect->is_valid() || + !phosphor_effect->is_valid() || + !focus_effect->is_valid() || + !deconverge_effect->is_valid() || + !color_effect->is_valid() || + !yiq_encode_effect->is_valid() || + !yiq_decode_effect->is_valid() || + !bloom_effect->is_valid() || + !downsample_effect->is_valid() || + !vector_effect->is_valid()) + { + return 1; + } yiq_encode_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); yiq_encode_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS); @@ -1028,8 +1076,6 @@ int shaders::create_resources(bool reset) bloom_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); - simple_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); - post_effect->add_uniform("SourceDims", uniform::UT_VEC2, uniform::CU_SOURCE_DIMS); post_effect->add_uniform("SourceRect", uniform::UT_VEC2, uniform::CU_SOURCE_RECT); post_effect->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS); @@ -1070,12 +1116,13 @@ int shaders::create_resources(bool reset) void shaders::begin_draw() { if (!master_enable || !d3dintf->post_fx_available) + { return; + } curr_effect = default_effect; default_effect->set_technique("TestTechnique"); - simple_effect->set_technique("TestTechnique"); post_effect->set_technique("ScanMaskTechnique"); phosphor_effect->set_technique("TestTechnique"); focus_effect->set_technique("TestTechnique"); @@ -1085,7 +1132,10 @@ void shaders::begin_draw() yiq_decode_effect->set_technique("DecodeTechnique"); HRESULT result = (*d3dintf->device.get_render_target)(d3d->get_device(), 0, &backbuffer); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result); + if (result != D3D_OK) + { + osd_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result); + } } @@ -1103,44 +1153,54 @@ void shaders::begin_frame() // shaders::blit //============================================================ -void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYPE prim_type, - UINT32 prim_index, UINT32 prim_count) +void shaders::blit( + surface *dst, + bool clear_dst, + D3DPRIMITIVETYPE prim_type, + UINT32 prim_index, + UINT32 prim_count) { - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + HRESULT result; - curr_effect = default_effect; - curr_effect->update_uniforms(); + if (dst != NULL) + { + result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, dst); + if (result != D3D_OK) + { + osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); + } - curr_effect->set_texture("Diffuse", src); - curr_effect->set_float("PostPass", 1.0f); - curr_effect->set_float("Brighten", 1.0f); + if (clear_dst) + { + result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0); + if (result != D3D_OK) + { + osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + } + } + } - unsigned int num_passes = 0; + UINT num_passes = 0; curr_effect->begin(&num_passes, 0); for (UINT pass = 0; pass < num_passes; pass++) { curr_effect->begin_pass(pass); + // add the primitives - HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); + result = (*d3dintf->device.draw_primitive)(d3d->get_device(), prim_type, prim_index, prim_count); + if (result != D3D_OK) + { + osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); + } + curr_effect->end_pass(); } curr_effect->end(); - - curr_effect->set_float("Brighten", 0.0f); - - if (new_dst) - { - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, new_dst); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - } } + //============================================================ // shaders::end_frame //============================================================ @@ -1148,32 +1208,21 @@ void shaders::blit(surface *dst, texture *src, surface *new_dst, D3DPRIMITIVETYP void shaders::end_frame() { if (!master_enable || !d3dintf->post_fx_available) + { return; + } - if(render_snap && snap_rendered) + if (render_snap && snap_rendered) { render_snapshot(snap_target); } if (!lines_pending) - return; - - lines_pending = false; - - /*render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); - if (rt == NULL) { - return; + return; } - blit(backbuffer, rt->render_texture[1], NULL, vecbuf_type, vecbuf_index, vecbuf_count); - - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - 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);*/ + lines_pending = false; } @@ -1183,26 +1232,7 @@ void shaders::end_frame() void shaders::init_effect_info(poly_info *poly) { - if (!master_enable || !d3dintf->post_fx_available) - return; - - texture_info *texture = poly->get_texture(); - - if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && texture != NULL) - { - // Plug in all of the shader settings we're going to need - // This is extremely slow, but we're not rendering models here, - // just post-processing. - curr_effect = post_effect; - - curr_effect->set_float("ScanlineOffset", (texture->get_cur_frame() == 0) ? 0.0f : options->scanline_offset); - } - else - { - curr_effect = default_effect; - - curr_effect->set_float("FixedAlpha", 1.0f); - } + // nothing to do } @@ -1212,13 +1242,16 @@ void shaders::init_effect_info(poly_info *poly) render_target* shaders::find_render_target(texture_info *info) { - render_target *curr = targethead; UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata; UINT32 screen_index = screen_index_data >> 1; UINT32 page_index = screen_index_data & 1; - while (curr != NULL && (curr->screen_index != screen_index || curr->page_index != page_index || - curr->width != info->get_texinfo().width || curr->height != info->get_texinfo().height)) + render_target *curr = targethead; + while (curr != NULL && ( + curr->screen_index != screen_index || + curr->page_index != page_index || + curr->width != info->get_texinfo().width || + curr->height != info->get_texinfo().height)) { curr = curr->next; } @@ -1234,8 +1267,11 @@ render_target* shaders::find_render_target(texture_info *info) render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index) { render_target *curr = targethead; - - while (curr != NULL && (curr->width != width || curr->height != height || curr->screen_index != screen_index || curr->page_index != page_index)) + while (curr != NULL && ( + curr->width != width || + curr->height != height || + curr->screen_index != screen_index || + curr->page_index != page_index)) { curr = curr->next; } @@ -1251,8 +1287,10 @@ render_target* shaders::find_render_target(int width, int height, UINT32 screen_ cache_target* shaders::find_cache_target(UINT32 screen_index, int width, int height) { cache_target *curr = cachehead; - - while (curr != NULL && (curr->screen_index != screen_index || curr->width != width || curr->height != height)) + while (curr != NULL && ( + curr->screen_index != screen_index || + curr->width != width || + curr->height != height)) { curr = curr->next; } @@ -1260,202 +1298,117 @@ cache_target* shaders::find_cache_target(UINT32 screen_index, int width, int hei return curr; } -void shaders::ntsc_pass(render_target *rt, vec2f &sourcedims, vec2f &delta) +int shaders::ntsc_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) { - UINT num_passes = 0; + int next_index = source_index; - if(options->yiq_enable) + if (!options->yiq_enable) { - // Convert our signal into YIQ - curr_effect = yiq_encode_effect; - curr_effect->update_uniforms(); - - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[4]); - - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); - - // Convert our signal from YIQ - curr_effect = yiq_decode_effect; - - curr_effect->set_texture("Composite", rt->render_texture[4]); - curr_effect->set_texture("Diffuse", curr_texture->get_finaltex()); - curr_effect->update_uniforms(); - - result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]); + return next_index; + } - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + // Convert our signal into YIQ + curr_effect = yiq_encode_effect; + curr_effect->update_uniforms(); + + // initial "Diffuse" texture is set in shaders::set_texture() - curr_effect->begin(&num_passes, 0); + next_index = rt->next_index(next_index); + blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); + // Convert our signal from YIQ + curr_effect = yiq_decode_effect; + curr_effect->update_uniforms(); + curr_effect->set_texture("Composite", rt->native_texture[next_index]); + curr_effect->set_texture("Diffuse", curr_texture->get_finaltex()); - curr_effect = color_effect; + next_index = rt->next_index(next_index); + blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); + + color_effect->set_texture("Diffuse", rt->native_texture[next_index]); - curr_effect->set_texture("Diffuse", rt->render_texture[3]); - } + return next_index; } -void shaders::color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims) +int shaders::color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) { - UINT num_passes = 0; + int next_index = source_index; curr_effect = color_effect; curr_effect->update_uniforms(); + + // initial "Diffuse" texture is set in shaders::set_texture() or the result of shaders::ntsc_pass() - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->smalltarget); - - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } + next_index = rt->next_index(next_index); + blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - curr_effect->end(); + return next_index; } -void shaders::prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims) +int shaders::prescale_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) { - UINT num_passes = 0; + int next_index = source_index; curr_effect = prescale_effect; curr_effect->update_uniforms(); - curr_effect->set_texture("Diffuse", rt->smalltexture); - - curr_effect->begin(&num_passes, 0); + curr_effect->set_texture("Diffuse", rt->native_texture[next_index]); - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->prescaletarget); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - curr_effect->end(); + return next_index; } -void shaders::deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims) +int shaders::deconverge_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) { - UINT num_passes = 0; + int next_index = source_index; curr_effect = deconverge_effect; curr_effect->update_uniforms(); - curr_effect->set_texture("Diffuse", rt->prescaletexture); - - curr_effect->begin(&num_passes, 0); - - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); - curr_effect->end(); + return next_index; } -void shaders::defocus_pass(render_target *rt, vec2f &texsize) +int shaders::defocus_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) { - UINT num_passes = 0; + int next_index = source_index; + + float defocus_x = options->defocus[0]; + float defocus_y = options->defocus[1]; + bool focus_enable = defocus_x != 0.0f || defocus_y != 0.0f; + + if (!focus_enable) + { + return next_index; + } float prescale[2] = { (float)hlsl_prescale_x, (float)hlsl_prescale_y }; // Defocus pass 1 curr_effect = focus_effect; curr_effect->update_uniforms(); - curr_effect->set_texture("Diffuse", rt->render_texture[2]); + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); curr_effect->set_vector("Prescale", 2, prescale); - curr_effect->begin(&num_passes, 0); - - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); // Defocus pass 2 + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); - curr_effect->set_texture("Diffuse", rt->render_texture[0]); - - curr_effect->begin(&num_passes, 0); - - result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result); + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], false, D3DPT_TRIANGLELIST, 0, 2); - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); + return next_index; } -void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable) +int shaders::phosphor_pass(render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum) { - UINT num_passes = 0; + int next_index = source_index; phosphor_passthrough = false; @@ -1464,150 +1417,145 @@ void shaders::phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, float rtsize[2] = { rt->target_width, rt->target_height }; curr_effect->set_vector("TargetDims", 2, rtsize); - curr_effect->set_texture("Diffuse", focus_enable ? rt->render_texture[1] : rt->render_texture[2]); + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); curr_effect->set_texture("LastPass", ct->last_texture); - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2); + + phosphor_passthrough = true; // Pass along our phosphor'd screen - phosphor_passthrough = true; curr_effect->update_uniforms(); - curr_effect->set_texture("Diffuse", rt->render_texture[0]); - curr_effect->set_texture("LastPass", rt->render_texture[0]); - - result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, ct->last_target); // Avoid changing targets due to page flipping - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - curr_effect->begin(&num_passes, 0); + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); + curr_effect->set_texture("LastPass", rt->prescale_texture[next_index]); - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } + // Avoid changing targets due to page flipping + blit(ct->last_target, true, D3DPT_TRIANGLELIST, 0, 2); - curr_effect->end(); + return next_index; } -void shaders::post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum, bool prepare_bloom) +int shaders::post_pass(render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom) { - UINT num_passes = 0; + int next_index = source_index; - float prescale[2] = { (float)hlsl_prescale_x, (float)hlsl_prescale_y }; - bool orientation_swap_xy = (d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY; + texture_info *texture = poly->get_texture(); + + bool prepare_vector = PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; + float prescale[2] = { + prepare_vector ? 1.0f : (float)hlsl_prescale_x, + prepare_vector ? 1.0f : (float)hlsl_prescale_y }; + float target_dims[2] = { + poly->get_prim_width(), + poly->get_prim_height() }; + 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; - + curr_effect = post_effect; curr_effect->update_uniforms(); curr_effect->set_texture("ShadowTexture", shadow_texture == NULL ? NULL : shadow_texture->get_finaltex()); - curr_effect->set_texture("DiffuseTexture", rt->render_texture[0]); + curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]); + curr_effect->set_float("ScanlineOffset", texture->get_cur_frame() == 0 ? 0.0f : options->scanline_offset); curr_effect->set_vector("Prescale", 2, prescale); + curr_effect->set_vector("TargetDims", 2, target_dims); curr_effect->set_bool("OrientationSwapXY", orientation_swap_xy); curr_effect->set_bool("RotationSwapXY", rotation_swap_xy); curr_effect->set_bool("PrepareBloom", prepare_bloom); + curr_effect->set_bool("PrepareVector", prepare_vector); - d3d->set_wrap(D3DTADDRESS_MIRROR); + if (prepare_vector) + { + int texture_width = 0; + int texture_height = 0; - HRESULT result = prepare_bloom - ? (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]) // target which is used by bloom effect - : (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[2]); + texture_info::compute_size_subroutine(d3d->get_texture_manager(), (int)target_dims[0], (int)target_dims[1], &texture_width, &texture_height); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(1,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + float source_dims[2] = { (float)texture_width, (float)texture_height }; + float source_rect[2] = { target_dims[0] / texture_width , target_dims[1] / texture_height }; - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); + // override uniforms + curr_effect->set_vector("SourceDims", 2, source_dims); + curr_effect->set_vector("SourceRect", 2, source_rect); } - curr_effect->end(); + d3d->set_wrap(D3DTADDRESS_MIRROR); + next_index = rt->next_index(next_index); + blit(prepare_bloom ? rt->native_target[next_index] : rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); + d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(poly->get_texture()->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP); + + return next_index; } -void shaders::bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum) +int shaders::downsample_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) { - UINT num_passes = 0; - - float prescale[2] = { (float)hlsl_prescale_x, (float)hlsl_prescale_y }; + int next_index = source_index; curr_effect = downsample_effect; curr_effect->update_uniforms(); - curr_effect->set_float("BloomRescale", options->raster_bloom_scale); - curr_effect->set_vector("Prescale", 2, prescale); float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height(); int bloom_index = 0; float bloom_width = rt->target_width; float bloom_height = rt->target_height; - float bloom_dims[11][2]; - for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) + for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) { bloom_dims[bloom_index][0] = bloom_width; bloom_dims[bloom_index][1] = bloom_height; - curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]); - - curr_effect->begin(&num_passes, 0); - - curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[3] : rt->bloom_texture[bloom_index - 1]); - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->bloom_target[bloom_index]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - //result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } + curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]); + curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->native_texture[next_index] : rt->bloom_texture[bloom_index - 1]); - curr_effect->end(); + blit(rt->bloom_target[bloom_index], true, poly->get_type(), vertnum, poly->get_count()); bloom_index++; bloom_width *= 0.5f; bloom_height *= 0.5f; } + + bloom_count = bloom_index; + + return next_index; +} + +int shaders::bloom_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +{ + int next_index = source_index; + + bool prepare_vector = PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; + float prescale[2] = { + prepare_vector ? 1.0f : (float)hlsl_prescale_x / 2.0f, + prepare_vector ? 1.0f : (float)hlsl_prescale_y / 2.0f }; // no prescale for vector, half prescale for raster + float bloom_rescale = prepare_vector + ? options->vector_bloom_scale + : options->raster_bloom_scale; curr_effect = bloom_effect; curr_effect->update_uniforms(); + curr_effect->set_vector("Prescale", 2, prescale); - float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight }; - float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight }; - float weight89A[3] = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight }; + float weight0123[4] = { + options->bloom_level0_weight, + options->bloom_level1_weight * bloom_rescale, + options->bloom_level2_weight * bloom_rescale, + options->bloom_level3_weight * bloom_rescale + }; + float weight4567[4] = { + options->bloom_level4_weight * bloom_rescale, + options->bloom_level5_weight * bloom_rescale, + options->bloom_level6_weight * bloom_rescale, + options->bloom_level7_weight * bloom_rescale + }; + float weight89A[3] = { + options->bloom_level8_weight * bloom_rescale, + options->bloom_level9_weight * bloom_rescale, + options->bloom_level10_weight * bloom_rescale + }; curr_effect->set_vector("Level0123Weight", 4, weight0123); curr_effect->set_vector("Level4567Weight", 4, weight4567); curr_effect->set_vector("Level89AWeight", 3, weight89A); @@ -1618,107 +1566,57 @@ void shaders::bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_i curr_effect->set_vector("Level89Size", 4, bloom_dims[8]); curr_effect->set_vector("LevelASize", 2, bloom_dims[10]); - curr_effect->set_texture("DiffuseA", rt->render_texture[2]); - - curr_effect->set_vector("Prescale", 2, prescale); + curr_effect->set_texture("DiffuseA", rt->prescale_texture[next_index]); char name[9] = "Diffuse*"; - for(int index = 1; index < bloom_index; index++) + for (int index = 1; index < bloom_count; index++) { name[7] = 'A' + index; curr_effect->set_texture(name, rt->bloom_texture[index - 1]); } - for(int index = bloom_index; index < 11; index++) + for (int index = bloom_count; index < 11; index++) { name[7] = 'A' + index; curr_effect->set_texture(name, black_texture); } - curr_effect->begin(&num_passes, 0); - - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); - curr_effect->end(); + return next_index; } -void shaders::screen_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum) -{ - UINT num_passes = 0; +int shaders::screen_pass(render_target *rt, int source_index, poly_info *poly, int vertnum) +{ + int next_index = source_index; + + bool prepare_vector = PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable; - curr_effect = simple_effect; + curr_effect = default_effect; curr_effect->update_uniforms(); - curr_effect->set_texture("DiffuseTexture", rt->render_texture[1]); - HRESULT 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); + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); + curr_effect->set_bool("PostPass", true); + curr_effect->set_float("Brighten", prepare_vector ? 1.0f : 0.0f); - curr_effect->begin(&num_passes, 0); + blit(backbuffer, true, poly->get_type(), vertnum, poly->get_count()); - for (UINT pass = 0; pass < num_passes; pass++) + if (avi_output_file != NULL) { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); + blit(avi_final_target, false, poly->get_type(), vertnum, poly->get_count()); } - curr_effect->end(); - - // Scanlines and shadow mask, at high res for AVI logging - if(avi_output_file != NULL) + if (render_snap) { - result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, avi_final_target); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); - } - - if(render_snap) - { - result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, snap_target); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); + blit(snap_target, false, poly->get_type(), vertnum, poly->get_count()); snap_rendered = true; } + + return next_index; } + //============================================================ // shaders::render_quad //============================================================ @@ -1726,48 +1624,50 @@ void shaders::screen_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_ void shaders::render_quad(poly_info *poly, int vertnum) { if (!master_enable || !d3dintf->post_fx_available) + { return; + } - UINT num_passes = 0; curr_texture = poly->get_texture(); - if(PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != NULL) + if (PRIMFLAG_GET_SCREENTEX(d3d->get_last_texture_flags()) && curr_texture != NULL) { render_target *rt = find_render_target(curr_texture); if (rt == NULL) { return; } + cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_texinfo().width, curr_texture->get_texinfo().height); - vec2f& sourcedims = curr_texture->get_rawdims(); - vec2f delta = curr_texture->get_uvstop() - curr_texture->get_uvstart(); - vec2f texsize(rt->width, rt->height); - float defocus_x = options->defocus[0]; - float defocus_y = options->defocus[1]; - bool focus_enable = defocus_x != 0.0f || defocus_y != 0.0f; - - ntsc_pass(rt, sourcedims, delta); - color_convolution_pass(rt, texsize, sourcedims); - prescale_pass(rt, texsize, sourcedims); - deconverge_pass(rt, texsize, delta, sourcedims); - if (focus_enable) - { - defocus_pass(rt, texsize); - } - phosphor_pass(rt, ct, texsize, focus_enable); - post_pass(rt, texsize, delta, sourcedims, poly, vertnum, true); - post_pass(rt, texsize, delta, sourcedims, poly, vertnum, false); - bloom_pass(rt, texsize, delta, poly, vertnum); - screen_pass(rt, texsize, delta, poly, vertnum); + int next_index = 0; + + next_index = ntsc_pass(rt, next_index, poly, vertnum); + next_index = color_convolution_pass(rt, next_index, poly, vertnum); + next_index = prescale_pass(rt, next_index, poly, vertnum); + next_index = deconverge_pass(rt, next_index, poly, vertnum); + next_index = defocus_pass(rt, next_index, poly, vertnum); + next_index = phosphor_pass(rt, ct, next_index, poly, vertnum); + + // create bloom textures + int phosphor_index = next_index; + next_index = post_pass(rt, next_index, poly, vertnum, true); + next_index = downsample_pass(rt, next_index, poly, vertnum); + + // apply bloom textures + next_index = phosphor_index; + next_index = post_pass(rt, next_index, poly, vertnum, false); + next_index = bloom_pass(rt, next_index, poly, vertnum); + + // render on screen + next_index = screen_pass(rt, next_index, poly, vertnum); curr_texture->increment_frame_count(); curr_texture->mask_frame_count(options->yiq_phase_count); options->params_dirty = false; - } - else if(PRIMFLAG_GET_VECTOR(poly->get_flags()) && vector_enable) + else if (PRIMFLAG_GET_VECTOR(poly->get_flags()) && vector_enable) { render_target *rt = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0); if (rt == NULL) @@ -1777,37 +1677,23 @@ void shaders::render_quad(poly_info *poly, int vertnum) lines_pending = true; - curr_effect = vector_effect; - curr_effect->update_uniforms(); + int next_index = 0; float time_params[2] = { 0.0f, 0.0f }; float length_params[3] = { poly->get_line_length(), options->vector_length_scale, options->vector_length_ratio }; + + curr_effect = vector_effect; + curr_effect->update_uniforms(); curr_effect->set_vector("TimeParams", 2, time_params); curr_effect->set_vector("LengthParams", 3, length_params); - curr_effect->begin(&num_passes, 0); - - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); + blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); - for (UINT pass = 0; pass < num_passes; pass++) + HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer); + if (result != D3D_OK) { - curr_effect->begin_pass(pass); - // add the primitives - HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); + osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); } - - curr_effect->end(); - - 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); - - curr_effect = default_effect; - curr_effect->update_uniforms(); - - curr_effect->set_float("FixedAlpha", 1.0f); } else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable) { @@ -1816,167 +1702,58 @@ void shaders::render_quad(poly_info *poly, int vertnum) { return; } + + cache_target *ct = find_cache_target(rt->screen_index, rt->width, rt->height); - /* Bloom, todo: merge with bloom_pass() */ - curr_effect = downsample_effect; - curr_effect->update_uniforms(); - curr_effect->set_float("BloomRescale", options->vector_bloom_scale); - curr_effect->set_bool("PrepareVector", true); - - float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height(); - int bloom_index = 0; - float bloom_width = rt->target_width; - float bloom_height = rt->target_height; - float bloom_dims[11][2]; - for(; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f) - { - bloom_dims[bloom_index][0] = bloom_width; - bloom_dims[bloom_index][1] = bloom_height; - curr_effect->set_vector("TargetSize", 2, bloom_dims[bloom_index]); - - curr_effect->begin(&num_passes, 0); - - curr_effect->set_texture("DiffuseTexture", (bloom_index == 0) ? rt->render_texture[0] : rt->bloom_texture[bloom_index - 1]); - - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->bloom_target[bloom_index]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); - - bloom_index++; - bloom_width *= 0.5f; - bloom_height *= 0.5f; - } + int next_index = 0; - // Bloom composite pass - curr_effect = bloom_effect; + curr_effect = default_effect; curr_effect->update_uniforms(); - float weight0123[4] = { options->bloom_level0_weight, options->bloom_level1_weight, options->bloom_level2_weight, options->bloom_level3_weight }; - float weight4567[4] = { options->bloom_level4_weight, options->bloom_level5_weight, options->bloom_level6_weight, options->bloom_level7_weight }; - float weight89A[3] = { options->bloom_level8_weight, options->bloom_level9_weight, options->bloom_level10_weight }; - curr_effect->set_vector("Level0123Weight", 4, weight0123); - curr_effect->set_vector("Level4567Weight", 4, weight4567); - curr_effect->set_vector("Level89AWeight", 3, weight89A); - curr_effect->set_vector("Level01Size", 4, bloom_dims[0]); - curr_effect->set_vector("Level23Size", 4, bloom_dims[2]); - curr_effect->set_vector("Level45Size", 4, bloom_dims[4]); - curr_effect->set_vector("Level67Size", 4, bloom_dims[6]); - curr_effect->set_vector("Level89Size", 4, bloom_dims[8]); - curr_effect->set_vector("LevelASize", 2, bloom_dims[10]); - - curr_effect->set_texture("DiffuseA", rt->render_texture[0]); - - curr_effect->set_bool("PrepareVector", true); - - char name[9] = "Diffuse*"; - for(int index = 1; index < bloom_index; index++) - { - name[7] = 'A' + index; - curr_effect->set_texture(name, rt->bloom_texture[index - 1]); - } - for(int index = bloom_index; index < 11; index++) - { - name[7] = 'A' + index; - curr_effect->set_texture(name, black_texture); - } - - curr_effect->begin(&num_passes, 0); + curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]); + curr_effect->set_bool("PostPass", true); + curr_effect->set_float("Brighten", 1.0f); - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[1]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + next_index = rt->next_index(next_index); + blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count()); - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } + next_index = phosphor_pass(rt, ct, next_index, poly, vertnum); - curr_effect->end(); - - /* Phosphor, todo: merge with phosphor_pass() */ - phosphor_passthrough = false; - - curr_effect = phosphor_effect; - curr_effect->update_uniforms(); + // create bloom textures + int phosphor_index = next_index; + next_index = post_pass(rt, next_index, poly, vertnum, true); + next_index = downsample_pass(rt, next_index, poly, vertnum); - float target_dims[2] = { d3d->get_width(), d3d->get_height() }; - curr_effect->set_vector("TargetDims", 2, target_dims); - curr_effect->set_texture("Diffuse", rt->render_texture[1]); - curr_effect->set_texture("LastPass", rt->render_texture[2]); + // apply bloom textures + next_index = phosphor_index; + next_index = post_pass(rt, next_index, poly, vertnum, false); + next_index = bloom_pass(rt, next_index, poly, vertnum); - result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[3]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); + // render on screen + next_index = screen_pass(rt, next_index, poly, vertnum); - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) + HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer); + if (result != D3D_OK) { - curr_effect->begin_pass(pass); - // add the primitives - result = (*d3dintf->device.draw_primitive)(d3d->get_device(), D3DPT_TRIANGLELIST, 0, 2); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); + osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); } - curr_effect->end(); - - blit(rt->target[2], rt->render_texture[3], NULL, poly->get_type(), vertnum, poly->get_count()); - blit(backbuffer, rt->render_texture[3], backbuffer, poly->get_type(), vertnum, poly->get_count()); - - result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, rt->target[0]); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); - result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); - 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); - lines_pending = false; } else { curr_effect = default_effect; curr_effect->update_uniforms(); + curr_effect->set_bool("PostPass", false); + curr_effect->set_float("Brighten", 0.0f); - curr_effect->set_float("PostPass", 0.0f); - - curr_effect->begin(&num_passes, 0); - - for (UINT pass = 0; pass < num_passes; pass++) - { - curr_effect->begin_pass(pass); - // add the primitives - HRESULT result = (*d3dintf->device.draw_primitive)(d3d->get_device(), poly->get_type(), vertnum, poly->get_count()); - if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result); - curr_effect->end_pass(); - } - - curr_effect->end(); + blit(NULL, false, poly->get_type(), vertnum, poly->get_count()); } curr_texture = NULL; } - //============================================================ // shaders::end_draw //============================================================ @@ -1984,7 +1761,9 @@ void shaders::render_quad(poly_info *poly, int vertnum) void shaders::end_draw() { if (!master_enable || !d3dintf->post_fx_available) + { return; + } (*d3dintf->surface.release)(backbuffer); } @@ -2056,6 +1835,7 @@ void shaders::create_vector_target(render_primitive *prim) } } + //============================================================ // shaders::add_render_target - register a render target //============================================================ @@ -2104,7 +1884,7 @@ bool shaders::add_render_target(renderer* d3d, texture_info* info, int width, in target->height = d3d->get_height(); } - HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->target[0]); + HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->prescale_target[0]); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result); result = (*d3dintf->device.clear)(d3d->get_device(), 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result); @@ -2136,6 +1916,7 @@ bool shaders::add_render_target(renderer* d3d, texture_info* info, int width, in return true; } + //============================================================ // shaders::enumerate_screens //============================================================ @@ -2192,13 +1973,16 @@ bool shaders::register_texture(texture_info *texture) hlsl_prescale_y = ((hlsl_prescale_y == 0) ? 1 : hlsl_prescale_y); if (!add_render_target(d3d, texture, width, height, xscale * hlsl_prescale_x, yscale * hlsl_prescale_y)) + { return false; + } options->params_dirty = true; return true; } + //============================================================ // shaders::delete_resources //============================================================ @@ -2206,7 +1990,9 @@ bool shaders::register_texture(texture_info *texture) void shaders::delete_resources(bool reset) { if (!master_enable || !d3dintf->post_fx_available) + { return; + } initialized = false; @@ -2246,11 +2032,6 @@ void shaders::delete_resources(bool reset) delete default_effect; default_effect = NULL; } - if (simple_effect != NULL) - { - delete simple_effect; - simple_effect = NULL; - } if (post_effect != NULL) { delete post_effect; @@ -2343,25 +2124,25 @@ void shaders::delete_resources(bool reset) static void get_vector(const char *data, int count, float *out, int report_error) { - if (count > 3) + if (count > 3 && + sscanf(data, "%f,%f,%f,%f", &out[0], &out[1], &out[2], &out[3]) < 4 && report_error) { - if (sscanf(data, "%f,%f,%f,%f", &out[0], &out[1], &out[2], &out[3]) < 4 && report_error) - osd_printf_error("Illegal quad vector value = %s\n", data); + osd_printf_error("Illegal quad vector value = %s\n", data); } - else if(count > 2) + else if (count > 2 && + sscanf(data, "%f,%f,%f", &out[0], &out[1], &out[2]) < 3 && report_error) { - if (sscanf(data, "%f,%f,%f", &out[0], &out[1], &out[2]) < 3 && report_error) - osd_printf_error("Illegal triple vector value = %s\n", data); + osd_printf_error("Illegal triple vector value = %s\n", data); } - else if(count > 1) + else if (count > 1 && + sscanf(data, "%f,%f", &out[0], &out[1]) < 2 && report_error) { - if (sscanf(data, "%f,%f", &out[0], &out[1]) < 2 && report_error) - osd_printf_error("Illegal double vector value = %s\n", data); + osd_printf_error("Illegal double vector value = %s\n", data); } - else if(count > 0) + else if (count > 0 && + sscanf(data, "%f", &out[0]) < 1 && report_error) { - if (sscanf(data, "%f", &out[0]) < 1 && report_error) - osd_printf_error("Illegal single vector value = %s\n", data); + osd_printf_error("Illegal single vector value = %s\n", data); } } @@ -2395,8 +2176,15 @@ static slider_state *slider_alloc(running_machine &machine, const char *title, I static INT32 slider_set(float *option, float scale, const char *fmt, std::string *str, INT32 newval) { - if (option != NULL && newval != SLIDER_NOCHANGE) *option = (float)newval * scale; - if (str != NULL) strprintf(*str, fmt, *option); + if (option != NULL && newval != SLIDER_NOCHANGE) + { + *option = (float)newval * scale; + } + if (str != NULL) + { + strprintf(*str, fmt, *option); + } + return floor(*option / scale + 0.5f); } @@ -2408,18 +2196,32 @@ static INT32 slider_shadow_mask_alpha(running_machine &machine, void *arg, std:: static INT32 slider_shadow_mask_x_count(running_machine &machine, void *arg, std::string *str, INT32 newval) { hlsl_options *options = (hlsl_options*)arg; - if (newval != SLIDER_NOCHANGE) options->shadow_mask_count_x = newval; - if (str != NULL) strprintf(*str, "%d", options->shadow_mask_count_x); + if (newval != SLIDER_NOCHANGE) + { + options->shadow_mask_count_x = newval; + } + if (str != NULL) + { + strprintf(*str, "%d", options->shadow_mask_count_x); + } options->params_dirty = true; + return options->shadow_mask_count_x; } static INT32 slider_shadow_mask_y_count(running_machine &machine, void *arg, std::string *str, INT32 newval) { hlsl_options *options = (hlsl_options*)arg; - if (newval != SLIDER_NOCHANGE) options->shadow_mask_count_y = newval; - if (str != NULL) strprintf(*str, "%d", options->shadow_mask_count_y); + if (newval != SLIDER_NOCHANGE) + { + options->shadow_mask_count_y = newval; + } + if (str != NULL) + { + strprintf(*str, "%d", options->shadow_mask_count_y); + } options->params_dirty = true; + return options->shadow_mask_count_y; } @@ -2831,6 +2633,7 @@ static INT32 slider_bloom_lvl10_scale(running_machine &machine, void *arg, std:: return slider_set(&(((hlsl_options*)arg)->bloom_level10_weight), 0.01f, "%1.2f", str, newval); } + //============================================================ // init_slider_list //============================================================ @@ -2932,6 +2735,7 @@ slider_state *shaders::init_slider_list() return listhead; } + //============================================================ // uniform functions //============================================================ @@ -2950,24 +2754,24 @@ uniform::uniform(effect *shader, const char *name, uniform_type type, int id) switch (type) { - case UT_INT: - case UT_FLOAT: - case UT_MATRIX: - case UT_SAMPLER: - m_count = 1; - break; - case UT_VEC2: - m_count = 2; - break; - case UT_VEC3: - m_count = 3; - break; - case UT_VEC4: - m_count = 4; - break; - default: - m_count = 1; - break; + case UT_INT: + case UT_FLOAT: + case UT_MATRIX: + case UT_SAMPLER: + m_count = 1; + break; + case UT_VEC2: + m_count = 2; + break; + case UT_VEC3: + m_count = 3; + break; + case UT_VEC4: + m_count = 4; + break; + default: + m_count = 1; + break; } } @@ -2987,8 +2791,7 @@ void uniform::update() hlsl_options *options = shadersys->options; renderer *d3d = shadersys->d3d; - - switch(m_id) + switch (m_id) { case CU_SCREEN_DIMS: { @@ -3225,7 +3028,7 @@ void uniform::set(texture *tex) void uniform::upload() { - switch(m_type) + switch (m_type) { case UT_INT: m_shader->set_int(m_handle, m_ival); @@ -3247,6 +3050,7 @@ void uniform::upload() } } + //============================================================ // effect functions //============================================================ @@ -3267,9 +3071,9 @@ effect::effect(shaders *shadersys, device *dev, const char *name, const char *pa TCHAR *effect_name = tstring_from_utf8(name_cstr); HRESULT hr = (*g_load_effect)(device, effect_name, NULL, NULL, 0, NULL, &m_effect, &buffer_errors); - if(FAILED(hr)) + if (FAILED(hr)) { - if(buffer_errors != NULL) + if (buffer_errors != NULL) { LPVOID compile_errors = buffer_errors->GetBufferPointer(); printf("Unable to compile shader: %s\n", (const char*)compile_errors); fflush(stdout); @@ -3360,13 +3164,21 @@ void effect::set_vector(D3DXHANDLE param, int count, float *vector) { static D3DXVECTOR4 out_vector; if (count > 0) + { out_vector.x = vector[0]; + } if (count > 1) + { out_vector.y = vector[1]; + } if (count > 2) + { out_vector.z = vector[2]; + } if (count > 3) + { out_vector.w = vector[3]; + } m_effect->SetVector(param, &out_vector); } @@ -3407,6 +3219,7 @@ ULONG effect::release() } + //============================================================ // get_slider_list //============================================================ @@ -3417,7 +3230,6 @@ void *windows_osd_interface::get_slider_list() } - // NOTE: The function below is taken directly from src/emu/video.c and should likely be moved into a global helper function. //------------------------------------------------- // open_next - open the next non-existing file of @@ -3433,13 +3245,17 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp const char *snapname = templ ? templ : d3d->window().machine().options().snap_name(); if (snapname == NULL || snapname[0] == 0) + { snapname = "%g/%i"; + } std::string snapstr(snapname); // strip any extension in the provided name int index = snapstr.find_last_of('.'); if (index != -1) + { snapstr.substr(0, index); + } // handle %d in the template (for image devices) std::string snapdev("%d_"); @@ -3449,7 +3265,9 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp { // if more %d are found, revert to default and ignore them all if (snapstr.find(snapdev, pos + 3) != -1) + { snapstr.assign("%g/%i"); + } // else if there is a single %d, try to create the correct snapname else { @@ -3461,16 +3279,26 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp int end = -1; if ((end1 != -1) && (end2 != -1)) + { end = MIN(end1, end2); + } else if (end1 != -1) + { end = end1; + } else if (end2 != -1) + { end = end2; + } else + { end = snapstr.length(); + } if (end - pos < 3) + { fatalerror("Something very wrong is going on!!!\n"); + } // copy the device name to a string std::string snapdevname; @@ -3504,7 +3332,9 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp // or fallback to default if (name_found == 0) + { snapstr.assign("%g/%i"); + } } } @@ -3519,7 +3349,9 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp // determine if the template has an index; if not, we always use the same name std::string fname; if (snapstr.find("%i") == -1) + { fname.assign(snapstr); + } // otherwise, we scan for the next available filename else @@ -3536,7 +3368,9 @@ static file_error open_next(d3d::renderer *d3d, emu_file &file, const char *temp // try to open the file; stop when we fail file_error filerr = file.open(fname.c_str()); if (filerr != FILERR_NONE) + { break; + } } } diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h index fd069823a5f..5862fb26e5f 100644 --- a/src/osd/modules/render/d3d/d3dhlsl.h +++ b/src/osd/modules/render/d3d/d3dhlsl.h @@ -314,8 +314,7 @@ public: }; private: - void blit(surface *dst, texture *src, surface *new_dst, - D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count); + void blit(surface *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, UINT32 prim_index, UINT32 prim_count); void enumerate_screens(); void end_avi_recording(); @@ -328,15 +327,16 @@ private: void remove_cache_target(cache_target *cache); // Shader passes - void ntsc_pass(render_target *rt, vec2f &texsize, vec2f &delta); - void color_convolution_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims); - void prescale_pass(render_target *rt, vec2f &texsize, vec2f &sourcedims); - void deconverge_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims); - void defocus_pass(render_target *rt, vec2f &texsize); - void phosphor_pass(render_target *rt, cache_target *ct, vec2f &texsize, bool focus_enable); - void post_pass(render_target *rt, vec2f &texsize, vec2f &delta, vec2f &sourcedims, poly_info *poly, int vertnum, bool prepare_bloom); - void bloom_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum); - void screen_pass(render_target *rt, vec2f &texsize, vec2f &delta, poly_info *poly, int vertnum); + int ntsc_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int color_convolution_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int prescale_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int deconverge_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int defocus_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int phosphor_pass(render_target *rt, cache_target *ct, int source_index, poly_info *poly, int vertnum); + int post_pass(render_target *rt, int source_index, poly_info *poly, int vertnum, bool prepare_bloom); + int downsample_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int bloom_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); + int screen_pass(render_target *rt, int source_index, poly_info *poly, int vertnum); base * d3dintf; // D3D interface @@ -358,6 +358,8 @@ private: int prescale_size_y; // prescale size y int hlsl_prescale_x; // hlsl prescale x int hlsl_prescale_y; // hlsl prescale y + float bloom_dims[11][2]; // bloom texture dimensions + int bloom_count; // count of used bloom textures int preset; // preset, if relevant bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader texture_info * shadow_texture; // shadow mask texture for post-processing shader @@ -395,7 +397,6 @@ private: surface * backbuffer; // pointer to our device's backbuffer effect * curr_effect; // pointer to the currently active effect object effect * default_effect; // pointer to the primary-effect object - effect * simple_effect; // pointer to the simple-effect object effect * prescale_effect; // pointer to the prescale-effect object effect * post_effect; // pointer to the post-effect object effect * focus_effect; // pointer to the focus-effect object diff --git a/src/osd/modules/render/drawd3d.c b/src/osd/modules/render/drawd3d.c index 8057581d61f..bcd823be909 100644 --- a/src/osd/modules/render/drawd3d.c +++ b/src/osd/modules/render/drawd3d.c @@ -44,7 +44,6 @@ #include "drawd3d.h" - //============================================================ // DEBUGGING //============================================================ @@ -52,7 +51,6 @@ extern void mtlog_add(const char *event); - //============================================================ // CONSTANTS //============================================================ @@ -67,7 +65,6 @@ enum }; - //============================================================ // MACROS //============================================================ @@ -75,7 +72,6 @@ enum #define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0) - //============================================================ // GLOBALS //============================================================ @@ -95,6 +91,7 @@ static const line_aa_step line_aa_4step[] = { 0 } }; + //============================================================ // INLINES //============================================================ @@ -167,12 +164,14 @@ INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) return rgb_t(0xff, r, g, b); } + //============================================================ // drawd3d_init //============================================================ static d3d::base * d3dintf; // FIX ME + //============================================================ // PROTOTYPES //============================================================ @@ -180,6 +179,7 @@ static d3d::base * d3dintf; // FIX ME // core functions static void drawd3d_exit(void); + //============================================================ // drawd3d_window_init //============================================================ @@ -196,6 +196,7 @@ int d3d::renderer::create() return 0; } + //============================================================ // drawd3d_exit //============================================================ @@ -222,7 +223,6 @@ void d3d::renderer::save() } - //============================================================ // drawd3d_window_destroy //============================================================ @@ -235,7 +235,6 @@ void d3d::renderer::destroy() } - //============================================================ // drawd3d_window_get_primitives //============================================================ @@ -253,6 +252,7 @@ render_primitive_list *d3d::renderer::get_primitives() return &window().target()->get_primitives(); } + //============================================================ // drawnone_create //============================================================ @@ -283,6 +283,7 @@ int drawd3d_init(running_machine &machine, osd_draw_callbacks *callbacks) return 0; } + //============================================================ // drawd3d_window_draw //============================================================ @@ -314,7 +315,6 @@ void renderer::set_texture(texture_info *texture) } } - void renderer::set_filter(int filter) { if (filter != m_last_filter) @@ -331,7 +331,6 @@ void renderer::set_filter(int filter) } } - void renderer::set_wrap(D3DTEXTUREADDRESS wrap) { if (wrap != m_last_wrap) @@ -348,7 +347,6 @@ void renderer::set_wrap(D3DTEXTUREADDRESS wrap) } } - void renderer::set_modmode(DWORD modmode) { if (modmode != m_last_modmode) @@ -361,7 +359,6 @@ void renderer::set_modmode(DWORD modmode) } } - void renderer::set_blendmode(int blendmode) { int blendenable; @@ -409,7 +406,6 @@ void renderer::set_blendmode(int blendmode) } } - void renderer::reset_render_states() { // this ensures subsequent calls to the above setters will force-update the data @@ -422,8 +418,6 @@ void renderer::reset_render_states() m_last_wrap = (D3DTEXTUREADDRESS)-1; } - - texture_manager::texture_manager(renderer *d3d) { m_renderer = d3d; @@ -737,7 +731,7 @@ void renderer::begin_frame() m_texture_manager->update_textures(); // begin the scene -mtlog_add("drawd3d_window_draw: begin_scene"); + mtlog_add("drawd3d_window_draw: begin_scene"); result = (*d3dintf->device.begin_scene)(m_device); if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result); @@ -934,7 +928,6 @@ try_again: } - //============================================================ // device_create_resources //============================================================ @@ -1000,7 +993,6 @@ int renderer::device_create_resources() } - //============================================================ // device_delete //============================================================ @@ -1039,6 +1031,7 @@ void renderer::device_delete() m_device = NULL; } + //============================================================ // device_delete_resources //============================================================ @@ -1054,7 +1047,6 @@ void renderer::device_delete_resources() } - //============================================================ // device_verify_caps //============================================================ @@ -1125,7 +1117,6 @@ int renderer::device_verify_caps() } - //============================================================ // device_test_cooperative //============================================================ @@ -1174,7 +1165,6 @@ int renderer::device_test_cooperative() } - //============================================================ // config_adapter_mode //============================================================ @@ -1250,7 +1240,6 @@ int renderer::config_adapter_mode() } - //============================================================ // get_adapter_for_monitor //============================================================ @@ -1277,7 +1266,6 @@ int renderer::get_adapter_for_monitor() } - //============================================================ // pick_best_mode //============================================================ @@ -1366,7 +1354,6 @@ void renderer::pick_best_mode() } - //============================================================ // update_window_size //============================================================ @@ -1401,6 +1388,7 @@ int renderer::update_window_size() return TRUE; } + //============================================================ // batch_vectors //============================================================ @@ -1554,6 +1542,7 @@ void renderer::batch_vector(const render_primitive *prim, float line_time) } } + //============================================================ // draw_line //============================================================ @@ -1638,7 +1627,6 @@ void renderer::draw_line(const render_primitive *prim) } - //============================================================ // draw_quad //============================================================ @@ -1752,6 +1740,7 @@ void poly_info::init(D3DPRIMITIVETYPE type, UINT32 count, UINT32 numverts, m_prim_height = prim_height; } + //============================================================ // primitive_alloc //============================================================ @@ -1791,7 +1780,6 @@ vertex *renderer::mesh_alloc(int numverts) } - //============================================================ // primitive_flush_pending //============================================================ @@ -1877,6 +1865,7 @@ void renderer::primitive_flush_pending() m_numpolys = 0; } + //============================================================ // texture_info destructor //============================================================ @@ -1904,6 +1893,7 @@ texture_info::~texture_info() } } + //============================================================ // texture_info constructor //============================================================ @@ -2080,18 +2070,17 @@ error: } - //============================================================ // texture_info::compute_size_subroutine //============================================================ -void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height) +void texture_info::compute_size_subroutine(texture_manager* texture_manager, 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)) + if (!(texture_manager->get_texture_caps() & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)) { // first the width if (finalwidth & (finalwidth - 1)) @@ -2115,7 +2104,7 @@ void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_w } // round up to square if we need to - if (m_texture_manager->get_texture_caps() & D3DPTEXTURECAPS_SQUAREONLY) + if (texture_manager->get_texture_caps() & D3DPTEXTURECAPS_SQUAREONLY) { if (finalwidth < finalheight) finalwidth = finalheight; @@ -2124,11 +2113,11 @@ void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_w } // adjust the aspect ratio if we need to - while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager->get_max_texture_aspect()) + while (finalwidth < finalheight && finalheight / finalwidth > texture_manager->get_max_texture_aspect()) { finalwidth *= 2; } - while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager->get_max_texture_aspect()) + while (finalheight < finalwidth && finalwidth / finalheight > texture_manager->get_max_texture_aspect()) { finalheight *= 2; } @@ -2137,6 +2126,7 @@ void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_w *p_height = finalheight; } + //============================================================ // texture_info::compute_size //============================================================ @@ -2161,7 +2151,7 @@ void texture_info::compute_size(int texwidth, int texheight) finalwidth += 2 * m_xborderpix; finalheight += 2 * m_yborderpix; - compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight); + texture_info::compute_size_subroutine(m_texture_manager, 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()) @@ -2172,7 +2162,7 @@ void texture_info::compute_size(int texwidth, int texheight) m_xborderpix = 0; m_yborderpix = 0; - compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight); + texture_info::compute_size_subroutine(m_texture_manager, finalwidth, finalheight, &finalwidth, &finalheight); } // if we're above the max width/height, do what? @@ -2195,7 +2185,6 @@ void texture_info::compute_size(int texwidth, int texheight) } - //============================================================ // copyline_palette16 //============================================================ @@ -2214,7 +2203,6 @@ INLINE void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const } - //============================================================ // copyline_palettea16 //============================================================ @@ -2233,7 +2221,6 @@ INLINE void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const } - //============================================================ // copyline_rgb32 //============================================================ @@ -2277,7 +2264,6 @@ INLINE void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_ } - //============================================================ // copyline_argb32 //============================================================ @@ -2321,7 +2307,6 @@ INLINE void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb } - //============================================================ // copyline_yuy16_to_yuy2 //============================================================ @@ -2387,7 +2372,6 @@ INLINE void copyline_yuy16_to_yuy2(UINT16 *dst, const UINT16 *src, int width, co } - //============================================================ // copyline_yuy16_to_uyvy //============================================================ @@ -2451,7 +2435,6 @@ INLINE void copyline_yuy16_to_uyvy(UINT16 *dst, const UINT16 *src, int width, co } - //============================================================ // copyline_yuy16_to_argb //============================================================ @@ -2529,7 +2512,6 @@ INLINE void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, co } - //============================================================ // texture_set_data //============================================================ @@ -2612,7 +2594,6 @@ void texture_info::set_data(const render_texinfo *texsource, UINT32 flags) } - //============================================================ // texture_info::prescale //============================================================ @@ -2804,6 +2785,7 @@ bool cache_target::init(renderer *d3d, base *d3dintf, int width, int height, int return true; } + //============================================================ // render_target::~render_target //============================================================ @@ -2822,42 +2804,30 @@ render_target::~render_target() (*d3dintf->surface.release)(bloom_target[index]); bloom_target[index] = NULL; } - } - - for (int index = 0; index < 5; index++) + } + + for (int index = 0; index < 2; index++) { - if (render_texture[index] != NULL) + if (native_texture[index] != NULL) { - (*d3dintf->texture.release)(render_texture[index]); - render_texture[index] = NULL; + (*d3dintf->texture.release)(native_texture[index]); + native_texture[index] = NULL; } - if (target[index] != NULL) + if (native_target[index] != NULL) { - (*d3dintf->surface.release)(target[index]); - target[index] = NULL; + (*d3dintf->surface.release)(native_target[index]); + native_target[index] = NULL; + } + if (prescale_texture[index] != NULL) + { + (*d3dintf->texture.release)(prescale_texture[index]); + prescale_texture[index] = NULL; + } + if (prescale_target[index] != NULL) + { + (*d3dintf->surface.release)(prescale_target[index]); + prescale_target[index] = NULL; } - } - - if (prescaletexture != NULL) - { - (*d3dintf->texture.release)(prescaletexture); - prescaletexture = NULL; - } - if (prescaletarget != NULL) - { - (*d3dintf->surface.release)(prescaletarget); - prescaletarget = NULL; - } - - if (smalltexture != NULL) - { - (*d3dintf->texture.release)(smalltexture); - smalltexture = NULL; - } - if (smalltarget != NULL) - { - (*d3dintf->surface.release)(smalltarget); - smalltarget = NULL; } } @@ -2869,41 +2839,21 @@ render_target::~render_target() bool render_target::init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y) { D3DFORMAT format = D3DFMT_A8R8G8B8; + + HRESULT result; + + for (int index = 0; index < 2; index++) + { + result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &native_texture[index]); + if (result != D3D_OK) + return false; + (*d3dintf->texture.get_surface_level)(native_texture[index], 0, &native_target[index]); - HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[0]); - if (result != D3D_OK) - return false; - (*d3dintf->texture.get_surface_level)(render_texture[0], 0, &target[0]); - - result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[1]); - if (result != D3D_OK) - return false; - (*d3dintf->texture.get_surface_level)(render_texture[1], 0, &target[1]); - - result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &render_texture[2]); - if (result != D3D_OK) - return false; - (*d3dintf->texture.get_surface_level)(render_texture[2], 0, &target[2]); - - result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[3]); - if (result != D3D_OK) - return false; - (*d3dintf->texture.get_surface_level)(render_texture[3], 0, &target[3]); - - result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &render_texture[4]); - if (result != D3D_OK) - return false; - (*d3dintf->texture.get_surface_level)(render_texture[4], 0, &target[4]); - - result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &smalltexture); - if (result != D3D_OK) - return false; - (*d3dintf->texture.get_surface_level)(smalltexture, 0, &smalltarget); - - result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescaletexture); - if (result != D3D_OK) - return false; - (*d3dintf->texture.get_surface_level)(prescaletexture, 0, &prescaletarget); + result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescale_texture[index]); + if (result != D3D_OK) + return false; + (*d3dintf->texture.get_surface_level)(prescale_texture[index], 0, &prescale_target[index]); + } float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height(); int bloom_index = 0; diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h index e736b0e45cd..dace1ce342d 100644 --- a/src/osd/modules/render/drawd3d.h +++ b/src/osd/modules/render/drawd3d.h @@ -67,6 +67,7 @@ public: ~render_target(); bool init(renderer *d3d, base *d3dintf, int width, int height, int prescale_x, int prescale_y); + int next_index(int index) { return ++index > 1 ? 0 : index; } int target_width; int target_height; @@ -80,12 +81,10 @@ public: int screen_index; int page_index; - surface *prescaletarget; - texture *prescaletexture; - surface *smalltarget; - texture *smalltexture; - surface *target[5]; - texture *render_texture[5]; + surface *prescale_target[2]; + texture *prescale_texture[2]; + surface *native_target[2]; + texture *native_texture[2]; render_target *next; render_target *prev; |