mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
D3D: Eliminate black borders, add 4:3 and 16:9 settings, and the widescreen hack. Unfortunately this temporarily breaks MSAA (in d3d only) until I have time to fix it.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4263 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -33,17 +33,19 @@
|
||||
#include "PixelShaderManager.h"
|
||||
#include "VertexShaderCache.h"
|
||||
#include "PixelShaderCache.h"
|
||||
#include "VertexLoaderManager.h"
|
||||
#include "TextureCache.h"
|
||||
#include "Utils.h"
|
||||
#include "EmuWindow.h"
|
||||
#include "AVIDump.h"
|
||||
#include "OnScreenDisplay.h"
|
||||
#include "FramebufferManager.h"
|
||||
#include "Fifo.h"
|
||||
|
||||
#include "debugger/debugger.h"
|
||||
|
||||
static int s_targetWidth;
|
||||
static int s_targetHeight;
|
||||
static int s_target_width;
|
||||
static int s_target_height;
|
||||
|
||||
static int s_backbuffer_width;
|
||||
static int s_backbuffer_height;
|
||||
@ -60,23 +62,46 @@ static bool s_AVIDumping;
|
||||
#define NUMWNDRES 6
|
||||
extern int g_Res[NUMWNDRES][2];
|
||||
|
||||
void SetupDeviceObjects()
|
||||
{
|
||||
D3D::font.Init();
|
||||
VertexLoaderManager::Init();
|
||||
FBManager::Create();
|
||||
}
|
||||
|
||||
// Kill off all POOL_DEFAULT device objects.
|
||||
void TeardownDeviceObjects()
|
||||
{
|
||||
FBManager::Destroy();
|
||||
D3D::font.Shutdown();
|
||||
TextureCache::Invalidate(false);
|
||||
VertexManager::DestroyDeviceObjects();
|
||||
VertexLoaderManager::Shutdown();
|
||||
VertexShaderCache::Clear();
|
||||
PixelShaderCache::Clear();
|
||||
|
||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
|
||||
}
|
||||
|
||||
bool Renderer::Init()
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
EmuWindow::SetSize(g_Res[g_ActiveConfig.iWindowedRes][0], g_Res[g_ActiveConfig.iWindowedRes][1]);
|
||||
|
||||
int backbuffer_ms_mode = g_ActiveConfig.iMultisampleMode;
|
||||
int backbuffer_ms_mode = 0; // g_ActiveConfig.iMultisampleMode;
|
||||
D3D::Create(g_ActiveConfig.iAdapter, EmuWindow::GetWnd(), g_ActiveConfig.bFullscreen,
|
||||
g_ActiveConfig.iFSResolution, backbuffer_ms_mode);
|
||||
|
||||
s_targetWidth = D3D::GetDisplayWidth();
|
||||
s_targetHeight = D3D::GetDisplayHeight();
|
||||
s_backbuffer_width = D3D::GetBackBufferWidth();
|
||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||
|
||||
s_backbuffer_width = s_targetWidth;
|
||||
s_backbuffer_height = s_targetHeight;
|
||||
// TODO: Grab target width from configured resolution?
|
||||
s_target_width = s_backbuffer_width * EFB_WIDTH / 640;
|
||||
s_target_height = s_backbuffer_height * EFB_HEIGHT / 480;
|
||||
|
||||
xScale = (float)s_targetWidth / (float)EFB_WIDTH;
|
||||
yScale = (float)s_targetHeight / (float)EFB_HEIGHT;
|
||||
xScale = (float)s_target_width / (float)EFB_WIDTH;
|
||||
yScale = (float)s_target_height / (float)EFB_HEIGHT;
|
||||
|
||||
s_LastFrameDumped = false;
|
||||
s_AVIDumping = false;
|
||||
@ -87,18 +112,26 @@ bool Renderer::Init()
|
||||
D3DXMatrixIdentity(&mtx);
|
||||
D3D::dev->SetTransform(D3DTS_VIEW, &mtx);
|
||||
D3D::dev->SetTransform(D3DTS_WORLD, &mtx);
|
||||
D3D::font.Init();
|
||||
|
||||
SetupDeviceObjects();
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
D3D::dev->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 16);
|
||||
|
||||
D3D::BeginFrame(true, 0, 1.0f);
|
||||
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
|
||||
|
||||
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
|
||||
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
|
||||
|
||||
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0x0, 1.0f, 0);
|
||||
|
||||
D3D::BeginFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::Shutdown()
|
||||
{
|
||||
D3D::font.Shutdown();
|
||||
TeardownDeviceObjects();
|
||||
D3D::EndFrame();
|
||||
D3D::Close();
|
||||
|
||||
@ -108,14 +141,10 @@ void Renderer::Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
float Renderer::GetTargetScaleX()
|
||||
{
|
||||
return xScale;
|
||||
}
|
||||
float Renderer::GetTargetScaleY()
|
||||
{
|
||||
return yScale;
|
||||
}
|
||||
int Renderer::GetTargetWidth() { return s_target_width; }
|
||||
int Renderer::GetTargetHeight() { return s_target_height; }
|
||||
float Renderer::GetTargetScaleX() { return xScale; }
|
||||
float Renderer::GetTargetScaleY() { return yScale; }
|
||||
|
||||
void Renderer::RenderText(const char *text, int left, int top, u32 color)
|
||||
{
|
||||
@ -135,10 +164,10 @@ void dumpMatrix(D3DXMATRIX &mtx)
|
||||
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||
{
|
||||
TargetRectangle result;
|
||||
result.left = (rc.left * s_targetWidth) / EFB_WIDTH;
|
||||
result.top = (rc.top * s_targetHeight) / EFB_HEIGHT;
|
||||
result.right = (rc.right * s_targetWidth) / EFB_WIDTH;
|
||||
result.bottom = (rc.bottom * s_targetHeight) / EFB_HEIGHT;
|
||||
result.left = (rc.left * s_target_width) / EFB_WIDTH;
|
||||
result.top = (rc.top * s_target_height) / EFB_HEIGHT;
|
||||
result.right = (rc.right * s_target_width) / EFB_WIDTH;
|
||||
result.bottom = (rc.bottom * s_target_height) / EFB_HEIGHT;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -156,14 +185,14 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::SwapBuffers()
|
||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
|
||||
{
|
||||
if (g_bSkipCurrentFrame)
|
||||
return;
|
||||
|
||||
// Center window again.
|
||||
if (EmuWindow::GetParentWnd())
|
||||
{
|
||||
// Re-stretch window to parent window size again, if it has a parent window.
|
||||
RECT rcWindow;
|
||||
GetWindowRect(EmuWindow::GetParentWnd(), &rcWindow);
|
||||
|
||||
@ -173,7 +202,7 @@ void Renderer::SwapBuffers()
|
||||
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||
}
|
||||
|
||||
// Frame dumping routine
|
||||
// Frame dumping routine - seems buggy and wrong, esp. regarding buffer sizes
|
||||
if (g_ActiveConfig.bDumpFrames) {
|
||||
D3DDISPLAYMODE DisplayMode;
|
||||
if (SUCCEEDED(D3D::dev->GetDisplayMode(0, &DisplayMode))) {
|
||||
@ -214,7 +243,7 @@ void Renderer::SwapBuffers()
|
||||
}
|
||||
else
|
||||
{
|
||||
if(s_LastFrameDumped && s_AVIDumping) {
|
||||
if (s_LastFrameDumped && s_AVIDumping) {
|
||||
AVIDump::Stop();
|
||||
s_AVIDumping = false;
|
||||
}
|
||||
@ -222,6 +251,18 @@ void Renderer::SwapBuffers()
|
||||
s_LastFrameDumped = false;
|
||||
}
|
||||
|
||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||
D3D::dev->SetDepthStencilSurface(NULL);
|
||||
|
||||
// Blit our render target onto the backbuffer.
|
||||
// TODO: Change to a quad so we can do post processing.
|
||||
TargetRectangle src_rect, dst_rect;
|
||||
src_rect = ConvertEFBRectangle(sourceRc);
|
||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||
D3D::dev->StretchRect(FBManager::GetEFBColorRTSurface(), src_rect.AsRECT(),
|
||||
D3D::GetBackBufferSurface(), dst_rect.AsRECT(),
|
||||
D3DTEXF_LINEAR);
|
||||
|
||||
char st[8192];
|
||||
// Finish up the current frame, print some stats
|
||||
if (g_ActiveConfig.bOverlayStats)
|
||||
@ -237,20 +278,6 @@ void Renderer::SwapBuffers()
|
||||
}
|
||||
|
||||
OSD::DrawMessages();
|
||||
|
||||
#if defined(DVPROFILE)
|
||||
if (g_bWriteProfile) {
|
||||
//g_bWriteProfile = 0;
|
||||
static int framenum = 0;
|
||||
const int UPDATE_FRAMES = 8;
|
||||
if (++framenum >= UPDATE_FRAMES) {
|
||||
DVProfWrite("prof.txt", UPDATE_FRAMES);
|
||||
DVProfClear();
|
||||
framenum = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
D3D::EndFrame();
|
||||
|
||||
DEBUGGER_PAUSE_COUNT_N_WITHOUT_UPDATE(NEXT_FRAME);
|
||||
@ -265,53 +292,57 @@ void Renderer::SwapBuffers()
|
||||
// Make any new configuration settings active.
|
||||
UpdateActiveConfig();
|
||||
|
||||
/*
|
||||
TODO: Resize backbuffer if window size has changed. This code crashes, debug it.
|
||||
// TODO: Resize backbuffer if window size has changed. This code crashes, debug it.
|
||||
|
||||
while (EmuWindow::IsSizing())
|
||||
{
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
RECT rcWindow;
|
||||
GetClientRect(EmuWindow::GetWnd(), &rcWindow);
|
||||
if (rcWindow.right - rcWindow.left != s_backbuffer_width ||
|
||||
rcWindow.bottom - rcWindow.top != s_backbuffer_height)
|
||||
{
|
||||
D3D::Reset();
|
||||
s_backbuffer_width = D3D::GetDisplayWidth();
|
||||
s_backbuffer_height = D3D::GetDisplayHeight();
|
||||
}
|
||||
*/
|
||||
TeardownDeviceObjects();
|
||||
|
||||
//Begin new frame
|
||||
//Set default viewport and scissor, for the clear to work correctly
|
||||
D3D::Reset();
|
||||
|
||||
SetupDeviceObjects();
|
||||
s_backbuffer_width = D3D::GetBackBufferWidth();
|
||||
s_backbuffer_height = D3D::GetBackBufferHeight();
|
||||
}
|
||||
|
||||
g_VideoInitialize.pCopiedToXFB(false);
|
||||
|
||||
// Begin new frame
|
||||
// Set default viewport and scissor, for the clear to work correctly
|
||||
stats.ResetFrame();
|
||||
// u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
D3D::BeginFrame();
|
||||
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0);
|
||||
|
||||
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
|
||||
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
|
||||
|
||||
D3DVIEWPORT9 vp;
|
||||
vp.X = 0;
|
||||
vp.Y = 0;
|
||||
vp.Width = (DWORD)s_targetWidth;
|
||||
vp.Height = (DWORD)s_targetHeight;
|
||||
vp.Width = (DWORD)s_target_width;
|
||||
vp.Height = (DWORD)s_target_height;
|
||||
vp.MinZ = 0;
|
||||
vp.MaxZ = 1.0f;
|
||||
D3D::dev->SetViewport(&vp);
|
||||
|
||||
RECT rc;
|
||||
rc.left = 0;
|
||||
rc.top = 0;
|
||||
rc.right = (LONG)s_targetWidth;
|
||||
rc.bottom = (LONG)s_targetHeight;
|
||||
rc.right = (LONG)s_target_width;
|
||||
rc.bottom = (LONG)s_target_height;
|
||||
D3D::dev->SetScissorRect(&rc);
|
||||
D3D::dev->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
|
||||
|
||||
// We probably shouldn't clear here.
|
||||
// D3D::dev->Clear(0, 0, D3DCLEAR_TARGET, 0x00000000, 0, 0);
|
||||
|
||||
u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
D3D::BeginFrame(false, clearColor, 1.0f);
|
||||
|
||||
// This probably causes problems, and the visual difference is tiny anyway.
|
||||
// So let's keep it commented out.
|
||||
// D3D::EnableAlphaToCoverage();
|
||||
|
||||
UpdateViewport();
|
||||
|
||||
if (g_ActiveConfig.bOldCard)
|
||||
D3D::font.SetRenderStates(); //compatibility with low end cards
|
||||
}
|
||||
|
||||
bool Renderer::SetScissorRect()
|
||||
@ -328,6 +359,12 @@ bool Renderer::SetScissorRect()
|
||||
rc.top = (int)(rc.top * yScale);
|
||||
rc.right = (int)(rc.right * xScale);
|
||||
rc.bottom = (int)(rc.bottom * yScale);
|
||||
|
||||
if (rc.left < 0) rc.left = 0;
|
||||
if (rc.right > s_target_width) rc.right = s_target_width;
|
||||
if (rc.top < 0) rc.top = 0;
|
||||
if (rc.bottom > s_target_height) rc.bottom = s_target_height;
|
||||
|
||||
if (rc.right >= rc.left && rc.bottom >= rc.top)
|
||||
{
|
||||
D3D::dev->SetScissorRect(&rc);
|
||||
@ -422,14 +459,13 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||
// and perhaps blending.
|
||||
// WARN_LOG(VIDEOINTERFACE, "This is probably some kind of software rendering");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// mtx.m[0][3] = pMatrix[1]; // -0.5f/s_targetWidth; <-- fix d3d pixel center?
|
||||
// mtx.m[1][3] = pMatrix[3]; // +0.5f/s_targetHeight; <-- fix d3d pixel center?
|
||||
// mtx.m[0][3] = pMatrix[1]; // -0.5f/s_target_width; <-- fix d3d pixel center?
|
||||
// mtx.m[1][3] = pMatrix[3]; // +0.5f/s_target_height; <-- fix d3d pixel center?
|
||||
|
||||
// Called from VertexShaderManager
|
||||
void UpdateViewport()
|
||||
@ -452,5 +488,9 @@ void UpdateViewport()
|
||||
vp.MinZ = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777215.0f;
|
||||
vp.MaxZ = xfregs.rawViewport[5] / 16777215.0f;
|
||||
|
||||
// This seems to happen a lot - the above calc is probably wrong.
|
||||
if (vp.MinZ < 0.0f) vp.MinZ = 0.0f;
|
||||
if (vp.MaxZ > 1.0f) vp.MaxZ = 1.0f;
|
||||
|
||||
D3D::dev->SetViewport(&vp);
|
||||
}
|
||||
|
Reference in New Issue
Block a user