From 7e3cd987cd0715fc2f0e9689bcbe8a2cc1006935 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 12 Nov 2015 14:47:43 +0100 Subject: [PATCH] Fixes to D3D viewport management. For some reason, still having strange driver-bug-ish problems in unbuffered... --- GPU/Directx9/FramebufferDX9.cpp | 30 +++++++++++++----------------- GPU/Directx9/GPU_DX9.cpp | 3 +-- GPU/Directx9/StencilBufferDX9.cpp | 4 ++-- GPU/Directx9/TextureCacheDX9.cpp | 10 +--------- GPU/Directx9/helper/dx_state.cpp | 3 +-- GPU/Directx9/helper/dx_state.h | 4 ++-- GPU/Directx9/helper/global.cpp | 11 +++++++++++ GPU/Directx9/helper/global.h | 2 ++ 8 files changed, 33 insertions(+), 34 deletions(-) diff --git a/GPU/Directx9/FramebufferDX9.cpp b/GPU/Directx9/FramebufferDX9.cpp index 7bd9c518d..d8f58cb13 100644 --- a/GPU/Directx9/FramebufferDX9.cpp +++ b/GPU/Directx9/FramebufferDX9.cpp @@ -200,16 +200,17 @@ namespace DX9 { void FramebufferManagerDX9::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { if (useBufferedRendering_ && vfb && vfb->fbo) { fbo_bind_as_render_target(vfb->fbo); - dxstate.viewport.set(0, 0, vfb->renderWidth, vfb->renderHeight); + DXSetViewport(0, 0, vfb->renderWidth, vfb->renderHeight); } else { float x, y, w, h; CenterDisplayOutputRect(&x, &y, &w, &h, 480.0f, 272.0f, (float)pixelWidth_, (float)pixelHeight_, ROTATION_LOCKED_HORIZONTAL); - dxstate.viewport.set(x, y, w, h); + DXSetViewport(x, y, w, h); } MakePixelTexture(srcPixels, srcPixelFormat, srcStride, width, height); DisableState(); DrawActiveTexture(drawPixelsTex_, dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL); textureCache_->ForgetLastTexture(); + dxstate.viewport.restore(); } void FramebufferManagerDX9::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { @@ -515,20 +516,14 @@ namespace DX9 { shaderManager_->DirtyLastShader(); pD3Ddevice->SetTexture(0, nullptr); - D3DVIEWPORT9 vp; - vp.MinZ = 0; - vp.MaxZ = 1; - vp.X = 0; - vp.Y = 0; - vp.Width = vfb->renderWidth; - vp.Height = vfb->renderHeight; - pD3Ddevice->SetViewport(&vp); + DXSetViewport(0, 0, vfb->renderWidth, vfb->renderHeight); // This should clear stencil and alpha without changing the other colors. HRESULT hr = pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coord, 5 * sizeof(float)); if (FAILED(hr)) { ERROR_LOG_REPORT(G3D, "ReformatFramebufferFrom() failed: %08x", hr); } + dxstate.viewport.restore(); } RebindFramebuffer(); @@ -682,9 +677,10 @@ namespace DX9 { } void FramebufferManagerDX9::CopyDisplayToOutput() { - fbo_unbind(); - dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + if (useBufferedRendering_) { + DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + } currentRenderVfb_ = 0; u32 offsetX = 0; @@ -794,7 +790,7 @@ namespace DX9 { HRESULT hr = fbo_blit_color(vfb->fbo, &srcRect, nullptr, &dstRect, g_Config.iBufFilter == SCALE_LINEAR ? D3DTEXF_LINEAR : D3DTEXF_POINT); if (FAILED(hr)) { ERROR_LOG_REPORT_ONCE(blit_fail, G3D, "fbo_blit_color failed on display: %08x", hr); - dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); // These are in the output display coordinates if (g_Config.iBufFilter == SCALE_LINEAR) { dxstate.texMagFilter.set(D3DTEXF_LINEAR); @@ -814,7 +810,7 @@ namespace DX9 { fbo_bind_as_render_target(extraFBOs_[0]); int fbo_w, fbo_h; fbo_get_dimensions(extraFBOs_[0], &fbo_w, &fbo_h); - dxstate.viewport.set(0, 0, fbo_w, fbo_h); + DXSetViewport(0, 0, fbo_w, fbo_h); DrawActiveTexture(colorTexture, 0, 0, fbo_w, fbo_h, fbo_w, fbo_h, true, 1.0f, 1.0f, postShaderProgram_); fbo_unbind(); @@ -826,18 +822,19 @@ namespace DX9 { return; } colorTexture = fbo_get_color_texture(extraFBOs_[0]); - dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); // These are in the output display coordinates DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, 480.0f / (float)vfb->width, 272.0f / (float)vfb->height); } else { // Use post-shader, but run shader at output resolution. - dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); + DXSetViewport(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); // These are in the output display coordinates DrawActiveTexture(colorTexture, x, y, w, h, (float)PSP_CoreParameter().pixelWidth, (float)PSP_CoreParameter().pixelHeight, true, 480.0f / (float)vfb->width, 272.0f / (float)vfb->height, postShaderProgram_); } */ pD3Ddevice->SetTexture(0, NULL); } + dxstate.viewport.restore(); } void FramebufferManagerDX9::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool sync, int x, int y, int w, int h) { @@ -1107,7 +1104,6 @@ namespace DX9 { void FramebufferManagerDX9::EndFrame() { if (resized_) { DestroyAllFBOs(); - dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); // Actually, auto mode should be more granular... // Round up to a zoom factor for the render size. int zoom = g_Config.iInternalResolution; diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 2a7493458..777405ef9 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -509,7 +509,6 @@ void DIRECTX9_GPU::InitClearInternal() { dxstate.colorMask.set(true, true, true, true); pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.f, 0); } - dxstate.viewport.set(0, 0, PSP_CoreParameter().pixelWidth, PSP_CoreParameter().pixelHeight); } void DIRECTX9_GPU::DumpNextFrame() { @@ -521,7 +520,7 @@ void DIRECTX9_GPU::BeginFrame() { } void DIRECTX9_GPU::ReapplyGfxStateInternal() { - DX9::dxstate.Restore(); + dxstate.Restore(); GPUCommon::ReapplyGfxStateInternal(); } diff --git a/GPU/Directx9/StencilBufferDX9.cpp b/GPU/Directx9/StencilBufferDX9.cpp index 11cfa7206..84ca55bc4 100644 --- a/GPU/Directx9/StencilBufferDX9.cpp +++ b/GPU/Directx9/StencilBufferDX9.cpp @@ -221,7 +221,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer if (dstBuffer->fbo) { fbo_bind_as_render_target(dstBuffer->fbo); } - dxstate.viewport.set(0, 0, w, h); + DXSetViewport(0, 0, w, h); MakePixelTexture(src, dstBuffer->format, dstBuffer->fb_stride, dstBuffer->bufferWidth, dstBuffer->bufferHeight); @@ -279,7 +279,7 @@ bool FramebufferManagerDX9::NotifyStencilUpload(u32 addr, int size, bool skipZer } } dxstate.stencilMask.set(0xFF); - + dxstate.viewport.restore(); RebindFramebuffer(); return true; } diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 408072a54..d25c1143a 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -1042,15 +1042,7 @@ void TextureCacheDX9::ApplyTextureFramebuffer(TexCacheEntry *entry, VirtualFrame pD3Ddevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); pD3Ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - D3DVIEWPORT9 vp; - vp.MinZ = 0; - vp.MaxZ = 1; - vp.X = 0; - vp.Y = 0; - vp.Width = framebuffer->renderWidth; - vp.Height = framebuffer->renderHeight; - pD3Ddevice->SetViewport(&vp); - + DXSetViewport(0, 0, framebuffer->renderWidth, framebuffer->renderHeight); HRESULT hr = pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, (3 + 2) * sizeof(float)); if (FAILED(hr)) { ERROR_LOG_REPORT(G3D, "Depal render failed: %08x", hr); diff --git a/GPU/Directx9/helper/dx_state.cpp b/GPU/Directx9/helper/dx_state.cpp index ccfdc821b..b5bc4fdf7 100644 --- a/GPU/Directx9/helper/dx_state.cpp +++ b/GPU/Directx9/helper/dx_state.cpp @@ -37,8 +37,7 @@ void DirectXState::Restore() { colorMask.restore(); count++; - // why not? - // viewport.restore(); count++; + viewport.restore(); count++; alphaTest.restore(); count++; alphaTestFunc.restore(); count++; diff --git a/GPU/Directx9/helper/dx_state.h b/GPU/Directx9/helper/dx_state.h index 156abf0ab..3a74f669e 100644 --- a/GPU/Directx9/helper/dx_state.h +++ b/GPU/Directx9/helper/dx_state.h @@ -342,6 +342,7 @@ private: class StateVp { D3DVIEWPORT9 viewport; public: + StateVp() { memset(&viewport, 0, sizeof(viewport)); } inline void set(int x, int y, int w, int h, float n = 0.f, float f = 1.f) { D3DVIEWPORT9 newviewport; newviewport.X = x; @@ -350,8 +351,7 @@ private: newviewport.Height = h; newviewport.MinZ = n; newviewport.MaxZ = f; - - if (memcmp(&viewport, &newviewport, sizeof(viewport))) { + if (memcmp(&viewport, &newviewport, sizeof(viewport)) != 0) { viewport = newviewport; restore(); } diff --git a/GPU/Directx9/helper/global.cpp b/GPU/Directx9/helper/global.cpp index d814cb321..351e90efc 100644 --- a/GPU/Directx9/helper/global.cpp +++ b/GPU/Directx9/helper/global.cpp @@ -11,6 +11,17 @@ LPDIRECT3DDEVICE9 pD3Ddevice = NULL; LPDIRECT3DDEVICE9EX pD3DdeviceEx = NULL; LPDIRECT3D9 pD3D = NULL; +void DXSetViewport(float x, float y, float w, float h, float minZ, float maxZ) { + D3DVIEWPORT9 vp; + vp.X = (DWORD)x; + vp.Y = (DWORD)y; + vp.Width = (DWORD)w; + vp.Height = (DWORD)h; + vp.MinZ = minZ; + vp.MaxZ = maxZ; + pD3Ddevice->SetViewport(&vp); +} + static const char * vscode = "struct VS_IN {\n" " float4 ObjPos : POSITION;\n" diff --git a/GPU/Directx9/helper/global.h b/GPU/Directx9/helper/global.h index 4eebbca15..ef6a8eb45 100644 --- a/GPU/Directx9/helper/global.h +++ b/GPU/Directx9/helper/global.h @@ -31,6 +31,8 @@ bool CompileVertexShader(const char *code, LPDIRECT3DVERTEXSHADER9 *pShader, ID3 void DestroyShaders(); void DirectxInit(HWND window); +void DXSetViewport(float x, float y, float w, float h, float minZ = 0.0f, float maxZ = 1.0f); + #define D3DBLEND_UNK D3DBLEND_FORCE_DWORD };