From 3bba8977997b70f6569b52d39a6587a6e2523526 Mon Sep 17 00:00:00 2001 From: "sl1nk3.s" Date: Wed, 2 Sep 2009 04:10:40 +0000 Subject: [PATCH] D3D: Fixed dstAlpha, aka "when everything is broken, at least mario have a nice shadow", and removed Cg leftover from it. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4152 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugin_VideoDX9/Plugin_VideoDX9.vcproj | 20 ++--- .../Plugins/Plugin_VideoDX9/Src/D3DBase.cpp | 7 +- .../Plugins/Plugin_VideoDX9/Src/D3DShader.cpp | 24 +++--- .../Plugins/Plugin_VideoDX9/Src/D3DShader.h | 4 +- .../Plugin_VideoDX9/Src/PixelShaderCache.cpp | 32 ++------ .../Plugin_VideoDX9/Src/PixelShaderCache.h | 2 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 73 ++++--------------- Source/Plugins/Plugin_VideoDX9/Src/Render.h | 3 +- .../Plugin_VideoDX9/Src/VertexManager.cpp | 54 +++++++++++++- .../Plugin_VideoDX9/Src/VertexShaderCache.cpp | 32 ++------ 10 files changed, 107 insertions(+), 144 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj index 71b1686904..32f8ca81e9 100644 --- a/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj +++ b/Source/Plugins/Plugin_VideoDX9/Plugin_VideoDX9.vcproj @@ -1,7 +1,7 @@ SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')); - Renderer::SetRenderState( D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C') ); + if (GetCurAdapter().ident.VendorId == VENDOR_ATI) + Renderer::SetRenderState(D3DRS_POINTSIZE, (D3DFORMAT)MAKEFOURCC('A', '2', 'M', '1')); + else + Renderer::SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')); } void InitPP(int adapter, int resolution, int aa_mode, D3DPRESENT_PARAMETERS *pp) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp index aadf241901..b3d550610b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp @@ -23,19 +23,20 @@ namespace D3D { + +extern Shader Ps; +extern Shader Vs; -LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len, bool assembly) +LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len) { //try to compile LPD3DXBUFFER shaderBuffer = 0; LPD3DXBUFFER errorBuffer = 0; LPDIRECT3DVERTEXSHADER9 vShader = 0; HRESULT hr; + static char *versions[5] = {"ERROR", "vs_1_4", "vs_2_0", "vs_3_0", "vs_4_0"}; - if (assembly) - hr = D3DXAssembleShader(code, len, 0, 0, 0, &shaderBuffer, &errorBuffer); - else - hr = D3DXCompileShader(code, len, 0, 0, "main", "vs_2_0", 0, &shaderBuffer, &errorBuffer, 0); + hr = D3DXCompileShader(code, len, 0, 0, "main", versions[Vs.Major], 0, &shaderBuffer, &errorBuffer, 0); if (FAILED(hr)) { @@ -69,18 +70,17 @@ LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len, bool asse return vShader; } -LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len, bool assembly) +LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len) { LPD3DXBUFFER shaderBuffer = 0; LPD3DXBUFFER errorBuffer = 0; LPDIRECT3DPIXELSHADER9 pShader = 0; - static char *versions[6] = {"ERROR", "ps_1_1", "ps_1_4", "ps_2_0", "ps_3_0", "ps_4_0"}; + static char *versions[5] = {"ERROR", "ps_1_4", "ps_2_0", "ps_3_0", "ps_4_0"}; - HRESULT hr; - if (assembly) - hr = D3DXAssembleShader(code, len, 0, 0, 0, &shaderBuffer, &errorBuffer); - else - hr = D3DXCompileShader(code, len, 0, 0, "main", "ps_2_0", // Pixel Shader 2.0 is enough for all we do + HRESULT hr; + // For some reasons, i had this kind of errors : "Shader uses texture addressing operations + // in a dependency chain that is too complex for the target shader model (ps_2_0) to handle." + hr = D3DXCompileShader(code, len, 0, 0, "main", versions[Ps.Major], 0, &shaderBuffer, &errorBuffer, 0); if (FAILED(hr)) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.h index e0de09685b..21cfb55cc1 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.h @@ -21,6 +21,6 @@ namespace D3D { - LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len, bool assembly); - LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len, bool assembly); + LPDIRECT3DVERTEXSHADER9 CompileVertexShader(const char *code, int len); + LPDIRECT3DPIXELSHADER9 CompilePixelShader(const char *code, int len); } \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp index 58f5cffdec..2ead9f17c0 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp @@ -28,9 +28,6 @@ #include "BPMemory.h" #include "XFMemory.h" -#include -#include - PixelShaderCache::PSCache PixelShaderCache::PixelShaders; const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry; @@ -58,14 +55,14 @@ void PixelShaderCache::Shutdown() PixelShaders.clear(); } -void PixelShaderCache::SetShader() +void PixelShaderCache::SetShader(bool dstAlpha) { static LPDIRECT3DPIXELSHADER9 last_shader = NULL; DVSTARTPROFILE(); PIXELSHADERUID uid; - GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), false); + GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), dstAlpha); PSCache::iterator iter; iter = PixelShaders.find(uid); @@ -83,9 +80,9 @@ void PixelShaderCache::SetShader() return; } - bool HLSL = true; - const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), false, HLSL); - LPDIRECT3DPIXELSHADER9 shader = HLSL ? D3D::CompilePixelShader(code, (int)strlen(code), false) : CompileCgShader(code); + const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), dstAlpha, true); + LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePixelShader(code, (int)strlen(code)); + if (shader) { //Make an entry in the table @@ -111,25 +108,6 @@ void PixelShaderCache::SetShader() } } -LPDIRECT3DPIXELSHADER9 PixelShaderCache::CompileCgShader(const char *pstrprogram) -{ - const char *opts[] = {"-profileopts", "MaxLocalParams=256", "-O2", "-q", NULL}; - //const char **opts = cgD3D9GetOptimalOptions(g_cgvProf); - CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts); - if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { - ERROR_LOG(VIDEO, "Failed to create ps %s:\n", cgGetLastListing(g_cgcontext)); - ERROR_LOG(VIDEO, pstrprogram); - return false; - } - - char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); - - LPDIRECT3DPIXELSHADER9 pixel_shader = D3D::CompilePixelShader(pcompiledprog, (int)strlen(pcompiledprog), true); - cgDestroyProgram(tempprog); - tempprog = NULL; - return pixel_shader; -} - void PixelShaderCache::Cleanup() { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h index 749a92877d..22cb68f8df 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h @@ -56,7 +56,7 @@ public: static void Init(); static void Cleanup(); static void Shutdown(); - static void SetShader(); + static void SetShader(bool dstAlpha); #ifdef _DEBUG static std::string GetCurrentShaderCode(); #endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index d77f36f39e..58fc3c0ba4 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -39,13 +39,6 @@ #include "EmuWindow.h" #include "AVIDump.h" -#include -#include - -CGcontext g_cgcontext; -CGprofile g_cgvProf; -CGprofile g_cgfProf; - float Renderer::m_x; float Renderer::m_y; float Renderer::m_width; @@ -78,30 +71,11 @@ struct Message static std::list s_listMsgs; -void HandleCgError(CGcontext ctx, CGerror err, void* appdata) -{ - if(!g_Config.bShowShaderErrors) - return; - - PanicAlert("Cg error: %s\n", cgGetErrorString(err)); - const char* listing = cgGetLastListing(g_cgcontext); - if (listing != NULL) { - PanicAlert("last listing: %s\n", listing); - } -} - void Renderer::Init(SVideoInitialize &_VideoInitialize) { EmuWindow::SetSize(g_Res[g_Config.iWindowedRes][0], g_Res[g_Config.iWindowedRes][1]); D3D::Create(g_Config.iAdapter, EmuWindow::GetWnd(), g_Config.bFullscreen, g_Config.iFSResolution, g_Config.iMultisampleMode); - g_cgcontext = cgCreateContext(); - - cgGetError(); - cgSetErrorHandler(HandleCgError, NULL); - cgD3D9SetDevice(D3D::dev); - g_cgvProf = cgGetProfile("vs_2_0"); //cgD3D9GetLatestVertexProfile(); - g_cgfProf = cgGetProfile("ps_2_0"); //cgD3D9GetLatestPixelProfile(); float width = (float)D3D::GetDisplayWidth(); float height = (float)D3D::GetDisplayHeight(); @@ -110,8 +84,8 @@ void Renderer::Init(SVideoInitialize &_VideoInitialize) m_y = 0; m_width = width; m_height = height; - xScale = width / (float)EFB_WIDTH; - yScale = height / (float)EFB_HEIGHT; + xScale = m_width / (float)EFB_WIDTH; + yScale = m_height / (float)EFB_HEIGHT; m_LastFrameDumped = false; m_AVIDumping = false; @@ -129,10 +103,6 @@ void Renderer::Init(SVideoInitialize &_VideoInitialize) void Renderer::Shutdown() { - cgD3D9SetDevice(NULL); - cgDestroyContext(g_cgcontext); - g_cgcontext = NULL; - D3D::font.Shutdown(); D3D::EndFrame(); D3D::Close(); @@ -390,7 +360,7 @@ void Renderer::SwapBuffers() // clearColor |= 0x003F003F; // D3D::BeginFrame(true,clearColor,1.0f); D3D::BeginFrame(false, clearColor, 1.0f); - // D3D::EnableAlphaToCoverage(); + D3D::EnableAlphaToCoverage(); Postprocess::BeginFrame(); VertexManager::BeginFrame(); @@ -438,7 +408,6 @@ void Renderer::SetViewport(float* _Viewport) } */ - void Renderer::SetScissorRect() { int xoff = bpmem.scissorOffset.x * 2 - 342; @@ -568,8 +537,8 @@ void Renderer::SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Va // Called from VertexShaderManager void UpdateViewport() { - // HACK: Update viewport causes overlay to disappear and the games to move to the - // bottom of the screen for some reason. + // TODO : remove this HACK: Update viewport is still a bit wrong and causes the + // image to be y-offset for some reason though. return; // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) // [0] = width/2 @@ -585,31 +554,19 @@ void UpdateViewport() (rawViewport[5] - rawViewport[2]) / 16777215.0f, rawViewport[5] / 16777215.0f);*/ D3DVIEWPORT9 vp; - - // Keep aspect ratio at 4:3 - // rawViewport[0] = 320, rawViewport[1] = -240 + int scissorXOff = bpmem.scissorOffset.x * 2 - 342; int scissorYOff = bpmem.scissorOffset.y * 2 - 342; - float fourThree = 4.0f / 3.0f; - // These were commented out to fix "unreferenced local variable" compiler warnings. - // float wAdj, hAdj; - // float actualRatiow, actualRatioh; - // int overfl; - // int actualWid, actualHei; - int xoffs = 0; - int yoffs = 0; - int wid, hei; - vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2])/16777215.0f; - vp.MaxZ = xfregs.rawViewport[5]/16777215.0f; - - wid = int(ceil(fabs(2 * xfregs.rawViewport[0]))); - hei = int(ceil(fabs(2 * xfregs.rawViewport[1]))); + vp.X = (int)((xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff) * Renderer::GetXScale()); + vp.Y = (int)(Renderer::GetTargetHeight() - (xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff) * Renderer::GetYScale()); - vp.X = (int)(xfregs.rawViewport[3] - xfregs.rawViewport[0] - 342 - scissorXOff) + xoffs; - vp.Y = (int)(xfregs.rawViewport[4] - xfregs.rawViewport[1] - 342 - scissorYOff) + yoffs; - vp.Width = wid; - vp.Height = hei; + vp.Width = (int)ceil(fabs(2 * xfregs.rawViewport[0]) * Renderer::GetXScale()); + vp.Height = (int)ceil(fabs(2 * xfregs.rawViewport[1]) * Renderer::GetYScale()); + + vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777215.0f; // NearZ + vp.MaxZ = xfregs.rawViewport[5] / 16777215.0f; // FarZ D3D::dev->SetViewport(&vp); -} \ No newline at end of file +} + diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h index d018404164..f116d8f0a1 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.h @@ -66,9 +66,10 @@ public: static float GetXScale() { return xScale; } static float GetYScale() { return yScale; } + static float GetTargetWidth() { return m_width; } + static float GetTargetHeight() { return m_height; } static void SetScissorRect(); -// static void SetViewport(float* _Viewport); // static void SetProjection(float* _pProjection, int constantIndex = -1); // The little status display. diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 8952b762a6..ddae369406 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -239,7 +239,7 @@ void Flush() VertexShaderManager::SetConstants(); PixelShaderManager::SetConstants(); - PixelShaderCache::SetShader(); + PixelShaderCache::SetShader(false); VertexShaderCache::SetShader(g_nativeVertexFmt->m_components); int stride = g_nativeVertexFmt->GetVertexStride(); @@ -249,9 +249,7 @@ void Flush() int numPrimitives = indexGen.GetNumPrims(); if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( pts[(int)collection], - 0, - numVertices, - numPrimitives, + 0, numVertices, numPrimitives, fakeIBuffer, D3DFMT_INDEX16, fakeVBuffer, @@ -270,6 +268,54 @@ void Flush() D3D::dev->SetIndices(0); D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride); } + + if (bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate) + { + DWORD write = 0; + PixelShaderCache::SetShader(true); + + // update alpha only + Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); + Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, false); + + g_nativeVertexFmt->SetupVertexPointers(); + if (collection != C_POINTS) + { + int numPrimitives = indexGen.GetNumPrims(); + if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( + pts[(int)collection], + 0, numVertices, numPrimitives, + fakeIBuffer, + D3DFMT_INDEX16, + fakeVBuffer, + stride))) { +#ifdef _DEBUG + std::string error_shaders; + error_shaders.append(VertexShaderCache::GetCurrentShaderCode()); + error_shaders.append(PixelShaderCache::GetCurrentShaderCode()); + File::WriteStringToFile(true, error_shaders, "bad_shader_combo.txt"); + PanicAlert("DrawIndexedPrimitiveUP failed. Shaders written to shaders.txt."); +#endif + } + } + else + { + D3D::dev->SetIndices(0); + D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, numVertices, fakeVBuffer, stride); + } + + if (bpmem.blendmode.alphaupdate) + write = D3DCOLORWRITEENABLE_ALPHA; + if (bpmem.blendmode.colorupdate) + write |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE; + if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) + Renderer::SetRenderState(D3DRS_ALPHABLENDENABLE, true); + + Renderer::SetRenderState(D3DRS_COLORWRITEENABLE, write); + + INCSTAT(stats.thisFrame.numDrawCalls); + } + INCSTAT(stats.thisFrame.numDrawCalls); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp index ad9fdb3c76..023094d7e4 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp @@ -28,9 +28,6 @@ #include "BPMemory.h" #include "XFMemory.h" -#include -#include - VertexShaderCache::VSCache VertexShaderCache::vshaders; const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry; @@ -83,9 +80,9 @@ void VertexShaderCache::SetShader(u32 components) return; } - bool HLSL = true; - const char *code = GenerateVertexShader(components, HLSL); - LPDIRECT3DVERTEXSHADER9 shader = HLSL ? D3D::CompileVertexShader(code, (int)strlen(code), false) : CompileCgShader(code); + const char *code = GenerateVertexShader(components, true); + LPDIRECT3DVERTEXSHADER9 shader = D3D::CompileVertexShader(code, (int)strlen(code)); + if (shader) { // Make an entry in the table @@ -108,28 +105,9 @@ void VertexShaderCache::SetShader(u32 components) { PanicAlert("Failed to compile Vertex Shader:\n\n%s", code); } + Renderer::SetFVF(NULL); - D3D::dev->SetVertexShader(shader); -} - -LPDIRECT3DVERTEXSHADER9 VertexShaderCache::CompileCgShader(const char *pstrprogram) -{ - //char stropt[64]; - //sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); - const char *opts[] = {"-profileopts", "MaxLocalParams=256", "-O2", "-q", NULL}; - //const char **opts = cgD3D9GetOptimalOptions(g_cgvProf); - CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts); - if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { - ERROR_LOG(VIDEO, "Failed to load vs %s:\n", cgGetLastListing(g_cgcontext)); - ERROR_LOG(VIDEO, pstrprogram); - return NULL; - } - const char *pcompiledprog = cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); - - LPDIRECT3DVERTEXSHADER9 vertex_shader = D3D::CompileVertexShader(pcompiledprog, (int)strlen(pcompiledprog), true); - cgDestroyProgram(tempprog); - tempprog = NULL; - return vertex_shader; + //D3D::dev->SetVertexShader(shader); } void VertexShaderCache::Cleanup()