From a1d8d8ce872f52dd7032590429fb880dbf846c9e Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Sun, 11 Aug 2013 12:26:20 -0300 Subject: [PATCH 1/8] fix for 4x super sampling AA. make the distance of the samples from the center smaller to minimize errors. --- .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 12 +++++++----- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 18 +++++++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index a4a788c7e3..22e31ad192 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -177,12 +177,14 @@ static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConv "in float uv1 : TEXCOORD1){\n" "float4 texcol = tex2D(samp0,uv0.xy);\n"); break; - case 1: // 1 Samples SSAA - WRITE(p, "in float2 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1){\n" - "float4 texcol = tex2D(samp0,uv0.xy);\n"); + case 1: // 4 Samples in 4x SSAA buffer + WRITE(p, "in float4 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3){\n" + "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); break; - case 2: // 4 Samples SSAA + case 2: // 4 Samples in 9x SSAA buffer WRITE(p, "in float4 uv0 : TEXCOORD0,\n" "in float uv1 : TEXCOORD1,\n" "in float4 uv2 : TEXCOORD2,\n" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 2d11368a6d..93cd7a67df 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -92,15 +92,19 @@ void VertexShaderCache::Init() sprintf(vProg, "struct VSOUTPUT\n" "{\n" "float4 vPosition : POSITION;\n" - "float2 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inInvTexSize : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" "{\n" "VSOUTPUT OUT;" "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0;\n" - "OUT.vTexCoord1 = inTEX2;\n" + "OUT.vTexCoord = inTEX0.xyyx;\n" + "OUT.vTexCoord1 = inTEX2.x;\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" "return OUT;\n" "}\n"); SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); @@ -119,8 +123,8 @@ void VertexShaderCache::Init() "OUT.vPosition = inPosition;\n" "OUT.vTexCoord = inTEX0.xyyx;\n" "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-1.0f,-0.5f, 1.0f,-0.5f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 1.0f, 0.5f,-1.0f, 0.5f) * inTEX1.xyyx);\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" "return OUT;\n" "}\n"); SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); From f4000b6b42acb508bd2c80ec9f5cf10da2355994 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Sun, 11 Aug 2013 18:48:31 -0300 Subject: [PATCH 2/8] Add the ability to force Dual Source Blending in the configuration file. this way everyone can check if their hardware support this feature in dx9 --- Source/Core/VideoCommon/Src/VideoConfig.cpp | 2 ++ Source/Core/VideoCommon/Src/VideoConfig.h | 3 ++- Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 19 ++++++++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index d422c3d01d..e8c87774d4 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -96,6 +96,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true); iniFile.Get("Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable, false); iniFile.Get("Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false); + iniFile.Get("Hacks", "ForceDualSourceBlend", &bForceDualSourceBlend, false); iniFile.Get("Hardware", "Adapter", &iAdapter, 0); @@ -251,6 +252,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled); iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); + iniFile.Set("Hacks", "ForceDualSourceBlend", bForceDualSourceBlend); iniFile.Set("Hardware", "Adapter", iAdapter); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index a0a5cabacf..dff1beb77f 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -123,7 +123,8 @@ struct VideoConfig bool bEnablePixelLighting; bool bHackedBufferUpload; bool bFastDepthCalc; - + //for dx9-backend + bool bForceDualSourceBlend; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 1a4e1bf84d..9170713e51 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -93,7 +93,21 @@ void InitBackendInfo() g_Config.backend_info.bSupportsPrimitiveRestart = false; // TODO: figure out if it does g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; // Dual source blend disabled by default until a proper method to test for support is found - g_Config.backend_info.bSupportsDualSourceBlend = false; + g_Config.backend_info.bSupports3DVision = true; + OSVERSIONINFO info; + ZeroMemory(&info, sizeof(OSVERSIONINFO)); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx(&info)) + { + // dual source blending is only supported in windows 7 o newer. sorry xp users + // we cannot test for device caps because most drivers just declare the minimun caps + // and don't expose their support for some functionalities + g_Config.backend_info.bSupportsDualSourceBlend = info.dwPlatformId == VER_PLATFORM_WIN32_NT && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); + } + else + { + g_Config.backend_info.bSupportsDualSourceBlend = false; + } g_Config.backend_info.bSupportsFormatReinterpretation = true; g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; g_Config.backend_info.bSupportsEarlyZ = false; @@ -139,6 +153,9 @@ bool VideoBackend::Initialize(void *&window_handle) g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str()); g_Config.UpdateProjectionHack(); g_Config.VerifyValidity(); + // as only some driver/hardware configurations support dual source blending only enable it if is + // configured by user + g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; UpdateActiveConfig(); window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); From 0ec92f986b74ebe2fb1eaa95e47c4dbfaf470338 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Tue, 13 Aug 2013 17:31:50 -0300 Subject: [PATCH 3/8] small correction, we cannot use dual source blending if separate alpha function is not supported --- Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 9170713e51..ab5e85d64d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -102,7 +102,7 @@ void InitBackendInfo() // dual source blending is only supported in windows 7 o newer. sorry xp users // we cannot test for device caps because most drivers just declare the minimun caps // and don't expose their support for some functionalities - g_Config.backend_info.bSupportsDualSourceBlend = info.dwPlatformId == VER_PLATFORM_WIN32_NT && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); + g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); } else { From a5e34dd5cb4793fef52e0ef02a87c6b47a46c8f4 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Thu, 15 Aug 2013 14:43:58 -0300 Subject: [PATCH 4/8] merge changes from other back ends to the PerfQuery functionality --- Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp index 8a1d5c59a9..fafd06e901 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PerfQuery.cpp @@ -35,6 +35,8 @@ void PerfQuery::DestroyDeviceObjects() void PerfQuery::EnableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; // Is this sane? if (m_query_count > ARRAYSIZE(m_query_buffer) / 2) WeakFlush(); @@ -58,6 +60,8 @@ void PerfQuery::EnableQuery(PerfQueryGroup type) void PerfQuery::DisableQuery(PerfQueryGroup type) { + if (!ShouldEmulate()) + return; // stop query if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) { @@ -74,6 +78,8 @@ void PerfQuery::ResetQuery() u32 PerfQuery::GetQueryResult(PerfQueryType type) { + if (!ShouldEmulate()) + return 0; u32 result = 0; if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC) @@ -98,6 +104,8 @@ u32 PerfQuery::GetQueryResult(PerfQueryType type) void PerfQuery::FlushOne() { + if (!ShouldEmulate()) + return; auto& entry = m_query_buffer[m_query_read_pos]; DWORD result = 0; @@ -118,12 +126,16 @@ void PerfQuery::FlushOne() // TODO: could selectively flush things, but I don't think that will do much void PerfQuery::FlushResults() { + if (!ShouldEmulate()) + return; while (!IsFlushed()) FlushOne(); } void PerfQuery::WeakFlush() { + if (!ShouldEmulate()) + return; while (!IsFlushed()) { auto& entry = m_query_buffer[m_query_read_pos]; @@ -148,6 +160,8 @@ void PerfQuery::WeakFlush() bool PerfQuery::IsFlushed() const { + if (!ShouldEmulate()) + return true; return 0 == m_query_count; } From 8e9bbdeb2fa59a8496e91cae751a49097e5d52c8 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Thu, 15 Aug 2013 15:14:48 -0300 Subject: [PATCH 5/8] some fixes for point rendering --- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 2114 ++++++++--------- .../Plugin_VideoDX9/Src/VertexManager.cpp | 676 +++--- 2 files changed, 1399 insertions(+), 1391 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 625db5f44e..9fcabb4796 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -63,165 +63,165 @@ static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL; void SetupDeviceObjects() { - D3D::font.Init(); - VertexLoaderManager::Init(); - g_framebuffer_manager = new FramebufferManager; + D3D::font.Init(); + VertexLoaderManager::Init(); + g_framebuffer_manager = new FramebufferManager; - VertexShaderManager::Dirty(); - PixelShaderManager::Dirty(); - TextureConverter::Init(); - - // To avoid shader compilation stutters, read back all shaders from cache. - VertexShaderCache::Init(); - PixelShaderCache::Init(); - g_vertex_manager->CreateDeviceObjects(); - ((PerfQuery*)g_perf_query)->CreateDeviceObjects(); - // Texture cache will recreate themselves over time. + VertexShaderManager::Dirty(); + PixelShaderManager::Dirty(); + TextureConverter::Init(); + + // To avoid shader compilation stutters, read back all shaders from cache. + VertexShaderCache::Init(); + PixelShaderCache::Init(); + g_vertex_manager->CreateDeviceObjects(); + ((PerfQuery*)g_perf_query)->CreateDeviceObjects(); + // Texture cache will recreate themselves over time. } // Kill off all POOL_DEFAULT device objects. void TeardownDeviceObjects() { - if(ScreenShootMEMSurface) - ScreenShootMEMSurface->Release(); - ScreenShootMEMSurface = NULL; - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - delete g_framebuffer_manager; - ((PerfQuery*)g_perf_query)->DestroyDeviceObjects(); - D3D::font.Shutdown(); - TextureCache::Invalidate(); - VertexLoaderManager::Shutdown(); - VertexShaderCache::Shutdown(); - PixelShaderCache::Shutdown(); - TextureConverter::Shutdown(); - g_vertex_manager->DestroyDeviceObjects(); + if(ScreenShootMEMSurface) + ScreenShootMEMSurface->Release(); + ScreenShootMEMSurface = NULL; + D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); + D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); + delete g_framebuffer_manager; + ((PerfQuery*)g_perf_query)->DestroyDeviceObjects(); + D3D::font.Shutdown(); + TextureCache::Invalidate(); + VertexLoaderManager::Shutdown(); + VertexShaderCache::Shutdown(); + PixelShaderCache::Shutdown(); + TextureConverter::Shutdown(); + g_vertex_manager->DestroyDeviceObjects(); } // Init functions Renderer::Renderer() { - InitFPSCounter(); + InitFPSCounter(); - st = new char[32768]; + st = new char[32768]; - int fullScreenRes, x, y, w_temp, h_temp; - s_blendMode = 0; - // Multisample Anti-aliasing hasn't been implemented yet use supersamling instead - int backbuffer_ms_mode = 0; + int fullScreenRes, x, y, w_temp, h_temp; + s_blendMode = 0; + // Multisample Anti-aliasing hasn't been implemented yet use supersamling instead + int backbuffer_ms_mode = 0; - Host_GetRenderWindowSize(x, y, w_temp, h_temp); + Host_GetRenderWindowSize(x, y, w_temp, h_temp); - for (fullScreenRes = 0; fullScreenRes < (int)D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size(); fullScreenRes++) - { - if ((D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].xres == w_temp) && - (D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].yres == h_temp)) - break; - } - if (fullScreenRes == D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size()) - fullScreenRes = 0; + for (fullScreenRes = 0; fullScreenRes < (int)D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size(); fullScreenRes++) + { + if ((D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].xres == w_temp) && + (D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].yres == h_temp)) + break; + } + if (fullScreenRes == D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size()) + fullScreenRes = 0; - D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), - fullScreenRes, backbuffer_ms_mode, false); + D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), + fullScreenRes, backbuffer_ms_mode, false); - IS_AMD = D3D::IsATIDevice(); + IS_AMD = D3D::IsATIDevice(); - // Decide framebuffer size - s_backbuffer_width = D3D::GetBackBufferWidth(); - s_backbuffer_height = D3D::GetBackBufferHeight(); + // Decide framebuffer size + s_backbuffer_width = D3D::GetBackBufferWidth(); + s_backbuffer_height = D3D::GetBackBufferHeight(); - FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH); - FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT); + FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH); + FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT); - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); + UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - s_LastAA = g_ActiveConfig.iMultisampleMode; - int SupersampleCoeficient = (s_LastAA % 3) + 1; + s_LastAA = g_ActiveConfig.iMultisampleMode; + int SupersampleCoeficient = (s_LastAA % 3) + 1; - s_LastEFBScale = g_ActiveConfig.iEFBScale; - CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); + s_LastEFBScale = g_ActiveConfig.iEFBScale; + CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); - // Make sure to use valid texture sizes - D3D::FixTextureSize(s_target_width, s_target_height); + // Make sure to use valid texture sizes + D3D::FixTextureSize(s_target_width, s_target_height); - // We're not using fixed function. - // Let's just set the matrices to identity to be sure. - D3DXMATRIX mtx; - D3DXMatrixIdentity(&mtx); - D3D::dev->SetTransform(D3DTS_VIEW, &mtx); - D3D::dev->SetTransform(D3DTS_WORLD, &mtx); + // We're not using fixed function. + // Let's just set the matrices to identity to be sure. + D3DXMATRIX mtx; + D3DXMatrixIdentity(&mtx); + D3D::dev->SetTransform(D3DTS_VIEW, &mtx); + D3D::dev->SetTransform(D3DTS_WORLD, &mtx); - SetupDeviceObjects(); + SetupDeviceObjects(); - for (int stage = 0; stage < 8; stage++) - D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, 1 << g_ActiveConfig.iMaxAnisotropy); + for (int stage = 0; stage < 8; stage++) + D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, 1 << g_ActiveConfig.iMaxAnisotropy); - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); - - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - vp.X = 0; - vp.Y = 0; - vp.Width = s_target_width; - vp.Height = s_target_height; - D3D::dev->SetViewport(&vp); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); - D3D::BeginFrame(); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); - D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false); - m_fMaxPointSize = D3D::GetCaps().MaxPointSize; - // Handle VSync on/off - s_vsync = g_ActiveConfig.IsVSync(); + D3DVIEWPORT9 vp; + vp.X = 0; + vp.Y = 0; + vp.Width = s_backbuffer_width; + vp.Height = s_backbuffer_height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); + + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + vp.X = 0; + vp.Y = 0; + vp.Width = s_target_width; + vp.Height = s_target_height; + D3D::dev->SetViewport(&vp); + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); + D3D::BeginFrame(); + D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); + D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); + D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false); + m_fMaxPointSize = D3D::GetCaps().MaxPointSize; + // Handle VSync on/off + s_vsync = g_ActiveConfig.IsVSync(); } Renderer::~Renderer() { - TeardownDeviceObjects(); - D3D::EndFrame(); - D3D::Present(); - D3D::Close(); - - delete[] st; + TeardownDeviceObjects(); + D3D::EndFrame(); + D3D::Present(); + D3D::Close(); + + delete[] st; } void Renderer::RenderText(const char *text, int left, int top, u32 color) { - D3D::font.DrawTextScaled((float)left, (float)top, 20, 20, 0.0f, color, text); + D3D::font.DrawTextScaled((float)left, (float)top, 20, 20, 0.0f, color, text); } TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) { - TargetRectangle result; - result.left = EFBToScaledX(rc.left); - result.top = EFBToScaledY(rc.top); - result.right = EFBToScaledX(rc.right); - result.bottom = EFBToScaledY(rc.bottom); - return result; + TargetRectangle result; + result.left = EFBToScaledX(rc.left); + result.top = EFBToScaledY(rc.top); + result.right = EFBToScaledX(rc.right); + result.bottom = EFBToScaledY(rc.bottom); + return result; } } void formatBufferDump(const u8* in, u8* out, int w, int h, int p) { - for (int y = 0; y < h; y++) - { - auto line = in + (h - y - 1) * p; - for (int x = 0; x < w; x++) - { - memcpy(out, line, 3); - out += 3; - line += 4; - } - } + for (int y = 0; y < h; y++) + { + auto line = in + (h - y - 1) * p; + for (int x = 0; x < w; x++) + { + memcpy(out, line, 3); + out += 3; + line += 4; + } + } } namespace DX9 @@ -231,63 +231,63 @@ namespace DX9 // size. bool Renderer::CheckForResize() { - while (EmuWindow::IsSizing()) - Sleep(10); + while (EmuWindow::IsSizing()) + Sleep(10); - if (EmuWindow::GetParentWnd()) - { - // Re-stretch window to parent window size again, if it has a parent window. - RECT rcParentWindow; - GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); - int width = rcParentWindow.right - rcParentWindow.left; - int height = rcParentWindow.bottom - rcParentWindow.top; - if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight()) - MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); - } + if (EmuWindow::GetParentWnd()) + { + // Re-stretch window to parent window size again, if it has a parent window. + RECT rcParentWindow; + GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); + int width = rcParentWindow.right - rcParentWindow.left; + int height = rcParentWindow.bottom - rcParentWindow.top; + if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight()) + MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); + } - RECT rcWindow; - GetClientRect(EmuWindow::GetWnd(), &rcWindow); - int client_width = rcWindow.right - rcWindow.left; - int client_height = rcWindow.bottom - rcWindow.top; + RECT rcWindow; + GetClientRect(EmuWindow::GetWnd(), &rcWindow); + int client_width = rcWindow.right - rcWindow.left; + int client_height = rcWindow.bottom - rcWindow.top; - // Sanity check - if ((client_width != Renderer::GetBackbufferWidth() || - client_height != Renderer::GetBackbufferHeight()) && - client_width >= 4 && client_height >= 4) - { - TeardownDeviceObjects(); + // Sanity check + if ((client_width != Renderer::GetBackbufferWidth() || + client_height != Renderer::GetBackbufferHeight()) && + client_width >= 4 && client_height >= 4) + { + TeardownDeviceObjects(); - D3D::Reset(); - s_backbuffer_width = D3D::GetBackBufferWidth(); - s_backbuffer_height = D3D::GetBackBufferHeight(); - if(ScreenShootMEMSurface) - ScreenShootMEMSurface->Release(); - D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(), - D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); + D3D::Reset(); + s_backbuffer_width = D3D::GetBackBufferWidth(); + s_backbuffer_height = D3D::GetBackBufferHeight(); + if(ScreenShootMEMSurface) + ScreenShootMEMSurface->Release(); + D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(), + D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - return true; - } - - return false; + return true; + } + + return false; } void Renderer::SetScissorRect(const TargetRectangle& rc) { - D3D::dev->SetScissorRect(rc.AsRECT()); + D3D::dev->SetScissorRect(rc.AsRECT()); } void Renderer::SetColorMask() { - // Only enable alpha channel if it's supported by the current EFB format - DWORD color_mask = 0; - if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) - { - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) - color_mask = D3DCOLORWRITEENABLE_ALPHA; - if (bpmem.blendmode.colorupdate) - color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - } - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); + // Only enable alpha channel if it's supported by the current EFB format + DWORD color_mask = 0; + if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) + { + if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) + color_mask = D3DCOLORWRITEENABLE_ALPHA; + if (bpmem.blendmode.colorupdate) + color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + } + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); } // This function allows the CPU to directly access the EFB. @@ -306,191 +306,191 @@ void Renderer::SetColorMask() // - GX_PokeZMode (TODO) u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) { - if (!g_ActiveConfig.bEFBAccessEnable) - return 0; + if (!g_ActiveConfig.bEFBAccessEnable) + return 0; - if (type == POKE_Z) - { - static bool alert_only_once = true; - if (!alert_only_once) return 0; - PanicAlert("EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d))", poke_data, x, y); - alert_only_once = false; - return 0; - } + if (type == POKE_Z) + { + static bool alert_only_once = true; + if (!alert_only_once) return 0; + PanicAlert("EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d))", poke_data, x, y); + alert_only_once = false; + return 0; + } - // if depth textures aren't supported by the hardware, just return - if (type == PEEK_Z) - if (FramebufferManager::GetEFBDepthTexture() == NULL) - return 0; + // if depth textures aren't supported by the hardware, just return + if (type == PEEK_Z) + if (FramebufferManager::GetEFBDepthTexture() == NULL) + return 0; - // We're using three surfaces here: - // - pEFBSurf: EFB Surface. Source surface when peeking, destination surface when poking. - // - pBufferRT: A render target surface. When peeking, we render a textured quad to this surface. - // - pSystemBuf: An offscreen surface. Used to retrieve the pixel data from pBufferRT. - LPDIRECT3DSURFACE9 pEFBSurf, pBufferRT, pSystemBuf; - if(type == PEEK_Z || type == POKE_Z) - { - pEFBSurf = FramebufferManager::GetEFBDepthRTSurface(); - pBufferRT = FramebufferManager::GetEFBDepthReadSurface(); - pSystemBuf = FramebufferManager::GetEFBDepthOffScreenRTSurface(); - } - else //if(type == PEEK_COLOR || type == POKE_COLOR) - { - pEFBSurf = FramebufferManager::GetEFBColorRTSurface(); - pBufferRT = FramebufferManager::GetEFBColorReadSurface(); - pSystemBuf = FramebufferManager::GetEFBColorOffScreenRTSurface(); - } + // We're using three surfaces here: + // - pEFBSurf: EFB Surface. Source surface when peeking, destination surface when poking. + // - pBufferRT: A render target surface. When peeking, we render a textured quad to this surface. + // - pSystemBuf: An offscreen surface. Used to retrieve the pixel data from pBufferRT. + LPDIRECT3DSURFACE9 pEFBSurf, pBufferRT, pSystemBuf; + if(type == PEEK_Z || type == POKE_Z) + { + pEFBSurf = FramebufferManager::GetEFBDepthRTSurface(); + pBufferRT = FramebufferManager::GetEFBDepthReadSurface(); + pSystemBuf = FramebufferManager::GetEFBDepthOffScreenRTSurface(); + } + else //if(type == PEEK_COLOR || type == POKE_COLOR) + { + pEFBSurf = FramebufferManager::GetEFBColorRTSurface(); + pBufferRT = FramebufferManager::GetEFBColorReadSurface(); + pSystemBuf = FramebufferManager::GetEFBColorOffScreenRTSurface(); + } - // Buffer not found alert - if (!pEFBSurf) { - PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB"); - return 0; - } + // Buffer not found alert + if (!pEFBSurf) { + PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB"); + return 0; + } - // Convert EFB dimensions to the ones of our render target - EFBRectangle efbPixelRc; - efbPixelRc.left = x; - efbPixelRc.top = y; - efbPixelRc.right = x + 1; - efbPixelRc.bottom = y + 1; + // Convert EFB dimensions to the ones of our render target + EFBRectangle efbPixelRc; + efbPixelRc.left = x; + efbPixelRc.top = y; + efbPixelRc.right = x + 1; + efbPixelRc.bottom = y + 1; - TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc); + TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc); - HRESULT hr; - RECT RectToLock; - RectToLock.bottom = targetPixelRc.bottom; - RectToLock.left = targetPixelRc.left; - RectToLock.right = targetPixelRc.right; - RectToLock.top = targetPixelRc.top; - if (type == PEEK_Z) - { - // TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them? - if (FramebufferManager::GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8) - return 0; + HRESULT hr; + RECT RectToLock; + RectToLock.bottom = targetPixelRc.bottom; + RectToLock.left = targetPixelRc.left; + RectToLock.right = targetPixelRc.right; + RectToLock.top = targetPixelRc.top; + if (type == PEEK_Z) + { + // TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them? + if (FramebufferManager::GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8) + return 0; - RECT PixelRect; - PixelRect.bottom = 4; - PixelRect.left = 0; - PixelRect.right = 4; - PixelRect.top = 0; - RectToLock.bottom+=2; - RectToLock.right+=1; - RectToLock.top-=1; - RectToLock.left-=2; - if ((RectToLock.bottom - RectToLock.top) > 4) - RectToLock.bottom--; - if ((RectToLock.right - RectToLock.left) > 4) - RectToLock.left++; + RECT PixelRect; + PixelRect.bottom = 4; + PixelRect.left = 0; + PixelRect.right = 4; + PixelRect.top = 0; + RectToLock.bottom+=2; + RectToLock.right+=1; + RectToLock.top-=1; + RectToLock.left-=2; + if ((RectToLock.bottom - RectToLock.top) > 4) + RectToLock.bottom--; + if ((RectToLock.right - RectToLock.left) > 4) + RectToLock.left++; - ResetAPIState(); // Reset any game specific settings - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, pBufferRT); + ResetAPIState(); // Reset any game specific settings + D3D::dev->SetDepthStencilSurface(NULL); + D3D::dev->SetRenderTarget(0, pBufferRT); - // Stretch picture with increased internal resolution - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = 4; - vp.Height = 4; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); + // Stretch picture with increased internal resolution + D3DVIEWPORT9 vp; + vp.X = 0; + vp.Y = 0; + vp.Width = 4; + vp.Height = 4; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); - float colmat[28] = {0.0f}; - colmat[0] = colmat[5] = colmat[10] = 1.0f; - PixelShaderManager::SetColorMatrix(colmat); // set transformation - LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBDepthTexture(); - - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + float colmat[28] = {0.0f}; + colmat[0] = colmat[5] = colmat[10] = 1.0f; + PixelShaderManager::SetColorMatrix(colmat); // set transformation + LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBDepthTexture(); - D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); + D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3D::drawShadedTexQuad( - read_texture, - &RectToLock, - Renderer::GetTargetWidth(), - Renderer::GetTargetHeight(), - 4, 4, - PixelShaderCache::GetDepthMatrixProgram(0, bformat != FOURCC_RAWZ), - VertexShaderCache::GetSimpleVertexShader(0)); + D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); + D3D::drawShadedTexQuad( + read_texture, + &RectToLock, + Renderer::GetTargetWidth(), + Renderer::GetTargetHeight(), + 4, 4, + PixelShaderCache::GetDepthMatrixProgram(0, bformat != FOURCC_RAWZ), + VertexShaderCache::GetSimpleVertexShader(0)); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - RestoreAPIState(); + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - // Retrieve the pixel data to the local memory buffer - RectToLock.bottom = 4; - RectToLock.left = 0; - RectToLock.right = 4; - RectToLock.top = 0; - D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + RestoreAPIState(); - // EFB data successfully retrieved, now get the pixel data - D3DLOCKED_RECT drect; - pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); - u32 z = ((u32*)drect.pBits)[6]; // 24 bit depth value - pSystemBuf->UnlockRect(); + // Retrieve the pixel data to the local memory buffer + RectToLock.bottom = 4; + RectToLock.left = 0; + RectToLock.right = 4; + RectToLock.top = 0; + D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); - // if Z is in 16 bit format you must return a 16 bit integer - if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) { - z >>= 8; - } + // EFB data successfully retrieved, now get the pixel data + D3DLOCKED_RECT drect; + pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); + u32 z = ((u32*)drect.pBits)[6]; // 24 bit depth value + pSystemBuf->UnlockRect(); - return z; - } - else if(type == PEEK_COLOR) - { - // We can't directly StretchRect to System buf because is not supported by all implementations - // this is the only safe path that works in most cases - hr = D3D::dev->StretchRect(pEFBSurf, &RectToLock, pBufferRT, NULL, D3DTEXF_NONE); - D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); + // if Z is in 16 bit format you must return a 16 bit integer + if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) { + z >>= 8; + } - // EFB data successfully retrieved, now get the pixel data - RectToLock.bottom = 1; - RectToLock.left = 0; - RectToLock.right = 1; - RectToLock.top = 0; + return z; + } + else if(type == PEEK_COLOR) + { + // We can't directly StretchRect to System buf because is not supported by all implementations + // this is the only safe path that works in most cases + hr = D3D::dev->StretchRect(pEFBSurf, &RectToLock, pBufferRT, NULL, D3DTEXF_NONE); + D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); - D3DLOCKED_RECT drect; - pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); - u32 ret = ((u32*)drect.pBits)[0]; - pSystemBuf->UnlockRect(); + // EFB data successfully retrieved, now get the pixel data + RectToLock.bottom = 1; + RectToLock.left = 0; + RectToLock.right = 1; + RectToLock.top = 0; - // check what to do with the alpha channel (GX_PokeAlphaRead) - PixelEngine::UPEAlphaReadReg alpha_read_mode; - PixelEngine::Read16((u16&)alpha_read_mode, PE_ALPHAREAD); + D3DLOCKED_RECT drect; + pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); + u32 ret = ((u32*)drect.pBits)[0]; + pSystemBuf->UnlockRect(); - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) - { - ret = RGBA8ToRGBA6ToRGBA8(ret); - } - else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) - { - ret = RGBA8ToRGB565ToRGBA8(ret); - } - if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24) - { - ret |= 0xFF000000; - } + // check what to do with the alpha channel (GX_PokeAlphaRead) + PixelEngine::UPEAlphaReadReg alpha_read_mode; + PixelEngine::Read16((u16&)alpha_read_mode, PE_ALPHAREAD); - if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE - else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF - else return (ret & 0x00FFFFFF); // GX_READ_00 - } - else //if(type == POKE_COLOR) - { - // TODO: Speed this up by batching pokes? - ResetAPIState(); - D3D::drawColorQuad(poke_data, - (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, - (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.bottom * 2.f / (float)Renderer::GetTargetHeight() + 1.f); - RestoreAPIState(); - return 0; - } + if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) + { + ret = RGBA8ToRGBA6ToRGBA8(ret); + } + else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) + { + ret = RGBA8ToRGB565ToRGBA8(ret); + } + if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24) + { + ret |= 0xFF000000; + } + + if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE + else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF + else return (ret & 0x00FFFFFF); // GX_READ_00 + } + else //if(type == POKE_COLOR) + { + // TODO: Speed this up by batching pokes? + ResetAPIState(); + D3D::drawColorQuad(poke_data, + (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, + - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, + (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, + - (float)RectToLock.bottom * 2.f / (float)Renderer::GetTargetHeight() + 1.f); + RestoreAPIState(); + return 0; + } } // Viewport correction: @@ -503,884 +503,884 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // [ 0 0 1 0 ] // [ 0 0 0 1 ] static void ViewportCorrectionMatrix(Matrix44& result, - float ix, float iy, float iw, float ih, // Intended viewport (x, y, width, height) - float ax, float ay, float aw, float ah) // Actual viewport (x, y, width, height) + float ix, float iy, float iw, float ih, // Intended viewport (x, y, width, height) + float ax, float ay, float aw, float ah) // Actual viewport (x, y, width, height) { - Matrix44::LoadIdentity(result); - if (aw == 0.f || ah == 0.f) - return; - result.data[4*0+0] = iw / aw; - result.data[4*0+3] = (iw - 2.f * (ax - ix)) / aw - 1.f; - result.data[4*1+1] = ih / ah; - result.data[4*1+3] = (-ih + 2.f * (ay - iy)) / ah + 1.f; + Matrix44::LoadIdentity(result); + if (aw == 0.f || ah == 0.f) + return; + result.data[4*0+0] = iw / aw; + result.data[4*0+3] = (iw - 2.f * (ax - ix)) / aw - 1.f; + result.data[4*1+1] = ih / ah; + result.data[4*1+3] = (-ih + 2.f * (ay - iy)) / ah + 1.f; } // Called from VertexShaderManager void Renderer::UpdateViewport(Matrix44& vpCorrection) { - // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) - // [0] = width/2 - // [1] = height/2 - // [2] = 16777215 * (farz - nearz) - // [3] = xorig + width/2 + 342 - // [4] = yorig + height/2 + 342 - // [5] = 16777215 * farz + // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) + // [0] = width/2 + // [1] = height/2 + // [2] = 16777215 * (farz - nearz) + // [3] = xorig + width/2 + 342 + // [4] = yorig + height/2 + 342 + // [5] = 16777215 * farz - int scissorXOff = bpmem.scissorOffset.x * 2; - int scissorYOff = bpmem.scissorOffset.y * 2; + int scissorXOff = bpmem.scissorOffset.x * 2; + int scissorYOff = bpmem.scissorOffset.y * 2; - // TODO: ceil, floor or just cast to int? - int intendedX = EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff)); - int intendedY = EFBToScaledY((int)ceil(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff)); - int intendedWd = EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); - int intendedHt = EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); - if (intendedWd < 0) - { - intendedX += intendedWd; - intendedWd = -intendedWd; - } - if (intendedHt < 0) - { - intendedY += intendedHt; - intendedHt = -intendedHt; - } + // TODO: ceil, floor or just cast to int? + int intendedX = EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff)); + int intendedY = EFBToScaledY((int)ceil(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff)); + int intendedWd = EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); + int intendedHt = EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); + if (intendedWd < 0) + { + intendedX += intendedWd; + intendedWd = -intendedWd; + } + if (intendedHt < 0) + { + intendedY += intendedHt; + intendedHt = -intendedHt; + } - // In D3D, the viewport rectangle must fit within the render target. - int X = intendedX; - if (X < 0) - X = 0; - int Y = intendedY; - if (Y < 0) - Y = 0; - int Wd = intendedWd; - if (X + Wd > GetTargetWidth()) - Wd = GetTargetWidth() - X; - int Ht = intendedHt; - if (Y + Ht > GetTargetHeight()) - Ht = GetTargetHeight() - Y; + // In D3D, the viewport rectangle must fit within the render target. + int X = intendedX; + if (X < 0) + X = 0; + int Y = intendedY; + if (Y < 0) + Y = 0; + int Wd = intendedWd; + if (X + Wd > GetTargetWidth()) + Wd = GetTargetWidth() - X; + int Ht = intendedHt; + if (Y + Ht > GetTargetHeight()) + Ht = GetTargetHeight() - Y; - // If GX viewport is off the render target, we must clamp our viewport - // within the bounds. Use the correction matrix to compensate. - ViewportCorrectionMatrix(vpCorrection, - (float)intendedX, (float)intendedY, (float)intendedWd, (float)intendedHt, - (float)X, (float)Y, (float)Wd, (float)Ht); + // If GX viewport is off the render target, we must clamp our viewport + // within the bounds. Use the correction matrix to compensate. + ViewportCorrectionMatrix(vpCorrection, + (float)intendedX, (float)intendedY, (float)intendedWd, (float)intendedHt, + (float)X, (float)Y, (float)Wd, (float)Ht); - D3DVIEWPORT9 vp; - vp.X = X; - vp.Y = Y; - vp.Width = Wd; - vp.Height = Ht; + D3DVIEWPORT9 vp; + vp.X = X; + vp.Y = Y; + vp.Width = Wd; + vp.Height = Ht; - // Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work - vp.MinZ = 0.0f; // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; - vp.MaxZ = 1.0f; // xfregs.viewport.farZ / 16777216.0f; - D3D::dev->SetViewport(&vp); + // Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work + vp.MinZ = 0.0f; // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; + vp.MaxZ = 1.0f; // xfregs.viewport.farZ / 16777216.0f; + D3D::dev->SetViewport(&vp); } void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) { - // Reset rendering pipeline while keeping color masks and depth buffer settings - ResetAPIState(); + // Reset rendering pipeline while keeping color masks and depth buffer settings + ResetAPIState(); - DWORD color_mask = 0; - if (alphaEnable) - color_mask = D3DCOLORWRITEENABLE_ALPHA; - if (colorEnable) - color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, color_mask); + DWORD color_mask = 0; + if (alphaEnable) + color_mask = D3DCOLORWRITEENABLE_ALPHA; + if (colorEnable) + color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, color_mask); - if (zEnable) - { - D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); - D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, TRUE); - D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - } - else - { - D3D::ChangeRenderState(D3DRS_ZENABLE, FALSE); - } + if (zEnable) + { + D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); + D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, TRUE); + D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + } + else + { + D3D::ChangeRenderState(D3DRS_ZENABLE, FALSE); + } - // Update the viewport for clearing the target EFB rect - TargetRectangle targetRc = ConvertEFBRectangle(rc); - D3DVIEWPORT9 vp; - vp.X = targetRc.left; - vp.Y = targetRc.top; - vp.Width = targetRc.GetWidth(); - vp.Height = targetRc.GetHeight(); - vp.MinZ = 0.0; - vp.MaxZ = 1.0; - D3D::dev->SetViewport(&vp); - D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); - RestoreAPIState(); + // Update the viewport for clearing the target EFB rect + TargetRectangle targetRc = ConvertEFBRectangle(rc); + D3DVIEWPORT9 vp; + vp.X = targetRc.left; + vp.Y = targetRc.top; + vp.Width = targetRc.GetWidth(); + vp.Height = targetRc.GetHeight(); + vp.MinZ = 0.0; + vp.MaxZ = 1.0; + D3D::dev->SetViewport(&vp); + D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); + RestoreAPIState(); } void Renderer::ReinterpretPixelData(unsigned int convtype) { - RECT source; - SetRect(&source, 0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); + RECT source; + SetRect(&source, 0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); - LPDIRECT3DPIXELSHADER9 pixel_shader; - if (convtype == 0) pixel_shader = PixelShaderCache::ReinterpRGB8ToRGBA6(); - else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8(); - else - { - ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype); - return; - } + LPDIRECT3DPIXELSHADER9 pixel_shader; + if (convtype == 0) pixel_shader = PixelShaderCache::ReinterpRGB8ToRGBA6(); + else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8(); + else + { + ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype); + return; + } - // convert data and set the target texture as our new EFB - g_renderer->ResetAPIState(); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorReinterpretSurface()); - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = g_renderer->GetTargetWidth(); - vp.Height = g_renderer->GetTargetHeight(); - vp.MinZ = 0.0; - vp.MaxZ = 1.0; - D3D::dev->SetViewport(&vp); - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture(), &source, - g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - pixel_shader, VertexShaderCache::GetSimpleVertexShader(0)); - FramebufferManager::SwapReinterpretTexture(); - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - g_renderer->RestoreAPIState(); + // convert data and set the target texture as our new EFB + g_renderer->ResetAPIState(); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorReinterpretSurface()); + D3DVIEWPORT9 vp; + vp.X = 0; + vp.Y = 0; + vp.Width = g_renderer->GetTargetWidth(); + vp.Height = g_renderer->GetTargetHeight(); + vp.MinZ = 0.0; + vp.MaxZ = 1.0; + D3D::dev->SetViewport(&vp); + D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture(), &source, + g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), + g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), + pixel_shader, VertexShaderCache::GetSimpleVertexShader(0)); + FramebufferManager::SwapReinterpretTexture(); + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); + g_renderer->RestoreAPIState(); } void Renderer::SetBlendMode(bool forceUpdate) { - // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel - // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. - bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - //bDstAlphaPass is taken into account because the ability to disable alpha composition is - //really useful for debugging shader and blending errors - bool use_DstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha; - bool use_DualSource = use_DstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; - const D3DBLEND d3dSrcFactors[8] = - { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_DESTCOLOR, - D3DBLEND_INVDESTCOLOR, - (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, - (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, - (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, - (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO - }; - const D3DBLEND d3dDestFactors[8] = - { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVSRCCOLOR, - (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, - (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, - (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, - (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO - }; + // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel + // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. + bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + //bDstAlphaPass is taken into account because the ability to disable alpha composition is + //really useful for debugging shader and blending errors + bool use_DstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha; + bool use_DualSource = use_DstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; + const D3DBLEND d3dSrcFactors[8] = + { + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_DESTCOLOR, + D3DBLEND_INVDESTCOLOR, + (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, + (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, + (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, + (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO + }; + const D3DBLEND d3dDestFactors[8] = + { + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_SRCCOLOR, + D3DBLEND_INVSRCCOLOR, + (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, + (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, + (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, + (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO + }; - if (bpmem.blendmode.logicopenable && !forceUpdate) - { - D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE , false); - return; - } + if (bpmem.blendmode.logicopenable && !forceUpdate) + { + D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE , false); + return; + } - bool blend_enable = bpmem.blendmode.subtract || bpmem.blendmode.blendenable; - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, blend_enable); - D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, blend_enable && g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction); - if (blend_enable) - { - D3DBLENDOP op = D3DBLENDOP_ADD; - u32 srcidx = bpmem.blendmode.srcfactor; - u32 dstidx = bpmem.blendmode.dstfactor; - if (bpmem.blendmode.subtract) - { - op = D3DBLENDOP_REVSUBTRACT; - srcidx = GX_BL_ONE; - dstidx = GX_BL_ONE; - } - D3D::SetRenderState(D3DRS_BLENDOP, op); - D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[srcidx]); - D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[dstidx]); - if (g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction) - { - if (use_DualSource) - { - op = D3DBLENDOP_ADD; - srcidx = GX_BL_ONE; - dstidx = GX_BL_ZERO; - } - else - { - // we can't use D3DBLEND_DESTCOLOR or D3DBLEND_INVDESTCOLOR for source in alpha channel so use their alpha equivalent instead - if (srcidx == GX_BL_DSTCLR) srcidx = GX_BL_DSTALPHA; - if (srcidx == GX_BL_INVDSTCLR) srcidx = GX_BL_INVDSTALPHA; - // we can't use D3DBLEND_SRCCOLOR or D3DBLEND_INVSRCCOLOR for destination in alpha channel so use their alpha equivalent instead - if (dstidx == GX_BL_SRCCLR) dstidx = GX_BL_SRCALPHA; - if (dstidx == GX_BL_INVSRCCLR) dstidx = GX_BL_INVSRCALPHA; - } - D3D::SetRenderState(D3DRS_BLENDOPALPHA, op); - D3D::SetRenderState(D3DRS_SRCBLENDALPHA, d3dSrcFactors[srcidx]); - D3D::SetRenderState(D3DRS_DESTBLENDALPHA, d3dDestFactors[dstidx]); - } - } + bool blend_enable = bpmem.blendmode.subtract || bpmem.blendmode.blendenable; + D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, blend_enable); + D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, blend_enable && g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction); + if (blend_enable) + { + D3DBLENDOP op = D3DBLENDOP_ADD; + u32 srcidx = bpmem.blendmode.srcfactor; + u32 dstidx = bpmem.blendmode.dstfactor; + if (bpmem.blendmode.subtract) + { + op = D3DBLENDOP_REVSUBTRACT; + srcidx = GX_BL_ONE; + dstidx = GX_BL_ONE; + } + D3D::SetRenderState(D3DRS_BLENDOP, op); + D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[srcidx]); + D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[dstidx]); + if (g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction) + { + if (use_DualSource) + { + op = D3DBLENDOP_ADD; + srcidx = GX_BL_ONE; + dstidx = GX_BL_ZERO; + } + else + { + // we can't use D3DBLEND_DESTCOLOR or D3DBLEND_INVDESTCOLOR for source in alpha channel so use their alpha equivalent instead + if (srcidx == GX_BL_DSTCLR) srcidx = GX_BL_DSTALPHA; + if (srcidx == GX_BL_INVDSTCLR) srcidx = GX_BL_INVDSTALPHA; + // we can't use D3DBLEND_SRCCOLOR or D3DBLEND_INVSRCCOLOR for destination in alpha channel so use their alpha equivalent instead + if (dstidx == GX_BL_SRCCLR) dstidx = GX_BL_SRCALPHA; + if (dstidx == GX_BL_INVSRCCLR) dstidx = GX_BL_INVSRCALPHA; + } + D3D::SetRenderState(D3DRS_BLENDOPALPHA, op); + D3D::SetRenderState(D3DRS_SRCBLENDALPHA, d3dSrcFactors[srcidx]); + D3D::SetRenderState(D3DRS_DESTBLENDALPHA, d3dDestFactors[dstidx]); + } + } } bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &dst_rect) { - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); - if(FAILED(hr)) - { - PanicAlert("Error dumping surface data."); - return false; - } - hr = PD3DXSaveSurfaceToFileA(filename.c_str(), D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT()); - if(FAILED(hr)) - { - PanicAlert("Error saving screen."); - return false; - } + HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); + if(FAILED(hr)) + { + PanicAlert("Error dumping surface data."); + return false; + } + hr = PD3DXSaveSurfaceToFileA(filename.c_str(), D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT()); + if(FAILED(hr)) + { + PanicAlert("Error saving screen."); + return false; + } - return true; + return true; } // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { - if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) - { - if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); + if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) + { + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - Core::Callback_VideoCopiedToXFB(false); - return; - } + Core::Callback_VideoCopiedToXFB(false); + return; + } - if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; - u32 xfbCount = 0; - const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); - if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) - { - if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); + if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; + u32 xfbCount = 0; + const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) + { + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - Core::Callback_VideoCopiedToXFB(false); - return; - } + Core::Callback_VideoCopiedToXFB(false); + return; + } - ResetAPIState(); + ResetAPIState(); - if(g_ActiveConfig.bAnaglyphStereo) - { - static bool RightFrame = false; - if(RightFrame) - { - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); - VertexShaderManager::ResetView(); - VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); - VertexShaderManager::RotateView(-0.0001f *g_ActiveConfig.iAnaglyphFocalAngle,0.0f); - RightFrame = false; - } - else - { - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED); - VertexShaderManager::ResetView(); - VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); - VertexShaderManager::RotateView(0.0001f * g_ActiveConfig.iAnaglyphFocalAngle,0.0f); - RightFrame = true; - } - } + if(g_ActiveConfig.bAnaglyphStereo) + { + static bool RightFrame = false; + if(RightFrame) + { + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); + VertexShaderManager::ResetView(); + VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); + VertexShaderManager::RotateView(-0.0001f *g_ActiveConfig.iAnaglyphFocalAngle,0.0f); + RightFrame = false; + } + else + { + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED); + VertexShaderManager::ResetView(); + VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); + VertexShaderManager::RotateView(0.0001f * g_ActiveConfig.iAnaglyphFocalAngle,0.0f); + RightFrame = true; + } + } - // Prepare to copy the XFBs to our backbuffer - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - D3DVIEWPORT9 vp; + // Prepare to copy the XFBs to our backbuffer + D3D::dev->SetDepthStencilSurface(NULL); + D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - // Clear full target screen (edges, borders etc) - if(g_ActiveConfig.bAnaglyphStereo) { - // use a clear quad to keep old red or blue/green data - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); - } - else - { - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); - } + UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); + D3DVIEWPORT9 vp; - int X = GetTargetRectangle().left; - int Y = GetTargetRectangle().top; - int Width = GetTargetRectangle().right - GetTargetRectangle().left; - int Height = GetTargetRectangle().bottom - GetTargetRectangle().top; + // Clear full target screen (edges, borders etc) + if(g_ActiveConfig.bAnaglyphStereo) { + // use a clear quad to keep old red or blue/green data + vp.X = 0; + vp.Y = 0; + vp.Width = s_backbuffer_width; + vp.Height = s_backbuffer_height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); + D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); + } + else + { + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + } - // Sanity check - if (X < 0) X = 0; - if (Y < 0) Y = 0; - if (X > s_backbuffer_width) X = s_backbuffer_width; - if (Y > s_backbuffer_height) Y = s_backbuffer_height; - if (Width < 0) Width = 0; - if (Height < 0) Height = 0; - if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; - if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; + int X = GetTargetRectangle().left; + int Y = GetTargetRectangle().top; + int Width = GetTargetRectangle().right - GetTargetRectangle().left; + int Height = GetTargetRectangle().bottom - GetTargetRectangle().top; - vp.X = X; - vp.Y = Y; - vp.Width = Width; - vp.Height = Height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; + // Sanity check + if (X < 0) X = 0; + if (Y < 0) Y = 0; + if (X > s_backbuffer_width) X = s_backbuffer_width; + if (Y > s_backbuffer_height) Y = s_backbuffer_height; + if (Width < 0) Width = 0; + if (Height < 0) Height = 0; + if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; + if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; - D3D::dev->SetViewport(&vp); + vp.X = X; + vp.Y = Y; + vp.Width = Width; + vp.Height = Height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + D3D::dev->SetViewport(&vp); - const XFBSourceBase* xfbSource = NULL; + D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - if(g_ActiveConfig.bUseXFB) - { - // draw each xfb source - // Render to the real buffer now. - for (u32 i = 0; i < xfbCount; ++i) - { - xfbSource = xfbSourceList[i]; + const XFBSourceBase* xfbSource = NULL; - MathUtil::Rectangle sourceRc; - - sourceRc.left = 0; - sourceRc.top = 0; - sourceRc.right = (float)xfbSource->texWidth; - sourceRc.bottom = (float)xfbSource->texHeight; + if(g_ActiveConfig.bUseXFB) + { + // draw each xfb source + // Render to the real buffer now. + for (u32 i = 0; i < xfbCount; ++i) + { + xfbSource = xfbSourceList[i]; - MathUtil::Rectangle drawRc; + MathUtil::Rectangle sourceRc; - if (g_ActiveConfig.bUseRealXFB) - { - drawRc.top = -1; - drawRc.bottom = 1; - drawRc.left = -1; - drawRc.right = 1; - } - else - { - // use virtual xfb with offset - int xfbHeight = xfbSource->srcHeight; - int xfbWidth = xfbSource->srcWidth; - int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); + sourceRc.left = 0; + sourceRc.top = 0; + sourceRc.right = (float)xfbSource->texWidth; + sourceRc.bottom = (float)xfbSource->texHeight; - drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight); - drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); - drawRc.left = -(xfbWidth / (float)fbWidth); - drawRc.right = (xfbWidth / (float)fbWidth); + MathUtil::Rectangle drawRc; - // The following code disables auto stretch. Kept for reference. - // scale draw area for a 1 to 1 pixel mapping with the draw target - //float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight(); - //float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth(); - //drawRc.top *= vScale; - //drawRc.bottom *= vScale; - //drawRc.left *= hScale; - //drawRc.right *= hScale; - } + if (g_ActiveConfig.bUseRealXFB) + { + drawRc.top = -1; + drawRc.bottom = 1; + drawRc.left = -1; + drawRc.right = 1; + } + else + { + // use virtual xfb with offset + int xfbHeight = xfbSource->srcHeight; + int xfbWidth = xfbSource->srcWidth; + int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); - xfbSource->Draw(sourceRc, drawRc, Width, Height); - } - } - else - { - TargetRectangle targetRc = ConvertEFBRectangle(rc); - LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture(); - D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(), - Renderer::GetTargetWidth(),Renderer::GetTargetHeight(), - Width,Height, - PixelShaderCache::GetColorCopyProgram(g_ActiveConfig.iMultisampleMode), - VertexShaderCache::GetSimpleVertexShader(g_ActiveConfig.iMultisampleMode),Gamma); - - } - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); + drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight); + drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); + drawRc.left = -(xfbWidth / (float)fbWidth); + drawRc.right = (xfbWidth / (float)fbWidth); - if(g_ActiveConfig.bAnaglyphStereo) - { - DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); - } + // The following code disables auto stretch. Kept for reference. + // scale draw area for a 1 to 1 pixel mapping with the draw target + //float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight(); + //float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth(); + //drawRc.top *= vScale; + //drawRc.bottom *= vScale; + //drawRc.left *= hScale; + //drawRc.right *= hScale; + } - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); + xfbSource->Draw(sourceRc, drawRc, Width, Height); + } + } + else + { + TargetRectangle targetRc = ConvertEFBRectangle(rc); + LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture(); + D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(), + Renderer::GetTargetWidth(),Renderer::GetTargetHeight(), + Width,Height, + PixelShaderCache::GetColorCopyProgram(g_ActiveConfig.iMultisampleMode), + VertexShaderCache::GetSimpleVertexShader(g_ActiveConfig.iMultisampleMode),Gamma); - // Save screenshot - if (s_bScreenshot) - { - std::lock_guard lk(s_criticalScreenshot); - SaveScreenshot(s_sScreenshotName, GetTargetRectangle()); - s_bScreenshot = false; - } + } + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); + D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); - // Dump frames - static int w = 0, h = 0; - if (g_ActiveConfig.bDumpFrames) - { - static int s_recordWidth; - static int s_recordHeight; + if(g_ActiveConfig.bAnaglyphStereo) + { + DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); + } - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); - if (!bLastFrameDumped) - { - s_recordWidth = GetTargetRectangle().GetWidth(); - s_recordHeight = GetTargetRectangle().GetHeight(); - bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); - if (!bAVIDumping) - { - PanicAlert("Error dumping frames to AVI."); - } - else - { - char msg [255]; - sprintf_s(msg,255, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", - File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight); - OSD::AddMessage(msg, 2000); - } - } - if (bAVIDumping) - { - D3DLOCKED_RECT rect; - if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) - { - if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) - { - frame_data.resize(3 * s_recordWidth * s_recordHeight); - w = s_recordWidth; - h = s_recordHeight; - } - formatBufferDump((const u8*)rect.pBits, &frame_data[0], s_recordWidth, s_recordHeight, rect.Pitch); - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - ScreenShootMEMSurface->UnlockRect(); - } - } - bLastFrameDumped = true; - } - else - { - if (bLastFrameDumped && bAVIDumping) - { - std::vector().swap(frame_data); - w = h = 0; - AVIDump::Stop(); - bAVIDumping = false; - OSD::AddMessage("Stop dumping frames to AVI", 2000); - } - bLastFrameDumped = false; - } + vp.X = 0; + vp.Y = 0; + vp.Width = s_backbuffer_width; + vp.Height = s_backbuffer_height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); - // Finish up the current frame, print some stats - if (g_ActiveConfig.bShowFPS) - { - char fps[20]; - StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); - D3D::font.DrawTextScaled(0, 0, 20, 20, 0.0f, 0xFF00FFFF, fps); - } + // Save screenshot + if (s_bScreenshot) + { + std::lock_guard lk(s_criticalScreenshot); + SaveScreenshot(s_sScreenshotName, GetTargetRectangle()); + s_bScreenshot = false; + } - if (SConfig::GetInstance().m_ShowLag) - { - char lag[10]; - StringCchPrintfA(lag, 10, "Lag: %llu\n", Movie::g_currentLagCount); - D3D::font.DrawTextScaled(0, 18, 20, 20, 0.0f, 0xFF00FFFF, lag); - } + // Dump frames + static int w = 0, h = 0; + if (g_ActiveConfig.bDumpFrames) + { + static int s_recordWidth; + static int s_recordHeight; - if (g_ActiveConfig.bShowInputDisplay) - { - char inputDisplay[1000]; - StringCchPrintfA(inputDisplay, 1000, Movie::GetInputDisplay().c_str()); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, inputDisplay); - } + HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); + if (!bLastFrameDumped) + { + s_recordWidth = GetTargetRectangle().GetWidth(); + s_recordHeight = GetTargetRectangle().GetHeight(); + bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); + if (!bAVIDumping) + { + PanicAlert("Error dumping frames to AVI."); + } + else + { + char msg [255]; + sprintf_s(msg,255, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight); + OSD::AddMessage(msg, 2000); + } + } + if (bAVIDumping) + { + D3DLOCKED_RECT rect; + if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) + { + if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) + { + frame_data.resize(3 * s_recordWidth * s_recordHeight); + w = s_recordWidth; + h = s_recordHeight; + } + formatBufferDump((const u8*)rect.pBits, &frame_data[0], s_recordWidth, s_recordHeight, rect.Pitch); + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); + ScreenShootMEMSurface->UnlockRect(); + } + } + bLastFrameDumped = true; + } + else + { + if (bLastFrameDumped && bAVIDumping) + { + std::vector().swap(frame_data); + w = h = 0; + AVIDump::Stop(); + bAVIDumping = false; + OSD::AddMessage("Stop dumping frames to AVI", 2000); + } + bLastFrameDumped = false; + } - Renderer::DrawDebugText(); + // Finish up the current frame, print some stats + if (g_ActiveConfig.bShowFPS) + { + char fps[20]; + StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); + D3D::font.DrawTextScaled(0, 0, 20, 20, 0.0f, 0xFF00FFFF, fps); + } - if (g_ActiveConfig.bOverlayStats) - { - Statistics::ToString(st); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); - } - else if (g_ActiveConfig.bOverlayProjStats) - { - Statistics::ToStringProj(st); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); - } + if (SConfig::GetInstance().m_ShowLag) + { + char lag[10]; + StringCchPrintfA(lag, 10, "Lag: %llu\n", Movie::g_currentLagCount); + D3D::font.DrawTextScaled(0, 18, 20, 20, 0.0f, 0xFF00FFFF, lag); + } - OSD::DrawMessages(); - D3D::EndFrame(); - ++frameCount; + if (g_ActiveConfig.bShowInputDisplay) + { + char inputDisplay[1000]; + StringCchPrintfA(inputDisplay, 1000, Movie::GetInputDisplay().c_str()); + D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, inputDisplay); + } - GFX_DEBUGGER_PAUSE_AT(NEXT_FRAME, true); + Renderer::DrawDebugText(); - DLCache::ProgressiveCleanup(); - TextureCache::Cleanup(); - // Flip/present backbuffer to frontbuffer here - D3D::Present(); - // Enable configuration changes - UpdateActiveConfig(); - TextureCache::OnConfigChanged(g_ActiveConfig); + if (g_ActiveConfig.bOverlayStats) + { + Statistics::ToString(st); + D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); + } + else if (g_ActiveConfig.bOverlayProjStats) + { + Statistics::ToStringProj(st); + D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); + } - SetWindowSize(fbWidth, fbHeight); + OSD::DrawMessages(); + D3D::EndFrame(); + ++frameCount; - const bool windowResized = CheckForResize(); + GFX_DEBUGGER_PAUSE_AT(NEXT_FRAME, true); - bool xfbchanged = false; + DLCache::ProgressiveCleanup(); + TextureCache::Cleanup(); + // Flip/present backbuffer to frontbuffer here + D3D::Present(); + // Enable configuration changes + UpdateActiveConfig(); + TextureCache::OnConfigChanged(g_ActiveConfig); - if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight) - { - xfbchanged = true; - unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth; - unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight; - FramebufferManagerBase::SetLastXfbWidth(w); - FramebufferManagerBase::SetLastXfbHeight(h); - } + SetWindowSize(fbWidth, fbHeight); - u32 newAA = g_ActiveConfig.iMultisampleMode; + const bool windowResized = CheckForResize(); - if (xfbchanged || windowResized || s_LastEFBScale != g_ActiveConfig.iEFBScale || s_LastAA != newAA) - { - s_LastAA = newAA; + bool xfbchanged = false; - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - - int SupersampleCoeficient = (s_LastAA % 3) + 1; + if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight) + { + xfbchanged = true; + unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth; + unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight; + FramebufferManagerBase::SetLastXfbWidth(w); + FramebufferManagerBase::SetLastXfbHeight(h); + } - s_LastEFBScale = g_ActiveConfig.iEFBScale; - CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); + u32 newAA = g_ActiveConfig.iMultisampleMode; - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - if (windowResized) - { - // device objects lost, so recreate all of them - SetupDeviceObjects(); - } - else - { - // just resize the frame buffer - delete g_framebuffer_manager; - g_framebuffer_manager = new FramebufferManager; - } - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); - } + if (xfbchanged || windowResized || s_LastEFBScale != g_ActiveConfig.iEFBScale || s_LastAA != newAA) + { + s_LastAA = newAA; - if (XFBWrited) - s_fps = UpdateFPSCounter(); + UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - // Begin new frame - // Set default viewport and scissor, for the clear to work correctly - // New frame - stats.ResetFrame(); + int SupersampleCoeficient = (s_LastAA % 3) + 1; - // Handle vsync changes during execution - if(s_vsync != g_ActiveConfig.IsVSync()) - { - s_vsync = g_ActiveConfig.IsVSync(); - TeardownDeviceObjects(); - D3D::Reset(); - // device objects lost, so recreate all of them - SetupDeviceObjects(); - } - D3D::BeginFrame(); - RestoreAPIState(); + s_LastEFBScale = g_ActiveConfig.iEFBScale; + CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - VertexShaderManager::SetViewportChanged(); + D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); + D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); + if (windowResized) + { + // device objects lost, so recreate all of them + SetupDeviceObjects(); + } + else + { + // just resize the frame buffer + delete g_framebuffer_manager; + g_framebuffer_manager = new FramebufferManager; + } + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); + SetLineWidth(); + } - Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)); - XFBWrited = false; + if (XFBWrited) + s_fps = UpdateFPSCounter(); + + // Begin new frame + // Set default viewport and scissor, for the clear to work correctly + // New frame + stats.ResetFrame(); + + // Handle vsync changes during execution + if(s_vsync != g_ActiveConfig.IsVSync()) + { + s_vsync = g_ActiveConfig.IsVSync(); + TeardownDeviceObjects(); + D3D::Reset(); + // device objects lost, so recreate all of them + SetupDeviceObjects(); + } + D3D::BeginFrame(); + RestoreAPIState(); + + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + VertexShaderManager::SetViewportChanged(); + + Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)); + XFBWrited = false; } void Renderer::ApplyState(bool bUseDstAlpha) { - if (bUseDstAlpha) - { - // If we get here we are sure that we are using dst alpha pass. (bpmem.dstalpha.enable) - // Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) - // We must disable blend because we want to write alpha value directly to the alpha channel without modifications. - D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); - D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); - if(bpmem.zmode.testenable && bpmem.zmode.updateenable) - { - // This is needed to draw to the correct pixels in multi-pass algorithms - // to avoid z-fighting and grants that you write to the same pixels - // affected by the last pass - D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); - D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); - } - } + if (bUseDstAlpha) + { + // If we get here we are sure that we are using dst alpha pass. (bpmem.dstalpha.enable) + // Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) + // We must disable blend because we want to write alpha value directly to the alpha channel without modifications. + D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); + D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); + if(bpmem.zmode.testenable && bpmem.zmode.updateenable) + { + // This is needed to draw to the correct pixels in multi-pass algorithms + // to avoid z-fighting and grants that you write to the same pixels + // affected by the last pass + D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); + D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + } + } } void Renderer::RestoreState() { - D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); - D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); - if(bpmem.zmode.testenable && bpmem.zmode.updateenable) - { - D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); - D3D::RefreshRenderState(D3DRS_ZFUNC); - } - // TODO: Enable this code. Caused glitches for me however (neobrain) -// for (unsigned int i = 0; i < 8; ++i) -// D3D::dev->SetTexture(i, NULL); + D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); + D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); + if(bpmem.zmode.testenable && bpmem.zmode.updateenable) + { + D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); + D3D::RefreshRenderState(D3DRS_ZFUNC); + } + // TODO: Enable this code. Caused glitches for me however (neobrain) + // for (unsigned int i = 0; i < 8; ++i) + // D3D::dev->SetTexture(i, NULL); } // ALWAYS call RestoreAPIState for each ResetAPIState call you're doing void Renderer::ResetAPIState() { - D3D::SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - D3D::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); + D3D::SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + D3D::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + D3D::SetRenderState(D3DRS_ZENABLE, FALSE); + D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); } void Renderer::RestoreAPIState() { - // Gets us back into a more game-like state. - D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - VertexShaderManager::SetViewportChanged(); - BPFunctions::SetScissor(); - if (bpmem.zmode.testenable) { - D3D::SetRenderState(D3DRS_ZENABLE, TRUE); - if (bpmem.zmode.updateenable) - D3D::SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - } - SetColorMask(); - SetLogicOpMode(); - SetGenerationMode(); + // Gets us back into a more game-like state. + D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); + D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + VertexShaderManager::SetViewportChanged(); + BPFunctions::SetScissor(); + if (bpmem.zmode.testenable) { + D3D::SetRenderState(D3DRS_ZENABLE, TRUE); + if (bpmem.zmode.updateenable) + D3D::SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + } + SetColorMask(); + SetLogicOpMode(); + SetGenerationMode(); } void Renderer::SetGenerationMode() { - const D3DCULL d3dCullModes[4] = - { - D3DCULL_NONE, - D3DCULL_CCW, - D3DCULL_CW, - D3DCULL_CCW - }; + const D3DCULL d3dCullModes[4] = + { + D3DCULL_NONE, + D3DCULL_CCW, + D3DCULL_CW, + D3DCULL_CCW + }; - D3D::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]); + D3D::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]); } void Renderer::SetDepthMode() { - const D3DCMPFUNC d3dCmpFuncs[8] = - { - D3DCMP_NEVER, - D3DCMP_LESS, - D3DCMP_EQUAL, - D3DCMP_LESSEQUAL, - D3DCMP_GREATER, - D3DCMP_NOTEQUAL, - D3DCMP_GREATEREQUAL, - D3DCMP_ALWAYS - }; + const D3DCMPFUNC d3dCmpFuncs[8] = + { + D3DCMP_NEVER, + D3DCMP_LESS, + D3DCMP_EQUAL, + D3DCMP_LESSEQUAL, + D3DCMP_GREATER, + D3DCMP_NOTEQUAL, + D3DCMP_GREATEREQUAL, + D3DCMP_ALWAYS + }; - if (bpmem.zmode.testenable) - { - D3D::SetRenderState(D3DRS_ZENABLE, TRUE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable); - D3D::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]); - } - else - { - // if the test is disabled write is disabled too - D3D::SetRenderState(D3DRS_ZENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - } + if (bpmem.zmode.testenable) + { + D3D::SetRenderState(D3DRS_ZENABLE, TRUE); + D3D::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable); + D3D::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]); + } + else + { + // if the test is disabled write is disabled too + D3D::SetRenderState(D3DRS_ZENABLE, FALSE); + D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + } } void Renderer::SetLogicOpMode() { - // D3D9 doesn't support logic blending, so this is a huge hack + // D3D9 doesn't support logic blending, so this is a huge hack - // 0 0x00 - // 1 Source & destination - // 2 Source & ~destination - // 3 Source - // 4 ~Source & destination - // 5 Destination - // 6 Source ^ destination = Source & ~destination | ~Source & destination - // 7 Source | destination - // 8 ~(Source | destination) - // 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination - // 10 ~Destination - // 11 Source | ~destination - // 12 ~Source - // 13 ~Source | destination - // 14 ~(Source & destination) - // 15 0xff - const D3DBLENDOP d3dLogicOpop[16] = - { - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_SUBTRACT, - D3DBLENDOP_ADD, - D3DBLENDOP_REVSUBTRACT, - D3DBLENDOP_ADD, - D3DBLENDOP_MAX, - D3DBLENDOP_ADD, - D3DBLENDOP_MAX, - D3DBLENDOP_MAX, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD - }; - const D3DBLEND d3dLogicOpSrcFactors[16] = - { - D3DBLEND_ZERO, - D3DBLEND_DESTCOLOR, - D3DBLEND_ONE, - D3DBLEND_ONE, - D3DBLEND_DESTCOLOR, - D3DBLEND_ZERO, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_ONE - }; - const D3DBLEND d3dLogicOpDestFactors[16] = - { - D3DBLEND_ZERO, - D3DBLEND_ZERO, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE - }; + // 0 0x00 + // 1 Source & destination + // 2 Source & ~destination + // 3 Source + // 4 ~Source & destination + // 5 Destination + // 6 Source ^ destination = Source & ~destination | ~Source & destination + // 7 Source | destination + // 8 ~(Source | destination) + // 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination + // 10 ~Destination + // 11 Source | ~destination + // 12 ~Source + // 13 ~Source | destination + // 14 ~(Source & destination) + // 15 0xff + const D3DBLENDOP d3dLogicOpop[16] = + { + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_SUBTRACT, + D3DBLENDOP_ADD, + D3DBLENDOP_REVSUBTRACT, + D3DBLENDOP_ADD, + D3DBLENDOP_MAX, + D3DBLENDOP_ADD, + D3DBLENDOP_MAX, + D3DBLENDOP_MAX, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD + }; + const D3DBLEND d3dLogicOpSrcFactors[16] = + { + D3DBLEND_ZERO, + D3DBLEND_DESTCOLOR, + D3DBLEND_ONE, + D3DBLEND_ONE, + D3DBLEND_DESTCOLOR, + D3DBLEND_ZERO, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_ONE, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_ONE + }; + const D3DBLEND d3dLogicOpDestFactors[16] = + { + D3DBLEND_ZERO, + D3DBLEND_ZERO, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_ONE, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ONE, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_SRCCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ONE, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ONE + }; - if (bpmem.blendmode.logicopenable) - { - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, true); - D3D::SetRenderState(D3DRS_BLENDOP, d3dLogicOpop[bpmem.blendmode.logicmode]); - D3D::SetRenderState(D3DRS_SRCBLEND, d3dLogicOpSrcFactors[bpmem.blendmode.logicmode]); - D3D::SetRenderState(D3DRS_DESTBLEND, d3dLogicOpDestFactors[bpmem.blendmode.logicmode]); - } - else - { - SetBlendMode(true); - } + if (bpmem.blendmode.logicopenable) + { + D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, true); + D3D::SetRenderState(D3DRS_BLENDOP, d3dLogicOpop[bpmem.blendmode.logicmode]); + D3D::SetRenderState(D3DRS_SRCBLEND, d3dLogicOpSrcFactors[bpmem.blendmode.logicmode]); + D3D::SetRenderState(D3DRS_DESTBLEND, d3dLogicOpDestFactors[bpmem.blendmode.logicmode]); + } + else + { + SetBlendMode(true); + } } void Renderer::SetDitherMode() { - D3D::SetRenderState(D3DRS_DITHERENABLE, bpmem.blendmode.dither); + D3D::SetRenderState(D3DRS_DITHERENABLE, bpmem.blendmode.dither); } void Renderer::SetLineWidth() { - // We can't change line width in D3D unless we use ID3DXLine - float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; - float psize = bpmem.lineptwidth.linesize * fratio / 6.0f; - //little hack to compensate scaling problems in dx9 must be taken out when scaling is fixed. - psize *= 2.0f; - if (psize > m_fMaxPointSize) - { - psize = m_fMaxPointSize; - } - D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); - D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize)); - D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize)); + // We can't change line width in D3D unless we use ID3DXLine + float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; + float psize = bpmem.lineptwidth.pointsize * fratio / 6.0f; + psize = psize > 0 ? psize : 1.0; + if (psize > m_fMaxPointSize) + { + psize = m_fMaxPointSize; + } + D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize)); } void Renderer::SetSamplerState(int stage, int texindex) { - const D3DTEXTUREFILTERTYPE d3dMipFilters[4] = - { - D3DTEXF_NONE, - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_NONE, //reserved - }; - const D3DTEXTUREADDRESS d3dClamps[4] = - { - D3DTADDRESS_CLAMP, - D3DTADDRESS_WRAP, - D3DTADDRESS_MIRROR, - D3DTADDRESS_WRAP //reserved - }; + const D3DTEXTUREFILTERTYPE d3dMipFilters[4] = + { + D3DTEXF_NONE, + D3DTEXF_POINT, + D3DTEXF_LINEAR, + D3DTEXF_NONE, //reserved + }; + const D3DTEXTUREADDRESS d3dClamps[4] = + { + D3DTADDRESS_CLAMP, + D3DTADDRESS_WRAP, + D3DTADDRESS_MIRROR, + D3DTADDRESS_WRAP //reserved + }; - const FourTexUnits &tex = bpmem.tex[texindex]; - const TexMode0 &tm0 = tex.texMode0[stage]; - const TexMode1 &tm1 = tex.texMode1[stage]; - - D3DTEXTUREFILTERTYPE min, mag, mip; - if (g_ActiveConfig.bForceFiltering) - { - min = mag = mip = D3DTEXF_LINEAR; - } - else - { - min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; - mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT; - mip = d3dMipFilters[tm0.min_filter & 3]; - } - if (texindex) - stage += 4; + const FourTexUnits &tex = bpmem.tex[texindex]; + const TexMode0 &tm0 = tex.texMode0[stage]; + const TexMode1 &tm1 = tex.texMode1[stage]; - if (mag == D3DTEXF_LINEAR && min == D3DTEXF_LINEAR && g_ActiveConfig.iMaxAnisotropy) - { - min = D3DTEXF_ANISOTROPIC; - } - D3D::SetSamplerState(stage, D3DSAMP_MINFILTER, min); - D3D::SetSamplerState(stage, D3DSAMP_MAGFILTER, mag); - D3D::SetSamplerState(stage, D3DSAMP_MIPFILTER, mip); - - D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); - D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); + D3DTEXTUREFILTERTYPE min, mag, mip; + if (g_ActiveConfig.bForceFiltering) + { + min = mag = mip = D3DTEXF_LINEAR; + } + else + { + min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; + mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT; + mip = d3dMipFilters[tm0.min_filter & 3]; + } + if (texindex) + stage += 4; - float lodbias = (s32)tm0.lod_bias / 32.0f; - D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); - D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4); + if (mag == D3DTEXF_LINEAR && min == D3DTEXF_LINEAR && g_ActiveConfig.iMaxAnisotropy) + { + min = D3DTEXF_ANISOTROPIC; + } + D3D::SetSamplerState(stage, D3DSAMP_MINFILTER, min); + D3D::SetSamplerState(stage, D3DSAMP_MAGFILTER, mag); + D3D::SetSamplerState(stage, D3DSAMP_MIPFILTER, mip); + + D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); + D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); + + float lodbias = (s32)tm0.lod_bias / 32.0f; + D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); + D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4); } void Renderer::SetInterlacingMode() { - // TODO + // TODO } } // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index adb4ddf580..12f3b88576 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -36,375 +36,383 @@ const u32 MAX_VBUFFER_COUNT = 2; inline void DumpBadShaders() { #if defined(_DEBUG) || defined(DEBUGFAST) - // TODO: Reimplement! -/* std::string error_shaders; - error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); - error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); - char filename[512] = "bad_shader_combo_0.txt"; - int which = 0; - while (File::Exists(filename)) - { - which++; - sprintf(filename, "bad_shader_combo_%i.txt", which); - } - File::WriteStringToFile(true, error_shaders, filename); - PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/ + // TODO: Reimplement! + /* std::string error_shaders; + error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); + error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); + char filename[512] = "bad_shader_combo_0.txt"; + int which = 0; + while (File::Exists(filename)) + { + which++; + sprintf(filename, "bad_shader_combo_%i.txt", which); + } + File::WriteStringToFile(true, error_shaders, filename); + PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/ #endif } void VertexManager::CreateDeviceObjects() { - m_buffers_count = 0; - m_vertex_buffers = NULL; - m_index_buffers = NULL; - D3DCAPS9 DeviceCaps = D3D::GetCaps(); - u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; - //Calculate Device Dependant size - m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; - m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; - //if device caps are not enough for Vbuffer fall back to vertex arrays - if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; - - m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; - m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; + m_buffers_count = 0; + m_vertex_buffers = NULL; + m_index_buffers = NULL; + D3DCAPS9 DeviceCaps = D3D::GetCaps(); + u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; + //Calculate Device Dependant size + m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; + m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; + //if device caps are not enough for Vbuffer fall back to vertex arrays + if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; - bool Fail = false; - for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) - { - m_vertex_buffers[m_current_vertex_buffer] = NULL; - m_index_buffers[m_current_vertex_buffer] = NULL; - } - for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) - { - if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) - { - Fail = true; - break; - } - if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) - { - Fail = true; - return; - } - } - m_buffers_count = m_current_vertex_buffer; - m_current_vertex_buffer = 0; - m_current_index_buffer = 0; - m_index_buffer_cursor = m_index_buffer_size; - m_vertex_buffer_cursor = m_vertex_buffer_size; - m_current_stride = 0; - if (Fail) - { - m_buffers_count--; - if (m_buffers_count < 2) - { - //Error creating Vertex buffers. clean and fall to Vertex arrays - m_buffers_count = MAX_VBUFFER_COUNT; - DestroyDeviceObjects(); - } - } + m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; + m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; + + bool Fail = false; + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) + { + m_vertex_buffers[m_current_vertex_buffer] = NULL; + m_index_buffers[m_current_vertex_buffer] = NULL; + } + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) + { + if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) + { + Fail = true; + break; + } + if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) + { + Fail = true; + return; + } + } + m_buffers_count = m_current_vertex_buffer; + m_current_vertex_buffer = 0; + m_current_index_buffer = 0; + m_index_buffer_cursor = m_index_buffer_size; + m_vertex_buffer_cursor = m_vertex_buffer_size; + m_current_stride = 0; + if (Fail) + { + m_buffers_count--; + if (m_buffers_count < 2) + { + //Error creating Vertex buffers. clean and fall to Vertex arrays + m_buffers_count = MAX_VBUFFER_COUNT; + DestroyDeviceObjects(); + } + } } void VertexManager::DestroyDeviceObjects() { - D3D::SetStreamSource( 0, NULL, 0, 0); - D3D::SetIndices(NULL); - for (int i = 0; i < MAX_VBUFFER_COUNT; i++) - { - if(m_vertex_buffers) - { - if (m_vertex_buffers[i]) - { - m_vertex_buffers[i]->Release(); - m_vertex_buffers[i] = NULL; - } - } + D3D::SetStreamSource( 0, NULL, 0, 0); + D3D::SetIndices(NULL); + for (int i = 0; i < MAX_VBUFFER_COUNT; i++) + { + if(m_vertex_buffers) + { + if (m_vertex_buffers[i]) + { + m_vertex_buffers[i]->Release(); + m_vertex_buffers[i] = NULL; + } + } - if (m_index_buffers[i]) - { - m_index_buffers[i]->Release(); - m_index_buffers[i] = NULL; - } - } - if(m_vertex_buffers) - delete [] m_vertex_buffers; - if(m_index_buffers) - delete [] m_index_buffers; - m_vertex_buffers = NULL; - m_index_buffers = NULL; + if (m_index_buffers[i]) + { + m_index_buffers[i]->Release(); + m_index_buffers[i] = NULL; + } + } + if(m_vertex_buffers) + delete [] m_vertex_buffers; + if(m_index_buffers) + delete [] m_index_buffers; + m_vertex_buffers = NULL; + m_index_buffers = NULL; } void VertexManager::PrepareDrawBuffers(u32 stride) { - if (!m_buffers_count) - { - return; - } - u8* pVertices; - u16* pIndices; - int datasize = IndexGenerator::GetNumVerts() * stride; - int TdataSize = IndexGenerator::GetTriangleindexLen(); - int LDataSize = IndexGenerator::GetLineindexLen(); - int PDataSize = IndexGenerator::GetPointindexLen(); - int IndexDataSize = TdataSize + LDataSize; - DWORD LockMode = D3DLOCK_NOOVERWRITE; - m_vertex_buffer_cursor--; - m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; - if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) - { - LockMode = D3DLOCK_DISCARD; - m_vertex_buffer_cursor = 0; - m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; - } - if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) - { - DestroyDeviceObjects(); - return; - } - memcpy(pVertices, s_pBaseBufferPointer, datasize); - m_vertex_buffers[m_current_vertex_buffer]->Unlock(); + if (!m_buffers_count) + { + return; + } + u8* pVertices; + u16* pIndices; + int datasize = IndexGenerator::GetNumVerts() * stride; + int TdataSize = IndexGenerator::GetTriangleindexLen(); + int LDataSize = IndexGenerator::GetLineindexLen(); + int IndexDataSize = TdataSize + LDataSize; + if(IndexDataSize) + { + DWORD LockMode = D3DLOCK_NOOVERWRITE; + m_vertex_buffer_cursor--; + m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; + if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) + { + LockMode = D3DLOCK_DISCARD; + m_vertex_buffer_cursor = 0; + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; + } + if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) + { + DestroyDeviceObjects(); + return; + } + memcpy(pVertices, s_pBaseBufferPointer, datasize); + m_vertex_buffers[m_current_vertex_buffer]->Unlock(); - LockMode = D3DLOCK_NOOVERWRITE; - if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) - { - LockMode = D3DLOCK_DISCARD; - m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; - } - - if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) - { - DestroyDeviceObjects(); - return; - } - if(TdataSize) - { - memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); - pIndices += TdataSize; - } - if(LDataSize) - { - memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); - pIndices += LDataSize; - } - m_index_buffers[m_current_index_buffer]->Unlock(); - if(m_current_stride != stride || m_vertex_buffer_cursor == 0) - { - m_current_stride = stride; - D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, stride); - } - if (m_index_buffer_cursor == 0) - { - D3D::SetIndices(m_index_buffers[m_current_index_buffer]); - } - - ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); - ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); + LockMode = D3DLOCK_NOOVERWRITE; + if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) + { + LockMode = D3DLOCK_DISCARD; + m_index_buffer_cursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + } + + if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) + { + DestroyDeviceObjects(); + return; + } + if(TdataSize) + { + memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); + pIndices += TdataSize; + } + if(LDataSize) + { + memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); + pIndices += LDataSize; + } + m_index_buffers[m_current_index_buffer]->Unlock(); + } + if(m_current_stride != stride || m_vertex_buffer_cursor == 0) + { + m_current_stride = stride; + D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride); + } + if (m_index_buffer_cursor == 0) + { + D3D::SetIndices(m_index_buffers[m_current_index_buffer]); + } + + ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); + ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); } void VertexManager::DrawVertexBuffer(int stride) { - int triangles = IndexGenerator::GetNumTriangles(); - int lines = IndexGenerator::GetNumLines(); - int points = IndexGenerator::GetNumPoints(); - int numverts = IndexGenerator::GetNumVerts(); - int StartIndex = m_index_buffer_cursor; - int basevertex = m_vertex_buffer_cursor / stride; - if (triangles > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - basevertex, - 0, - numverts, - StartIndex, - triangles))) - { - DumpBadShaders(); - } - StartIndex += IndexGenerator::GetTriangleindexLen(); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (lines > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_LINELIST, - basevertex, - 0, - numverts, - StartIndex, - IndexGenerator::GetNumLines()))) - { - DumpBadShaders(); - } - StartIndex += IndexGenerator::GetLineindexLen(); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (points > 0) - { - //DrawIndexedPrimitive does not support point list so we have to draw the points one by one - for (int i = 0; i < points; i++) - { - if (FAILED(D3D::dev->DrawPrimitive( - D3DPT_POINTLIST, - basevertex + GetPointIndexBuffer()[i], - 1))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numDrawCalls); - } - - - } - + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + int StartIndex = m_index_buffer_cursor; + int basevertex = m_vertex_buffer_cursor / stride; + if (triangles > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_TRIANGLELIST, + basevertex, + 0, + numverts, + StartIndex, + triangles))) + { + DumpBadShaders(); + } + StartIndex += IndexGenerator::GetTriangleindexLen(); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (lines > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_LINELIST, + basevertex, + 0, + numverts, + StartIndex, + IndexGenerator::GetNumLines()))) + { + DumpBadShaders(); + } + StartIndex += IndexGenerator::GetLineindexLen(); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (points > 0) + { + //DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive + u16* PointIndexBuffer = GetPointIndexBuffer(); + int i = 0; + do + { + int count = i + 1; + while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count]) + { + count++; + } + if (FAILED(D3D::dev->DrawPrimitive( + D3DPT_POINTLIST, + basevertex + PointIndexBuffer[i], + count - i))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numDrawCalls); + i = count; + } while (i < points); + } + } void VertexManager::DrawVertexArray(int stride) { - int triangles = IndexGenerator::GetNumTriangles(); - int lines = IndexGenerator::GetNumLines(); - int points = IndexGenerator::GetNumPoints(); - int numverts = IndexGenerator::GetNumVerts(); - if (triangles > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_TRIANGLELIST, - 0, numverts, triangles, - GetTriangleIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (lines > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_LINELIST, - 0, numverts, lines, - GetLineIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (points > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_POINTLIST, - 0, numverts, points, - GetPointIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + if (triangles > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_TRIANGLELIST, + 0, numverts, triangles, + GetTriangleIndexBuffer(), + D3DFMT_INDEX16, + s_pBaseBufferPointer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (lines > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_LINELIST, + 0, numverts, lines, + GetLineIndexBuffer(), + D3DFMT_INDEX16, + s_pBaseBufferPointer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (points > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_POINTLIST, + 0, numverts, points, + GetPointIndexBuffer(), + D3DFMT_INDEX16, + s_pBaseBufferPointer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } } void VertexManager::vFlush() { - u32 usedtextures = 0; - for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) - if (bpmem.tevorders[i / 2].getEnable(i & 1)) - usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); + u32 usedtextures = 0; + for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) + if (bpmem.tevorders[i / 2].getEnable(i & 1)) + usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); - if (bpmem.genMode.numindstages > 0) - for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i) - if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) - usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); + if (bpmem.genMode.numindstages > 0) + for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i) + if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) + usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); - for (unsigned int i = 0; i < 8; i++) - { - if (usedtextures & (1 << i)) - { - g_renderer->SetSamplerState(i & 3, i >> 2); - FourTexUnits &tex = bpmem.tex[i >> 2]; - TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, - (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, - tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, - tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, - tex.texTlut[i&3].tlut_format, - (tex.texMode0[i&3].min_filter & 3), - (tex.texMode1[i&3].max_lod + 0xf) / 0x10, - tex.texImage1[i&3].image_type); + for (unsigned int i = 0; i < 8; i++) + { + if (usedtextures & (1 << i)) + { + g_renderer->SetSamplerState(i & 3, i >> 2); + FourTexUnits &tex = bpmem.tex[i >> 2]; + TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, + (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, + tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, + tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, + tex.texTlut[i&3].tlut_format, + (tex.texMode0[i&3].min_filter & 3), + (tex.texMode1[i&3].max_lod + 0xf) / 0x10, + tex.texImage1[i&3].image_type); - if (tentry) - { - // 0s are probably for no manual wrapping needed. - PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0); - } - else - ERROR_LOG(VIDEO, "Error loading texture"); - } - } + if (tentry) + { + // 0s are probably for no manual wrapping needed. + PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0); + } + else + ERROR_LOG(VIDEO, "Error loading texture"); + } + } - // set global constants - VertexShaderManager::SetConstants(); - PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); - u32 stride = g_nativeVertexFmt->GetVertexStride(); - bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && - bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; - DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE; + // set global constants + VertexShaderManager::SetConstants(); + PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); + u32 stride = g_nativeVertexFmt->GetVertexStride(); + bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && + bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; + DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE; - if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; - } - if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");}); - goto shader_fail; + if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components)) + { + GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); + goto shader_fail; + } + if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) + { + GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");}); + goto shader_fail; - } - PrepareDrawBuffers(stride); - g_nativeVertexFmt->SetupVertexPointers(); - g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - if(m_buffers_count) - { - DrawVertexBuffer(stride); - } - else - { - DrawVertexArray(stride); - } - g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - if (useDstAlpha && !useDualSource) - { - if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; - } - // update alpha only - g_renderer->ApplyState(true); - if(m_buffers_count) - { - DrawVertexBuffer(stride); - } - else - { - DrawVertexArray(stride); - } - g_renderer->RestoreState(); - } - GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); + } + PrepareDrawBuffers(stride); + g_nativeVertexFmt->SetupVertexPointers(); + g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } + g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + if (useDstAlpha && !useDualSource) + { + if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components)) + { + GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); + goto shader_fail; + } + // update alpha only + g_renderer->ApplyState(true); + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } + g_renderer->RestoreState(); + } + GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); shader_fail: - if(m_buffers_count) - { - m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); - m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; - } + if(m_buffers_count) + { + m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; + } } } From 08a6b8920b41737820f684582508ff8818c8a68c Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Thu, 15 Aug 2013 15:16:32 -0300 Subject: [PATCH 6/8] re indentation to follow emulators code rules in some files I'm modifying --- .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 564 +++++++++--------- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 364 +++++------ Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 328 +++++----- 3 files changed, 631 insertions(+), 625 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 22e31ad192..527fe5d177 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -40,15 +40,15 @@ static std::set unique_shaders; #define MAX_SSAA_SHADERS 3 enum { - COPY_TYPE_DIRECT, - COPY_TYPE_MATRIXCOLOR, - NUM_COPY_TYPES + COPY_TYPE_DIRECT, + COPY_TYPE_MATRIXCOLOR, + NUM_COPY_TYPES }; enum { - DEPTH_CONVERSION_TYPE_NONE, - DEPTH_CONVERSION_TYPE_ON, - NUM_DEPTH_CONVERSION_TYPES + DEPTH_CONVERSION_TYPE_NONE, + DEPTH_CONVERSION_TYPE_ON, + NUM_DEPTH_CONVERSION_TYPES }; static LPDIRECT3DPIXELSHADER9 s_CopyProgram[NUM_COPY_TYPES][NUM_DEPTH_CONVERSION_TYPES][MAX_SSAA_SHADERS]; @@ -59,30 +59,30 @@ static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL; class PixelShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) - { - PixelShaderCache::InsertByteCode(key, value, value_size, false); - } + void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) + { + PixelShaderCache::InsertByteCode(key, value, value_size, false); + } }; LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram(int SSAAMode) { - return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; + return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetDepthMatrixProgram(int SSAAMode, bool depthConversion) { - return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][depthConversion ? DEPTH_CONVERSION_TYPE_ON : DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; + return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][depthConversion ? DEPTH_CONVERSION_TYPE_ON : DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram(int SSAAMode) { - return s_CopyProgram[COPY_TYPE_DIRECT][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; + return s_CopyProgram[COPY_TYPE_DIRECT][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram() { - return s_ClearProgram; + return s_ClearProgram; } static LPDIRECT3DPIXELSHADER9 s_rgb8 = NULL; @@ -90,360 +90,360 @@ static LPDIRECT3DPIXELSHADER9 s_rgba6 = NULL; LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGBA6ToRGB8() { - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0){\n" - " ocol0 = tex2D(samp0,uv0);\n" - " float4 src6 = round(ocol0 * 63.f);\n" - " ocol0.r = floor(src6.r*4.f) + floor(src6.g/16.f);\n" // dst8r = (src6r<<2)|(src6g>>4); - " ocol0.g = frac(src6.g/16.f)*16.f*16.f + floor(src6.b/4.f);\n" // dst8g = ((src6g&0xF)<<4)|(src6b>>2); - " ocol0.b = frac(src6.b/4.f)*4.f*64.f + src6.a;\n" // dst8b = ((src6b&0x3)<<6)|src6a; - " ocol0.a = 255.f;\n" - " ocol0 /= 255.f;\n" - "}\n" - }; + const char code[] = + { + "uniform sampler samp0 : register(s0);\n" + "void main(\n" + " out float4 ocol0 : COLOR0,\n" + " in float2 uv0 : TEXCOORD0){\n" + " ocol0 = tex2D(samp0,uv0);\n" + " float4 src6 = round(ocol0 * 63.f);\n" + " ocol0.r = floor(src6.r*4.f) + floor(src6.g/16.f);\n" // dst8r = (src6r<<2)|(src6g>>4); + " ocol0.g = frac(src6.g/16.f)*16.f*16.f + floor(src6.b/4.f);\n" // dst8g = ((src6g&0xF)<<4)|(src6b>>2); + " ocol0.b = frac(src6.b/4.f)*4.f*64.f + src6.a;\n" // dst8b = ((src6b&0x3)<<6)|src6a; + " ocol0.a = 255.f;\n" + " ocol0 /= 255.f;\n" + "}\n" + }; - if (!s_rgba6_to_rgb8) - s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); + if (!s_rgba6_to_rgb8) + s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); - return s_rgba6_to_rgb8; + return s_rgba6_to_rgb8; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGB8ToRGBA6() { - /* old code here for reference - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0){\n" - " ocol0 = tex2D(samp0,uv0);\n" - " float4 src8 = round(ocol0*255.f);\n" - " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; - " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); - " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); - " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; - " ocol0 /= 63.f;\n" - "}\n" - }; - */ - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - "out float4 ocol0 : COLOR0,\n" - "in float2 uv0 : TEXCOORD0){\n" - "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" - "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" - "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" - "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" - "}\n" - }; - if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); - return s_rgb8_to_rgba6; + /* old code here for reference + const char code[] = + { + "uniform sampler samp0 : register(s0);\n" + "void main(\n" + " out float4 ocol0 : COLOR0,\n" + " in float2 uv0 : TEXCOORD0){\n" + " ocol0 = tex2D(samp0,uv0);\n" + " float4 src8 = round(ocol0*255.f);\n" + " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; + " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); + " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); + " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; + " ocol0 /= 63.f;\n" + "}\n" + }; + */ + const char code[] = + { + "uniform sampler samp0 : register(s0);\n" + "void main(\n" + "out float4 ocol0 : COLOR0,\n" + "in float2 uv0 : TEXCOORD0){\n" + "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" + "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" + "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" + "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" + "}\n" + }; + if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); + return s_rgb8_to_rgba6; } #define WRITE p+=sprintf static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConversionType, int SSAAMode) { - //Used for Copy/resolve the color buffer - //Color conversion Programs - //Depth copy programs - // this should create the same shaders as before (plus some extras added for DF16), just... more manageably than listing the full program for each combination - char text[3072]; + //Used for Copy/resolve the color buffer + //Color conversion Programs + //Depth copy programs + // this should create the same shaders as before (plus some extras added for DF16), just... more manageably than listing the full program for each combination + char text[3072]; - locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation - locale_t old_locale = uselocale(locale); // Apply the locale for this thread - text[sizeof(text) - 1] = 0x7C; // canary + locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation + locale_t old_locale = uselocale(locale); // Apply the locale for this thread + text[sizeof(text) - 1] = 0x7C; // canary - char* p = text; - WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode); + char* p = text; + WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode); - WRITE(p, "uniform sampler samp0 : register(s0);\n"); - if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) - WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX); - WRITE(p, "void main(\n" - "out float4 ocol0 : COLOR0,\n"); + WRITE(p, "uniform sampler samp0 : register(s0);\n"); + if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) + WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX); + WRITE(p, "void main(\n" + "out float4 ocol0 : COLOR0,\n"); - switch(SSAAMode % MAX_SSAA_SHADERS) - { - case 0: // 1 Sample - WRITE(p, "in float2 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1){\n" - "float4 texcol = tex2D(samp0,uv0.xy);\n"); - break; - case 1: // 4 Samples in 4x SSAA buffer - WRITE(p, "in float4 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1,\n" - "in float4 uv2 : TEXCOORD2,\n" - "in float4 uv3 : TEXCOORD3){\n" - "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); - break; - case 2: // 4 Samples in 9x SSAA buffer - WRITE(p, "in float4 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1,\n" - "in float4 uv2 : TEXCOORD2,\n" - "in float4 uv3 : TEXCOORD3){\n" - "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); - break; - } + switch(SSAAMode % MAX_SSAA_SHADERS) + { + case 0: // 1 Sample + WRITE(p, "in float2 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1){\n" + "float4 texcol = tex2D(samp0,uv0.xy);\n"); + break; + case 1: // 4 Samples in 4x SSAA buffer + WRITE(p, "in float4 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3){\n" + "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); + break; + case 2: // 4 Samples in 9x SSAA buffer + WRITE(p, "in float4 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3){\n" + "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); + break; + } - if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE) - { - // Watch out for the fire fumes effect in Metroid it's really sensitive to this, - // the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off. - WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n" - "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); - } - else - { - //Apply Gamma Correction - WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n"); - } + if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE) + { + // Watch out for the fire fumes effect in Metroid it's really sensitive to this, + // the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off. + WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n" + "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); + } + else + { + //Apply Gamma Correction + WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n"); + } - if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) - { - if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE) - WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n"); + if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) + { + if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE) + WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n"); - WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"); - } - else - WRITE(p, "ocol0 = texcol;\n"); + WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"); + } + else + WRITE(p, "ocol0 = texcol;\n"); - WRITE(p, "}\n"); - if (text[sizeof(text) - 1] != 0x7C) - PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!"); - - uselocale(old_locale); // restore locale - freelocale(locale); - return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); + WRITE(p, "}\n"); + if (text[sizeof(text) - 1] != 0x7C) + PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!"); + + uselocale(old_locale); // restore locale + freelocale(locale); + return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); } void PixelShaderCache::Init() { - last_entry = NULL; + last_entry = NULL; - //program used for clear screen - { - char pprog[3072]; - sprintf(pprog, "void main(\n" - "out float4 ocol0 : COLOR0,\n" - " in float4 incol0 : COLOR0){\n" - "ocol0 = incol0;\n" - "}\n"); - s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); - } + //program used for clear screen + { + char pprog[3072]; + sprintf(pprog, "void main(\n" + "out float4 ocol0 : COLOR0,\n" + " in float4 incol0 : COLOR0){\n" + "ocol0 = incol0;\n" + "}\n"); + s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); + } - int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF); - int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); + int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF); + int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); - // other screen copy/convert programs - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - { - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - { - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - { - if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1] - || depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode] - || copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]) - { - // if it failed at a lower setting, it's going to fail here for the same reason it did there, - // so skip this attempt to avoid duplicate error messages. - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; - } - else - { - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode); - } - } - } - } + // other screen copy/convert programs + for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) + { + for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) + { + for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) + { + if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1] + || depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode] + || copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]) + { + // if it failed at a lower setting, it's going to fail here for the same reason it did there, + // so skip this attempt to avoid duplicate error messages. + s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; + } + else + { + s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode); + } + } + } + } - Clear(); + Clear(); - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); - SETSTAT(stats.numPixelShadersCreated, 0); - SETSTAT(stats.numPixelShadersAlive, 0); + SETSTAT(stats.numPixelShadersCreated, 0); + SETSTAT(stats.numPixelShadersAlive, 0); - char cache_filename[MAX_PATH]; - sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - PixelShaderCacheInserter inserter; - g_ps_disk_cache.OpenAndRead(cache_filename, inserter); + char cache_filename[MAX_PATH]; + sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + PixelShaderCacheInserter inserter; + g_ps_disk_cache.OpenAndRead(cache_filename, inserter); - if (g_Config.bEnableShaderDebugging) - Clear(); + if (g_Config.bEnableShaderDebugging) + Clear(); } // ONLY to be used during shutdown. void PixelShaderCache::Clear() { - for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) - iter->second.Destroy(); - PixelShaders.clear(); - pixel_uid_checker.Invalidate(); + for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) + iter->second.Destroy(); + PixelShaders.clear(); + pixel_uid_checker.Invalidate(); - last_entry = NULL; + last_entry = NULL; } void PixelShaderCache::Shutdown() { - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - if(s_CopyProgram[copyMatrixType][depthType][ssaaMode] - && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) - s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release(); + for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) + for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) + for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) + if(s_CopyProgram[copyMatrixType][depthType][ssaaMode] + && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) + s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release(); - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; + for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) + for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) + for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) + s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; - if (s_ClearProgram) s_ClearProgram->Release(); - s_ClearProgram = NULL; - if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); - s_rgb8_to_rgba6 = NULL; - if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); - s_rgba6_to_rgb8 = NULL; + if (s_ClearProgram) s_ClearProgram->Release(); + s_ClearProgram = NULL; + if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); + s_rgb8_to_rgba6 = NULL; + if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); + s_rgba6_to_rgb8 = NULL; - Clear(); - g_ps_disk_cache.Sync(); - g_ps_disk_cache.Close(); + Clear(); + g_ps_disk_cache.Sync(); + g_ps_disk_cache.Close(); - unique_shaders.clear(); + unique_shaders.clear(); } bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { - const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30; - PixelShaderUid uid; - GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components); - if (g_ActiveConfig.bEnableShaderDebugging) - { - PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components); - pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); - } + const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30; + PixelShaderUid uid; + GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components); + if (g_ActiveConfig.bEnableShaderDebugging) + { + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components); + pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); + } - // Check if the shader is already set - if (last_entry) - { - if (uid == last_uid) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return last_entry->shader != NULL; - } - } + // Check if the shader is already set + if (last_entry) + { + if (uid == last_uid) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); + return last_entry->shader != NULL; + } + } - last_uid = uid; + last_uid = uid; - // Check if the shader is already in the cache - PSCache::iterator iter; - iter = PixelShaders.find(uid); - if (iter != PixelShaders.end()) - { - const PSCacheEntry &entry = iter->second; - last_entry = &entry; + // Check if the shader is already in the cache + PSCache::iterator iter; + iter = PixelShaders.find(uid); + if (iter != PixelShaders.end()) + { + const PSCacheEntry &entry = iter->second; + last_entry = &entry; - if (entry.shader) D3D::SetPixelShader(entry.shader); - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return (entry.shader != NULL); - } + if (entry.shader) D3D::SetPixelShader(entry.shader); + GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); + return (entry.shader != NULL); + } - // Need to compile a new shader - PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, api, components); + // Need to compile a new shader + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, api, components); - if (g_ActiveConfig.bEnableShaderDebugging) - { - u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer())); - unique_shaders.insert(code_hash); - SETSTAT(stats.numUniquePixelShaders, unique_shaders.size()); - } + if (g_ActiveConfig.bEnableShaderDebugging) + { + u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer())); + unique_shaders.insert(code_hash); + SETSTAT(stats.numUniquePixelShaders, unique_shaders.size()); + } #if defined(_DEBUG) || defined(DEBUGFAST) - if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { - static int counter = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); + if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { + static int counter = 0; + char szTemp[MAX_PATH]; + sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); - SaveData(szTemp, code.GetBuffer()); - } + SaveData(szTemp, code.GetBuffer()); + } #endif - u8 *bytecode = 0; - int bytecodelen = 0; - if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { - GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); - return false; - } + u8 *bytecode = 0; + int bytecodelen = 0; + if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { + GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); + return false; + } - // Insert the bytecode into the caches - g_ps_disk_cache.Append(uid, bytecode, bytecodelen); + // Insert the bytecode into the caches + g_ps_disk_cache.Append(uid, bytecode, bytecodelen); - // And insert it into the shader cache. - bool success = InsertByteCode(uid, bytecode, bytecodelen, true); - delete [] bytecode; + // And insert it into the shader cache. + bool success = InsertByteCode(uid, bytecode, bytecodelen, true); + delete [] bytecode; - if (g_ActiveConfig.bEnableShaderDebugging && success) - { - PixelShaders[uid].code = code.GetBuffer(); - } + if (g_ActiveConfig.bEnableShaderDebugging && success) + { + PixelShaders[uid].code = code.GetBuffer(); + } - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return success; + GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); + return success; } bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { - LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); + LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); - // Make an entry in the table - PSCacheEntry newentry; - newentry.shader = shader; - PixelShaders[uid] = newentry; - last_entry = &PixelShaders[uid]; + // Make an entry in the table + PSCacheEntry newentry; + newentry.shader = shader; + PixelShaders[uid] = newentry; + last_entry = &PixelShaders[uid]; - if (!shader) { - // INCSTAT(stats.numPixelShadersFailed); - return false; - } + if (!shader) { + // INCSTAT(stats.numPixelShadersFailed); + return false; + } - INCSTAT(stats.numPixelShadersCreated); - SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); - if (activate) - { - D3D::SetPixelShader(shader); - } - return true; + INCSTAT(stats.numPixelShadersCreated); + SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); + if (activate) + { + D3D::SetPixelShader(shader); + } + return true; } void Renderer::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { - float f[4] = { f1, f2, f3, f4 }; - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); + float f[4] = { f1, f2, f3, f4 }; + DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); } void Renderer::SetPSConstant4fv(unsigned int const_number, const float *f) { - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); + DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); } void Renderer::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) { - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count); + DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count); } } // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 93cd7a67df..2300291e7d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -37,251 +37,257 @@ LinearDiskCache g_vs_disk_cache; LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level) { - return SimpleVertexShader[level % MAX_SSAA_SHADERS]; + return SimpleVertexShader[level % MAX_SSAA_SHADERS]; } LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader() { - return ClearVertexShader; + return ClearVertexShader; } // this class will load the precompiled shaders into our cache class VertexShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) - { - VertexShaderCache::InsertByteCode(key, value, value_size, false); - } + void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) + { + VertexShaderCache::InsertByteCode(key, value, value_size, false); + } }; void VertexShaderCache::Init() { - char* vProg = new char[2048]; - sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float2 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0;\n" - "OUT.vTexCoord1 = inTEX2;\n" - "return OUT;\n" - "}\n"); + char* vProg = new char[2048]; + sprintf(vProg,"struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float2 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;\n" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0;\n" + "OUT.vTexCoord1 = inTEX2;\n" + "return OUT;\n" + "}\n"); - SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); + SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vColor0 : COLOR0;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vColor0 = inColor0;\n" - "return OUT;\n" - "}\n"); + sprintf(vProg,"struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vColor0 : COLOR0;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" + "{\n" + "VSOUTPUT OUT;\n" + "OUT.vPosition = inPosition;\n" + "OUT.vColor0 = inColor0;\n" + "return OUT;\n" + "}\n"); - ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "float4 vTexCoord2 : TEXCOORD2;\n" - "float4 vTexCoord3 : TEXCOORD3;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0.xyyx;\n" - "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" - "return OUT;\n" - "}\n"); - SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); + ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); + sprintf(vProg, "struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0.xyyx;\n" + "OUT.vTexCoord1 = inTEX2.x;\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" + "return OUT;\n" + "}\n"); + SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "float4 vTexCoord2 : TEXCOORD2;\n" - "float4 vTexCoord3 : TEXCOORD3;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0.xyyx;\n" - "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" - "return OUT;\n" - "}\n"); - SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - - Clear(); - delete [] vProg; + sprintf(vProg, "struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0.xyyx;\n" + "OUT.vTexCoord1 = inTEX2.x;\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" + "return OUT;\n" + "}\n"); + SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); + Clear(); + delete [] vProg; - SETSTAT(stats.numVertexShadersCreated, 0); - SETSTAT(stats.numVertexShadersAlive, 0); + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); - char cache_filename[MAX_PATH]; - sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - VertexShaderCacheInserter inserter; - g_vs_disk_cache.OpenAndRead(cache_filename, inserter); + SETSTAT(stats.numVertexShadersCreated, 0); + SETSTAT(stats.numVertexShadersAlive, 0); - if (g_Config.bEnableShaderDebugging) - Clear(); + char cache_filename[MAX_PATH]; + sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + VertexShaderCacheInserter inserter; + g_vs_disk_cache.OpenAndRead(cache_filename, inserter); - last_entry = NULL; + if (g_Config.bEnableShaderDebugging) + Clear(); + + last_entry = NULL; } void VertexShaderCache::Clear() { - for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) - iter->second.Destroy(); - vshaders.clear(); - vertex_uid_checker.Invalidate(); + for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) + iter->second.Destroy(); + vshaders.clear(); + vertex_uid_checker.Invalidate(); - last_entry = NULL; + last_entry = NULL; } void VertexShaderCache::Shutdown() { - for (int i = 0; i < MAX_SSAA_SHADERS; i++) - { - if (SimpleVertexShader[i]) - SimpleVertexShader[i]->Release(); - SimpleVertexShader[i] = NULL; - } + for (int i = 0; i < MAX_SSAA_SHADERS; i++) + { + if (SimpleVertexShader[i]) + SimpleVertexShader[i]->Release(); + SimpleVertexShader[i] = NULL; + } - if (ClearVertexShader) - ClearVertexShader->Release(); - ClearVertexShader = NULL; - - Clear(); - g_vs_disk_cache.Sync(); - g_vs_disk_cache.Close(); + if (ClearVertexShader) + ClearVertexShader->Release(); + ClearVertexShader = NULL; + + Clear(); + g_vs_disk_cache.Sync(); + g_vs_disk_cache.Close(); } bool VertexShaderCache::SetShader(u32 components) { - VertexShaderUid uid; - GetVertexShaderUid(uid, components, API_D3D9); - if (g_ActiveConfig.bEnableShaderDebugging) - { - VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D9); - vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); - } + VertexShaderUid uid; + GetVertexShaderUid(uid, components, API_D3D9); + if (g_ActiveConfig.bEnableShaderDebugging) + { + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_D3D9); + vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); + } - if (last_entry) - { - if (uid == last_uid) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (last_entry->shader != NULL); - } - } + if (last_entry) + { + if (uid == last_uid) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return (last_entry->shader != NULL); + } + } - last_uid = uid; + last_uid = uid; - VSCache::iterator iter = vshaders.find(uid); - if (iter != vshaders.end()) - { - const VSCacheEntry &entry = iter->second; - last_entry = &entry; + VSCache::iterator iter = vshaders.find(uid); + if (iter != vshaders.end()) + { + const VSCacheEntry &entry = iter->second; + last_entry = &entry; - if (entry.shader) D3D::SetVertexShader(entry.shader); - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (entry.shader != NULL); - } + if (entry.shader) D3D::SetVertexShader(entry.shader); + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return (entry.shader != NULL); + } - VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D9); + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_D3D9); - u8 *bytecode; - int bytecodelen; - if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); - return false; - } - g_vs_disk_cache.Append(uid, bytecode, bytecodelen); + u8 *bytecode; + int bytecodelen; + if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); + return false; + } + g_vs_disk_cache.Append(uid, bytecode, bytecodelen); - bool success = InsertByteCode(uid, bytecode, bytecodelen, true); - if (g_ActiveConfig.bEnableShaderDebugging && success) - { - vshaders[uid].code = code.GetBuffer(); - } - delete [] bytecode; - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return success; + bool success = InsertByteCode(uid, bytecode, bytecodelen, true); + if (g_ActiveConfig.bEnableShaderDebugging && success) + { + vshaders[uid].code = code.GetBuffer(); + } + delete [] bytecode; + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return success; } bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { - LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); + LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); - // Make an entry in the table - VSCacheEntry entry; - entry.shader = shader; + // Make an entry in the table + VSCacheEntry entry; + entry.shader = shader; - vshaders[uid] = entry; - last_entry = &vshaders[uid]; - if (!shader) - return false; + vshaders[uid] = entry; + last_entry = &vshaders[uid]; + if (!shader) + return false; - INCSTAT(stats.numVertexShadersCreated); - SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); - if (activate) - { - D3D::SetVertexShader(shader); - return true; - } - return false; + INCSTAT(stats.numVertexShadersCreated); + SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); + if (activate) + { + D3D::SetVertexShader(shader); + return true; + } + return false; } +float VSConstantbuffer[4*C_VENVCONST_END]; + void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { - const float f[4] = { f1, f2, f3, f4 }; - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); + float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; + VSConstantbuffer_pointer[0] = f1; + VSConstantbuffer_pointer[1] = f2; + VSConstantbuffer_pointer[2] = f3; + VSConstantbuffer_pointer[3] = f4; + DX9::D3D::dev->SetVertexShaderConstantF(const_number, VSConstantbuffer_pointer, 1); } void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f) { - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); + DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); } void Renderer::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f) { - float buf[4*C_VENVCONST_END]; - for (unsigned int i = 0; i < count; i++) - { - buf[4*i ] = *f++; - buf[4*i+1] = *f++; - buf[4*i+2] = *f++; - buf[4*i+3] = 0.f; - } - DX9::D3D::dev->SetVertexShaderConstantF(const_number, buf, count); + float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; + for (unsigned int i = 0; i < count; i++) + { + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = 0.f; + } + DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count); } void Renderer::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f) { - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, count); + DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, count); } } // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index ab5e85d64d..3c4c66d35f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -50,192 +50,192 @@ namespace DX9 { -unsigned int VideoBackend::PeekMessages() -{ - MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - return FALSE; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return TRUE; -} - -void VideoBackend::UpdateFPSDisplay(const char *text) -{ - TCHAR temp[512]; - swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); - EmuWindow::SetWindowText(temp); -} - -std::string VideoBackend::GetName() -{ - return "DX9"; -} - -std::string VideoBackend::GetDisplayName() -{ - return "Direct3D9 (deprecated)"; -} - -void InitBackendInfo() -{ - DX9::D3D::Init(); - D3DCAPS9 device_caps = DX9::D3D::GetCaps(); - const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); - const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); - g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30; - g_Config.backend_info.bUseRGBATextures = false; - g_Config.backend_info.bUseMinimalMipCount = true; - g_Config.backend_info.bSupports3DVision = true; - g_Config.backend_info.bSupportsPrimitiveRestart = false; // TODO: figure out if it does - g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; - // Dual source blend disabled by default until a proper method to test for support is found - g_Config.backend_info.bSupports3DVision = true; - OSVERSIONINFO info; - ZeroMemory(&info, sizeof(OSVERSIONINFO)); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&info)) + unsigned int VideoBackend::PeekMessages() { + MSG msg; + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + return FALSE; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return TRUE; + } + + void VideoBackend::UpdateFPSDisplay(const char *text) + { + TCHAR temp[512]; + swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); + EmuWindow::SetWindowText(temp); + } + + std::string VideoBackend::GetName() + { + return "DX9"; + } + + std::string VideoBackend::GetDisplayName() + { + return "Direct3D9 (deprecated)"; + } + + void InitBackendInfo() + { + DX9::D3D::Init(); + D3DCAPS9 device_caps = DX9::D3D::GetCaps(); + const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); + const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); + g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30; + g_Config.backend_info.bUseRGBATextures = false; + g_Config.backend_info.bUseMinimalMipCount = true; + g_Config.backend_info.bSupports3DVision = true; + g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart + g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; + // Dual source blend disabled by default until a proper method to test for support is found + g_Config.backend_info.bSupports3DVision = true; + OSVERSIONINFO info; + ZeroMemory(&info, sizeof(OSVERSIONINFO)); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx(&info)) + { // dual source blending is only supported in windows 7 o newer. sorry xp users // we cannot test for device caps because most drivers just declare the minimun caps // and don't expose their support for some functionalities g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); - } - else - { + } + else + { g_Config.backend_info.bSupportsDualSourceBlend = false; + } + g_Config.backend_info.bSupportsFormatReinterpretation = true; + g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; + g_Config.backend_info.bSupportsEarlyZ = false; + + // adapters + g_Config.backend_info.Adapters.clear(); + for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i) + g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description); + + // aamodes + g_Config.backend_info.AAModes.clear(); + if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) + { + const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); + + for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) + g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); + } + + // Clear ppshaders string vector + g_Config.backend_info.PPShaders.clear(); + + DX9::D3D::Shutdown(); } - g_Config.backend_info.bSupportsFormatReinterpretation = true; - g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; - g_Config.backend_info.bSupportsEarlyZ = false; - // adapters - g_Config.backend_info.Adapters.clear(); - for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i) - g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description); - - // aamodes - g_Config.backend_info.AAModes.clear(); - if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) - { - const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); - - for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) - g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); - } - - // Clear ppshaders string vector - g_Config.backend_info.PPShaders.clear(); - - DX9::D3D::Shutdown(); -} - -void VideoBackend::ShowConfig(void* parent) -{ + void VideoBackend::ShowConfig(void* parent) + { #if defined(HAVE_WX) && HAVE_WX - InitBackendInfo(); - VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9"); - diag.ShowModal(); + InitBackendInfo(); + VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9"); + diag.ShowModal(); #endif -} + } -bool VideoBackend::Initialize(void *&window_handle) -{ - InitializeShared(); - InitBackendInfo(); + bool VideoBackend::Initialize(void *&window_handle) + { + InitializeShared(); + InitBackendInfo(); - frameCount = 0; + frameCount = 0; - g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str()); - g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str()); - g_Config.UpdateProjectionHack(); - g_Config.VerifyValidity(); - // as only some driver/hardware configurations support dual source blending only enable it if is - // configured by user - g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; - UpdateActiveConfig(); + g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str()); + g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str()); + g_Config.UpdateProjectionHack(); + g_Config.VerifyValidity(); + // as only some driver/hardware configurations support dual source blending only enable it if is + // configured by user + g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; + UpdateActiveConfig(); - window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); - if (window_handle == NULL) - { - ERROR_LOG(VIDEO, "An error has occurred while trying to create the window."); - return false; - } - else if (FAILED(DX9::D3D::Init())) - { - MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK); - return false; - } + window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); + if (window_handle == NULL) + { + ERROR_LOG(VIDEO, "An error has occurred while trying to create the window."); + return false; + } + else if (FAILED(DX9::D3D::Init())) + { + MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK); + return false; + } - s_BackendInitialized = true; + s_BackendInitialized = true; - return true; -} + return true; + } -void VideoBackend::Video_Prepare() -{ - // Better be safe... - s_efbAccessRequested = FALSE; - s_FifoShuttingDown = FALSE; - s_swapRequested = FALSE; + void VideoBackend::Video_Prepare() + { + // Better be safe... + s_efbAccessRequested = FALSE; + s_FifoShuttingDown = FALSE; + s_swapRequested = FALSE; - // internal interfaces - g_vertex_manager = new VertexManager; - g_perf_query = new PerfQuery; - g_renderer = new Renderer; - g_texture_cache = new TextureCache; - // VideoCommon - BPInit(); - Fifo_Init(); - IndexGenerator::Init(); - VertexLoaderManager::Init(); - OpcodeDecoder_Init(); - VertexShaderManager::Init(); - PixelShaderManager::Init(); - CommandProcessor::Init(); - PixelEngine::Init(); - DLCache::Init(); - // Notify the core that the video backend is ready - Host_Message(WM_USER_CREATE); -} + // internal interfaces + g_vertex_manager = new VertexManager; + g_perf_query = new PerfQuery; + g_renderer = new Renderer; + g_texture_cache = new TextureCache; + // VideoCommon + BPInit(); + Fifo_Init(); + IndexGenerator::Init(); + VertexLoaderManager::Init(); + OpcodeDecoder_Init(); + VertexShaderManager::Init(); + PixelShaderManager::Init(); + CommandProcessor::Init(); + PixelEngine::Init(); + DLCache::Init(); + // Notify the core that the video backend is ready + Host_Message(WM_USER_CREATE); + } -void VideoBackend::Shutdown() -{ - s_BackendInitialized = false; + void VideoBackend::Shutdown() + { + s_BackendInitialized = false; - // TODO: should be in Video_Cleanup - if (g_renderer) - { - s_efbAccessRequested = FALSE; - s_FifoShuttingDown = FALSE; - s_swapRequested = FALSE; + // TODO: should be in Video_Cleanup + if (g_renderer) + { + s_efbAccessRequested = FALSE; + s_FifoShuttingDown = FALSE; + s_swapRequested = FALSE; - // VideoCommon - DLCache::Shutdown(); - Fifo_Shutdown(); - CommandProcessor::Shutdown(); - PixelShaderManager::Shutdown(); - VertexShaderManager::Shutdown(); - OpcodeDecoder_Shutdown(); - VertexLoaderManager::Shutdown(); + // VideoCommon + DLCache::Shutdown(); + Fifo_Shutdown(); + CommandProcessor::Shutdown(); + PixelShaderManager::Shutdown(); + VertexShaderManager::Shutdown(); + OpcodeDecoder_Shutdown(); + VertexLoaderManager::Shutdown(); - // internal interfaces - PixelShaderCache::Shutdown(); - VertexShaderCache::Shutdown(); - delete g_texture_cache; - delete g_renderer; - delete g_perf_query; - delete g_vertex_manager; - g_renderer = NULL; - g_texture_cache = NULL; - } - D3D::Shutdown(); -} + // internal interfaces + PixelShaderCache::Shutdown(); + VertexShaderCache::Shutdown(); + delete g_texture_cache; + delete g_renderer; + delete g_perf_query; + delete g_vertex_manager; + g_renderer = NULL; + g_texture_cache = NULL; + } + D3D::Shutdown(); + } -void VideoBackend::Video_Cleanup() { -} + void VideoBackend::Video_Cleanup() { + } } From 1de39a4a6e6b5ef3ec55bd717d4ba02c02ff8d29 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Thu, 15 Aug 2013 15:40:57 -0300 Subject: [PATCH 7/8] Revert wrong indentation of some files. sorry for that one i was really convinced that i read that spaces must be used instead of tabs :) --- .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 562 ++--- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 2092 ++++++++--------- .../Plugin_VideoDX9/Src/VertexManager.cpp | 676 +++--- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 362 +-- Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 324 +-- 5 files changed, 2008 insertions(+), 2008 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 527fe5d177..ea6503e9e0 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -40,15 +40,15 @@ static std::set unique_shaders; #define MAX_SSAA_SHADERS 3 enum { - COPY_TYPE_DIRECT, - COPY_TYPE_MATRIXCOLOR, - NUM_COPY_TYPES + COPY_TYPE_DIRECT, + COPY_TYPE_MATRIXCOLOR, + NUM_COPY_TYPES }; enum { - DEPTH_CONVERSION_TYPE_NONE, - DEPTH_CONVERSION_TYPE_ON, - NUM_DEPTH_CONVERSION_TYPES + DEPTH_CONVERSION_TYPE_NONE, + DEPTH_CONVERSION_TYPE_ON, + NUM_DEPTH_CONVERSION_TYPES }; static LPDIRECT3DPIXELSHADER9 s_CopyProgram[NUM_COPY_TYPES][NUM_DEPTH_CONVERSION_TYPES][MAX_SSAA_SHADERS]; @@ -59,30 +59,30 @@ static LPDIRECT3DPIXELSHADER9 s_rgb8_to_rgba6 = NULL; class PixelShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) - { - PixelShaderCache::InsertByteCode(key, value, value_size, false); - } + void Read(const PixelShaderUid &key, const u8 *value, u32 value_size) + { + PixelShaderCache::InsertByteCode(key, value, value_size, false); + } }; LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram(int SSAAMode) { - return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; + return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetDepthMatrixProgram(int SSAAMode, bool depthConversion) { - return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][depthConversion ? DEPTH_CONVERSION_TYPE_ON : DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; + return s_CopyProgram[COPY_TYPE_MATRIXCOLOR][depthConversion ? DEPTH_CONVERSION_TYPE_ON : DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram(int SSAAMode) { - return s_CopyProgram[COPY_TYPE_DIRECT][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; + return s_CopyProgram[COPY_TYPE_DIRECT][DEPTH_CONVERSION_TYPE_NONE][SSAAMode % MAX_SSAA_SHADERS]; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram() { - return s_ClearProgram; + return s_ClearProgram; } static LPDIRECT3DPIXELSHADER9 s_rgb8 = NULL; @@ -90,360 +90,360 @@ static LPDIRECT3DPIXELSHADER9 s_rgba6 = NULL; LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGBA6ToRGB8() { - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0){\n" - " ocol0 = tex2D(samp0,uv0);\n" - " float4 src6 = round(ocol0 * 63.f);\n" - " ocol0.r = floor(src6.r*4.f) + floor(src6.g/16.f);\n" // dst8r = (src6r<<2)|(src6g>>4); - " ocol0.g = frac(src6.g/16.f)*16.f*16.f + floor(src6.b/4.f);\n" // dst8g = ((src6g&0xF)<<4)|(src6b>>2); - " ocol0.b = frac(src6.b/4.f)*4.f*64.f + src6.a;\n" // dst8b = ((src6b&0x3)<<6)|src6a; - " ocol0.a = 255.f;\n" - " ocol0 /= 255.f;\n" - "}\n" - }; + const char code[] = + { + "uniform sampler samp0 : register(s0);\n" + "void main(\n" + " out float4 ocol0 : COLOR0,\n" + " in float2 uv0 : TEXCOORD0){\n" + " ocol0 = tex2D(samp0,uv0);\n" + " float4 src6 = round(ocol0 * 63.f);\n" + " ocol0.r = floor(src6.r*4.f) + floor(src6.g/16.f);\n" // dst8r = (src6r<<2)|(src6g>>4); + " ocol0.g = frac(src6.g/16.f)*16.f*16.f + floor(src6.b/4.f);\n" // dst8g = ((src6g&0xF)<<4)|(src6b>>2); + " ocol0.b = frac(src6.b/4.f)*4.f*64.f + src6.a;\n" // dst8b = ((src6b&0x3)<<6)|src6a; + " ocol0.a = 255.f;\n" + " ocol0 /= 255.f;\n" + "}\n" + }; - if (!s_rgba6_to_rgb8) - s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); + if (!s_rgba6_to_rgb8) + s_rgba6_to_rgb8 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); - return s_rgba6_to_rgb8; + return s_rgba6_to_rgb8; } LPDIRECT3DPIXELSHADER9 PixelShaderCache::ReinterpRGB8ToRGBA6() { - /* old code here for reference - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - " out float4 ocol0 : COLOR0,\n" - " in float2 uv0 : TEXCOORD0){\n" - " ocol0 = tex2D(samp0,uv0);\n" - " float4 src8 = round(ocol0*255.f);\n" - " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; - " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); - " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); - " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; - " ocol0 /= 63.f;\n" - "}\n" - }; - */ - const char code[] = - { - "uniform sampler samp0 : register(s0);\n" - "void main(\n" - "out float4 ocol0 : COLOR0,\n" - "in float2 uv0 : TEXCOORD0){\n" - "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" - "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" - "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" - "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" - "}\n" - }; - if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); - return s_rgb8_to_rgba6; + /* old code here for reference + const char code[] = + { + "uniform sampler samp0 : register(s0);\n" + "void main(\n" + " out float4 ocol0 : COLOR0,\n" + " in float2 uv0 : TEXCOORD0){\n" + " ocol0 = tex2D(samp0,uv0);\n" + " float4 src8 = round(ocol0*255.f);\n" + " ocol0.r = floor(src8.r/4.f);\n" // dst6r = src8r>>2; + " ocol0.g = frac(src8.r/4.f)*4.f*16.f + floor(src8.g/16.f);\n" // dst6g = ((src8r&0x3)<<4)|(src8g>>4); + " ocol0.b = frac(src8.g/16.f)*16.f*4.f + floor(src8.b/64.f);\n" // dst6b = ((src8g&0xF)<<2)|(src8b>>6); + " ocol0.a = frac(src8.b/64.f)*64.f;\n" // dst6a = src8b&0x3F; + " ocol0 /= 63.f;\n" + "}\n" + }; + */ + const char code[] = + { + "uniform sampler samp0 : register(s0);\n" + "void main(\n" + "out float4 ocol0 : COLOR0,\n" + "in float2 uv0 : TEXCOORD0){\n" + "float4 temp1 = float4(1.0f/4.0f,1.0f/16.0f,1.0f/64.0f,0.0f);\n" + "float4 temp2 = float4(1.0f,64.0f,255.0f,1.0f/63.0f);\n" + "float4 src8 = round(tex2D(samp0,uv0)*temp2.z) * temp1;\n" + "ocol0 = (frac(src8.wxyz) * temp2.xyyy + floor(src8)) * temp2.w;\n" + "}\n" + }; + if (!s_rgb8_to_rgba6) s_rgb8_to_rgba6 = D3D::CompileAndCreatePixelShader(code, (int)strlen(code)); + return s_rgb8_to_rgba6; } #define WRITE p+=sprintf static LPDIRECT3DPIXELSHADER9 CreateCopyShader(int copyMatrixType, int depthConversionType, int SSAAMode) { - //Used for Copy/resolve the color buffer - //Color conversion Programs - //Depth copy programs - // this should create the same shaders as before (plus some extras added for DF16), just... more manageably than listing the full program for each combination - char text[3072]; + //Used for Copy/resolve the color buffer + //Color conversion Programs + //Depth copy programs + // this should create the same shaders as before (plus some extras added for DF16), just... more manageably than listing the full program for each combination + char text[3072]; - locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation - locale_t old_locale = uselocale(locale); // Apply the locale for this thread - text[sizeof(text) - 1] = 0x7C; // canary + locale_t locale = newlocale(LC_NUMERIC_MASK, "C", NULL); // New locale for compilation + locale_t old_locale = uselocale(locale); // Apply the locale for this thread + text[sizeof(text) - 1] = 0x7C; // canary - char* p = text; - WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode); + char* p = text; + WRITE(p, "// Copy/Color Matrix/Depth Matrix shader (matrix=%d, depth=%d, ssaa=%d)\n", copyMatrixType, depthConversionType, SSAAMode); - WRITE(p, "uniform sampler samp0 : register(s0);\n"); - if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) - WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX); - WRITE(p, "void main(\n" - "out float4 ocol0 : COLOR0,\n"); + WRITE(p, "uniform sampler samp0 : register(s0);\n"); + if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) + WRITE(p, "uniform float4 cColMatrix[7] : register(c%d);\n", C_COLORMATRIX); + WRITE(p, "void main(\n" + "out float4 ocol0 : COLOR0,\n"); - switch(SSAAMode % MAX_SSAA_SHADERS) - { - case 0: // 1 Sample - WRITE(p, "in float2 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1){\n" - "float4 texcol = tex2D(samp0,uv0.xy);\n"); - break; - case 1: // 4 Samples in 4x SSAA buffer - WRITE(p, "in float4 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1,\n" - "in float4 uv2 : TEXCOORD2,\n" - "in float4 uv3 : TEXCOORD3){\n" - "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); - break; - case 2: // 4 Samples in 9x SSAA buffer - WRITE(p, "in float4 uv0 : TEXCOORD0,\n" - "in float uv1 : TEXCOORD1,\n" - "in float4 uv2 : TEXCOORD2,\n" - "in float4 uv3 : TEXCOORD3){\n" - "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); - break; - } + switch(SSAAMode % MAX_SSAA_SHADERS) + { + case 0: // 1 Sample + WRITE(p, "in float2 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1){\n" + "float4 texcol = tex2D(samp0,uv0.xy);\n"); + break; + case 1: // 4 Samples in 4x SSAA buffer + WRITE(p, "in float4 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3){\n" + "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); + break; + case 2: // 4 Samples in 9x SSAA buffer + WRITE(p, "in float4 uv0 : TEXCOORD0,\n" + "in float uv1 : TEXCOORD1,\n" + "in float4 uv2 : TEXCOORD2,\n" + "in float4 uv3 : TEXCOORD3){\n" + "float4 texcol = (tex2D(samp0,uv2.xy) + tex2D(samp0,uv2.wz) + tex2D(samp0,uv3.xy) + tex2D(samp0,uv3.wz))*0.25f;\n"); + break; + } - if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE) - { - // Watch out for the fire fumes effect in Metroid it's really sensitive to this, - // the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off. - WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n" - "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); - } - else - { - //Apply Gamma Correction - WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n"); - } + if(depthConversionType != DEPTH_CONVERSION_TYPE_NONE) + { + // Watch out for the fire fumes effect in Metroid it's really sensitive to this, + // the lighting in RE0 is also way beyond sensitive since the "good value" is hardcoded and Dolphin is almost always off. + WRITE(p, "float4 EncodedDepth = frac(texcol.r * (16777215.f/16777216.f) * float4(1.0f,256.0f,256.0f*256.0f,1.0f));\n" + "texcol = floor(EncodedDepth * float4(256.f,256.f,256.f,15.0f)) / float4(255.0f,255.0f,255.0f,15.0f);\n"); + } + else + { + //Apply Gamma Correction + WRITE(p, "texcol = pow(texcol,uv1.xxxx);\n"); + } - if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) - { - if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE) - WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n"); + if(copyMatrixType == COPY_TYPE_MATRIXCOLOR) + { + if(depthConversionType == DEPTH_CONVERSION_TYPE_NONE) + WRITE(p, "texcol = round(texcol * cColMatrix[5])*cColMatrix[6];\n"); - WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"); - } - else - WRITE(p, "ocol0 = texcol;\n"); + WRITE(p, "ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"); + } + else + WRITE(p, "ocol0 = texcol;\n"); - WRITE(p, "}\n"); - if (text[sizeof(text) - 1] != 0x7C) - PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!"); + WRITE(p, "}\n"); + if (text[sizeof(text) - 1] != 0x7C) + PanicAlert("PixelShaderCache copy shader generator - buffer too small, canary has been eaten!"); - uselocale(old_locale); // restore locale - freelocale(locale); - return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); + uselocale(old_locale); // restore locale + freelocale(locale); + return D3D::CompileAndCreatePixelShader(text, (int)strlen(text)); } void PixelShaderCache::Init() { - last_entry = NULL; + last_entry = NULL; - //program used for clear screen - { - char pprog[3072]; - sprintf(pprog, "void main(\n" - "out float4 ocol0 : COLOR0,\n" - " in float4 incol0 : COLOR0){\n" - "ocol0 = incol0;\n" - "}\n"); - s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); - } + //program used for clear screen + { + char pprog[3072]; + sprintf(pprog, "void main(\n" + "out float4 ocol0 : COLOR0,\n" + " in float4 incol0 : COLOR0){\n" + "ocol0 = incol0;\n" + "}\n"); + s_ClearProgram = D3D::CompileAndCreatePixelShader(pprog, (int)strlen(pprog)); + } - int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF); - int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); + int shaderModel = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF); + int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); - // other screen copy/convert programs - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - { - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - { - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - { - if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1] - || depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode] - || copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]) - { - // if it failed at a lower setting, it's going to fail here for the same reason it did there, - // so skip this attempt to avoid duplicate error messages. - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; - } - else - { - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode); - } - } - } - } + // other screen copy/convert programs + for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) + { + for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) + { + for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) + { + if(ssaaMode && !s_CopyProgram[copyMatrixType][depthType][ssaaMode-1] + || depthType && !s_CopyProgram[copyMatrixType][depthType-1][ssaaMode] + || copyMatrixType && !s_CopyProgram[copyMatrixType-1][depthType][ssaaMode]) + { + // if it failed at a lower setting, it's going to fail here for the same reason it did there, + // so skip this attempt to avoid duplicate error messages. + s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; + } + else + { + s_CopyProgram[copyMatrixType][depthType][ssaaMode] = CreateCopyShader(copyMatrixType, depthType, ssaaMode); + } + } + } + } - Clear(); + Clear(); - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); - SETSTAT(stats.numPixelShadersCreated, 0); - SETSTAT(stats.numPixelShadersAlive, 0); + SETSTAT(stats.numPixelShadersCreated, 0); + SETSTAT(stats.numPixelShadersAlive, 0); - char cache_filename[MAX_PATH]; - sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - PixelShaderCacheInserter inserter; - g_ps_disk_cache.OpenAndRead(cache_filename, inserter); + char cache_filename[MAX_PATH]; + sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + PixelShaderCacheInserter inserter; + g_ps_disk_cache.OpenAndRead(cache_filename, inserter); - if (g_Config.bEnableShaderDebugging) - Clear(); + if (g_Config.bEnableShaderDebugging) + Clear(); } // ONLY to be used during shutdown. void PixelShaderCache::Clear() { - for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) - iter->second.Destroy(); - PixelShaders.clear(); - pixel_uid_checker.Invalidate(); + for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++) + iter->second.Destroy(); + PixelShaders.clear(); + pixel_uid_checker.Invalidate(); - last_entry = NULL; + last_entry = NULL; } void PixelShaderCache::Shutdown() { - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - if(s_CopyProgram[copyMatrixType][depthType][ssaaMode] - && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) - s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release(); + for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) + for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) + for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) + if(s_CopyProgram[copyMatrixType][depthType][ssaaMode] + && (copyMatrixType == 0 || s_CopyProgram[copyMatrixType][depthType][ssaaMode] != s_CopyProgram[copyMatrixType-1][depthType][ssaaMode])) + s_CopyProgram[copyMatrixType][depthType][ssaaMode]->Release(); - for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) - for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) - for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) - s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; + for(int copyMatrixType = 0; copyMatrixType < NUM_COPY_TYPES; copyMatrixType++) + for(int depthType = 0; depthType < NUM_DEPTH_CONVERSION_TYPES; depthType++) + for(int ssaaMode = 0; ssaaMode < MAX_SSAA_SHADERS; ssaaMode++) + s_CopyProgram[copyMatrixType][depthType][ssaaMode] = NULL; - if (s_ClearProgram) s_ClearProgram->Release(); - s_ClearProgram = NULL; - if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); - s_rgb8_to_rgba6 = NULL; - if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); - s_rgba6_to_rgb8 = NULL; + if (s_ClearProgram) s_ClearProgram->Release(); + s_ClearProgram = NULL; + if (s_rgb8_to_rgba6) s_rgb8_to_rgba6->Release(); + s_rgb8_to_rgba6 = NULL; + if (s_rgba6_to_rgb8) s_rgba6_to_rgb8->Release(); + s_rgba6_to_rgb8 = NULL; - Clear(); - g_ps_disk_cache.Sync(); - g_ps_disk_cache.Close(); + Clear(); + g_ps_disk_cache.Sync(); + g_ps_disk_cache.Close(); - unique_shaders.clear(); + unique_shaders.clear(); } bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) { - const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30; - PixelShaderUid uid; - GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components); - if (g_ActiveConfig.bEnableShaderDebugging) - { - PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components); - pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); - } + const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30; + PixelShaderUid uid; + GetPixelShaderUid(uid, dstAlphaMode, API_D3D9, components); + if (g_ActiveConfig.bEnableShaderDebugging) + { + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D9, components); + pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); + } - // Check if the shader is already set - if (last_entry) - { - if (uid == last_uid) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return last_entry->shader != NULL; - } - } + // Check if the shader is already set + if (last_entry) + { + if (uid == last_uid) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); + return last_entry->shader != NULL; + } + } - last_uid = uid; + last_uid = uid; - // Check if the shader is already in the cache - PSCache::iterator iter; - iter = PixelShaders.find(uid); - if (iter != PixelShaders.end()) - { - const PSCacheEntry &entry = iter->second; - last_entry = &entry; + // Check if the shader is already in the cache + PSCache::iterator iter; + iter = PixelShaders.find(uid); + if (iter != PixelShaders.end()) + { + const PSCacheEntry &entry = iter->second; + last_entry = &entry; - if (entry.shader) D3D::SetPixelShader(entry.shader); - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return (entry.shader != NULL); - } + if (entry.shader) D3D::SetPixelShader(entry.shader); + GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); + return (entry.shader != NULL); + } - // Need to compile a new shader - PixelShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, api, components); + // Need to compile a new shader + PixelShaderCode code; + GeneratePixelShaderCode(code, dstAlphaMode, api, components); - if (g_ActiveConfig.bEnableShaderDebugging) - { - u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer())); - unique_shaders.insert(code_hash); - SETSTAT(stats.numUniquePixelShaders, unique_shaders.size()); - } + if (g_ActiveConfig.bEnableShaderDebugging) + { + u32 code_hash = HashAdler32((const u8 *)code.GetBuffer(), strlen(code.GetBuffer())); + unique_shaders.insert(code_hash); + SETSTAT(stats.numUniquePixelShaders, unique_shaders.size()); + } #if defined(_DEBUG) || defined(DEBUGFAST) - if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { - static int counter = 0; - char szTemp[MAX_PATH]; - sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); + if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { + static int counter = 0; + char szTemp[MAX_PATH]; + sprintf(szTemp, "%sps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), counter++); - SaveData(szTemp, code.GetBuffer()); - } + SaveData(szTemp, code.GetBuffer()); + } #endif - u8 *bytecode = 0; - int bytecodelen = 0; - if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { - GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); - return false; - } + u8 *bytecode = 0; + int bytecodelen = 0; + if (!D3D::CompilePixelShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) { + GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); + return false; + } - // Insert the bytecode into the caches - g_ps_disk_cache.Append(uid, bytecode, bytecodelen); + // Insert the bytecode into the caches + g_ps_disk_cache.Append(uid, bytecode, bytecodelen); - // And insert it into the shader cache. - bool success = InsertByteCode(uid, bytecode, bytecodelen, true); - delete [] bytecode; + // And insert it into the shader cache. + bool success = InsertByteCode(uid, bytecode, bytecodelen, true); + delete [] bytecode; - if (g_ActiveConfig.bEnableShaderDebugging && success) - { - PixelShaders[uid].code = code.GetBuffer(); - } + if (g_ActiveConfig.bEnableShaderDebugging && success) + { + PixelShaders[uid].code = code.GetBuffer(); + } - GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); - return success; + GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); + return success; } bool PixelShaderCache::InsertByteCode(const PixelShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { - LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); + LPDIRECT3DPIXELSHADER9 shader = D3D::CreatePixelShaderFromByteCode(bytecode, bytecodelen); - // Make an entry in the table - PSCacheEntry newentry; - newentry.shader = shader; - PixelShaders[uid] = newentry; - last_entry = &PixelShaders[uid]; + // Make an entry in the table + PSCacheEntry newentry; + newentry.shader = shader; + PixelShaders[uid] = newentry; + last_entry = &PixelShaders[uid]; - if (!shader) { - // INCSTAT(stats.numPixelShadersFailed); - return false; - } + if (!shader) { + // INCSTAT(stats.numPixelShadersFailed); + return false; + } - INCSTAT(stats.numPixelShadersCreated); - SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); - if (activate) - { - D3D::SetPixelShader(shader); - } - return true; + INCSTAT(stats.numPixelShadersCreated); + SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); + if (activate) + { + D3D::SetPixelShader(shader); + } + return true; } void Renderer::SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { - float f[4] = { f1, f2, f3, f4 }; - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); + float f[4] = { f1, f2, f3, f4 }; + DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); } void Renderer::SetPSConstant4fv(unsigned int const_number, const float *f) { - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); + DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, 1); } void Renderer::SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f) { - DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count); + DX9::D3D::dev->SetPixelShaderConstantF(const_number, f, count); } } // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 9fcabb4796..24b332b6ec 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -63,165 +63,165 @@ static LPDIRECT3DSURFACE9 ScreenShootMEMSurface = NULL; void SetupDeviceObjects() { - D3D::font.Init(); - VertexLoaderManager::Init(); - g_framebuffer_manager = new FramebufferManager; + D3D::font.Init(); + VertexLoaderManager::Init(); + g_framebuffer_manager = new FramebufferManager; - VertexShaderManager::Dirty(); - PixelShaderManager::Dirty(); - TextureConverter::Init(); + VertexShaderManager::Dirty(); + PixelShaderManager::Dirty(); + TextureConverter::Init(); - // To avoid shader compilation stutters, read back all shaders from cache. - VertexShaderCache::Init(); - PixelShaderCache::Init(); - g_vertex_manager->CreateDeviceObjects(); - ((PerfQuery*)g_perf_query)->CreateDeviceObjects(); - // Texture cache will recreate themselves over time. + // To avoid shader compilation stutters, read back all shaders from cache. + VertexShaderCache::Init(); + PixelShaderCache::Init(); + g_vertex_manager->CreateDeviceObjects(); + ((PerfQuery*)g_perf_query)->CreateDeviceObjects(); + // Texture cache will recreate themselves over time. } // Kill off all POOL_DEFAULT device objects. void TeardownDeviceObjects() { - if(ScreenShootMEMSurface) - ScreenShootMEMSurface->Release(); - ScreenShootMEMSurface = NULL; - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - delete g_framebuffer_manager; - ((PerfQuery*)g_perf_query)->DestroyDeviceObjects(); - D3D::font.Shutdown(); - TextureCache::Invalidate(); - VertexLoaderManager::Shutdown(); - VertexShaderCache::Shutdown(); - PixelShaderCache::Shutdown(); - TextureConverter::Shutdown(); - g_vertex_manager->DestroyDeviceObjects(); + if(ScreenShootMEMSurface) + ScreenShootMEMSurface->Release(); + ScreenShootMEMSurface = NULL; + D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); + D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); + delete g_framebuffer_manager; + ((PerfQuery*)g_perf_query)->DestroyDeviceObjects(); + D3D::font.Shutdown(); + TextureCache::Invalidate(); + VertexLoaderManager::Shutdown(); + VertexShaderCache::Shutdown(); + PixelShaderCache::Shutdown(); + TextureConverter::Shutdown(); + g_vertex_manager->DestroyDeviceObjects(); } // Init functions Renderer::Renderer() { - InitFPSCounter(); + InitFPSCounter(); - st = new char[32768]; + st = new char[32768]; - int fullScreenRes, x, y, w_temp, h_temp; - s_blendMode = 0; - // Multisample Anti-aliasing hasn't been implemented yet use supersamling instead - int backbuffer_ms_mode = 0; + int fullScreenRes, x, y, w_temp, h_temp; + s_blendMode = 0; + // Multisample Anti-aliasing hasn't been implemented yet use supersamling instead + int backbuffer_ms_mode = 0; - Host_GetRenderWindowSize(x, y, w_temp, h_temp); + Host_GetRenderWindowSize(x, y, w_temp, h_temp); - for (fullScreenRes = 0; fullScreenRes < (int)D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size(); fullScreenRes++) - { - if ((D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].xres == w_temp) && - (D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].yres == h_temp)) - break; - } - if (fullScreenRes == D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size()) - fullScreenRes = 0; + for (fullScreenRes = 0; fullScreenRes < (int)D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size(); fullScreenRes++) + { + if ((D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].xres == w_temp) && + (D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions[fullScreenRes].yres == h_temp)) + break; + } + if (fullScreenRes == D3D::GetAdapter(g_ActiveConfig.iAdapter).resolutions.size()) + fullScreenRes = 0; - D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), - fullScreenRes, backbuffer_ms_mode, false); + D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), + fullScreenRes, backbuffer_ms_mode, false); - IS_AMD = D3D::IsATIDevice(); + IS_AMD = D3D::IsATIDevice(); - // Decide framebuffer size - s_backbuffer_width = D3D::GetBackBufferWidth(); - s_backbuffer_height = D3D::GetBackBufferHeight(); + // Decide framebuffer size + s_backbuffer_width = D3D::GetBackBufferWidth(); + s_backbuffer_height = D3D::GetBackBufferHeight(); - FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH); - FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT); + FramebufferManagerBase::SetLastXfbWidth(MAX_XFB_WIDTH); + FramebufferManagerBase::SetLastXfbHeight(MAX_XFB_HEIGHT); - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); + UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - s_LastAA = g_ActiveConfig.iMultisampleMode; - int SupersampleCoeficient = (s_LastAA % 3) + 1; + s_LastAA = g_ActiveConfig.iMultisampleMode; + int SupersampleCoeficient = (s_LastAA % 3) + 1; - s_LastEFBScale = g_ActiveConfig.iEFBScale; - CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); + s_LastEFBScale = g_ActiveConfig.iEFBScale; + CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); - // Make sure to use valid texture sizes - D3D::FixTextureSize(s_target_width, s_target_height); + // Make sure to use valid texture sizes + D3D::FixTextureSize(s_target_width, s_target_height); - // We're not using fixed function. - // Let's just set the matrices to identity to be sure. - D3DXMATRIX mtx; - D3DXMatrixIdentity(&mtx); - D3D::dev->SetTransform(D3DTS_VIEW, &mtx); - D3D::dev->SetTransform(D3DTS_WORLD, &mtx); + // We're not using fixed function. + // Let's just set the matrices to identity to be sure. + D3DXMATRIX mtx; + D3DXMatrixIdentity(&mtx); + D3D::dev->SetTransform(D3DTS_VIEW, &mtx); + D3D::dev->SetTransform(D3DTS_WORLD, &mtx); - SetupDeviceObjects(); + SetupDeviceObjects(); - for (int stage = 0; stage < 8; stage++) - D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, 1 << g_ActiveConfig.iMaxAnisotropy); + for (int stage = 0; stage < 8; stage++) + D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, 1 << g_ActiveConfig.iMaxAnisotropy); - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); + D3DVIEWPORT9 vp; + vp.X = 0; + vp.Y = 0; + vp.Width = s_backbuffer_width; + vp.Height = s_backbuffer_height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - vp.X = 0; - vp.Y = 0; - vp.Width = s_target_width; - vp.Height = s_target_height; - D3D::dev->SetViewport(&vp); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); - D3D::BeginFrame(); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); - D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false); - m_fMaxPointSize = D3D::GetCaps().MaxPointSize; - // Handle VSync on/off - s_vsync = g_ActiveConfig.IsVSync(); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + vp.X = 0; + vp.Y = 0; + vp.Width = s_target_width; + vp.Height = s_target_height; + D3D::dev->SetViewport(&vp); + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); + D3D::BeginFrame(); + D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true); + D3D::dev->CreateOffscreenPlainSurface(s_backbuffer_width,s_backbuffer_height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); + D3D::SetRenderState(D3DRS_POINTSCALEENABLE,false); + m_fMaxPointSize = D3D::GetCaps().MaxPointSize; + // Handle VSync on/off + s_vsync = g_ActiveConfig.IsVSync(); } Renderer::~Renderer() { - TeardownDeviceObjects(); - D3D::EndFrame(); - D3D::Present(); - D3D::Close(); + TeardownDeviceObjects(); + D3D::EndFrame(); + D3D::Present(); + D3D::Close(); - delete[] st; + delete[] st; } void Renderer::RenderText(const char *text, int left, int top, u32 color) { - D3D::font.DrawTextScaled((float)left, (float)top, 20, 20, 0.0f, color, text); + D3D::font.DrawTextScaled((float)left, (float)top, 20, 20, 0.0f, color, text); } TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) { - TargetRectangle result; - result.left = EFBToScaledX(rc.left); - result.top = EFBToScaledY(rc.top); - result.right = EFBToScaledX(rc.right); - result.bottom = EFBToScaledY(rc.bottom); - return result; + TargetRectangle result; + result.left = EFBToScaledX(rc.left); + result.top = EFBToScaledY(rc.top); + result.right = EFBToScaledX(rc.right); + result.bottom = EFBToScaledY(rc.bottom); + return result; } } void formatBufferDump(const u8* in, u8* out, int w, int h, int p) { - for (int y = 0; y < h; y++) - { - auto line = in + (h - y - 1) * p; - for (int x = 0; x < w; x++) - { - memcpy(out, line, 3); - out += 3; - line += 4; - } - } + for (int y = 0; y < h; y++) + { + auto line = in + (h - y - 1) * p; + for (int x = 0; x < w; x++) + { + memcpy(out, line, 3); + out += 3; + line += 4; + } + } } namespace DX9 @@ -231,63 +231,63 @@ namespace DX9 // size. bool Renderer::CheckForResize() { - while (EmuWindow::IsSizing()) - Sleep(10); + while (EmuWindow::IsSizing()) + Sleep(10); - if (EmuWindow::GetParentWnd()) - { - // Re-stretch window to parent window size again, if it has a parent window. - RECT rcParentWindow; - GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); - int width = rcParentWindow.right - rcParentWindow.left; - int height = rcParentWindow.bottom - rcParentWindow.top; - if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight()) - MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); - } + if (EmuWindow::GetParentWnd()) + { + // Re-stretch window to parent window size again, if it has a parent window. + RECT rcParentWindow; + GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); + int width = rcParentWindow.right - rcParentWindow.left; + int height = rcParentWindow.bottom - rcParentWindow.top; + if (width != Renderer::GetBackbufferWidth() || height != Renderer::GetBackbufferHeight()) + MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); + } - RECT rcWindow; - GetClientRect(EmuWindow::GetWnd(), &rcWindow); - int client_width = rcWindow.right - rcWindow.left; - int client_height = rcWindow.bottom - rcWindow.top; + RECT rcWindow; + GetClientRect(EmuWindow::GetWnd(), &rcWindow); + int client_width = rcWindow.right - rcWindow.left; + int client_height = rcWindow.bottom - rcWindow.top; - // Sanity check - if ((client_width != Renderer::GetBackbufferWidth() || - client_height != Renderer::GetBackbufferHeight()) && - client_width >= 4 && client_height >= 4) - { - TeardownDeviceObjects(); + // Sanity check + if ((client_width != Renderer::GetBackbufferWidth() || + client_height != Renderer::GetBackbufferHeight()) && + client_width >= 4 && client_height >= 4) + { + TeardownDeviceObjects(); - D3D::Reset(); - s_backbuffer_width = D3D::GetBackBufferWidth(); - s_backbuffer_height = D3D::GetBackBufferHeight(); - if(ScreenShootMEMSurface) - ScreenShootMEMSurface->Release(); - D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(), - D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); + D3D::Reset(); + s_backbuffer_width = D3D::GetBackBufferWidth(); + s_backbuffer_height = D3D::GetBackBufferHeight(); + if(ScreenShootMEMSurface) + ScreenShootMEMSurface->Release(); + D3D::dev->CreateOffscreenPlainSurface(Renderer::GetBackbufferWidth(), Renderer::GetBackbufferHeight(), + D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &ScreenShootMEMSurface, NULL ); - return true; - } + return true; + } - return false; + return false; } void Renderer::SetScissorRect(const TargetRectangle& rc) { - D3D::dev->SetScissorRect(rc.AsRECT()); + D3D::dev->SetScissorRect(rc.AsRECT()); } void Renderer::SetColorMask() { - // Only enable alpha channel if it's supported by the current EFB format - DWORD color_mask = 0; - if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) - { - if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) - color_mask = D3DCOLORWRITEENABLE_ALPHA; - if (bpmem.blendmode.colorupdate) - color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - } - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); + // Only enable alpha channel if it's supported by the current EFB format + DWORD color_mask = 0; + if (bpmem.alpha_test.TestResult() != AlphaTest::FAIL) + { + if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)) + color_mask = D3DCOLORWRITEENABLE_ALPHA; + if (bpmem.blendmode.colorupdate) + color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + } + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); } // This function allows the CPU to directly access the EFB. @@ -306,191 +306,191 @@ void Renderer::SetColorMask() // - GX_PokeZMode (TODO) u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) { - if (!g_ActiveConfig.bEFBAccessEnable) - return 0; + if (!g_ActiveConfig.bEFBAccessEnable) + return 0; - if (type == POKE_Z) - { - static bool alert_only_once = true; - if (!alert_only_once) return 0; - PanicAlert("EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d))", poke_data, x, y); - alert_only_once = false; - return 0; - } + if (type == POKE_Z) + { + static bool alert_only_once = true; + if (!alert_only_once) return 0; + PanicAlert("EFB: Poke Z not implemented (tried to poke z value %#x at (%d,%d))", poke_data, x, y); + alert_only_once = false; + return 0; + } - // if depth textures aren't supported by the hardware, just return - if (type == PEEK_Z) - if (FramebufferManager::GetEFBDepthTexture() == NULL) - return 0; + // if depth textures aren't supported by the hardware, just return + if (type == PEEK_Z) + if (FramebufferManager::GetEFBDepthTexture() == NULL) + return 0; - // We're using three surfaces here: - // - pEFBSurf: EFB Surface. Source surface when peeking, destination surface when poking. - // - pBufferRT: A render target surface. When peeking, we render a textured quad to this surface. - // - pSystemBuf: An offscreen surface. Used to retrieve the pixel data from pBufferRT. - LPDIRECT3DSURFACE9 pEFBSurf, pBufferRT, pSystemBuf; - if(type == PEEK_Z || type == POKE_Z) - { - pEFBSurf = FramebufferManager::GetEFBDepthRTSurface(); - pBufferRT = FramebufferManager::GetEFBDepthReadSurface(); - pSystemBuf = FramebufferManager::GetEFBDepthOffScreenRTSurface(); - } - else //if(type == PEEK_COLOR || type == POKE_COLOR) - { - pEFBSurf = FramebufferManager::GetEFBColorRTSurface(); - pBufferRT = FramebufferManager::GetEFBColorReadSurface(); - pSystemBuf = FramebufferManager::GetEFBColorOffScreenRTSurface(); - } + // We're using three surfaces here: + // - pEFBSurf: EFB Surface. Source surface when peeking, destination surface when poking. + // - pBufferRT: A render target surface. When peeking, we render a textured quad to this surface. + // - pSystemBuf: An offscreen surface. Used to retrieve the pixel data from pBufferRT. + LPDIRECT3DSURFACE9 pEFBSurf, pBufferRT, pSystemBuf; + if(type == PEEK_Z || type == POKE_Z) + { + pEFBSurf = FramebufferManager::GetEFBDepthRTSurface(); + pBufferRT = FramebufferManager::GetEFBDepthReadSurface(); + pSystemBuf = FramebufferManager::GetEFBDepthOffScreenRTSurface(); + } + else //if(type == PEEK_COLOR || type == POKE_COLOR) + { + pEFBSurf = FramebufferManager::GetEFBColorRTSurface(); + pBufferRT = FramebufferManager::GetEFBColorReadSurface(); + pSystemBuf = FramebufferManager::GetEFBColorOffScreenRTSurface(); + } - // Buffer not found alert - if (!pEFBSurf) { - PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB"); - return 0; - } + // Buffer not found alert + if (!pEFBSurf) { + PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB"); + return 0; + } - // Convert EFB dimensions to the ones of our render target - EFBRectangle efbPixelRc; - efbPixelRc.left = x; - efbPixelRc.top = y; - efbPixelRc.right = x + 1; - efbPixelRc.bottom = y + 1; + // Convert EFB dimensions to the ones of our render target + EFBRectangle efbPixelRc; + efbPixelRc.left = x; + efbPixelRc.top = y; + efbPixelRc.right = x + 1; + efbPixelRc.bottom = y + 1; - TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc); + TargetRectangle targetPixelRc = ConvertEFBRectangle(efbPixelRc); - HRESULT hr; - RECT RectToLock; - RectToLock.bottom = targetPixelRc.bottom; - RectToLock.left = targetPixelRc.left; - RectToLock.right = targetPixelRc.right; - RectToLock.top = targetPixelRc.top; - if (type == PEEK_Z) - { - // TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them? - if (FramebufferManager::GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8) - return 0; + HRESULT hr; + RECT RectToLock; + RectToLock.bottom = targetPixelRc.bottom; + RectToLock.left = targetPixelRc.left; + RectToLock.right = targetPixelRc.right; + RectToLock.top = targetPixelRc.top; + if (type == PEEK_Z) + { + // TODO: why is D3DFMT_D24X8 singled out here? why not D3DFMT_D24X4S4/D24S8/D24FS8/D32/D16/D15S1 too, or none of them? + if (FramebufferManager::GetEFBDepthRTSurfaceFormat() == D3DFMT_D24X8) + return 0; - RECT PixelRect; - PixelRect.bottom = 4; - PixelRect.left = 0; - PixelRect.right = 4; - PixelRect.top = 0; - RectToLock.bottom+=2; - RectToLock.right+=1; - RectToLock.top-=1; - RectToLock.left-=2; - if ((RectToLock.bottom - RectToLock.top) > 4) - RectToLock.bottom--; - if ((RectToLock.right - RectToLock.left) > 4) - RectToLock.left++; + RECT PixelRect; + PixelRect.bottom = 4; + PixelRect.left = 0; + PixelRect.right = 4; + PixelRect.top = 0; + RectToLock.bottom+=2; + RectToLock.right+=1; + RectToLock.top-=1; + RectToLock.left-=2; + if ((RectToLock.bottom - RectToLock.top) > 4) + RectToLock.bottom--; + if ((RectToLock.right - RectToLock.left) > 4) + RectToLock.left++; - ResetAPIState(); // Reset any game specific settings - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, pBufferRT); + ResetAPIState(); // Reset any game specific settings + D3D::dev->SetDepthStencilSurface(NULL); + D3D::dev->SetRenderTarget(0, pBufferRT); - // Stretch picture with increased internal resolution - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = 4; - vp.Height = 4; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); + // Stretch picture with increased internal resolution + D3DVIEWPORT9 vp; + vp.X = 0; + vp.Y = 0; + vp.Width = 4; + vp.Height = 4; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); - float colmat[28] = {0.0f}; - colmat[0] = colmat[5] = colmat[10] = 1.0f; - PixelShaderManager::SetColorMatrix(colmat); // set transformation - LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBDepthTexture(); + float colmat[28] = {0.0f}; + colmat[0] = colmat[5] = colmat[10] = 1.0f; + PixelShaderManager::SetColorMatrix(colmat); // set transformation + LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBDepthTexture(); - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); + D3DFORMAT bformat = FramebufferManager::GetEFBDepthRTSurfaceFormat(); - D3D::drawShadedTexQuad( - read_texture, - &RectToLock, - Renderer::GetTargetWidth(), - Renderer::GetTargetHeight(), - 4, 4, - PixelShaderCache::GetDepthMatrixProgram(0, bformat != FOURCC_RAWZ), - VertexShaderCache::GetSimpleVertexShader(0)); + D3D::drawShadedTexQuad( + read_texture, + &RectToLock, + Renderer::GetTargetWidth(), + Renderer::GetTargetHeight(), + 4, 4, + PixelShaderCache::GetDepthMatrixProgram(0, bformat != FOURCC_RAWZ), + VertexShaderCache::GetSimpleVertexShader(0)); - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - RestoreAPIState(); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + RestoreAPIState(); - // Retrieve the pixel data to the local memory buffer - RectToLock.bottom = 4; - RectToLock.left = 0; - RectToLock.right = 4; - RectToLock.top = 0; - D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); + // Retrieve the pixel data to the local memory buffer + RectToLock.bottom = 4; + RectToLock.left = 0; + RectToLock.right = 4; + RectToLock.top = 0; + D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); - // EFB data successfully retrieved, now get the pixel data - D3DLOCKED_RECT drect; - pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); - u32 z = ((u32*)drect.pBits)[6]; // 24 bit depth value - pSystemBuf->UnlockRect(); + // EFB data successfully retrieved, now get the pixel data + D3DLOCKED_RECT drect; + pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); + u32 z = ((u32*)drect.pBits)[6]; // 24 bit depth value + pSystemBuf->UnlockRect(); - // if Z is in 16 bit format you must return a 16 bit integer - if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) { - z >>= 8; - } + // if Z is in 16 bit format you must return a 16 bit integer + if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) { + z >>= 8; + } - return z; - } - else if(type == PEEK_COLOR) - { - // We can't directly StretchRect to System buf because is not supported by all implementations - // this is the only safe path that works in most cases - hr = D3D::dev->StretchRect(pEFBSurf, &RectToLock, pBufferRT, NULL, D3DTEXF_NONE); - D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); + return z; + } + else if(type == PEEK_COLOR) + { + // We can't directly StretchRect to System buf because is not supported by all implementations + // this is the only safe path that works in most cases + hr = D3D::dev->StretchRect(pEFBSurf, &RectToLock, pBufferRT, NULL, D3DTEXF_NONE); + D3D::dev->GetRenderTargetData(pBufferRT, pSystemBuf); - // EFB data successfully retrieved, now get the pixel data - RectToLock.bottom = 1; - RectToLock.left = 0; - RectToLock.right = 1; - RectToLock.top = 0; + // EFB data successfully retrieved, now get the pixel data + RectToLock.bottom = 1; + RectToLock.left = 0; + RectToLock.right = 1; + RectToLock.top = 0; - D3DLOCKED_RECT drect; - pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); - u32 ret = ((u32*)drect.pBits)[0]; - pSystemBuf->UnlockRect(); + D3DLOCKED_RECT drect; + pSystemBuf->LockRect(&drect, &RectToLock, D3DLOCK_READONLY); + u32 ret = ((u32*)drect.pBits)[0]; + pSystemBuf->UnlockRect(); - // check what to do with the alpha channel (GX_PokeAlphaRead) - PixelEngine::UPEAlphaReadReg alpha_read_mode; - PixelEngine::Read16((u16&)alpha_read_mode, PE_ALPHAREAD); + // check what to do with the alpha channel (GX_PokeAlphaRead) + PixelEngine::UPEAlphaReadReg alpha_read_mode; + PixelEngine::Read16((u16&)alpha_read_mode, PE_ALPHAREAD); - if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) - { - ret = RGBA8ToRGBA6ToRGBA8(ret); - } - else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) - { - ret = RGBA8ToRGB565ToRGBA8(ret); - } - if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24) - { - ret |= 0xFF000000; - } + if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) + { + ret = RGBA8ToRGBA6ToRGBA8(ret); + } + else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16) + { + ret = RGBA8ToRGB565ToRGBA8(ret); + } + if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24) + { + ret |= 0xFF000000; + } - if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE - else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF - else return (ret & 0x00FFFFFF); // GX_READ_00 - } - else //if(type == POKE_COLOR) - { - // TODO: Speed this up by batching pokes? - ResetAPIState(); - D3D::drawColorQuad(poke_data, - (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, - (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, - - (float)RectToLock.bottom * 2.f / (float)Renderer::GetTargetHeight() + 1.f); - RestoreAPIState(); - return 0; - } + if(alpha_read_mode.ReadMode == 2) return ret; // GX_READ_NONE + else if(alpha_read_mode.ReadMode == 1) return (ret | 0xFF000000); // GX_READ_FF + else return (ret & 0x00FFFFFF); // GX_READ_00 + } + else //if(type == POKE_COLOR) + { + // TODO: Speed this up by batching pokes? + ResetAPIState(); + D3D::drawColorQuad(poke_data, + (float)RectToLock.left * 2.f / (float)Renderer::GetTargetWidth() - 1.f, + - (float)RectToLock.top * 2.f / (float)Renderer::GetTargetHeight() + 1.f, + (float)RectToLock.right * 2.f / (float)Renderer::GetTargetWidth() - 1.f, + - (float)RectToLock.bottom * 2.f / (float)Renderer::GetTargetHeight() + 1.f); + RestoreAPIState(); + return 0; + } } // Viewport correction: @@ -503,884 +503,884 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) // [ 0 0 1 0 ] // [ 0 0 0 1 ] static void ViewportCorrectionMatrix(Matrix44& result, - float ix, float iy, float iw, float ih, // Intended viewport (x, y, width, height) - float ax, float ay, float aw, float ah) // Actual viewport (x, y, width, height) + float ix, float iy, float iw, float ih, // Intended viewport (x, y, width, height) + float ax, float ay, float aw, float ah) // Actual viewport (x, y, width, height) { - Matrix44::LoadIdentity(result); - if (aw == 0.f || ah == 0.f) - return; - result.data[4*0+0] = iw / aw; - result.data[4*0+3] = (iw - 2.f * (ax - ix)) / aw - 1.f; - result.data[4*1+1] = ih / ah; - result.data[4*1+3] = (-ih + 2.f * (ay - iy)) / ah + 1.f; + Matrix44::LoadIdentity(result); + if (aw == 0.f || ah == 0.f) + return; + result.data[4*0+0] = iw / aw; + result.data[4*0+3] = (iw - 2.f * (ax - ix)) / aw - 1.f; + result.data[4*1+1] = ih / ah; + result.data[4*1+3] = (-ih + 2.f * (ay - iy)) / ah + 1.f; } // Called from VertexShaderManager void Renderer::UpdateViewport(Matrix44& vpCorrection) { - // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) - // [0] = width/2 - // [1] = height/2 - // [2] = 16777215 * (farz - nearz) - // [3] = xorig + width/2 + 342 - // [4] = yorig + height/2 + 342 - // [5] = 16777215 * farz + // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) + // [0] = width/2 + // [1] = height/2 + // [2] = 16777215 * (farz - nearz) + // [3] = xorig + width/2 + 342 + // [4] = yorig + height/2 + 342 + // [5] = 16777215 * farz - int scissorXOff = bpmem.scissorOffset.x * 2; - int scissorYOff = bpmem.scissorOffset.y * 2; + int scissorXOff = bpmem.scissorOffset.x * 2; + int scissorYOff = bpmem.scissorOffset.y * 2; - // TODO: ceil, floor or just cast to int? - int intendedX = EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff)); - int intendedY = EFBToScaledY((int)ceil(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff)); - int intendedWd = EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); - int intendedHt = EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); - if (intendedWd < 0) - { - intendedX += intendedWd; - intendedWd = -intendedWd; - } - if (intendedHt < 0) - { - intendedY += intendedHt; - intendedHt = -intendedHt; - } + // TODO: ceil, floor or just cast to int? + int intendedX = EFBToScaledX((int)ceil(xfregs.viewport.xOrig - xfregs.viewport.wd - scissorXOff)); + int intendedY = EFBToScaledY((int)ceil(xfregs.viewport.yOrig + xfregs.viewport.ht - scissorYOff)); + int intendedWd = EFBToScaledX((int)ceil(2.0f * xfregs.viewport.wd)); + int intendedHt = EFBToScaledY((int)ceil(-2.0f * xfregs.viewport.ht)); + if (intendedWd < 0) + { + intendedX += intendedWd; + intendedWd = -intendedWd; + } + if (intendedHt < 0) + { + intendedY += intendedHt; + intendedHt = -intendedHt; + } - // In D3D, the viewport rectangle must fit within the render target. - int X = intendedX; - if (X < 0) - X = 0; - int Y = intendedY; - if (Y < 0) - Y = 0; - int Wd = intendedWd; - if (X + Wd > GetTargetWidth()) - Wd = GetTargetWidth() - X; - int Ht = intendedHt; - if (Y + Ht > GetTargetHeight()) - Ht = GetTargetHeight() - Y; + // In D3D, the viewport rectangle must fit within the render target. + int X = intendedX; + if (X < 0) + X = 0; + int Y = intendedY; + if (Y < 0) + Y = 0; + int Wd = intendedWd; + if (X + Wd > GetTargetWidth()) + Wd = GetTargetWidth() - X; + int Ht = intendedHt; + if (Y + Ht > GetTargetHeight()) + Ht = GetTargetHeight() - Y; - // If GX viewport is off the render target, we must clamp our viewport - // within the bounds. Use the correction matrix to compensate. - ViewportCorrectionMatrix(vpCorrection, - (float)intendedX, (float)intendedY, (float)intendedWd, (float)intendedHt, - (float)X, (float)Y, (float)Wd, (float)Ht); + // If GX viewport is off the render target, we must clamp our viewport + // within the bounds. Use the correction matrix to compensate. + ViewportCorrectionMatrix(vpCorrection, + (float)intendedX, (float)intendedY, (float)intendedWd, (float)intendedHt, + (float)X, (float)Y, (float)Wd, (float)Ht); - D3DVIEWPORT9 vp; - vp.X = X; - vp.Y = Y; - vp.Width = Wd; - vp.Height = Ht; + D3DVIEWPORT9 vp; + vp.X = X; + vp.Y = Y; + vp.Width = Wd; + vp.Height = Ht; - // Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work - vp.MinZ = 0.0f; // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; - vp.MaxZ = 1.0f; // xfregs.viewport.farZ / 16777216.0f; - D3D::dev->SetViewport(&vp); + // Some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work + vp.MinZ = 0.0f; // (xfregs.viewport.farZ - xfregs.viewport.zRange) / 16777216.0f; + vp.MaxZ = 1.0f; // xfregs.viewport.farZ / 16777216.0f; + D3D::dev->SetViewport(&vp); } void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) { - // Reset rendering pipeline while keeping color masks and depth buffer settings - ResetAPIState(); + // Reset rendering pipeline while keeping color masks and depth buffer settings + ResetAPIState(); - DWORD color_mask = 0; - if (alphaEnable) - color_mask = D3DCOLORWRITEENABLE_ALPHA; - if (colorEnable) - color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, color_mask); + DWORD color_mask = 0; + if (alphaEnable) + color_mask = D3DCOLORWRITEENABLE_ALPHA; + if (colorEnable) + color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, color_mask); - if (zEnable) - { - D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); - D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, TRUE); - D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - } - else - { - D3D::ChangeRenderState(D3DRS_ZENABLE, FALSE); - } + if (zEnable) + { + D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); + D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, TRUE); + D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + } + else + { + D3D::ChangeRenderState(D3DRS_ZENABLE, FALSE); + } - // Update the viewport for clearing the target EFB rect - TargetRectangle targetRc = ConvertEFBRectangle(rc); - D3DVIEWPORT9 vp; - vp.X = targetRc.left; - vp.Y = targetRc.top; - vp.Width = targetRc.GetWidth(); - vp.Height = targetRc.GetHeight(); - vp.MinZ = 0.0; - vp.MaxZ = 1.0; - D3D::dev->SetViewport(&vp); - D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); - RestoreAPIState(); + // Update the viewport for clearing the target EFB rect + TargetRectangle targetRc = ConvertEFBRectangle(rc); + D3DVIEWPORT9 vp; + vp.X = targetRc.left; + vp.Y = targetRc.top; + vp.Width = targetRc.GetWidth(); + vp.Height = targetRc.GetHeight(); + vp.MinZ = 0.0; + vp.MaxZ = 1.0; + D3D::dev->SetViewport(&vp); + D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); + RestoreAPIState(); } void Renderer::ReinterpretPixelData(unsigned int convtype) { - RECT source; - SetRect(&source, 0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); + RECT source; + SetRect(&source, 0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight()); - LPDIRECT3DPIXELSHADER9 pixel_shader; - if (convtype == 0) pixel_shader = PixelShaderCache::ReinterpRGB8ToRGBA6(); - else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8(); - else - { - ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype); - return; - } + LPDIRECT3DPIXELSHADER9 pixel_shader; + if (convtype == 0) pixel_shader = PixelShaderCache::ReinterpRGB8ToRGBA6(); + else if (convtype == 2) pixel_shader = PixelShaderCache::ReinterpRGBA6ToRGB8(); + else + { + ERROR_LOG(VIDEO, "Trying to reinterpret pixel data with unsupported conversion type %d", convtype); + return; + } - // convert data and set the target texture as our new EFB - g_renderer->ResetAPIState(); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorReinterpretSurface()); - D3DVIEWPORT9 vp; - vp.X = 0; - vp.Y = 0; - vp.Width = g_renderer->GetTargetWidth(); - vp.Height = g_renderer->GetTargetHeight(); - vp.MinZ = 0.0; - vp.MaxZ = 1.0; - D3D::dev->SetViewport(&vp); - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture(), &source, - g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), - pixel_shader, VertexShaderCache::GetSimpleVertexShader(0)); - FramebufferManager::SwapReinterpretTexture(); - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - g_renderer->RestoreAPIState(); + // convert data and set the target texture as our new EFB + g_renderer->ResetAPIState(); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorReinterpretSurface()); + D3DVIEWPORT9 vp; + vp.X = 0; + vp.Y = 0; + vp.Width = g_renderer->GetTargetWidth(); + vp.Height = g_renderer->GetTargetHeight(); + vp.MinZ = 0.0; + vp.MaxZ = 1.0; + D3D::dev->SetViewport(&vp); + D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture(), &source, + g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), + g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), + pixel_shader, VertexShaderCache::GetSimpleVertexShader(0)); + FramebufferManager::SwapReinterpretTexture(); + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); + g_renderer->RestoreAPIState(); } void Renderer::SetBlendMode(bool forceUpdate) { - // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel - // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. - bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - //bDstAlphaPass is taken into account because the ability to disable alpha composition is - //really useful for debugging shader and blending errors - bool use_DstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha; - bool use_DualSource = use_DstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; - const D3DBLEND d3dSrcFactors[8] = - { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_DESTCOLOR, - D3DBLEND_INVDESTCOLOR, - (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, - (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, - (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, - (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO - }; - const D3DBLEND d3dDestFactors[8] = - { - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVSRCCOLOR, - (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, - (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, - (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, - (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO - }; + // Our render target always uses an alpha channel, so we need to override the blend functions to assume a destination alpha of 1 if the render target isn't supposed to have an alpha channel + // Example: D3DBLEND_DESTALPHA needs to be D3DBLEND_ONE since the result without an alpha channel is assumed to always be 1. + bool target_has_alpha = bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + //bDstAlphaPass is taken into account because the ability to disable alpha composition is + //really useful for debugging shader and blending errors + bool use_DstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && target_has_alpha; + bool use_DualSource = use_DstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; + const D3DBLEND d3dSrcFactors[8] = + { + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_DESTCOLOR, + D3DBLEND_INVDESTCOLOR, + (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, + (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, + (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, + (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO + }; + const D3DBLEND d3dDestFactors[8] = + { + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_SRCCOLOR, + D3DBLEND_INVSRCCOLOR, + (use_DualSource) ? D3DBLEND_SRCCOLOR2 : D3DBLEND_SRCALPHA, + (use_DualSource) ? D3DBLEND_INVSRCCOLOR2 : D3DBLEND_INVSRCALPHA, + (target_has_alpha) ? D3DBLEND_DESTALPHA : D3DBLEND_ONE, + (target_has_alpha) ? D3DBLEND_INVDESTALPHA : D3DBLEND_ZERO + }; - if (bpmem.blendmode.logicopenable && !forceUpdate) - { - D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE , false); - return; - } + if (bpmem.blendmode.logicopenable && !forceUpdate) + { + D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE , false); + return; + } - bool blend_enable = bpmem.blendmode.subtract || bpmem.blendmode.blendenable; - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, blend_enable); - D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, blend_enable && g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction); - if (blend_enable) - { - D3DBLENDOP op = D3DBLENDOP_ADD; - u32 srcidx = bpmem.blendmode.srcfactor; - u32 dstidx = bpmem.blendmode.dstfactor; - if (bpmem.blendmode.subtract) - { - op = D3DBLENDOP_REVSUBTRACT; - srcidx = GX_BL_ONE; - dstidx = GX_BL_ONE; - } - D3D::SetRenderState(D3DRS_BLENDOP, op); - D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[srcidx]); - D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[dstidx]); - if (g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction) - { - if (use_DualSource) - { - op = D3DBLENDOP_ADD; - srcidx = GX_BL_ONE; - dstidx = GX_BL_ZERO; - } - else - { - // we can't use D3DBLEND_DESTCOLOR or D3DBLEND_INVDESTCOLOR for source in alpha channel so use their alpha equivalent instead - if (srcidx == GX_BL_DSTCLR) srcidx = GX_BL_DSTALPHA; - if (srcidx == GX_BL_INVDSTCLR) srcidx = GX_BL_INVDSTALPHA; - // we can't use D3DBLEND_SRCCOLOR or D3DBLEND_INVSRCCOLOR for destination in alpha channel so use their alpha equivalent instead - if (dstidx == GX_BL_SRCCLR) dstidx = GX_BL_SRCALPHA; - if (dstidx == GX_BL_INVSRCCLR) dstidx = GX_BL_INVSRCALPHA; - } - D3D::SetRenderState(D3DRS_BLENDOPALPHA, op); - D3D::SetRenderState(D3DRS_SRCBLENDALPHA, d3dSrcFactors[srcidx]); - D3D::SetRenderState(D3DRS_DESTBLENDALPHA, d3dDestFactors[dstidx]); - } - } + bool blend_enable = bpmem.blendmode.subtract || bpmem.blendmode.blendenable; + D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, blend_enable); + D3D::SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, blend_enable && g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction); + if (blend_enable) + { + D3DBLENDOP op = D3DBLENDOP_ADD; + u32 srcidx = bpmem.blendmode.srcfactor; + u32 dstidx = bpmem.blendmode.dstfactor; + if (bpmem.blendmode.subtract) + { + op = D3DBLENDOP_REVSUBTRACT; + srcidx = GX_BL_ONE; + dstidx = GX_BL_ONE; + } + D3D::SetRenderState(D3DRS_BLENDOP, op); + D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[srcidx]); + D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[dstidx]); + if (g_ActiveConfig.backend_info.bSupportsSeparateAlphaFunction) + { + if (use_DualSource) + { + op = D3DBLENDOP_ADD; + srcidx = GX_BL_ONE; + dstidx = GX_BL_ZERO; + } + else + { + // we can't use D3DBLEND_DESTCOLOR or D3DBLEND_INVDESTCOLOR for source in alpha channel so use their alpha equivalent instead + if (srcidx == GX_BL_DSTCLR) srcidx = GX_BL_DSTALPHA; + if (srcidx == GX_BL_INVDSTCLR) srcidx = GX_BL_INVDSTALPHA; + // we can't use D3DBLEND_SRCCOLOR or D3DBLEND_INVSRCCOLOR for destination in alpha channel so use their alpha equivalent instead + if (dstidx == GX_BL_SRCCLR) dstidx = GX_BL_SRCALPHA; + if (dstidx == GX_BL_INVSRCCLR) dstidx = GX_BL_INVSRCALPHA; + } + D3D::SetRenderState(D3DRS_BLENDOPALPHA, op); + D3D::SetRenderState(D3DRS_SRCBLENDALPHA, d3dSrcFactors[srcidx]); + D3D::SetRenderState(D3DRS_DESTBLENDALPHA, d3dDestFactors[dstidx]); + } + } } bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle &dst_rect) { - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); - if(FAILED(hr)) - { - PanicAlert("Error dumping surface data."); - return false; - } - hr = PD3DXSaveSurfaceToFileA(filename.c_str(), D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT()); - if(FAILED(hr)) - { - PanicAlert("Error saving screen."); - return false; - } + HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); + if(FAILED(hr)) + { + PanicAlert("Error dumping surface data."); + return false; + } + hr = PD3DXSaveSurfaceToFileA(filename.c_str(), D3DXIFF_PNG, ScreenShootMEMSurface, NULL, dst_rect.AsRECT()); + if(FAILED(hr)) + { + PanicAlert("Error saving screen."); + return false; + } - return true; + return true; } // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { - if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) - { - if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); + if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) + { + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - Core::Callback_VideoCopiedToXFB(false); - return; - } + Core::Callback_VideoCopiedToXFB(false); + return; + } - if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; - u32 xfbCount = 0; - const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); - if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) - { - if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); + if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; + u32 xfbCount = 0; + const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) + { + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - Core::Callback_VideoCopiedToXFB(false); - return; - } + Core::Callback_VideoCopiedToXFB(false); + return; + } - ResetAPIState(); + ResetAPIState(); - if(g_ActiveConfig.bAnaglyphStereo) - { - static bool RightFrame = false; - if(RightFrame) - { - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); - VertexShaderManager::ResetView(); - VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); - VertexShaderManager::RotateView(-0.0001f *g_ActiveConfig.iAnaglyphFocalAngle,0.0f); - RightFrame = false; - } - else - { - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED); - VertexShaderManager::ResetView(); - VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); - VertexShaderManager::RotateView(0.0001f * g_ActiveConfig.iAnaglyphFocalAngle,0.0f); - RightFrame = true; - } - } + if(g_ActiveConfig.bAnaglyphStereo) + { + static bool RightFrame = false; + if(RightFrame) + { + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN); + VertexShaderManager::ResetView(); + VertexShaderManager::TranslateView(-0.001f * g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); + VertexShaderManager::RotateView(-0.0001f *g_ActiveConfig.iAnaglyphFocalAngle,0.0f); + RightFrame = false; + } + else + { + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED); + VertexShaderManager::ResetView(); + VertexShaderManager::TranslateView(0.001f *g_ActiveConfig.iAnaglyphStereoSeparation,0.0f); + VertexShaderManager::RotateView(0.0001f * g_ActiveConfig.iAnaglyphFocalAngle,0.0f); + RightFrame = true; + } + } - // Prepare to copy the XFBs to our backbuffer - D3D::dev->SetDepthStencilSurface(NULL); - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); + // Prepare to copy the XFBs to our backbuffer + D3D::dev->SetDepthStencilSurface(NULL); + D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - D3DVIEWPORT9 vp; + UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); + D3DVIEWPORT9 vp; - // Clear full target screen (edges, borders etc) - if(g_ActiveConfig.bAnaglyphStereo) { - // use a clear quad to keep old red or blue/green data - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); - D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); - } - else - { - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); - } + // Clear full target screen (edges, borders etc) + if(g_ActiveConfig.bAnaglyphStereo) { + // use a clear quad to keep old red or blue/green data + vp.X = 0; + vp.Y = 0; + vp.Width = s_backbuffer_width; + vp.Height = s_backbuffer_height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); + D3D::drawClearQuad(0, 1.0, PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader()); + } + else + { + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); + } - int X = GetTargetRectangle().left; - int Y = GetTargetRectangle().top; - int Width = GetTargetRectangle().right - GetTargetRectangle().left; - int Height = GetTargetRectangle().bottom - GetTargetRectangle().top; + int X = GetTargetRectangle().left; + int Y = GetTargetRectangle().top; + int Width = GetTargetRectangle().right - GetTargetRectangle().left; + int Height = GetTargetRectangle().bottom - GetTargetRectangle().top; - // Sanity check - if (X < 0) X = 0; - if (Y < 0) Y = 0; - if (X > s_backbuffer_width) X = s_backbuffer_width; - if (Y > s_backbuffer_height) Y = s_backbuffer_height; - if (Width < 0) Width = 0; - if (Height < 0) Height = 0; - if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; - if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; + // Sanity check + if (X < 0) X = 0; + if (Y < 0) Y = 0; + if (X > s_backbuffer_width) X = s_backbuffer_width; + if (Y > s_backbuffer_height) Y = s_backbuffer_height; + if (Width < 0) Width = 0; + if (Height < 0) Height = 0; + if (Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X; + if (Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y; - vp.X = X; - vp.Y = Y; - vp.Width = Width; - vp.Height = Height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; + vp.X = X; + vp.Y = Y; + vp.Width = Width; + vp.Height = Height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); + D3D::dev->SetViewport(&vp); - D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + D3D::ChangeSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - const XFBSourceBase* xfbSource = NULL; + const XFBSourceBase* xfbSource = NULL; - if(g_ActiveConfig.bUseXFB) - { - // draw each xfb source - // Render to the real buffer now. - for (u32 i = 0; i < xfbCount; ++i) - { - xfbSource = xfbSourceList[i]; + if(g_ActiveConfig.bUseXFB) + { + // draw each xfb source + // Render to the real buffer now. + for (u32 i = 0; i < xfbCount; ++i) + { + xfbSource = xfbSourceList[i]; - MathUtil::Rectangle sourceRc; + MathUtil::Rectangle sourceRc; - sourceRc.left = 0; - sourceRc.top = 0; - sourceRc.right = (float)xfbSource->texWidth; - sourceRc.bottom = (float)xfbSource->texHeight; + sourceRc.left = 0; + sourceRc.top = 0; + sourceRc.right = (float)xfbSource->texWidth; + sourceRc.bottom = (float)xfbSource->texHeight; - MathUtil::Rectangle drawRc; + MathUtil::Rectangle drawRc; - if (g_ActiveConfig.bUseRealXFB) - { - drawRc.top = -1; - drawRc.bottom = 1; - drawRc.left = -1; - drawRc.right = 1; - } - else - { - // use virtual xfb with offset - int xfbHeight = xfbSource->srcHeight; - int xfbWidth = xfbSource->srcWidth; - int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); + if (g_ActiveConfig.bUseRealXFB) + { + drawRc.top = -1; + drawRc.bottom = 1; + drawRc.left = -1; + drawRc.right = 1; + } + else + { + // use virtual xfb with offset + int xfbHeight = xfbSource->srcHeight; + int xfbWidth = xfbSource->srcWidth; + int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); - drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight); - drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); - drawRc.left = -(xfbWidth / (float)fbWidth); - drawRc.right = (xfbWidth / (float)fbWidth); + drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight); + drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight); + drawRc.left = -(xfbWidth / (float)fbWidth); + drawRc.right = (xfbWidth / (float)fbWidth); - // The following code disables auto stretch. Kept for reference. - // scale draw area for a 1 to 1 pixel mapping with the draw target - //float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight(); - //float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth(); - //drawRc.top *= vScale; - //drawRc.bottom *= vScale; - //drawRc.left *= hScale; - //drawRc.right *= hScale; - } + // The following code disables auto stretch. Kept for reference. + // scale draw area for a 1 to 1 pixel mapping with the draw target + //float vScale = (float)fbHeight / (float)GetTargetRectangle().GetHeight(); + //float hScale = (float)fbWidth / (float)GetTargetRectangle().GetWidth(); + //drawRc.top *= vScale; + //drawRc.bottom *= vScale; + //drawRc.left *= hScale; + //drawRc.right *= hScale; + } - xfbSource->Draw(sourceRc, drawRc, Width, Height); - } - } - else - { - TargetRectangle targetRc = ConvertEFBRectangle(rc); - LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture(); - D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(), - Renderer::GetTargetWidth(),Renderer::GetTargetHeight(), - Width,Height, - PixelShaderCache::GetColorCopyProgram(g_ActiveConfig.iMultisampleMode), - VertexShaderCache::GetSimpleVertexShader(g_ActiveConfig.iMultisampleMode),Gamma); + xfbSource->Draw(sourceRc, drawRc, Width, Height); + } + } + else + { + TargetRectangle targetRc = ConvertEFBRectangle(rc); + LPDIRECT3DTEXTURE9 read_texture = FramebufferManager::GetEFBColorTexture(); + D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(), + Renderer::GetTargetWidth(),Renderer::GetTargetHeight(), + Width,Height, + PixelShaderCache::GetColorCopyProgram(g_ActiveConfig.iMultisampleMode), + VertexShaderCache::GetSimpleVertexShader(g_ActiveConfig.iMultisampleMode),Gamma); - } - D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); - D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); + } + D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); + D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); - if(g_ActiveConfig.bAnaglyphStereo) - { - DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); - } + if(g_ActiveConfig.bAnaglyphStereo) + { + DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); + } - vp.X = 0; - vp.Y = 0; - vp.Width = s_backbuffer_width; - vp.Height = s_backbuffer_height; - vp.MinZ = 0.0f; - vp.MaxZ = 1.0f; - D3D::dev->SetViewport(&vp); + vp.X = 0; + vp.Y = 0; + vp.Width = s_backbuffer_width; + vp.Height = s_backbuffer_height; + vp.MinZ = 0.0f; + vp.MaxZ = 1.0f; + D3D::dev->SetViewport(&vp); - // Save screenshot - if (s_bScreenshot) - { - std::lock_guard lk(s_criticalScreenshot); - SaveScreenshot(s_sScreenshotName, GetTargetRectangle()); - s_bScreenshot = false; - } + // Save screenshot + if (s_bScreenshot) + { + std::lock_guard lk(s_criticalScreenshot); + SaveScreenshot(s_sScreenshotName, GetTargetRectangle()); + s_bScreenshot = false; + } - // Dump frames - static int w = 0, h = 0; - if (g_ActiveConfig.bDumpFrames) - { - static int s_recordWidth; - static int s_recordHeight; + // Dump frames + static int w = 0, h = 0; + if (g_ActiveConfig.bDumpFrames) + { + static int s_recordWidth; + static int s_recordHeight; - HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); - if (!bLastFrameDumped) - { - s_recordWidth = GetTargetRectangle().GetWidth(); - s_recordHeight = GetTargetRectangle().GetHeight(); - bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); - if (!bAVIDumping) - { - PanicAlert("Error dumping frames to AVI."); - } - else - { - char msg [255]; - sprintf_s(msg,255, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", - File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight); - OSD::AddMessage(msg, 2000); - } - } - if (bAVIDumping) - { - D3DLOCKED_RECT rect; - if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) - { - if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) - { - frame_data.resize(3 * s_recordWidth * s_recordHeight); - w = s_recordWidth; - h = s_recordHeight; - } - formatBufferDump((const u8*)rect.pBits, &frame_data[0], s_recordWidth, s_recordHeight, rect.Pitch); - AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); - ScreenShootMEMSurface->UnlockRect(); - } - } - bLastFrameDumped = true; - } - else - { - if (bLastFrameDumped && bAVIDumping) - { - std::vector().swap(frame_data); - w = h = 0; - AVIDump::Stop(); - bAVIDumping = false; - OSD::AddMessage("Stop dumping frames to AVI", 2000); - } - bLastFrameDumped = false; - } + HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); + if (!bLastFrameDumped) + { + s_recordWidth = GetTargetRectangle().GetWidth(); + s_recordHeight = GetTargetRectangle().GetHeight(); + bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); + if (!bAVIDumping) + { + PanicAlert("Error dumping frames to AVI."); + } + else + { + char msg [255]; + sprintf_s(msg,255, "Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), s_recordWidth, s_recordHeight); + OSD::AddMessage(msg, 2000); + } + } + if (bAVIDumping) + { + D3DLOCKED_RECT rect; + if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) + { + if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) + { + frame_data.resize(3 * s_recordWidth * s_recordHeight); + w = s_recordWidth; + h = s_recordHeight; + } + formatBufferDump((const u8*)rect.pBits, &frame_data[0], s_recordWidth, s_recordHeight, rect.Pitch); + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); + ScreenShootMEMSurface->UnlockRect(); + } + } + bLastFrameDumped = true; + } + else + { + if (bLastFrameDumped && bAVIDumping) + { + std::vector().swap(frame_data); + w = h = 0; + AVIDump::Stop(); + bAVIDumping = false; + OSD::AddMessage("Stop dumping frames to AVI", 2000); + } + bLastFrameDumped = false; + } - // Finish up the current frame, print some stats - if (g_ActiveConfig.bShowFPS) - { - char fps[20]; - StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); - D3D::font.DrawTextScaled(0, 0, 20, 20, 0.0f, 0xFF00FFFF, fps); - } + // Finish up the current frame, print some stats + if (g_ActiveConfig.bShowFPS) + { + char fps[20]; + StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); + D3D::font.DrawTextScaled(0, 0, 20, 20, 0.0f, 0xFF00FFFF, fps); + } - if (SConfig::GetInstance().m_ShowLag) - { - char lag[10]; - StringCchPrintfA(lag, 10, "Lag: %llu\n", Movie::g_currentLagCount); - D3D::font.DrawTextScaled(0, 18, 20, 20, 0.0f, 0xFF00FFFF, lag); - } + if (SConfig::GetInstance().m_ShowLag) + { + char lag[10]; + StringCchPrintfA(lag, 10, "Lag: %llu\n", Movie::g_currentLagCount); + D3D::font.DrawTextScaled(0, 18, 20, 20, 0.0f, 0xFF00FFFF, lag); + } - if (g_ActiveConfig.bShowInputDisplay) - { - char inputDisplay[1000]; - StringCchPrintfA(inputDisplay, 1000, Movie::GetInputDisplay().c_str()); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, inputDisplay); - } + if (g_ActiveConfig.bShowInputDisplay) + { + char inputDisplay[1000]; + StringCchPrintfA(inputDisplay, 1000, Movie::GetInputDisplay().c_str()); + D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, inputDisplay); + } - Renderer::DrawDebugText(); + Renderer::DrawDebugText(); - if (g_ActiveConfig.bOverlayStats) - { - Statistics::ToString(st); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); - } - else if (g_ActiveConfig.bOverlayProjStats) - { - Statistics::ToStringProj(st); - D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); - } + if (g_ActiveConfig.bOverlayStats) + { + Statistics::ToString(st); + D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); + } + else if (g_ActiveConfig.bOverlayProjStats) + { + Statistics::ToStringProj(st); + D3D::font.DrawTextScaled(0, 36, 20, 20, 0.0f, 0xFF00FFFF, st); + } - OSD::DrawMessages(); - D3D::EndFrame(); - ++frameCount; + OSD::DrawMessages(); + D3D::EndFrame(); + ++frameCount; - GFX_DEBUGGER_PAUSE_AT(NEXT_FRAME, true); + GFX_DEBUGGER_PAUSE_AT(NEXT_FRAME, true); - DLCache::ProgressiveCleanup(); - TextureCache::Cleanup(); - // Flip/present backbuffer to frontbuffer here - D3D::Present(); - // Enable configuration changes - UpdateActiveConfig(); - TextureCache::OnConfigChanged(g_ActiveConfig); + DLCache::ProgressiveCleanup(); + TextureCache::Cleanup(); + // Flip/present backbuffer to frontbuffer here + D3D::Present(); + // Enable configuration changes + UpdateActiveConfig(); + TextureCache::OnConfigChanged(g_ActiveConfig); - SetWindowSize(fbWidth, fbHeight); + SetWindowSize(fbWidth, fbHeight); - const bool windowResized = CheckForResize(); + const bool windowResized = CheckForResize(); - bool xfbchanged = false; + bool xfbchanged = false; - if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight) - { - xfbchanged = true; - unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth; - unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight; - FramebufferManagerBase::SetLastXfbWidth(w); - FramebufferManagerBase::SetLastXfbHeight(h); - } + if (FramebufferManagerBase::LastXfbWidth() != fbWidth || FramebufferManagerBase::LastXfbHeight() != fbHeight) + { + xfbchanged = true; + unsigned int w = (fbWidth < 1 || fbWidth > MAX_XFB_WIDTH) ? MAX_XFB_WIDTH : fbWidth; + unsigned int h = (fbHeight < 1 || fbHeight > MAX_XFB_HEIGHT) ? MAX_XFB_HEIGHT : fbHeight; + FramebufferManagerBase::SetLastXfbWidth(w); + FramebufferManagerBase::SetLastXfbHeight(h); + } - u32 newAA = g_ActiveConfig.iMultisampleMode; + u32 newAA = g_ActiveConfig.iMultisampleMode; - if (xfbchanged || windowResized || s_LastEFBScale != g_ActiveConfig.iEFBScale || s_LastAA != newAA) - { - s_LastAA = newAA; + if (xfbchanged || windowResized || s_LastEFBScale != g_ActiveConfig.iEFBScale || s_LastAA != newAA) + { + s_LastAA = newAA; - UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); + UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height); - int SupersampleCoeficient = (s_LastAA % 3) + 1; + int SupersampleCoeficient = (s_LastAA % 3) + 1; - s_LastEFBScale = g_ActiveConfig.iEFBScale; - CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); + s_LastEFBScale = g_ActiveConfig.iEFBScale; + CalculateTargetSize(s_backbuffer_width, s_backbuffer_height, SupersampleCoeficient); - D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); - D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); - if (windowResized) - { - // device objects lost, so recreate all of them - SetupDeviceObjects(); - } - else - { - // just resize the frame buffer - delete g_framebuffer_manager; - g_framebuffer_manager = new FramebufferManager; - } - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); - SetLineWidth(); - } + D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); + D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); + if (windowResized) + { + // device objects lost, so recreate all of them + SetupDeviceObjects(); + } + else + { + // just resize the frame buffer + delete g_framebuffer_manager; + g_framebuffer_manager = new FramebufferManager; + } + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); + SetLineWidth(); + } - if (XFBWrited) - s_fps = UpdateFPSCounter(); + if (XFBWrited) + s_fps = UpdateFPSCounter(); - // Begin new frame - // Set default viewport and scissor, for the clear to work correctly - // New frame - stats.ResetFrame(); + // Begin new frame + // Set default viewport and scissor, for the clear to work correctly + // New frame + stats.ResetFrame(); - // Handle vsync changes during execution - if(s_vsync != g_ActiveConfig.IsVSync()) - { - s_vsync = g_ActiveConfig.IsVSync(); - TeardownDeviceObjects(); - D3D::Reset(); - // device objects lost, so recreate all of them - SetupDeviceObjects(); - } - D3D::BeginFrame(); - RestoreAPIState(); + // Handle vsync changes during execution + if(s_vsync != g_ActiveConfig.IsVSync()) + { + s_vsync = g_ActiveConfig.IsVSync(); + TeardownDeviceObjects(); + D3D::Reset(); + // device objects lost, so recreate all of them + SetupDeviceObjects(); + } + D3D::BeginFrame(); + RestoreAPIState(); - D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); - D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); - VertexShaderManager::SetViewportChanged(); + D3D::dev->SetRenderTarget(0, FramebufferManager::GetEFBColorRTSurface()); + D3D::dev->SetDepthStencilSurface(FramebufferManager::GetEFBDepthRTSurface()); + VertexShaderManager::SetViewportChanged(); - Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)); - XFBWrited = false; + Core::Callback_VideoCopiedToXFB(XFBWrited || (g_ActiveConfig.bUseXFB && g_ActiveConfig.bUseRealXFB)); + XFBWrited = false; } void Renderer::ApplyState(bool bUseDstAlpha) { - if (bUseDstAlpha) - { - // If we get here we are sure that we are using dst alpha pass. (bpmem.dstalpha.enable) - // Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) - // We must disable blend because we want to write alpha value directly to the alpha channel without modifications. - D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); - D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); - if(bpmem.zmode.testenable && bpmem.zmode.updateenable) - { - // This is needed to draw to the correct pixels in multi-pass algorithms - // to avoid z-fighting and grants that you write to the same pixels - // affected by the last pass - D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); - D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); - } - } + if (bUseDstAlpha) + { + // If we get here we are sure that we are using dst alpha pass. (bpmem.dstalpha.enable) + // Alpha write is enabled. (because bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24) + // We must disable blend because we want to write alpha value directly to the alpha channel without modifications. + D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); + D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); + if(bpmem.zmode.testenable && bpmem.zmode.updateenable) + { + // This is needed to draw to the correct pixels in multi-pass algorithms + // to avoid z-fighting and grants that you write to the same pixels + // affected by the last pass + D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); + D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + } + } } void Renderer::RestoreState() { - D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); - D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); - if(bpmem.zmode.testenable && bpmem.zmode.updateenable) - { - D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); - D3D::RefreshRenderState(D3DRS_ZFUNC); - } - // TODO: Enable this code. Caused glitches for me however (neobrain) - // for (unsigned int i = 0; i < 8; ++i) - // D3D::dev->SetTexture(i, NULL); + D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); + D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); + if(bpmem.zmode.testenable && bpmem.zmode.updateenable) + { + D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); + D3D::RefreshRenderState(D3DRS_ZFUNC); + } + // TODO: Enable this code. Caused glitches for me however (neobrain) + // for (unsigned int i = 0; i < 8; ++i) + // D3D::dev->SetTexture(i, NULL); } // ALWAYS call RestoreAPIState for each ResetAPIState call you're doing void Renderer::ResetAPIState() { - D3D::SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - D3D::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; - D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); + D3D::SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + D3D::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + D3D::SetRenderState(D3DRS_ZENABLE, FALSE); + D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask); } void Renderer::RestoreAPIState() { - // Gets us back into a more game-like state. - D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); - D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - VertexShaderManager::SetViewportChanged(); - BPFunctions::SetScissor(); - if (bpmem.zmode.testenable) { - D3D::SetRenderState(D3DRS_ZENABLE, TRUE); - if (bpmem.zmode.updateenable) - D3D::SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - } - SetColorMask(); - SetLogicOpMode(); - SetGenerationMode(); + // Gets us back into a more game-like state. + D3D::SetRenderState(D3DRS_FILLMODE, g_ActiveConfig.bWireFrame ? D3DFILL_WIREFRAME : D3DFILL_SOLID); + D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + VertexShaderManager::SetViewportChanged(); + BPFunctions::SetScissor(); + if (bpmem.zmode.testenable) { + D3D::SetRenderState(D3DRS_ZENABLE, TRUE); + if (bpmem.zmode.updateenable) + D3D::SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + } + SetColorMask(); + SetLogicOpMode(); + SetGenerationMode(); } void Renderer::SetGenerationMode() { - const D3DCULL d3dCullModes[4] = - { - D3DCULL_NONE, - D3DCULL_CCW, - D3DCULL_CW, - D3DCULL_CCW - }; + const D3DCULL d3dCullModes[4] = + { + D3DCULL_NONE, + D3DCULL_CCW, + D3DCULL_CW, + D3DCULL_CCW + }; - D3D::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]); + D3D::SetRenderState(D3DRS_CULLMODE, d3dCullModes[bpmem.genMode.cullmode]); } void Renderer::SetDepthMode() { - const D3DCMPFUNC d3dCmpFuncs[8] = - { - D3DCMP_NEVER, - D3DCMP_LESS, - D3DCMP_EQUAL, - D3DCMP_LESSEQUAL, - D3DCMP_GREATER, - D3DCMP_NOTEQUAL, - D3DCMP_GREATEREQUAL, - D3DCMP_ALWAYS - }; + const D3DCMPFUNC d3dCmpFuncs[8] = + { + D3DCMP_NEVER, + D3DCMP_LESS, + D3DCMP_EQUAL, + D3DCMP_LESSEQUAL, + D3DCMP_GREATER, + D3DCMP_NOTEQUAL, + D3DCMP_GREATEREQUAL, + D3DCMP_ALWAYS + }; - if (bpmem.zmode.testenable) - { - D3D::SetRenderState(D3DRS_ZENABLE, TRUE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable); - D3D::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]); - } - else - { - // if the test is disabled write is disabled too - D3D::SetRenderState(D3DRS_ZENABLE, FALSE); - D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - } + if (bpmem.zmode.testenable) + { + D3D::SetRenderState(D3DRS_ZENABLE, TRUE); + D3D::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable); + D3D::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]); + } + else + { + // if the test is disabled write is disabled too + D3D::SetRenderState(D3DRS_ZENABLE, FALSE); + D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + } } void Renderer::SetLogicOpMode() { - // D3D9 doesn't support logic blending, so this is a huge hack + // D3D9 doesn't support logic blending, so this is a huge hack - // 0 0x00 - // 1 Source & destination - // 2 Source & ~destination - // 3 Source - // 4 ~Source & destination - // 5 Destination - // 6 Source ^ destination = Source & ~destination | ~Source & destination - // 7 Source | destination - // 8 ~(Source | destination) - // 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination - // 10 ~Destination - // 11 Source | ~destination - // 12 ~Source - // 13 ~Source | destination - // 14 ~(Source & destination) - // 15 0xff - const D3DBLENDOP d3dLogicOpop[16] = - { - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_SUBTRACT, - D3DBLENDOP_ADD, - D3DBLENDOP_REVSUBTRACT, - D3DBLENDOP_ADD, - D3DBLENDOP_MAX, - D3DBLENDOP_ADD, - D3DBLENDOP_MAX, - D3DBLENDOP_MAX, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD, - D3DBLENDOP_ADD - }; - const D3DBLEND d3dLogicOpSrcFactors[16] = - { - D3DBLEND_ZERO, - D3DBLEND_DESTCOLOR, - D3DBLEND_ONE, - D3DBLEND_ONE, - D3DBLEND_DESTCOLOR, - D3DBLEND_ZERO, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_ONE - }; - const D3DBLEND d3dLogicOpDestFactors[16] = - { - D3DBLEND_ZERO, - D3DBLEND_ZERO, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ZERO, - D3DBLEND_ONE, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_SRCCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVDESTCOLOR, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE, - D3DBLEND_INVSRCCOLOR, - D3DBLEND_ONE - }; + // 0 0x00 + // 1 Source & destination + // 2 Source & ~destination + // 3 Source + // 4 ~Source & destination + // 5 Destination + // 6 Source ^ destination = Source & ~destination | ~Source & destination + // 7 Source | destination + // 8 ~(Source | destination) + // 9 ~(Source ^ destination) = ~Source & ~destination | Source & destination + // 10 ~Destination + // 11 Source | ~destination + // 12 ~Source + // 13 ~Source | destination + // 14 ~(Source & destination) + // 15 0xff + const D3DBLENDOP d3dLogicOpop[16] = + { + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_SUBTRACT, + D3DBLENDOP_ADD, + D3DBLENDOP_REVSUBTRACT, + D3DBLENDOP_ADD, + D3DBLENDOP_MAX, + D3DBLENDOP_ADD, + D3DBLENDOP_MAX, + D3DBLENDOP_MAX, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD, + D3DBLENDOP_ADD + }; + const D3DBLEND d3dLogicOpSrcFactors[16] = + { + D3DBLEND_ZERO, + D3DBLEND_DESTCOLOR, + D3DBLEND_ONE, + D3DBLEND_ONE, + D3DBLEND_DESTCOLOR, + D3DBLEND_ZERO, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_ONE, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_ONE + }; + const D3DBLEND d3dLogicOpDestFactors[16] = + { + D3DBLEND_ZERO, + D3DBLEND_ZERO, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ZERO, + D3DBLEND_ONE, + D3DBLEND_ONE, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ONE, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_SRCCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVDESTCOLOR, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ONE, + D3DBLEND_INVSRCCOLOR, + D3DBLEND_ONE + }; - if (bpmem.blendmode.logicopenable) - { - D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, true); - D3D::SetRenderState(D3DRS_BLENDOP, d3dLogicOpop[bpmem.blendmode.logicmode]); - D3D::SetRenderState(D3DRS_SRCBLEND, d3dLogicOpSrcFactors[bpmem.blendmode.logicmode]); - D3D::SetRenderState(D3DRS_DESTBLEND, d3dLogicOpDestFactors[bpmem.blendmode.logicmode]); - } - else - { - SetBlendMode(true); - } + if (bpmem.blendmode.logicopenable) + { + D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, true); + D3D::SetRenderState(D3DRS_BLENDOP, d3dLogicOpop[bpmem.blendmode.logicmode]); + D3D::SetRenderState(D3DRS_SRCBLEND, d3dLogicOpSrcFactors[bpmem.blendmode.logicmode]); + D3D::SetRenderState(D3DRS_DESTBLEND, d3dLogicOpDestFactors[bpmem.blendmode.logicmode]); + } + else + { + SetBlendMode(true); + } } void Renderer::SetDitherMode() { - D3D::SetRenderState(D3DRS_DITHERENABLE, bpmem.blendmode.dither); + D3D::SetRenderState(D3DRS_DITHERENABLE, bpmem.blendmode.dither); } void Renderer::SetLineWidth() { - // We can't change line width in D3D unless we use ID3DXLine - float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; - float psize = bpmem.lineptwidth.pointsize * fratio / 6.0f; - psize = psize > 0 ? psize : 1.0; - if (psize > m_fMaxPointSize) - { - psize = m_fMaxPointSize; - } - D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); - D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize)); - D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize)); + // We can't change line width in D3D unless we use ID3DXLine + float fratio = xfregs.viewport.wd != 0 ? Renderer::EFBToScaledXf(1.f) : 1.0f; + float psize = bpmem.lineptwidth.pointsize * fratio / 6.0f; + psize = psize > 0 ? psize : 1.0; + if (psize > m_fMaxPointSize) + { + psize = m_fMaxPointSize; + } + D3D::SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MIN, *((DWORD*)&psize)); + D3D::SetRenderState(D3DRS_POINTSIZE_MAX, *((DWORD*)&psize)); } void Renderer::SetSamplerState(int stage, int texindex) { - const D3DTEXTUREFILTERTYPE d3dMipFilters[4] = - { - D3DTEXF_NONE, - D3DTEXF_POINT, - D3DTEXF_LINEAR, - D3DTEXF_NONE, //reserved - }; - const D3DTEXTUREADDRESS d3dClamps[4] = - { - D3DTADDRESS_CLAMP, - D3DTADDRESS_WRAP, - D3DTADDRESS_MIRROR, - D3DTADDRESS_WRAP //reserved - }; + const D3DTEXTUREFILTERTYPE d3dMipFilters[4] = + { + D3DTEXF_NONE, + D3DTEXF_POINT, + D3DTEXF_LINEAR, + D3DTEXF_NONE, //reserved + }; + const D3DTEXTUREADDRESS d3dClamps[4] = + { + D3DTADDRESS_CLAMP, + D3DTADDRESS_WRAP, + D3DTADDRESS_MIRROR, + D3DTADDRESS_WRAP //reserved + }; - const FourTexUnits &tex = bpmem.tex[texindex]; - const TexMode0 &tm0 = tex.texMode0[stage]; - const TexMode1 &tm1 = tex.texMode1[stage]; + const FourTexUnits &tex = bpmem.tex[texindex]; + const TexMode0 &tm0 = tex.texMode0[stage]; + const TexMode1 &tm1 = tex.texMode1[stage]; - D3DTEXTUREFILTERTYPE min, mag, mip; - if (g_ActiveConfig.bForceFiltering) - { - min = mag = mip = D3DTEXF_LINEAR; - } - else - { - min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; - mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT; - mip = d3dMipFilters[tm0.min_filter & 3]; - } - if (texindex) - stage += 4; + D3DTEXTUREFILTERTYPE min, mag, mip; + if (g_ActiveConfig.bForceFiltering) + { + min = mag = mip = D3DTEXF_LINEAR; + } + else + { + min = (tm0.min_filter & 4) ? D3DTEXF_LINEAR : D3DTEXF_POINT; + mag = tm0.mag_filter ? D3DTEXF_LINEAR : D3DTEXF_POINT; + mip = d3dMipFilters[tm0.min_filter & 3]; + } + if (texindex) + stage += 4; - if (mag == D3DTEXF_LINEAR && min == D3DTEXF_LINEAR && g_ActiveConfig.iMaxAnisotropy) - { - min = D3DTEXF_ANISOTROPIC; - } - D3D::SetSamplerState(stage, D3DSAMP_MINFILTER, min); - D3D::SetSamplerState(stage, D3DSAMP_MAGFILTER, mag); - D3D::SetSamplerState(stage, D3DSAMP_MIPFILTER, mip); + if (mag == D3DTEXF_LINEAR && min == D3DTEXF_LINEAR && g_ActiveConfig.iMaxAnisotropy) + { + min = D3DTEXF_ANISOTROPIC; + } + D3D::SetSamplerState(stage, D3DSAMP_MINFILTER, min); + D3D::SetSamplerState(stage, D3DSAMP_MAGFILTER, mag); + D3D::SetSamplerState(stage, D3DSAMP_MIPFILTER, mip); - D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); - D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); + D3D::SetSamplerState(stage, D3DSAMP_ADDRESSU, d3dClamps[tm0.wrap_s]); + D3D::SetSamplerState(stage, D3DSAMP_ADDRESSV, d3dClamps[tm0.wrap_t]); - float lodbias = (s32)tm0.lod_bias / 32.0f; - D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); - D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4); + float lodbias = (s32)tm0.lod_bias / 32.0f; + D3D::SetSamplerState(stage, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lodbias); + D3D::SetSamplerState(stage, D3DSAMP_MAXMIPLEVEL, tm1.min_lod >> 4); } void Renderer::SetInterlacingMode() { - // TODO + // TODO } } // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 12f3b88576..dc79d68def 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -36,383 +36,383 @@ const u32 MAX_VBUFFER_COUNT = 2; inline void DumpBadShaders() { #if defined(_DEBUG) || defined(DEBUGFAST) - // TODO: Reimplement! - /* std::string error_shaders; - error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); - error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); - char filename[512] = "bad_shader_combo_0.txt"; - int which = 0; - while (File::Exists(filename)) - { - which++; - sprintf(filename, "bad_shader_combo_%i.txt", which); - } - File::WriteStringToFile(true, error_shaders, filename); - PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/ + // TODO: Reimplement! + /* std::string error_shaders; + error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); + error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); + char filename[512] = "bad_shader_combo_0.txt"; + int which = 0; + while (File::Exists(filename)) + { + which++; + sprintf(filename, "bad_shader_combo_%i.txt", which); + } + File::WriteStringToFile(true, error_shaders, filename); + PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to %s", filename);*/ #endif } void VertexManager::CreateDeviceObjects() { - m_buffers_count = 0; - m_vertex_buffers = NULL; - m_index_buffers = NULL; - D3DCAPS9 DeviceCaps = D3D::GetCaps(); - u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; - //Calculate Device Dependant size - m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; - m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; - //if device caps are not enough for Vbuffer fall back to vertex arrays - if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; + m_buffers_count = 0; + m_vertex_buffers = NULL; + m_index_buffers = NULL; + D3DCAPS9 DeviceCaps = D3D::GetCaps(); + u32 devicevMaxBufferSize = DeviceCaps.MaxPrimitiveCount * 3 * DeviceCaps.MaxStreamStride; + //Calculate Device Dependant size + m_vertex_buffer_size = (VBUFFER_SIZE > devicevMaxBufferSize) ? devicevMaxBufferSize : VBUFFER_SIZE; + m_index_buffer_size = (IBUFFER_SIZE > DeviceCaps.MaxVertexIndex) ? DeviceCaps.MaxVertexIndex : IBUFFER_SIZE; + //if device caps are not enough for Vbuffer fall back to vertex arrays + if (m_index_buffer_size < MAXIBUFFERSIZE || m_vertex_buffer_size < MAXVBUFFERSIZE) return; - m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; - m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; + m_vertex_buffers = new LPDIRECT3DVERTEXBUFFER9[MAX_VBUFFER_COUNT]; + m_index_buffers = new LPDIRECT3DINDEXBUFFER9[MAX_VBUFFER_COUNT]; - bool Fail = false; - for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) - { - m_vertex_buffers[m_current_vertex_buffer] = NULL; - m_index_buffers[m_current_vertex_buffer] = NULL; - } - for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) - { - if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) - { - Fail = true; - break; - } - if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) - { - Fail = true; - return; - } - } - m_buffers_count = m_current_vertex_buffer; - m_current_vertex_buffer = 0; - m_current_index_buffer = 0; - m_index_buffer_cursor = m_index_buffer_size; - m_vertex_buffer_cursor = m_vertex_buffer_size; - m_current_stride = 0; - if (Fail) - { - m_buffers_count--; - if (m_buffers_count < 2) - { - //Error creating Vertex buffers. clean and fall to Vertex arrays - m_buffers_count = MAX_VBUFFER_COUNT; - DestroyDeviceObjects(); - } - } + bool Fail = false; + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) + { + m_vertex_buffers[m_current_vertex_buffer] = NULL; + m_index_buffers[m_current_vertex_buffer] = NULL; + } + for (m_current_vertex_buffer = 0; m_current_vertex_buffer < MAX_VBUFFER_COUNT; m_current_vertex_buffer++) + { + if(FAILED( D3D::dev->CreateVertexBuffer( m_vertex_buffer_size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertex_buffers[m_current_vertex_buffer], NULL ) ) ) + { + Fail = true; + break; + } + if( FAILED( D3D::dev->CreateIndexBuffer( m_index_buffer_size * sizeof(u16), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_index_buffers[m_current_vertex_buffer], NULL ) ) ) + { + Fail = true; + return; + } + } + m_buffers_count = m_current_vertex_buffer; + m_current_vertex_buffer = 0; + m_current_index_buffer = 0; + m_index_buffer_cursor = m_index_buffer_size; + m_vertex_buffer_cursor = m_vertex_buffer_size; + m_current_stride = 0; + if (Fail) + { + m_buffers_count--; + if (m_buffers_count < 2) + { + //Error creating Vertex buffers. clean and fall to Vertex arrays + m_buffers_count = MAX_VBUFFER_COUNT; + DestroyDeviceObjects(); + } + } } void VertexManager::DestroyDeviceObjects() { - D3D::SetStreamSource( 0, NULL, 0, 0); - D3D::SetIndices(NULL); - for (int i = 0; i < MAX_VBUFFER_COUNT; i++) - { - if(m_vertex_buffers) - { - if (m_vertex_buffers[i]) - { - m_vertex_buffers[i]->Release(); - m_vertex_buffers[i] = NULL; - } - } + D3D::SetStreamSource( 0, NULL, 0, 0); + D3D::SetIndices(NULL); + for (int i = 0; i < MAX_VBUFFER_COUNT; i++) + { + if(m_vertex_buffers) + { + if (m_vertex_buffers[i]) + { + m_vertex_buffers[i]->Release(); + m_vertex_buffers[i] = NULL; + } + } - if (m_index_buffers[i]) - { - m_index_buffers[i]->Release(); - m_index_buffers[i] = NULL; - } - } - if(m_vertex_buffers) - delete [] m_vertex_buffers; - if(m_index_buffers) - delete [] m_index_buffers; - m_vertex_buffers = NULL; - m_index_buffers = NULL; + if (m_index_buffers[i]) + { + m_index_buffers[i]->Release(); + m_index_buffers[i] = NULL; + } + } + if(m_vertex_buffers) + delete [] m_vertex_buffers; + if(m_index_buffers) + delete [] m_index_buffers; + m_vertex_buffers = NULL; + m_index_buffers = NULL; } void VertexManager::PrepareDrawBuffers(u32 stride) { - if (!m_buffers_count) - { - return; - } - u8* pVertices; - u16* pIndices; - int datasize = IndexGenerator::GetNumVerts() * stride; - int TdataSize = IndexGenerator::GetTriangleindexLen(); - int LDataSize = IndexGenerator::GetLineindexLen(); - int IndexDataSize = TdataSize + LDataSize; - if(IndexDataSize) - { - DWORD LockMode = D3DLOCK_NOOVERWRITE; - m_vertex_buffer_cursor--; - m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; - if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) - { - LockMode = D3DLOCK_DISCARD; - m_vertex_buffer_cursor = 0; - m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; - } - if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) - { - DestroyDeviceObjects(); - return; - } - memcpy(pVertices, s_pBaseBufferPointer, datasize); - m_vertex_buffers[m_current_vertex_buffer]->Unlock(); + if (!m_buffers_count) + { + return; + } + u8* pVertices; + u16* pIndices; + int datasize = IndexGenerator::GetNumVerts() * stride; + int TdataSize = IndexGenerator::GetTriangleindexLen(); + int LDataSize = IndexGenerator::GetLineindexLen(); + int IndexDataSize = TdataSize + LDataSize; + if(IndexDataSize) + { + DWORD LockMode = D3DLOCK_NOOVERWRITE; + m_vertex_buffer_cursor--; + m_vertex_buffer_cursor = m_vertex_buffer_cursor - (m_vertex_buffer_cursor % stride) + stride; + if (m_vertex_buffer_cursor > m_vertex_buffer_size - datasize) + { + LockMode = D3DLOCK_DISCARD; + m_vertex_buffer_cursor = 0; + m_current_vertex_buffer = (m_current_vertex_buffer + 1) % m_buffers_count; + } + if(FAILED(m_vertex_buffers[m_current_vertex_buffer]->Lock(m_vertex_buffer_cursor, datasize,(VOID**)(&pVertices), LockMode))) + { + DestroyDeviceObjects(); + return; + } + memcpy(pVertices, s_pBaseBufferPointer, datasize); + m_vertex_buffers[m_current_vertex_buffer]->Unlock(); - LockMode = D3DLOCK_NOOVERWRITE; - if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) - { - LockMode = D3DLOCK_DISCARD; - m_index_buffer_cursor = 0; - m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; - } + LockMode = D3DLOCK_NOOVERWRITE; + if (m_index_buffer_cursor > m_index_buffer_size - IndexDataSize) + { + LockMode = D3DLOCK_DISCARD; + m_index_buffer_cursor = 0; + m_current_index_buffer = (m_current_index_buffer + 1) % m_buffers_count; + } - if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) - { - DestroyDeviceObjects(); - return; - } - if(TdataSize) - { - memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); - pIndices += TdataSize; - } - if(LDataSize) - { - memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); - pIndices += LDataSize; - } - m_index_buffers[m_current_index_buffer]->Unlock(); - } - if(m_current_stride != stride || m_vertex_buffer_cursor == 0) - { - m_current_stride = stride; - D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride); - } - if (m_index_buffer_cursor == 0) - { - D3D::SetIndices(m_index_buffers[m_current_index_buffer]); - } + if(FAILED(m_index_buffers[m_current_index_buffer]->Lock(m_index_buffer_cursor * sizeof(u16), IndexDataSize * sizeof(u16), (VOID**)(&pIndices), LockMode ))) + { + DestroyDeviceObjects(); + return; + } + if(TdataSize) + { + memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); + pIndices += TdataSize; + } + if(LDataSize) + { + memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); + pIndices += LDataSize; + } + m_index_buffers[m_current_index_buffer]->Unlock(); + } + if(m_current_stride != stride || m_vertex_buffer_cursor == 0) + { + m_current_stride = stride; + D3D::SetStreamSource( 0, m_vertex_buffers[m_current_vertex_buffer], 0, m_current_stride); + } + if (m_index_buffer_cursor == 0) + { + D3D::SetIndices(m_index_buffers[m_current_index_buffer]); + } - ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); - ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); + ADDSTAT(stats.thisFrame.bytesVertexStreamed, datasize); + ADDSTAT(stats.thisFrame.bytesIndexStreamed, IndexDataSize); } void VertexManager::DrawVertexBuffer(int stride) { - int triangles = IndexGenerator::GetNumTriangles(); - int lines = IndexGenerator::GetNumLines(); - int points = IndexGenerator::GetNumPoints(); - int numverts = IndexGenerator::GetNumVerts(); - int StartIndex = m_index_buffer_cursor; - int basevertex = m_vertex_buffer_cursor / stride; - if (triangles > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_TRIANGLELIST, - basevertex, - 0, - numverts, - StartIndex, - triangles))) - { - DumpBadShaders(); - } - StartIndex += IndexGenerator::GetTriangleindexLen(); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (lines > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitive( - D3DPT_LINELIST, - basevertex, - 0, - numverts, - StartIndex, - IndexGenerator::GetNumLines()))) - { - DumpBadShaders(); - } - StartIndex += IndexGenerator::GetLineindexLen(); - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (points > 0) - { - //DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive - u16* PointIndexBuffer = GetPointIndexBuffer(); - int i = 0; - do - { - int count = i + 1; - while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count]) - { - count++; - } - if (FAILED(D3D::dev->DrawPrimitive( - D3DPT_POINTLIST, - basevertex + PointIndexBuffer[i], - count - i))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numDrawCalls); - i = count; - } while (i < points); - } + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + int StartIndex = m_index_buffer_cursor; + int basevertex = m_vertex_buffer_cursor / stride; + if (triangles > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_TRIANGLELIST, + basevertex, + 0, + numverts, + StartIndex, + triangles))) + { + DumpBadShaders(); + } + StartIndex += IndexGenerator::GetTriangleindexLen(); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (lines > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitive( + D3DPT_LINELIST, + basevertex, + 0, + numverts, + StartIndex, + IndexGenerator::GetNumLines()))) + { + DumpBadShaders(); + } + StartIndex += IndexGenerator::GetLineindexLen(); + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (points > 0) + { + //DrawIndexedPrimitive does not support point list so we have to draw them using DrawPrimitive + u16* PointIndexBuffer = GetPointIndexBuffer(); + int i = 0; + do + { + int count = i + 1; + while (count < points && PointIndexBuffer[count - 1] + 1 == PointIndexBuffer[count]) + { + count++; + } + if (FAILED(D3D::dev->DrawPrimitive( + D3DPT_POINTLIST, + basevertex + PointIndexBuffer[i], + count - i))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numDrawCalls); + i = count; + } while (i < points); + } } void VertexManager::DrawVertexArray(int stride) { - int triangles = IndexGenerator::GetNumTriangles(); - int lines = IndexGenerator::GetNumLines(); - int points = IndexGenerator::GetNumPoints(); - int numverts = IndexGenerator::GetNumVerts(); - if (triangles > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_TRIANGLELIST, - 0, numverts, triangles, - GetTriangleIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (lines > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_LINELIST, - 0, numverts, lines, - GetLineIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } - if (points > 0) - { - if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( - D3DPT_POINTLIST, - 0, numverts, points, - GetPointIndexBuffer(), - D3DFMT_INDEX16, - s_pBaseBufferPointer, - stride))) - { - DumpBadShaders(); - } - INCSTAT(stats.thisFrame.numIndexedDrawCalls); - } + int triangles = IndexGenerator::GetNumTriangles(); + int lines = IndexGenerator::GetNumLines(); + int points = IndexGenerator::GetNumPoints(); + int numverts = IndexGenerator::GetNumVerts(); + if (triangles > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_TRIANGLELIST, + 0, numverts, triangles, + GetTriangleIndexBuffer(), + D3DFMT_INDEX16, + s_pBaseBufferPointer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (lines > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_LINELIST, + 0, numverts, lines, + GetLineIndexBuffer(), + D3DFMT_INDEX16, + s_pBaseBufferPointer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } + if (points > 0) + { + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + D3DPT_POINTLIST, + 0, numverts, points, + GetPointIndexBuffer(), + D3DFMT_INDEX16, + s_pBaseBufferPointer, + stride))) + { + DumpBadShaders(); + } + INCSTAT(stats.thisFrame.numIndexedDrawCalls); + } } void VertexManager::vFlush() { - u32 usedtextures = 0; - for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) - if (bpmem.tevorders[i / 2].getEnable(i & 1)) - usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); + u32 usedtextures = 0; + for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) + if (bpmem.tevorders[i / 2].getEnable(i & 1)) + usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); - if (bpmem.genMode.numindstages > 0) - for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i) - if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) - usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); + if (bpmem.genMode.numindstages > 0) + for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i) + if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) + usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); - for (unsigned int i = 0; i < 8; i++) - { - if (usedtextures & (1 << i)) - { - g_renderer->SetSamplerState(i & 3, i >> 2); - FourTexUnits &tex = bpmem.tex[i >> 2]; - TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, - (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, - tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, - tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, - tex.texTlut[i&3].tlut_format, - (tex.texMode0[i&3].min_filter & 3), - (tex.texMode1[i&3].max_lod + 0xf) / 0x10, - tex.texImage1[i&3].image_type); + for (unsigned int i = 0; i < 8; i++) + { + if (usedtextures & (1 << i)) + { + g_renderer->SetSamplerState(i & 3, i >> 2); + FourTexUnits &tex = bpmem.tex[i >> 2]; + TextureCache::TCacheEntryBase* tentry = TextureCache::Load(i, + (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, + tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, + tex.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9, + tex.texTlut[i&3].tlut_format, + (tex.texMode0[i&3].min_filter & 3), + (tex.texMode1[i&3].max_lod + 0xf) / 0x10, + tex.texImage1[i&3].image_type); - if (tentry) - { - // 0s are probably for no manual wrapping needed. - PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0); - } - else - ERROR_LOG(VIDEO, "Error loading texture"); - } - } + if (tentry) + { + // 0s are probably for no manual wrapping needed. + PixelShaderManager::SetTexDims(i, tentry->native_width, tentry->native_height, 0, 0); + } + else + ERROR_LOG(VIDEO, "Error loading texture"); + } + } - // set global constants - VertexShaderManager::SetConstants(); - PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); - u32 stride = g_nativeVertexFmt->GetVertexStride(); - bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && - bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; - DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE; + // set global constants + VertexShaderManager::SetConstants(); + PixelShaderManager::SetConstants(g_nativeVertexFmt->m_components); + u32 stride = g_nativeVertexFmt->GetVertexStride(); + bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && + bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; + bool useDualSource = useDstAlpha && g_ActiveConfig.backend_info.bSupportsDualSourceBlend; + DSTALPHA_MODE AlphaMode = useDualSource ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE; - if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; - } - if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");}); - goto shader_fail; + if (!PixelShaderCache::SetShader(AlphaMode ,g_nativeVertexFmt->m_components)) + { + GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); + goto shader_fail; + } + if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) + { + GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");}); + goto shader_fail; - } - PrepareDrawBuffers(stride); - g_nativeVertexFmt->SetupVertexPointers(); - g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - if(m_buffers_count) - { - DrawVertexBuffer(stride); - } - else - { - DrawVertexArray(stride); - } - g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - if (useDstAlpha && !useDualSource) - { - if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components)) - { - GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; - } - // update alpha only - g_renderer->ApplyState(true); - if(m_buffers_count) - { - DrawVertexBuffer(stride); - } - else - { - DrawVertexArray(stride); - } - g_renderer->RestoreState(); - } - GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); + } + PrepareDrawBuffers(stride); + g_nativeVertexFmt->SetupVertexPointers(); + g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } + g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + if (useDstAlpha && !useDualSource) + { + if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components)) + { + GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); + goto shader_fail; + } + // update alpha only + g_renderer->ApplyState(true); + if(m_buffers_count) + { + DrawVertexBuffer(stride); + } + else + { + DrawVertexArray(stride); + } + g_renderer->RestoreState(); + } + GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); shader_fail: - if(m_buffers_count) - { - m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); - m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; - } + if(m_buffers_count) + { + m_index_buffer_cursor += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); + m_vertex_buffer_cursor += IndexGenerator::GetNumVerts() * stride; + } } } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index 2300291e7d..7c53bdfe23 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -37,257 +37,257 @@ LinearDiskCache g_vs_disk_cache; LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader(int level) { - return SimpleVertexShader[level % MAX_SSAA_SHADERS]; + return SimpleVertexShader[level % MAX_SSAA_SHADERS]; } LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetClearVertexShader() { - return ClearVertexShader; + return ClearVertexShader; } // this class will load the precompiled shaders into our cache class VertexShaderCacheInserter : public LinearDiskCacheReader { public: - void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) - { - VertexShaderCache::InsertByteCode(key, value, value_size, false); - } + void Read(const VertexShaderUid &key, const u8 *value, u32 value_size) + { + VertexShaderCache::InsertByteCode(key, value, value_size, false); + } }; void VertexShaderCache::Init() { - char* vProg = new char[2048]; - sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float2 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0;\n" - "OUT.vTexCoord1 = inTEX2;\n" - "return OUT;\n" - "}\n"); + char* vProg = new char[2048]; + sprintf(vProg,"struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float2 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;\n" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0;\n" + "OUT.vTexCoord1 = inTEX2;\n" + "return OUT;\n" + "}\n"); - SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); + SimpleVertexShader[0] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - sprintf(vProg,"struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vColor0 : COLOR0;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" - "{\n" - "VSOUTPUT OUT;\n" - "OUT.vPosition = inPosition;\n" - "OUT.vColor0 = inColor0;\n" - "return OUT;\n" - "}\n"); + sprintf(vProg,"struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vColor0 : COLOR0;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float4 inColor0: COLOR0)\n" + "{\n" + "VSOUTPUT OUT;\n" + "OUT.vPosition = inPosition;\n" + "OUT.vColor0 = inColor0;\n" + "return OUT;\n" + "}\n"); - ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "float4 vTexCoord2 : TEXCOORD2;\n" - "float4 vTexCoord3 : TEXCOORD3;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0.xyyx;\n" - "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" - "return OUT;\n" - "}\n"); - SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); + ClearVertexShader = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); + sprintf(vProg, "struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0.xyyx;\n" + "OUT.vTexCoord1 = inTEX2.x;\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.495f,-0.495f, 0.495f,-0.495f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.495f, 0.495f,-0.495f, 0.495f) * inTEX1.xyyx);\n" + "return OUT;\n" + "}\n"); + SimpleVertexShader[1] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - sprintf(vProg, "struct VSOUTPUT\n" - "{\n" - "float4 vPosition : POSITION;\n" - "float4 vTexCoord : TEXCOORD0;\n" - "float vTexCoord1 : TEXCOORD1;\n" - "float4 vTexCoord2 : TEXCOORD2;\n" - "float4 vTexCoord3 : TEXCOORD3;\n" - "};\n" - "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" - "{\n" - "VSOUTPUT OUT;" - "OUT.vPosition = inPosition;\n" - "OUT.vTexCoord = inTEX0.xyyx;\n" - "OUT.vTexCoord1 = inTEX2.x;\n" - "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" - "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" - "return OUT;\n" - "}\n"); - SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); + sprintf(vProg, "struct VSOUTPUT\n" + "{\n" + "float4 vPosition : POSITION;\n" + "float4 vTexCoord : TEXCOORD0;\n" + "float vTexCoord1 : TEXCOORD1;\n" + "float4 vTexCoord2 : TEXCOORD2;\n" + "float4 vTexCoord3 : TEXCOORD3;\n" + "};\n" + "VSOUTPUT main(float4 inPosition : POSITION,float2 inTEX0 : TEXCOORD0,float2 inTEX1 : TEXCOORD1,float inTEX2 : TEXCOORD2)\n" + "{\n" + "VSOUTPUT OUT;" + "OUT.vPosition = inPosition;\n" + "OUT.vTexCoord = inTEX0.xyyx;\n" + "OUT.vTexCoord1 = inTEX2.x;\n" + "OUT.vTexCoord2 = inTEX0.xyyx + (float4(-0.9f,-0.45f, 0.9f,-0.45f) * inTEX1.xyyx);\n" + "OUT.vTexCoord3 = inTEX0.xyyx + (float4( 0.9f, 0.45f,-0.9f, 0.45f) * inTEX1.xyyx);\n" + "return OUT;\n" + "}\n"); + SimpleVertexShader[2] = D3D::CompileAndCreateVertexShader(vProg, (int)strlen(vProg)); - Clear(); - delete [] vProg; + Clear(); + delete [] vProg; - if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) - File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); + if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) + File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX).c_str()); - SETSTAT(stats.numVertexShadersCreated, 0); - SETSTAT(stats.numVertexShadersAlive, 0); + SETSTAT(stats.numVertexShadersCreated, 0); + SETSTAT(stats.numVertexShadersAlive, 0); - char cache_filename[MAX_PATH]; - sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); - VertexShaderCacheInserter inserter; - g_vs_disk_cache.OpenAndRead(cache_filename, inserter); + char cache_filename[MAX_PATH]; + sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX).c_str(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID.c_str()); + VertexShaderCacheInserter inserter; + g_vs_disk_cache.OpenAndRead(cache_filename, inserter); - if (g_Config.bEnableShaderDebugging) - Clear(); + if (g_Config.bEnableShaderDebugging) + Clear(); - last_entry = NULL; + last_entry = NULL; } void VertexShaderCache::Clear() { - for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) - iter->second.Destroy(); - vshaders.clear(); - vertex_uid_checker.Invalidate(); + for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter) + iter->second.Destroy(); + vshaders.clear(); + vertex_uid_checker.Invalidate(); - last_entry = NULL; + last_entry = NULL; } void VertexShaderCache::Shutdown() { - for (int i = 0; i < MAX_SSAA_SHADERS; i++) - { - if (SimpleVertexShader[i]) - SimpleVertexShader[i]->Release(); - SimpleVertexShader[i] = NULL; - } + for (int i = 0; i < MAX_SSAA_SHADERS; i++) + { + if (SimpleVertexShader[i]) + SimpleVertexShader[i]->Release(); + SimpleVertexShader[i] = NULL; + } - if (ClearVertexShader) - ClearVertexShader->Release(); - ClearVertexShader = NULL; + if (ClearVertexShader) + ClearVertexShader->Release(); + ClearVertexShader = NULL; - Clear(); - g_vs_disk_cache.Sync(); - g_vs_disk_cache.Close(); + Clear(); + g_vs_disk_cache.Sync(); + g_vs_disk_cache.Close(); } bool VertexShaderCache::SetShader(u32 components) { - VertexShaderUid uid; - GetVertexShaderUid(uid, components, API_D3D9); - if (g_ActiveConfig.bEnableShaderDebugging) - { - VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D9); - vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); - } + VertexShaderUid uid; + GetVertexShaderUid(uid, components, API_D3D9); + if (g_ActiveConfig.bEnableShaderDebugging) + { + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_D3D9); + vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); + } - if (last_entry) - { - if (uid == last_uid) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (last_entry->shader != NULL); - } - } + if (last_entry) + { + if (uid == last_uid) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return (last_entry->shader != NULL); + } + } - last_uid = uid; + last_uid = uid; - VSCache::iterator iter = vshaders.find(uid); - if (iter != vshaders.end()) - { - const VSCacheEntry &entry = iter->second; - last_entry = &entry; + VSCache::iterator iter = vshaders.find(uid); + if (iter != vshaders.end()) + { + const VSCacheEntry &entry = iter->second; + last_entry = &entry; - if (entry.shader) D3D::SetVertexShader(entry.shader); - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return (entry.shader != NULL); - } + if (entry.shader) D3D::SetVertexShader(entry.shader); + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return (entry.shader != NULL); + } - VertexShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D9); + VertexShaderCode code; + GenerateVertexShaderCode(code, components, API_D3D9); - u8 *bytecode; - int bytecodelen; - if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) - { - GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); - return false; - } - g_vs_disk_cache.Append(uid, bytecode, bytecodelen); + u8 *bytecode; + int bytecodelen; + if (!D3D::CompileVertexShader(code.GetBuffer(), (int)strlen(code.GetBuffer()), &bytecode, &bytecodelen)) + { + GFX_DEBUGGER_PAUSE_AT(NEXT_ERROR, true); + return false; + } + g_vs_disk_cache.Append(uid, bytecode, bytecodelen); - bool success = InsertByteCode(uid, bytecode, bytecodelen, true); - if (g_ActiveConfig.bEnableShaderDebugging && success) - { - vshaders[uid].code = code.GetBuffer(); - } - delete [] bytecode; - GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); - return success; + bool success = InsertByteCode(uid, bytecode, bytecodelen, true); + if (g_ActiveConfig.bEnableShaderDebugging && success) + { + vshaders[uid].code = code.GetBuffer(); + } + delete [] bytecode; + GFX_DEBUGGER_PAUSE_AT(NEXT_VERTEX_SHADER_CHANGE, true); + return success; } bool VertexShaderCache::InsertByteCode(const VertexShaderUid &uid, const u8 *bytecode, int bytecodelen, bool activate) { - LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); + LPDIRECT3DVERTEXSHADER9 shader = D3D::CreateVertexShaderFromByteCode(bytecode, bytecodelen); - // Make an entry in the table - VSCacheEntry entry; - entry.shader = shader; + // Make an entry in the table + VSCacheEntry entry; + entry.shader = shader; - vshaders[uid] = entry; - last_entry = &vshaders[uid]; - if (!shader) - return false; + vshaders[uid] = entry; + last_entry = &vshaders[uid]; + if (!shader) + return false; - INCSTAT(stats.numVertexShadersCreated); - SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); - if (activate) - { - D3D::SetVertexShader(shader); - return true; - } - return false; + INCSTAT(stats.numVertexShadersCreated); + SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); + if (activate) + { + D3D::SetVertexShader(shader); + return true; + } + return false; } float VSConstantbuffer[4*C_VENVCONST_END]; void Renderer::SetVSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) { - float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; - VSConstantbuffer_pointer[0] = f1; - VSConstantbuffer_pointer[1] = f2; - VSConstantbuffer_pointer[2] = f3; - VSConstantbuffer_pointer[3] = f4; - DX9::D3D::dev->SetVertexShaderConstantF(const_number, VSConstantbuffer_pointer, 1); + float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; + VSConstantbuffer_pointer[0] = f1; + VSConstantbuffer_pointer[1] = f2; + VSConstantbuffer_pointer[2] = f3; + VSConstantbuffer_pointer[3] = f4; + DX9::D3D::dev->SetVertexShaderConstantF(const_number, VSConstantbuffer_pointer, 1); } void Renderer::SetVSConstant4fv(unsigned int const_number, const float *f) { - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); + DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, 1); } void Renderer::SetMultiVSConstant3fv(unsigned int const_number, unsigned int count, const float *f) { - float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; - for (unsigned int i = 0; i < count; i++) - { - *VSConstantbuffer_pointer++ = *f++; - *VSConstantbuffer_pointer++ = *f++; - *VSConstantbuffer_pointer++ = *f++; - *VSConstantbuffer_pointer++ = 0.f; - } - DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count); + float* VSConstantbuffer_pointer = &VSConstantbuffer[const_number]; + for (unsigned int i = 0; i < count; i++) + { + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = *f++; + *VSConstantbuffer_pointer++ = 0.f; + } + DX9::D3D::dev->SetVertexShaderConstantF(const_number, &VSConstantbuffer[const_number], count); } void Renderer::SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const float *f) { - DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, count); + DX9::D3D::dev->SetVertexShaderConstantF(const_number, f, count); } } // namespace DX9 diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 3c4c66d35f..f3ca31ba82 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -50,192 +50,192 @@ namespace DX9 { - unsigned int VideoBackend::PeekMessages() - { - MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - return FALSE; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return TRUE; - } +unsigned int VideoBackend::PeekMessages() +{ + MSG msg; + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + return FALSE; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return TRUE; +} - void VideoBackend::UpdateFPSDisplay(const char *text) - { - TCHAR temp[512]; - swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); - EmuWindow::SetWindowText(temp); - } +void VideoBackend::UpdateFPSDisplay(const char *text) +{ + TCHAR temp[512]; + swprintf_s(temp, sizeof(temp)/sizeof(TCHAR), _T("%hs | DX9 | %hs"), scm_rev_str, text); + EmuWindow::SetWindowText(temp); +} - std::string VideoBackend::GetName() - { - return "DX9"; - } +std::string VideoBackend::GetName() +{ + return "DX9"; +} - std::string VideoBackend::GetDisplayName() - { - return "Direct3D9 (deprecated)"; - } +std::string VideoBackend::GetDisplayName() +{ + return "Direct3D9 (deprecated)"; +} - void InitBackendInfo() - { - DX9::D3D::Init(); - D3DCAPS9 device_caps = DX9::D3D::GetCaps(); - const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); - const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); - g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30; - g_Config.backend_info.bUseRGBATextures = false; - g_Config.backend_info.bUseMinimalMipCount = true; - g_Config.backend_info.bSupports3DVision = true; - g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart - g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; - // Dual source blend disabled by default until a proper method to test for support is found - g_Config.backend_info.bSupports3DVision = true; - OSVERSIONINFO info; - ZeroMemory(&info, sizeof(OSVERSIONINFO)); - info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&info)) - { - // dual source blending is only supported in windows 7 o newer. sorry xp users - // we cannot test for device caps because most drivers just declare the minimun caps - // and don't expose their support for some functionalities - g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); - } - else - { - g_Config.backend_info.bSupportsDualSourceBlend = false; - } - g_Config.backend_info.bSupportsFormatReinterpretation = true; - g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; - g_Config.backend_info.bSupportsEarlyZ = false; +void InitBackendInfo() +{ + DX9::D3D::Init(); + D3DCAPS9 device_caps = DX9::D3D::GetCaps(); + const int shaderModel = ((device_caps.PixelShaderVersion >> 8) & 0xFF); + const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); + g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 : API_D3D9_SM30; + g_Config.backend_info.bUseRGBATextures = false; + g_Config.backend_info.bUseMinimalMipCount = true; + g_Config.backend_info.bSupports3DVision = true; + g_Config.backend_info.bSupportsPrimitiveRestart = false; // D3D9 does not support primitive restart + g_Config.backend_info.bSupportsSeparateAlphaFunction = device_caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND; + // Dual source blend disabled by default until a proper method to test for support is found + g_Config.backend_info.bSupports3DVision = true; + OSVERSIONINFO info; + ZeroMemory(&info, sizeof(OSVERSIONINFO)); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (GetVersionEx(&info)) + { + // dual source blending is only supported in windows 7 o newer. sorry xp users + // we cannot test for device caps because most drivers just declare the minimun caps + // and don't expose their support for some functionalities + g_Config.backend_info.bSupportsDualSourceBlend = g_Config.backend_info.bSupportsSeparateAlphaFunction && (info.dwPlatformId == VER_PLATFORM_WIN32_NT) && ((info.dwMajorVersion > 6) || ((info.dwMajorVersion == 6) && info.dwMinorVersion >= 1)); + } + else + { + g_Config.backend_info.bSupportsDualSourceBlend = false; + } + g_Config.backend_info.bSupportsFormatReinterpretation = true; + g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; + g_Config.backend_info.bSupportsEarlyZ = false; - // adapters - g_Config.backend_info.Adapters.clear(); - for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i) - g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description); + // adapters + g_Config.backend_info.Adapters.clear(); + for (int i = 0; i < DX9::D3D::GetNumAdapters(); ++i) + g_Config.backend_info.Adapters.push_back(DX9::D3D::GetAdapter(i).ident.Description); - // aamodes - g_Config.backend_info.AAModes.clear(); - if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) - { - const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); + // aamodes + g_Config.backend_info.AAModes.clear(); + if (g_Config.iAdapter < DX9::D3D::GetNumAdapters()) + { + const DX9::D3D::Adapter &adapter = DX9::D3D::GetAdapter(g_Config.iAdapter); - for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) - g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); - } + for (int i = 0; i < (int)adapter.aa_levels.size(); ++i) + g_Config.backend_info.AAModes.push_back(adapter.aa_levels[i].name); + } - // Clear ppshaders string vector - g_Config.backend_info.PPShaders.clear(); + // Clear ppshaders string vector + g_Config.backend_info.PPShaders.clear(); - DX9::D3D::Shutdown(); - } + DX9::D3D::Shutdown(); +} - void VideoBackend::ShowConfig(void* parent) - { +void VideoBackend::ShowConfig(void* parent) +{ #if defined(HAVE_WX) && HAVE_WX - InitBackendInfo(); - VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9"); - diag.ShowModal(); + InitBackendInfo(); + VideoConfigDiag diag((wxWindow*)parent, _trans("Direct3D9"), "gfx_dx9"); + diag.ShowModal(); #endif - } +} - bool VideoBackend::Initialize(void *&window_handle) - { - InitializeShared(); - InitBackendInfo(); +bool VideoBackend::Initialize(void *&window_handle) +{ + InitializeShared(); + InitBackendInfo(); - frameCount = 0; + frameCount = 0; - g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str()); - g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str()); - g_Config.UpdateProjectionHack(); - g_Config.VerifyValidity(); - // as only some driver/hardware configurations support dual source blending only enable it if is - // configured by user - g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; - UpdateActiveConfig(); + g_Config.Load((File::GetUserPath(D_CONFIG_IDX) + "gfx_dx9.ini").c_str()); + g_Config.GameIniLoad(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strGameIni.c_str()); + g_Config.UpdateProjectionHack(); + g_Config.VerifyValidity(); + // as only some driver/hardware configurations support dual source blending only enable it if is + // configured by user + g_Config.backend_info.bSupportsDualSourceBlend &= g_Config.bForceDualSourceBlend; + UpdateActiveConfig(); - window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); - if (window_handle == NULL) - { - ERROR_LOG(VIDEO, "An error has occurred while trying to create the window."); - return false; - } - else if (FAILED(DX9::D3D::Init())) - { - MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK); - return false; - } + window_handle = (void*)EmuWindow::Create((HWND)window_handle, GetModuleHandle(0), _T("Loading - Please wait.")); + if (window_handle == NULL) + { + ERROR_LOG(VIDEO, "An error has occurred while trying to create the window."); + return false; + } + else if (FAILED(DX9::D3D::Init())) + { + MessageBox(GetActiveWindow(), _T("Unable to initialize Direct3D. Please make sure that you have the latest version of DirectX 9.0c correctly installed."), _T("Fatal Error"), MB_ICONERROR|MB_OK); + return false; + } - s_BackendInitialized = true; + s_BackendInitialized = true; - return true; - } + return true; +} - void VideoBackend::Video_Prepare() - { - // Better be safe... - s_efbAccessRequested = FALSE; - s_FifoShuttingDown = FALSE; - s_swapRequested = FALSE; +void VideoBackend::Video_Prepare() +{ + // Better be safe... + s_efbAccessRequested = FALSE; + s_FifoShuttingDown = FALSE; + s_swapRequested = FALSE; - // internal interfaces - g_vertex_manager = new VertexManager; - g_perf_query = new PerfQuery; - g_renderer = new Renderer; - g_texture_cache = new TextureCache; - // VideoCommon - BPInit(); - Fifo_Init(); - IndexGenerator::Init(); - VertexLoaderManager::Init(); - OpcodeDecoder_Init(); - VertexShaderManager::Init(); - PixelShaderManager::Init(); - CommandProcessor::Init(); - PixelEngine::Init(); - DLCache::Init(); - // Notify the core that the video backend is ready - Host_Message(WM_USER_CREATE); - } + // internal interfaces + g_vertex_manager = new VertexManager; + g_perf_query = new PerfQuery; + g_renderer = new Renderer; + g_texture_cache = new TextureCache; + // VideoCommon + BPInit(); + Fifo_Init(); + IndexGenerator::Init(); + VertexLoaderManager::Init(); + OpcodeDecoder_Init(); + VertexShaderManager::Init(); + PixelShaderManager::Init(); + CommandProcessor::Init(); + PixelEngine::Init(); + DLCache::Init(); + // Notify the core that the video backend is ready + Host_Message(WM_USER_CREATE); +} - void VideoBackend::Shutdown() - { - s_BackendInitialized = false; +void VideoBackend::Shutdown() +{ + s_BackendInitialized = false; - // TODO: should be in Video_Cleanup - if (g_renderer) - { - s_efbAccessRequested = FALSE; - s_FifoShuttingDown = FALSE; - s_swapRequested = FALSE; + // TODO: should be in Video_Cleanup + if (g_renderer) + { + s_efbAccessRequested = FALSE; + s_FifoShuttingDown = FALSE; + s_swapRequested = FALSE; - // VideoCommon - DLCache::Shutdown(); - Fifo_Shutdown(); - CommandProcessor::Shutdown(); - PixelShaderManager::Shutdown(); - VertexShaderManager::Shutdown(); - OpcodeDecoder_Shutdown(); - VertexLoaderManager::Shutdown(); + // VideoCommon + DLCache::Shutdown(); + Fifo_Shutdown(); + CommandProcessor::Shutdown(); + PixelShaderManager::Shutdown(); + VertexShaderManager::Shutdown(); + OpcodeDecoder_Shutdown(); + VertexLoaderManager::Shutdown(); - // internal interfaces - PixelShaderCache::Shutdown(); - VertexShaderCache::Shutdown(); - delete g_texture_cache; - delete g_renderer; - delete g_perf_query; - delete g_vertex_manager; - g_renderer = NULL; - g_texture_cache = NULL; - } - D3D::Shutdown(); - } + // internal interfaces + PixelShaderCache::Shutdown(); + VertexShaderCache::Shutdown(); + delete g_texture_cache; + delete g_renderer; + delete g_perf_query; + delete g_vertex_manager; + g_renderer = NULL; + g_texture_cache = NULL; + } + D3D::Shutdown(); +} - void VideoBackend::Video_Cleanup() { - } +void VideoBackend::Video_Cleanup() { +} } From 40243a4fe7514db647c55bbd808471f59c6454f2 Mon Sep 17 00:00:00 2001 From: Rodolfo Bogado Date: Fri, 23 Aug 2013 22:28:17 -0300 Subject: [PATCH 8/8] Indentation Fix --- Source/Core/VideoCommon/Src/VideoConfig.cpp | 4 ++-- Source/Core/VideoCommon/Src/VideoConfig.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index b05f964891..736b988087 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -96,7 +96,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true); iniFile.Get("Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable, false); iniFile.Get("Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false); - iniFile.Get("Hacks", "ForceDualSourceBlend", &bForceDualSourceBlend, false); + iniFile.Get("Hacks", "ForceDualSourceBlend", &bForceDualSourceBlend, false); iniFile.Get("Hardware", "Adapter", &iAdapter, 0); @@ -253,7 +253,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled); iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); - iniFile.Set("Hacks", "ForceDualSourceBlend", bForceDualSourceBlend); + iniFile.Set("Hacks", "ForceDualSourceBlend", bForceDualSourceBlend); iniFile.Set("Hardware", "Adapter", iAdapter); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index c1b0c87c72..4a773d30e7 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -124,8 +124,8 @@ struct VideoConfig bool bEnablePixelLighting; bool bHackedBufferUpload; bool bFastDepthCalc; - //for dx9-backend - bool bForceDualSourceBlend; + //for dx9-backend + bool bForceDualSourceBlend; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped