Minor code formatting:

First step to bring a level of consistency between the video plug-ins - variable names, spacing, function names, function order, comments, file names.  This will help us identify common code for VideoMerge.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6235 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
skidau 2010-09-28 02:15:02 +00:00
parent 73f4bc4598
commit 88cd9f3df1
50 changed files with 1713 additions and 1555 deletions

View File

@ -716,11 +716,11 @@
Name="Render" Name="Render"
> >
<File <File
RelativePath=".\Src\FBManager.cpp" RelativePath=".\Src\FramebufferManager.cpp"
> >
</File> </File>
<File <File
RelativePath=".\Src\FBManager.h" RelativePath=".\Src\FramebufferManager.h"
> >
</File> </File>
<File <File

View File

@ -16,16 +16,21 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "BPFunctions.h" #include "BPFunctions.h"
#include "D3DBase.h"
#include "VideoConfig.h"
#include "Common.h" #include "Common.h"
#include "D3DBase.h"
#include "Render.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "Render.h" #include "VideoConfig.h"
namespace BPFunctions namespace BPFunctions
{ {
// ----------------------------------------------
// State translation lookup tables
// Reference: Yet Another Gamecube Documentation
// ----------------------------------------------
void FlushPipeline() void FlushPipeline()
{ {
@ -72,21 +77,18 @@ void SetColorMask(const BPCmd &bp)
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const int &scaleByHalf) void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const int &scaleByHalf)
{ {
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
if (!g_ActiveConfig.bEFBCopyDisable) if (!g_ActiveConfig.bEFBCopyDisable)
{ {
// if (g_ActiveConfig.bCopyEFBToTexture) TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
// {
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
// }
// else
// {
// PanicAlert("TODO: Implement EFB copying to RAM %s %d\n", __FILE__, __LINE__);
// }
} }
} }
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc) void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
{ {
// it seems that the GC is able to alpha blend on color-fill
// we cant do that so if alpha is != 255 we skip it
bool colorEnable = bpmem.blendmode.colorupdate; bool colorEnable = bpmem.blendmode.colorupdate;
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate); bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
bool zEnable = bpmem.zmode.updateenable; bool zEnable = bpmem.zmode.updateenable;

View File

@ -30,7 +30,7 @@ namespace D3D
CD3DFont font; CD3DFont font;
#define MAX_NUM_VERTICES 300 #define MAX_NUM_VERTICES 50*6
struct FONT2DVERTEX { struct FONT2DVERTEX {
float x,y,z; float x,y,z;
float col[4]; float col[4];
@ -102,9 +102,10 @@ const char fontvertshader[] = {
int CD3DFont::Init() int CD3DFont::Init()
{ {
// Create vertex buffer for the letters
HRESULT hr; HRESULT hr;
// prepare to create a bitmap // Prepare to create a bitmap
unsigned int* pBitmapBits; unsigned int* pBitmapBits;
BITMAPINFO bmi; BITMAPINFO bmi;
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
@ -115,7 +116,7 @@ int CD3DFont::Init()
bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biBitCount = 32;
// create a DC and a bitmap for the font // Create a DC and a bitmap for the font
HDC hDC = CreateCompatibleDC(NULL); HDC hDC = CreateCompatibleDC(NULL);
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0); HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
SetMapMode(hDC, MM_TEXT); SetMapMode(hDC, MM_TEXT);
@ -130,7 +131,7 @@ int CD3DFont::Init()
HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap); HGDIOBJ hOldbmBitmap = SelectObject(hDC, hbmBitmap);
HGDIOBJ hOldFont = SelectObject(hDC, hFont); HGDIOBJ hOldFont = SelectObject(hDC, hFont);
// set text properties // Set text properties
SetTextColor(hDC, 0xFFFFFF); SetTextColor(hDC, 0xFFFFFF);
SetBkColor (hDC, 0); SetBkColor (hDC, 0);
SetTextAlign(hDC, TA_TOP); SetTextAlign(hDC, TA_TOP);
@ -139,8 +140,8 @@ int CD3DFont::Init()
GetTextMetricsW(hDC, &tm); GetTextMetricsW(hDC, &tm);
m_LineHeight = tm.tmHeight; m_LineHeight = tm.tmHeight;
// loop through all printable characters and output them to the bitmap // Loop through all printable characters and output them to the bitmap
// meanwhile, keep track of the corresponding tex coords for each character. // Meanwhile, keep track of the corresponding tex coords for each character.
int x = 0, y = 0; int x = 0, y = 0;
char str[2] = "\0"; char str[2] = "\0";
for (int c = 0; c < 127 - 32; c++) for (int c = 0; c < 127 - 32; c++)
@ -155,15 +156,15 @@ int CD3DFont::Init()
} }
ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL); ExtTextOutA(hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL);
m_fTexCoords[c][0] = (float) x /m_dwTexWidth; m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth;
m_fTexCoords[c][1] = (float) y /m_dwTexHeight; m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight;
m_fTexCoords[c][2] = (float)(x+size.cx)/m_dwTexWidth; m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
m_fTexCoords[c][3] = (float)(y+size.cy)/m_dwTexHeight; m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i) x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i)
} }
// create a new texture for the font // Create a new texture for the font
// possible optimization: store the converted data in a buffer and fill the texture on creation. // possible optimization: store the converted data in a buffer and fill the texture on creation.
// That way, we can use a static texture // That way, we can use a static texture
ID3D11Texture2D* buftex; ID3D11Texture2D* buftex;
@ -178,7 +179,7 @@ int CD3DFont::Init()
} }
D3D::SetDebugObjectName((ID3D11DeviceChild*)buftex, "texture of a CD3DFont object"); D3D::SetDebugObjectName((ID3D11DeviceChild*)buftex, "texture of a CD3DFont object");
// lock the surface and write the alpha values for the set pixels // Lock the surface and write the alpha values for the set pixels
D3D11_MAPPED_SUBRESOURCE texmap; D3D11_MAPPED_SUBRESOURCE texmap;
hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap); hr = context->Map(buftex, 0, D3D11_MAP_WRITE_DISCARD, 0, &texmap);
if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__); if (FAILED(hr)) PanicAlert("Failed to map a texture at %s %d\n", __FILE__, __LINE__);
@ -193,7 +194,7 @@ int CD3DFont::Init()
} }
} }
// clean up // Done updating texture, so clean up used objects
context->Unmap(buftex, 0); context->Unmap(buftex, 0);
hr = D3D::device->CreateShaderResourceView(buftex, NULL, &m_pTexture); hr = D3D::device->CreateShaderResourceView(buftex, NULL, &m_pTexture);
if (FAILED(hr)) PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__); if (FAILED(hr)) PanicAlert("Failed to create shader resource view at %s %d\n", __FILE__, __LINE__);
@ -274,7 +275,8 @@ int CD3DFont::Shutdown()
int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor, const char* strText, bool center) int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dwColor, const char* strText, bool center)
{ {
if (!m_pVB) return 0; if (!m_pVB)
return 0;
UINT stride = sizeof(FONT2DVERTEX); UINT stride = sizeof(FONT2DVERTEX);
UINT bufoffset = 0; UINT bufoffset = 0;
@ -288,7 +290,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
float sy = 1.f - y * scaley; float sy = 1.f - y * scaley;
char c; char c;
// fill vertex buffer // Fill vertex buffer
FONT2DVERTEX* pVertices; FONT2DVERTEX* pVertices;
int dwNumTriangles = 0L; int dwNumTriangles = 0L;
@ -336,7 +338,8 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
sx = fStartX; sx = fStartX;
sy -= scaley * size; sy -= scaley * size;
} }
if (c < (' ')) continue; if (c < (' '))
continue;
c -= 32; c -= 32;
float tx1 = m_fTexCoords[c][0]; float tx1 = m_fTexCoords[c][0];
@ -348,10 +351,10 @@ int CD3DFont::DrawTextScaled(float x, float y, float size, float spacing, u32 dw
float h = (float)(ty1-ty2) * m_dwTexHeight * scaley * sizeratio; float h = (float)(ty1-ty2) * m_dwTexHeight * scaley * sizeratio;
FONT2DVERTEX v[6]; FONT2DVERTEX v[6];
v[0] = InitFont2DVertex( sx, h+sy, dwColor, tx1, ty2); v[0] = InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2);
v[1] = InitFont2DVertex( sx, sy, dwColor, tx1, ty1); v[1] = InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
v[2] = InitFont2DVertex(w+sx, h+sy, dwColor, tx2, ty2); v[2] = InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2);
v[3] = InitFont2DVertex(w+sx, sy, dwColor, tx2, ty1); v[3] = InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1);
v[4] = v[2]; v[4] = v[2];
v[5] = v[1]; v[5] = v[1];

View File

@ -164,7 +164,7 @@ void OSDMenu(WPARAM wParam)
case '7': case '7':
OSDChoice = 5; OSDChoice = 5;
g_Config.bDisableLighting = !g_Config.bDisableLighting; g_Config.bDisableLighting = !g_Config.bDisableLighting;
break; break;
} }
} }

View File

@ -19,12 +19,12 @@
#include "D3DTexture.h" #include "D3DTexture.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "Render.h" #include "Render.h"
#include "FBManager.h" #include "FramebufferManager.h"
#include "VideoConfig.h" #include "VideoConfig.h"
#include "PixelShaderCache.h" #include "PixelShaderCache.h"
#include "VertexShaderCache.h" #include "VertexShaderCache.h"
FramebufferManager FBManager; FramebufferManager g_framebufferManager;
D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; } D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; }
ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; } ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; }
@ -120,19 +120,19 @@ FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtual
return it; return it;
} }
// that address is not in the Virtual XFB list. // That address is not in the Virtual XFB list.
return m_virtualXFBList.end(); return m_virtualXFBList.end();
} }
void FramebufferManager::replaceVirtualXFB() void FramebufferManager::replaceVirtualXFB()
{ {
VirtualXFBListType::iterator it = m_virtualXFBList.begin(); VirtualXFBListType::iterator it = m_virtualXFBList.begin();
s32 srcLower = it->xfbAddr; s32 srcLower = it->xfbAddr;
s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
s32 lineSize = 2 * it->xfbWidth; s32 lineSize = 2 * it->xfbWidth;
it++; ++it;
while (it != m_virtualXFBList.end()) while (it != m_virtualXFBList.end())
{ {
@ -141,13 +141,13 @@ void FramebufferManager::replaceVirtualXFB()
if (dstLower >= srcLower && dstUpper <= srcUpper) if (dstLower >= srcLower && dstUpper <= srcUpper)
{ {
// invalidate the data // Invalidate the data
it->xfbAddr = 0; it->xfbAddr = 0;
it->xfbHeight = 0; it->xfbHeight = 0;
it->xfbWidth = 0; it->xfbWidth = 0;
} }
else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
{ {
s32 upperOverlap = (srcUpper - dstLower) / lineSize; s32 upperOverlap = (srcUpper - dstLower) / lineSize;
s32 lowerOverlap = (dstUpper - srcLower) / lineSize; s32 lowerOverlap = (dstUpper - srcLower) / lineSize;
@ -162,7 +162,7 @@ void FramebufferManager::replaceVirtualXFB()
} }
} }
it++; ++it;
} }
} }
@ -195,15 +195,17 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
targetSource.right = (int)(sourceRc.right * scaleX); targetSource.right = (int)(sourceRc.right * scaleX);
unsigned int target_width = targetSource.right - targetSource.left; unsigned int target_width = targetSource.right - targetSource.left;
unsigned int target_height = targetSource.bottom - targetSource.top; unsigned int target_height = targetSource.bottom - targetSource.top;
if (it != m_virtualXFBList.end()) // overwrite an existing Virtual XFB if (it != m_virtualXFBList.end())
{ {
// Overwrite an existing Virtual XFB.
it->xfbAddr = xfbAddr; it->xfbAddr = xfbAddr;
it->xfbWidth = fbWidth; it->xfbWidth = fbWidth;
it->xfbHeight = fbHeight; it->xfbHeight = fbHeight;
it->xfbSource.srcAddr = xfbAddr; it->xfbSource.srcAddr = xfbAddr;
it->xfbSource.srcWidth = fbWidth; it->xfbSource.srcWidth = fbWidth;
it->xfbSource.srcHeight = fbHeight; it->xfbSource.srcHeight = fbHeight;
if (it->xfbSource.texWidth != target_width || it->xfbSource.texHeight != target_height || !(it->xfbSource.tex)) if (it->xfbSource.texWidth != target_width || it->xfbSource.texHeight != target_height || !(it->xfbSource.tex))
{ {
@ -222,8 +224,9 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
// keep stale XFB data from being used // keep stale XFB data from being used
replaceVirtualXFB(); replaceVirtualXFB();
} }
else // create a new Virtual XFB and place it at the front of the list else
{ {
// Create a new Virtual XFB and place it at the front of the list.
VirtualXFB newVirt; VirtualXFB newVirt;
newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM);
@ -253,7 +256,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
Renderer::ResetAPIState(); // reset any game specific settings Renderer::ResetAPIState(); // reset any game specific settings
// copy EFB data to XFB and restore render target again // Copy EFB data to XFB and restore render target again
D3D11_RECT sourcerect = CD3D11_RECT(efbSource.left, efbSource.top, efbSource.right, efbSource.bottom); D3D11_RECT sourcerect = CD3D11_RECT(efbSource.left, efbSource.top, efbSource.right, efbSource.bottom);
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)target_width, (float)target_height); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)target_width, (float)target_height);
D3D::context->RSSetViewports(1, &vp); D3D::context->RSSetViewports(1, &vp);
@ -277,8 +280,11 @@ const XFBSource** FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 fbWid
{ {
xfbCount = 0; xfbCount = 0;
if (m_virtualXFBList.size() == 0) // no Virtual XFBs available if (m_virtualXFBList.size() == 0)
{
// No Virtual XFBs available.
return NULL; return NULL;
}
u32 srcLower = xfbAddr; u32 srcLower = xfbAddr;
u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight; u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight;
@ -297,5 +303,6 @@ const XFBSource** FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 fbWid
xfbCount++; xfbCount++;
} }
} }
return &m_overlappingXFBArray[0]; return &m_overlappingXFBArray[0];
} }

View File

@ -130,8 +130,8 @@ private:
const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); const XFBSource** getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); const XFBSource** getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
XFBSource m_realXFBSource; // used in real XFB mode XFBSource m_realXFBSource; // Only used in Real XFB mode
VirtualXFBListType m_virtualXFBList; // used in virtual XFB mode VirtualXFBListType m_virtualXFBList; // Only used in Virtual XFB mode
const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB]; const XFBSource* m_overlappingXFBArray[MAX_VIRTUAL_XFB];
@ -146,6 +146,6 @@ private:
} m_efb; } m_efb;
}; };
extern FramebufferManager FBManager; extern FramebufferManager g_framebufferManager;
#endif #endif

View File

@ -23,7 +23,6 @@
#include "ABI.h" #include "ABI.h"
#include "MemoryUtil.h" #include "MemoryUtil.h"
#include "VertexShaderGen.h" #include "VertexShaderGen.h"
#include "VertexShaderCache.h"
#include "CPMemory.h" #include "CPMemory.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
@ -66,11 +65,11 @@ DXGI_FORMAT VarToD3D(VarType t, int size)
switch (size) switch (size)
{ {
case 1: retval = lookup1[t]; break; case 1: retval = lookup1[t]; break;
case 2: retval = lookup2[t]; break; case 2: retval = lookup2[t]; break;
case 3: retval = lookup3[t]; break; case 3: retval = lookup3[t]; break;
case 4: retval = lookup4[t]; break; case 4: retval = lookup4[t]; break;
default: break; default: break;
} }
if (retval == DXGI_FORMAT_UNKNOWN) if (retval == DXGI_FORMAT_UNKNOWN)
{ {

View File

@ -199,6 +199,9 @@ void PixelShaderCache::Init()
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
SETSTAT(stats.numPixelShadersCreated, 0);
SETSTAT(stats.numPixelShadersAlive, 0);
char cache_filename[MAX_PATH]; char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id); sprintf(cache_filename, "%sdx11-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
PixelShaderCacheInserter inserter; PixelShaderCacheInserter inserter;
@ -230,7 +233,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
PIXELSHADERUID uid; PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlpha); GetPixelShaderId(&uid, dstAlpha);
// check if the shader is already set // Check if the shader is already set
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount) if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
{ {
PSCache::const_iterator iter = PixelShaders.find(uid); PSCache::const_iterator iter = PixelShaders.find(uid);
@ -239,7 +242,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID)); memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
// check if the shader is already in the cache // Check if the shader is already in the cache
PSCache::iterator iter; PSCache::iterator iter;
iter = PixelShaders.find(uid); iter = PixelShaders.find(uid);
if (iter != PixelShaders.end()) if (iter != PixelShaders.end())
@ -252,7 +255,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
return (entry.shader != NULL); return (entry.shader != NULL);
} }
// need to compile a new shader // Need to compile a new shader
const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11,components); const char* code = GeneratePixelShaderCode(dstAlpha, API_D3D11,components);
D3DBlob* pbytecode; D3DBlob* pbytecode;
@ -262,7 +265,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
return false; return false;
} }
// insert the bytecode into the caches // Insert the bytecode into the caches
g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size()); g_ps_disk_cache.Append((u8*)&uid, sizeof(uid), (const u8*)pbytecode->Data(), pbytecode->Size());
g_ps_disk_cache.Sync(); g_ps_disk_cache.Sync();
@ -283,15 +286,19 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, void* bytecode,
// TODO: Somehow make the debug name a bit more specific // TODO: Somehow make the debug name a bit more specific
D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache"); D3D::SetDebugObjectName((ID3D11DeviceChild*)shader, "a pixel shader of PixelShaderCache");
// make an entry in the table // Make an entry in the table
PSCacheEntry newentry; PSCacheEntry newentry;
newentry.shader = shader; newentry.shader = shader;
newentry.frameCount = frameCount; newentry.frameCount = frameCount;
PixelShaders[uid] = newentry; PixelShaders[uid] = newentry;
last_entry = &PixelShaders[uid]; last_entry = &PixelShaders[uid];
if (!shader) {
// INCSTAT(stats.numPixelShadersFailed);
return false;
}
INCSTAT(stats.numPixelShadersCreated); INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, PixelShaders.size()); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
return true; return true;
} }

View File

@ -42,7 +42,7 @@
#include "EmuWindow.h" #include "EmuWindow.h"
#include "AVIDump.h" #include "AVIDump.h"
#include "OnScreenDisplay.h" #include "OnScreenDisplay.h"
#include "FBManager.h" #include "FramebufferManager.h"
#include "Fifo.h" #include "Fifo.h"
#include "DLCache.h" #include "DLCache.h"
@ -83,7 +83,7 @@ ID3D11RasterizerState* resetraststate = NULL;
bool reset_called = false; bool reset_called = false;
// state translation lookup tables // State translation lookup tables
static const D3D11_BLEND d3dSrcFactors[8] = static const D3D11_BLEND d3dSrcFactors[8] =
{ {
D3D11_BLEND_ZERO, D3D11_BLEND_ZERO,
@ -230,7 +230,7 @@ static const D3D11_TEXTURE_ADDRESS_MODE d3dClamps[4] =
void SetupDeviceObjects() void SetupDeviceObjects()
{ {
FBManager.Create(); g_framebufferManager.Create();
HRESULT hr; HRESULT hr;
float colmat[20]= {0.0f}; float colmat[20]= {0.0f};
@ -296,9 +296,10 @@ void SetupDeviceObjects()
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState"); D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState");
} }
// Kill off all POOL_DEFAULT device objects.
void TeardownDeviceObjects() void TeardownDeviceObjects()
{ {
FBManager.Destroy(); g_framebufferManager.Destroy();
SAFE_RELEASE(access_efb_cbuf); SAFE_RELEASE(access_efb_cbuf);
SAFE_RELEASE(cleardepthstates[0]); SAFE_RELEASE(cleardepthstates[0]);
SAFE_RELEASE(cleardepthstates[1]); SAFE_RELEASE(cleardepthstates[1]);
@ -342,14 +343,14 @@ bool Renderer::Init()
D3D::gfxstate->samplerdesc[stage].MaxAnisotropy = g_ActiveConfig.iMaxAnisotropy; D3D::gfxstate->samplerdesc[stage].MaxAnisotropy = g_ActiveConfig.iMaxAnisotropy;
float ClearColor[4] = { 0.f, 0.f, 0.f, 0.f }; float ClearColor[4] = { 0.f, 0.f, 0.f, 0.f };
D3D::context->ClearRenderTargetView(FBManager.GetEFBColorTexture()->GetRTV(), ClearColor); D3D::context->ClearRenderTargetView(g_framebufferManager.GetEFBColorTexture()->GetRTV(), ClearColor);
D3D::context->ClearDepthStencilView(FBManager.GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0); D3D::context->ClearDepthStencilView(g_framebufferManager.GetEFBDepthTexture()->GetDSV(), D3D11_CLEAR_DEPTH, 1.f, 0);
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)(s_Fulltarget_width - s_target_width) / 2.f, D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)(s_Fulltarget_width - s_target_width) / 2.f,
(float)(s_Fulltarget_height - s_target_height) / 2.f, (float)(s_Fulltarget_height - s_target_height) / 2.f,
(float)s_target_width, (float)s_target_height); (float)s_target_width, (float)s_target_height);
D3D::context->RSSetViewports(1, &vp); D3D::context->RSSetViewports(1, &vp);
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV()); D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
D3D::BeginFrame(); D3D::BeginFrame();
D3D::gfxstate->rastdesc.ScissorEnable = TRUE; D3D::gfxstate->rastdesc.ScissorEnable = TRUE;
@ -372,16 +373,18 @@ int Renderer::GetFullTargetHeight() { return s_Fulltarget_height; }
float Renderer::GetTargetScaleX() { return xScale; } float Renderer::GetTargetScaleX() { return xScale; }
float Renderer::GetTargetScaleY() { return yScale; } float Renderer::GetTargetScaleY() { return yScale; }
// Return the framebuffer size
int Renderer::GetFrameBufferWidth() int Renderer::GetFrameBufferWidth()
{ {
return s_backbuffer_width; return s_backbuffer_width;
} }
int Renderer::GetFrameBufferHeight() int Renderer::GetFrameBufferHeight()
{ {
return s_backbuffer_height; return s_backbuffer_height;
} }
// create On-Screen-Messages // Create On-Screen-Messages
void Renderer::DrawDebugText() void Renderer::DrawDebugText()
{ {
// OSD menu messages // OSD menu messages
@ -418,31 +421,35 @@ void Renderer::DrawDebugText()
g_ActiveConfig.bCrop ? " (crop)" : ""; g_ActiveConfig.bCrop ? " (crop)" : "";
std::string OSDM3 = "Disabled"; std::string OSDM3 = "Disabled";
// if there is more text than this we will have a collission // If there is more text than this we will have a collision
if (g_ActiveConfig.bShowFPS) if (g_ActiveConfig.bShowFPS)
{ T1 += "\n\n"; T2 += "\n\n"; } {
T1 += "\n\n";
T2 += "\n\n";
}
// The rows
T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str())); T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str()));
T0.push_back(StringFromFormat("4: Aspect Ratio: %s%s\n", OSDM21.c_str(), OSDM22.c_str())); T0.push_back(StringFromFormat("4: Aspect Ratio: %s%s\n", OSDM21.c_str(), OSDM22.c_str()));
T0.push_back(StringFromFormat("5: Copy EFB: %s\n", OSDM3.c_str())); T0.push_back(StringFromFormat("5: Copy EFB: %s\n", OSDM3.c_str()));
T0.push_back(StringFromFormat("6: Fog: %s\n", g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled")); T0.push_back(StringFromFormat("6: Fog: %s\n", g_ActiveConfig.bDisableFog ? "Disabled" : "Enabled"));
T0.push_back(StringFromFormat("7: Material Lighting: %s\n", g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled")); T0.push_back(StringFromFormat("7: Material Lighting: %s\n", g_ActiveConfig.bDisableLighting ? "Disabled" : "Enabled"));
// latest changed setting in yellow // The latest changed setting in yellow
T1 += (OSDChoice == -1) ? T0.at(0) : "\n"; T1 += (OSDChoice == -1) ? T0.at(0) : "\n";
T1 += (OSDChoice == -2) ? T0.at(1) : "\n"; T1 += (OSDChoice == -2) ? T0.at(1) : "\n";
T1 += (OSDChoice == -3) ? T0.at(2) : "\n"; T1 += (OSDChoice == -3) ? T0.at(2) : "\n";
T1 += (OSDChoice == -4) ? T0.at(3) : "\n"; T1 += (OSDChoice == -4) ? T0.at(3) : "\n";
T1 += (OSDChoice == -5) ? T0.at(4) : "\n"; T1 += (OSDChoice == -5) ? T0.at(4) : "\n";
// other settings in cyan // The other settings in cyan
T2 += (OSDChoice != -1) ? T0.at(0) : "\n"; T2 += (OSDChoice != -1) ? T0.at(0) : "\n";
T2 += (OSDChoice != -2) ? T0.at(1) : "\n"; T2 += (OSDChoice != -2) ? T0.at(1) : "\n";
T2 += (OSDChoice != -3) ? T0.at(2) : "\n"; T2 += (OSDChoice != -3) ? T0.at(2) : "\n";
T2 += (OSDChoice != -4) ? T0.at(3) : "\n"; T2 += (OSDChoice != -4) ? T0.at(3) : "\n";
T2 += (OSDChoice != -5) ? T0.at(4) : "\n"; T2 += (OSDChoice != -5) ? T0.at(4) : "\n";
// render a shadow, and then the text // Render a shadow, and then the text
Renderer::RenderText(T1.c_str(), 21, 21, 0xDD000000); Renderer::RenderText(T1.c_str(), 21, 21, 0xDD000000);
Renderer::RenderText(T1.c_str(), 20, 20, 0xFFffff00); Renderer::RenderText(T1.c_str(), 20, 20, 0xFFffff00);
Renderer::RenderText(T2.c_str(), 21, 21, 0xDD000000); Renderer::RenderText(T2.c_str(), 21, 21, 0xDD000000);
@ -451,7 +458,7 @@ void Renderer::DrawDebugText()
} }
} }
void Renderer::RenderText(const char* text, int left, int top, u32 color) void Renderer::RenderText(const char *text, int left, int top, u32 color)
{ {
D3D::font.DrawTextScaled((float)left, (float)top, 20.f, 0.0f, color, text, false); D3D::font.DrawTextScaled((float)left, (float)top, 20.f, 0.0f, color, text, false);
} }
@ -468,6 +475,9 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
return result; return result;
} }
// With D3D, we have to resize the backbuffer if the window changed
// size.
void CheckForResize() void CheckForResize()
{ {
while (EmuWindow::IsSizing()) while (EmuWindow::IsSizing())
@ -475,21 +485,22 @@ void CheckForResize()
if (EmuWindow::GetParentWnd()) if (EmuWindow::GetParentWnd())
{ {
// re-stretch window to parent window size again, if it has a parent window. // Re-stretch window to parent window size again, if it has a parent window.
RECT rcParentWindow; RECT rcParentWindow;
GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow); GetWindowRect(EmuWindow::GetParentWnd(), &rcParentWindow);
int width = rcParentWindow.right - rcParentWindow.left; int width = rcParentWindow.right - rcParentWindow.left;
int height = rcParentWindow.bottom - rcParentWindow.top; int height = rcParentWindow.bottom - rcParentWindow.top;
if (width != s_backbuffer_width || height != s_backbuffer_height) if (width != s_backbuffer_width || height != s_backbuffer_height)
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
} }
RECT rcWindow; RECT rcWindow;
GetClientRect(EmuWindow::GetWnd(), &rcWindow); GetClientRect(EmuWindow::GetWnd(), &rcWindow);
int client_width = rcWindow.right - rcWindow.left; int client_width = rcWindow.right - rcWindow.left;
int client_height = rcWindow.bottom - rcWindow.top; int client_height = rcWindow.bottom - rcWindow.top;
// sanity check // Sanity check
if ((client_width != s_backbuffer_width || client_height != s_backbuffer_height) && if ((client_width != s_backbuffer_width ||
client_height != s_backbuffer_height) &&
client_width >= 4 && client_height >= 4) client_width >= 4 && client_height >= 4)
{ {
WindowResized = true; WindowResized = true;
@ -507,7 +518,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
// just use progressive. // just use progressive.
if (g_ActiveConfig.bUseXFB) if (g_ActiveConfig.bUseXFB)
{ {
FBManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); g_framebufferManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
} }
else else
{ {
@ -559,7 +570,7 @@ bool Renderer::SetScissorRect()
rc.bottom = rc.top; rc.bottom = rc.top;
rc.top = temp; rc.top = temp;
} }
if (rc.right >= rc.left && rc.bottom >= rc.top) if (rc.right >= rc.left && rc.bottom >= rc.top)
{ {
D3D::context->RSSetScissorRects(1, &rc); D3D::context->RSSetScissorRects(1, &rc);
@ -599,7 +610,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
return 0; return 0;
} }
// get the rectangular target region covered by the EFB pixel // Get the rectangular target region covered by the EFB pixel
EFBRectangle efbPixelRc; EFBRectangle efbPixelRc;
efbPixelRc.left = x; efbPixelRc.left = x;
efbPixelRc.top = y; efbPixelRc.top = y;
@ -624,15 +635,15 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
if ((RectToLock.right - RectToLock.left) > 4) if ((RectToLock.right - RectToLock.left) > 4)
RectToLock.left++; RectToLock.left++;
ResetAPIState(); // reset any game specific settings ResetAPIState(); // Reset any game specific settings
// Stretch picture with increased internal resolution // Stretch picture with increased internal resolution
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 4.f, 4.f); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, 4.f, 4.f);
D3D::context->RSSetViewports(1, &vp); D3D::context->RSSetViewports(1, &vp);
D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf); D3D::context->PSSetConstantBuffers(0, 1, &access_efb_cbuf);
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBDepthReadTexture()->GetRTV(), NULL); D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBDepthReadTexture()->GetRTV(), NULL);
D3D::SetPointCopySampler(); D3D::SetPointCopySampler();
D3D::drawShadedTexQuad(FBManager.GetEFBDepthTexture()->GetSRV(), D3D::drawShadedTexQuad(g_framebufferManager.GetEFBDepthTexture()->GetSRV(),
&RectToLock, &RectToLock,
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetWidth(),
Renderer::GetFullTargetHeight(), Renderer::GetFullTargetHeight(),
@ -640,21 +651,21 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleVertexShader(),
VertexShaderCache::GetSimpleInputLayout()); VertexShaderCache::GetSimpleInputLayout());
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV()); D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
RestoreAPIState(); RestoreAPIState();
RectToLock = CD3D11_RECT(0, 0, 4, 4); RectToLock = CD3D11_RECT(0, 0, 4, 4);
// copy to system memory // copy to system memory
D3D11_BOX box = CD3D11_BOX(0, 0, 0, 4, 4, 1); D3D11_BOX box = CD3D11_BOX(0, 0, 0, 4, 4, 1);
read_tex = FBManager.GetEFBDepthStagingBuffer(); read_tex = g_framebufferManager.GetEFBDepthStagingBuffer();
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FBManager.GetEFBDepthReadTexture()->GetTex(), 0, &box); D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBDepthReadTexture()->GetTex(), 0, &box);
} }
else else
{ {
// we can directly copy to system memory here // we can directly copy to system memory here
read_tex = FBManager.GetEFBColorStagingBuffer(); read_tex = g_framebufferManager.GetEFBColorStagingBuffer();
D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1); D3D11_BOX box = CD3D11_BOX(RectToLock.left, RectToLock.top, 0, RectToLock.right, RectToLock.bottom, 1);
D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, FBManager.GetEFBColorTexture()->GetTex(), 0, &box); D3D::context->CopySubresourceRegion(read_tex, 0, 0, 0, 0, g_framebufferManager.GetEFBColorTexture()->GetTex(), 0, &box);
RectToLock = CD3D11_RECT(0, 0, 1, 1); RectToLock = CD3D11_RECT(0, 0, 1, 1);
} }
@ -662,21 +673,35 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
D3D11_MAPPED_SUBRESOURCE map; D3D11_MAPPED_SUBRESOURCE map;
D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map); D3D::context->Map(read_tex, 0, D3D11_MAP_READ, 0, &map);
switch(type) { switch(type)
case PEEK_Z: {
val = ((float*)map.pData)[0]; case PEEK_Z:
z = ((u32)(val * 0xffffff)); val = ((float*)map.pData)[0];
break; z = ((u32)(val * 0xffffff));
break;
case PEEK_COLOR: case POKE_Z:
z = ((u32*)map.pData)[0]; // TODO: Implement
break; break;
case PEEK_COLOR:
z = ((u32*)map.pData)[0];
break;
case POKE_COLOR:
// TODO: Implement. One way is to draw a tiny pixel-sized rectangle at
// the exact location. Note: EFB pokes are susceptible to Z-buffering
// and perhaps blending.
//WARN_LOG(VIDEOINTERFACE, "This is probably some kind of software rendering");
break;
// TODO: Implement POKE_Z and POKE_COLOR // TODO: Implement POKE_Z and POKE_COLOR
default: default:
break; break;
} }
D3D::context->Unmap(read_tex, 0); D3D::context->Unmap(read_tex, 0);
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
return z; return z;
} }
@ -728,7 +753,7 @@ void UpdateViewport()
{ {
s_Fulltarget_height -= 2 * Y; s_Fulltarget_height -= 2 * Y;
Y = 0; Y = 0;
sizeChanged=true; sizeChanged = true;
} }
float newx = (float)X; float newx = (float)X;
@ -755,29 +780,30 @@ void UpdateViewport()
else else
{ {
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
FBManager.Destroy(); g_framebufferManager.Destroy();
FBManager.Create(); g_framebufferManager.Create();
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV()); D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
} }
} }
// some games set invalids values MinDepth and MaxDepth so fix them to the max an min allowed and let the shaders do this work // 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
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(newx, newy, newwidth, newheight, D3D11_VIEWPORT vp = CD3D11_VIEWPORT(newx, newy, newwidth, newheight,
0.f, // (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f; 0.f, // (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
1.f); // xfregs.rawViewport[5] / 16777216.0f; 1.f); // xfregs.rawViewport[5] / 16777216.0f;
D3D::context->RSSetViewports(1, &vp); D3D::context->RSSetViewports(1, &vp);
} }
// Tino: color is passed in bgra mode so need to convert it to rgba // Tino: color is passed in bgra mode so need to convert it to rgba
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
{ {
// Update the view port for clearing the picture
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
// update the view port for clearing the picture
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(), D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(),
0.f, 0.f,
1.f); 1.f);
D3D::context->RSSetViewports(1, &vp); D3D::context->RSSetViewports(1, &vp);
// always set the scissor in case it was set by the game and has not been reset // Always set the scissor in case it was set by the game and has not been reset
D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom); D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom);
D3D::context->RSSetScissorRects(1, &sirc); D3D::context->RSSetScissorRects(1, &sirc);
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000); u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
@ -806,7 +832,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
D3D::gfxstate->SetSrcBlend(d3dSrcFactors[1]); D3D::gfxstate->SetSrcBlend(d3dSrcFactors[1]);
D3D::gfxstate->SetDestBlend(d3dDestFactors[1]); D3D::gfxstate->SetDestBlend(d3dDestFactors[1]);
} }
else else
{ {
D3D::gfxstate->SetAlphaBlendEnable(bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0))); D3D::gfxstate->SetAlphaBlendEnable(bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0)));
if (bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0))) if (bpmem.blendmode.blendenable && (!( bpmem.blendmode.srcfactor == 1 && bpmem.blendmode.dstfactor == 0)))
@ -815,10 +841,10 @@ void Renderer::SetBlendMode(bool forceUpdate)
D3D::gfxstate->SetSrcBlend(d3dSrcFactors[bpmem.blendmode.srcfactor]); D3D::gfxstate->SetSrcBlend(d3dSrcFactors[bpmem.blendmode.srcfactor]);
D3D::gfxstate->SetDestBlend(d3dDestFactors[bpmem.blendmode.dstfactor]); D3D::gfxstate->SetDestBlend(d3dDestFactors[bpmem.blendmode.dstfactor]);
} }
} }
} }
// 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) void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc)
{ {
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight) if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
@ -829,10 +855,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// this function is called after the XFB field is changed, not after // this function is called after the XFB field is changed, not after
// EFB is copied to XFB. In this way, flickering is reduced in games // EFB is copied to XFB. In this way, flickering is reduced in games
// and seems to also give more FPS in ZTP // and seems to also give more FPS in ZTP
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0; u32 xfbCount = 0;
const XFBSource** xfbSourceList = FBManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); const XFBSource** xfbSourceList = g_framebufferManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{ {
g_VideoInitialize.pCopiedToXFB(false); g_VideoInitialize.pCopiedToXFB(false);
@ -841,7 +867,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
Renderer::ResetAPIState(); Renderer::ResetAPIState();
// prepare copying the XFBs to our backbuffer // Prepare to copy the XFBs to our backbuffer
TargetRectangle dst_rect; TargetRectangle dst_rect;
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect); ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_backbuffer_width, (float)s_backbuffer_height); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)s_backbuffer_width, (float)s_backbuffer_height);
@ -876,13 +902,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// draw each xfb source // draw each xfb source
for (u32 i = 0; i < xfbCount; ++i) for (u32 i = 0; i < xfbCount; ++i)
{ {
xfbSource = xfbSourceList[i]; xfbSource = xfbSourceList[i];
MathUtil::Rectangle<float> sourceRc; MathUtil::Rectangle<float> sourceRc;
sourceRc.left = 0; sourceRc.left = 0;
sourceRc.top = 0; sourceRc.top = 0;
sourceRc.right = xfbSource->texWidth; sourceRc.right = xfbSource->texWidth;
sourceRc.bottom = xfbSource->texHeight; sourceRc.bottom = xfbSource->texHeight;
MathUtil::Rectangle<float> drawRc; MathUtil::Rectangle<float> drawRc;
@ -893,11 +919,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
int xfbWidth = xfbSource->srcWidth; int xfbWidth = xfbSource->srcWidth;
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
drawRc.bottom = 1.0f - 2.0f * ((hOffset) / (float)fbHeight); drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight);
drawRc.top = 1.0f - 2.0f * ((hOffset + xfbHeight) / (float)fbHeight); drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight);
drawRc.left = -(xfbWidth / (float)fbWidth); drawRc.left = -(xfbWidth / (float)fbWidth);
drawRc.right = (xfbWidth / (float)fbWidth); drawRc.right = (xfbWidth / (float)fbWidth);
if (!g_ActiveConfig.bAutoScale) if (!g_ActiveConfig.bAutoScale)
{ {
@ -918,13 +943,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
drawRc.left = -1; drawRc.left = -1;
drawRc.right = 1; drawRc.right = 1;
} }
D3D::drawShadedTexSubQuad(xfbSource->tex->GetSRV(), &sourceRc, xfbSource->texWidth, xfbSource->texHeight, &drawRc, PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); D3D::drawShadedTexSubQuad(xfbSource->tex->GetSRV(), &sourceRc, xfbSource->texWidth, xfbSource->texHeight, &drawRc, PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
} }
} }
else else
{ {
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
D3DTexture2D* read_texture = FBManager.GetEFBColorTexture(); D3DTexture2D* read_texture = g_framebufferManager.GetEFBColorTexture();
D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); D3D::drawShadedTexQuad(read_texture->GetSRV(), targetRc.AsRECT(), Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
} }
// done with drawing the game stuff, good moment to save a screenshot // done with drawing the game stuff, good moment to save a screenshot
@ -958,12 +984,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
s_bScreenshot = false; s_bScreenshot = false;
} }
// finally present some information // Finish up the current frame, print some stats
if (g_ActiveConfig.bShowFPS) if (g_ActiveConfig.bShowFPS)
{ {
char fps[20]; char fps[20];
StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps); StringCchPrintfA(fps, 20, "FPS: %d\n", s_fps);
D3D::font.DrawTextScaled(0,30,20,0.0f,0xFF00FFFF,fps,false); D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, fps, false);
} }
Renderer::DrawDebugText(); Renderer::DrawDebugText();
@ -971,13 +997,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
{ {
char buf[32768]; char buf[32768];
Statistics::ToString(buf); Statistics::ToString(buf);
D3D::font.DrawTextScaled(0,30,20,0.0f,0xFF00FFFF,buf,false); D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, buf, false);
} }
else if (g_ActiveConfig.bOverlayProjStats) else if (g_ActiveConfig.bOverlayProjStats)
{ {
char buf[32768]; char buf[32768];
Statistics::ToStringProj(buf); Statistics::ToStringProj(buf);
D3D::font.DrawTextScaled(0,30,20,0.0f,0xFF00FFFF,buf,false); D3D::font.DrawTextScaled(0, 30, 20, 0.0f, 0xFF00FFFF, buf, false);
} }
OSD::DrawMessages(); OSD::DrawMessages();
@ -986,13 +1012,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
DLCache::ProgressiveCleanup(); DLCache::ProgressiveCleanup();
TextureCache::Cleanup(); TextureCache::Cleanup();
// enable any configuration changes // Enable any configuration changes
UpdateActiveConfig(); UpdateActiveConfig();
WindowResized = false; WindowResized = false;
CheckForResize(); CheckForResize();
bool xfbchanged = false; bool xfbchanged = false;
if (s_XFB_width != fbWidth || s_XFB_height != fbHeight) if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
{ {
xfbchanged = true; xfbchanged = true;
@ -1007,18 +1033,21 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// update FPS counter // update FPS counter
static int fpscount = 0; static int fpscount = 0;
static unsigned long lasttime = 0; static unsigned long lasttime = 0;
if (Common::Timer::GetTimeMs() - lasttime >= 1000) if (Common::Timer::GetTimeMs() - lasttime >= 1000)
{ {
lasttime = Common::Timer::GetTimeMs(); lasttime = Common::Timer::GetTimeMs();
s_fps = fpscount; s_fps = fpscount;
fpscount = 0; fpscount = 0;
} }
if (XFBWrited) ++fpscount; if (XFBWrited)
++fpscount;
// set default viewport and scissor, for the clear to work correctly // Begin new frame
// Set default viewport and scissor, for the clear to work correctly
// New frame
stats.ResetFrame(); stats.ResetFrame();
// done. Show our work ;) // Flip/present backbuffer to frontbuffer here
D3D::Present(); D3D::Present();
// resize the back buffers NOW to avoid flickering when resizing windows // resize the back buffers NOW to avoid flickering when resizing windows
@ -1038,16 +1067,20 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
s_target_height = (int)(EFB_HEIGHT * yScale); s_target_height = (int)(EFB_HEIGHT * yScale);
D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL); D3D::context->OMSetRenderTargets(1, &D3D::GetBackBuffer()->GetRTV(), NULL);
FBManager.Destroy(); g_framebufferManager.Destroy();
FBManager.Create(); g_framebufferManager.Create();
} }
// begin next frame // begin next frame
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
D3D::BeginFrame(); D3D::BeginFrame();
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV()); D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
UpdateViewport(); UpdateViewport();
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();
// For testing zbuffer targets.
// Renderer::SetZBufferRender();
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
// GetTargetWidth(), GetTargetHeight());
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB); g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
XFBWrited = false; XFBWrited = false;
} }
@ -1065,7 +1098,7 @@ void Renderer::ResetAPIState()
void Renderer::RestoreAPIState() void Renderer::RestoreAPIState()
{ {
// gets us back into a more game-like state. // Gets us back into a more game-like state.
if (reset_called) if (reset_called)
{ {
D3D::stateman->PopBlendState(); D3D::stateman->PopBlendState();
@ -1094,6 +1127,7 @@ void Renderer::SetDepthMode()
} }
else else
{ {
// if the test is disabled write is disabled too
D3D::gfxstate->depthdesc.DepthEnable = FALSE; D3D::gfxstate->depthdesc.DepthEnable = FALSE;
D3D::gfxstate->depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; D3D::gfxstate->depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
} }
@ -1184,7 +1218,7 @@ void Renderer::SetInterlacingMode()
} }
// Save screenshot // Save screenshot
void Renderer::SetScreenshot(const char* filename) void Renderer::SetScreenshot(const char *filename)
{ {
s_criticalScreenshot.Enter(); s_criticalScreenshot.Enter();
strcpy_s(s_sScreenshotName, filename); strcpy_s(s_sScreenshotName, filename);

View File

@ -28,7 +28,7 @@
#include "D3DBase.h" #include "D3DBase.h"
#include "D3DTexture.h" #include "D3DTexture.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "FBManager.h" #include "FramebufferManager.h"
#include "PixelShaderCache.h" #include "PixelShaderCache.h"
#include "PixelShaderManager.h" #include "PixelShaderManager.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
@ -59,7 +59,7 @@ void TextureCache::TCacheEntry::Destroy(bool shutdown)
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache) if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache)
{ {
u32* ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr); u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
if (ptr && *ptr == hash) if (ptr && *ptr == hash)
*ptr = oldpixel; *ptr = oldpixel;
} }
@ -123,30 +123,6 @@ void TextureCache::Invalidate(bool shutdown)
HiresTextures::Shutdown(); HiresTextures::Shutdown();
} }
void TextureCache::InvalidateRange(u32 start_address, u32 size)
{
TexCache::iterator iter = textures.begin();
while (iter != textures.end())
{
if (iter->second.IntersectsMemoryRange(start_address, size))
{
iter->second.Destroy(false);
textures.erase(iter++);
}
else
{
++iter;
}
}
}
bool TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
{
if (addr + size_in_bytes < range_address) return false;
if (addr >= range_address + range_size) return false;
return true;
}
void TextureCache::Shutdown() void TextureCache::Shutdown()
{ {
Invalidate(true); Invalidate(true);
@ -178,6 +154,31 @@ void TextureCache::Cleanup()
} }
} }
void TextureCache::InvalidateRange(u32 start_address, u32 size)
{
TexCache::iterator iter = textures.begin();
while (iter != textures.end())
{
if (iter->second.IntersectsMemoryRange(start_address, size))
{
iter->second.Destroy(false);
textures.erase(iter++);
}
else
{
++iter;
}
}
}
bool TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
{
if (addr + size_in_bytes < range_address) return false;
if (addr >= range_address + range_size) return false;
return true;
}
// returns the exponent of the smallest power of two which is greater than val // returns the exponent of the smallest power of two which is greater than val
unsigned int GetPow2(unsigned int val) unsigned int GetPow2(unsigned int val)
{ {
@ -188,21 +189,47 @@ unsigned int GetPow2(unsigned int val)
TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, unsigned int width, unsigned int height, unsigned int tex_format, unsigned int tlutaddr, unsigned int tlutfmt, bool UseNativeMips, unsigned int maxlevel) TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, unsigned int width, unsigned int height, unsigned int tex_format, unsigned int tlutaddr, unsigned int tlutfmt, bool UseNativeMips, unsigned int maxlevel)
{ {
if (address == 0) return NULL; // notes (about "UNsafe texture cache"):
// Have to be removed soon.
// But we keep it until the "safe" way became rock solid
// pros: it has an unique ID held by the texture data itself (@address) once cached.
// cons: it writes this unique ID in the gc RAM <- very dangerous (break MP1) and ugly
u8* ptr = g_VideoInitialize.pGetMemoryPointer(address); // notes (about "safe texture cache"):
// Metroids text issue (character table):
// Same addr, same GX_TF_C4 texture data but different TLUT (hence different outputs).
// That's why we have to hash the TLUT too for TLUT tex_format dependent textures (ie. GX_TF_C4, GX_TF_C8, GX_TF_C14X2).
// And since the address and tex data don't change, the key index in the cacheEntry map can't be the address but
// have to be a real unique ID.
// DONE but not satifiying yet -> may break copyEFBToTexture sometimes.
// Pokemon Colosseum text issue (plain text):
// Use a GX_TF_I4 512x512 text-flush-texture at a const address.
// The problem here was just the sparse hash on the texture. This texture is partly overwrited (what is needed only)
// so lot's of remaning old text. Thin white chars on black bg too.
// TODO: - clean this up when ready to kill old "unsafe texture cache"
// - fix the key index situation with CopyRenderTargetToTexture.
// Could happen only for GX_TF_C4, GX_TF_C8 and GX_TF_C14X2 fmt.
// Wonder if we can't use tex width&height to know if EFB might be copied to it...
// raw idea: TOCHECK if addresses are aligned we have few bits left...
if (address == 0)
return NULL;
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
unsigned int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16; unsigned int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
unsigned int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16; unsigned int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format); unsigned int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
unsigned int expandedWidth = (width + bsw) & (~bsw); unsigned int expandedWidth = (width + bsw) & (~bsw);
unsigned int expandedHeight = (height + bsh) & (~bsh); unsigned int expandedHeight = (height + bsh) & (~bsh);
u64 hash_value; u64 hash_value = 0;
u32 texID = address; u32 texID = address;
u64 texHash; u64 texHash = 0;
u32 FullFormat = tex_format; u32 FullFormat = tex_format;
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
u32 FullFormat = (tex_format | (tlutfmt << 16)); FullFormat = (tex_format | (tlutfmt << 16));
// hires textures and texture dumping not supported, yet // hires textures and texture dumping not supported, yet
if (g_ActiveConfig.bSafeTextureCache/* || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures*/) if (g_ActiveConfig.bSafeTextureCache/* || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures*/)
@ -264,7 +291,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
} }
} }
// make an entry in the table // Make an entry in the table
TCacheEntry& entry = textures[texID]; TCacheEntry& entry = textures[texID];
PC_TexFormat pcfmt = PC_TEX_FMT_NONE; PC_TexFormat pcfmt = PC_TEX_FMT_NONE;
@ -306,6 +333,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
{ {
D3D::ReplaceRGBATexture2D(entry.texture->GetTex(), temp, width, height, expandedWidth, 0, usage); D3D::ReplaceRGBATexture2D(entry.texture->GetTex(), temp, width, height, expandedWidth, 0, usage);
} }
entry.addr = address; entry.addr = address;
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format); entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format);
entry.isRenderTarget = false; entry.isRenderTarget = false;
@ -340,7 +368,7 @@ TextureCache::TCacheEntry* TextureCache::Load(unsigned int stage, u32 address, u
entry.fmt = FullFormat; entry.fmt = FullFormat;
INCSTAT(stats.numTexturesCreated); INCSTAT(stats.numTexturesCreated);
SETSTAT(stats.numTexturesAlive, (int)textures.size()); SETSTAT(stats.numTexturesAlive, textures.size());
D3D::gfxstate->SetShaderResource(stage, entry.texture->GetSRV()); D3D::gfxstate->SetShaderResource(stage, entry.texture->GetSRV());
@ -370,7 +398,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
} }
else else
{ {
// remove it and recreate it as a render target // Remove it and recreate it as a render target
SAFE_RELEASE(iter->second.texture); SAFE_RELEASE(iter->second.texture);
textures.erase(iter); textures.erase(iter);
} }
@ -557,13 +585,13 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
D3D::stateman->PushDepthState(efbcopydepthstate); D3D::stateman->PushDepthState(efbcopydepthstate);
D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL); D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL);
D3D::drawShadedTexQuad( D3D::drawShadedTexQuad(
(bFromZBuffer) ? FBManager.GetEFBDepthTexture()->GetSRV() : FBManager.GetEFBColorTexture()->GetSRV(), (bFromZBuffer) ? g_framebufferManager.GetEFBDepthTexture()->GetSRV() : g_framebufferManager.GetEFBColorTexture()->GetSRV(),
&sourcerect, &sourcerect,
Renderer::GetFullTargetWidth(), Renderer::GetFullTargetWidth(),
Renderer::GetFullTargetHeight(), Renderer::GetFullTargetHeight(),
(bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); (bFromZBuffer) ? PixelShaderCache::GetDepthMatrixProgram() : PixelShaderCache::GetColorMatrixProgram(), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout());
D3D::context->OMSetRenderTargets(1, &FBManager.GetEFBColorTexture()->GetRTV(), FBManager.GetEFBDepthTexture()->GetDSV()); D3D::context->OMSetRenderTargets(1, &g_framebufferManager.GetEFBColorTexture()->GetRTV(), g_framebufferManager.GetEFBDepthTexture()->GetDSV());
D3D::stateman->PopBlendState(); D3D::stateman->PopBlendState();
D3D::stateman->PopDepthState(); D3D::stateman->PopDepthState();
D3D::stateman->PopRasterizerState(); D3D::stateman->PopRasterizerState();

View File

@ -24,7 +24,7 @@
#include "Fifo.h" #include "Fifo.h"
#include "Statistics.h" #include "Statistics.h"
#include "Profiler.h" #include "Profiler.h"
#include "FBManager.h" #include "FramebufferManager.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "IndexGenerator.h" #include "IndexGenerator.h"
@ -47,11 +47,18 @@ using std::string;
using namespace D3D; using namespace D3D;
extern NativeVertexFormat* g_nativeVertexFmt; // internal state for loading vertices
extern NativeVertexFormat *g_nativeVertexFmt;
namespace VertexManager namespace VertexManager
{ {
static int lastPrimitive;
static u8 *LocalVBuffer;
static u16 *TIBuffer;
static u16 *LIBuffer;
static u16 *PIBuffer;
#define MAXVBUFFERSIZE 0x50000 #define MAXVBUFFERSIZE 0x50000
#define MAXIBUFFERSIZE 0x10000 #define MAXIBUFFERSIZE 0x10000
@ -59,12 +66,6 @@ namespace VertexManager
#define NUM_VERTEXBUFFERS 8 #define NUM_VERTEXBUFFERS 8
#define NUM_INDEXBUFFERS 10 #define NUM_INDEXBUFFERS 10
int lastPrimitive;
u8* LocalVBuffer = NULL;
u16* TIBuffer = NULL;
u16* LIBuffer = NULL;
u16* PIBuffer = NULL;
bool Flushed=false; bool Flushed=false;
ID3D11Buffer* indexbuffers[NUM_INDEXBUFFERS] = {NULL}; ID3D11Buffer* indexbuffers[NUM_INDEXBUFFERS] = {NULL};
@ -147,17 +148,17 @@ void Shutdown()
ResetBuffer(); ResetBuffer();
} }
void AddIndices(int _primitive, int _numVertices) void AddIndices(int primitive, int numVertices)
{ {
switch (_primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: IndexGenerator::AddQuads(_numVertices); break; case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(_numVertices); break; case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(_numVertices); break; case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(_numVertices); break; case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(_numVertices); break; case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
case GX_DRAW_LINES: IndexGenerator::AddLineList(_numVertices); break; case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
case GX_DRAW_POINTS: IndexGenerator::AddPoints(_numVertices); break; case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
} }
} }
@ -170,53 +171,54 @@ int GetRemainingVertices(int primitive)
{ {
switch (primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: case GX_DRAW_QUADS:
case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLES:
case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_STRIP:
case GX_DRAW_TRIANGLE_FAN: case GX_DRAW_TRIANGLE_FAN:
return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen())/3; return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen())/3;
case GX_DRAW_LINE_STRIP: case GX_DRAW_LINE_STRIP:
case GX_DRAW_LINES: case GX_DRAW_LINES:
return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen())/2; return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen())/2;
case GX_DRAW_POINTS: case GX_DRAW_POINTS:
return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen()); return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen());
default: return 0; default: return 0;
} }
} }
void AddVertices(int _primitive, int _numVertices) void AddVertices(int primitive, int numVertices)
{ {
if (_numVertices <= 0) return; if (numVertices <= 0)
return;
switch (_primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: case GX_DRAW_QUADS:
case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLES:
case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_STRIP:
case GX_DRAW_TRIANGLE_FAN: case GX_DRAW_TRIANGLE_FAN:
if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * _numVertices) if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
Flush(); Flush();
break; break;
case GX_DRAW_LINE_STRIP: case GX_DRAW_LINE_STRIP:
case GX_DRAW_LINES: case GX_DRAW_LINES:
if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * _numVertices) if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * numVertices)
Flush(); Flush();
break; break;
case GX_DRAW_POINTS: case GX_DRAW_POINTS:
if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < _numVertices) if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < numVertices)
Flush(); Flush();
break; break;
default: return; default: return;
} }
if (Flushed) if (Flushed)
{ {
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer); IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
Flushed=false; Flushed=false;
} }
lastPrimitive = _primitive; lastPrimitive = primitive;
ADDSTAT(stats.thisFrame.numPrims, _numVertices); ADDSTAT(stats.thisFrame.numPrims, numVertices);
INCSTAT(stats.thisFrame.numPrimitiveJoins); INCSTAT(stats.thisFrame.numPrimitiveJoins);
AddIndices(_primitive, _numVertices); AddIndices(primitive, numVertices);
} }
inline void Draw(u32 stride, bool alphapass) inline void Draw(u32 stride, bool alphapass)
@ -303,10 +305,8 @@ void Flush()
u32 usedtextures = 0; u32 usedtextures = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
{ if (bpmem.tevorders[i / 2].getEnable(i & 1))
if (bpmem.tevorders[i/2].getEnable(i & 1))
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
}
if (bpmem.genMode.numindstages > 0) if (bpmem.genMode.numindstages > 0)
for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i) for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
@ -320,24 +320,24 @@ void Flush()
Renderer::SetSamplerState(i & 3, i >> 2); Renderer::SetSamplerState(i & 3, i >> 2);
FourTexUnits &tex = bpmem.tex[i >> 2]; FourTexUnits &tex = bpmem.tex[i >> 2];
TextureCache::TCacheEntry* tentry = TextureCache::Load(i, TextureCache::TCacheEntry* tentry = TextureCache::Load(i,
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, 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.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format, tex.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips, (tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
(tex.texMode1[i&3].max_lod >> 4)); (tex.texMode1[i&3].max_lod >> 4));
if (tentry) if (tentry)
{ {
// 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0); PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
} }
else else
{
ERROR_LOG(VIDEO, "error loading texture"); ERROR_LOG(VIDEO, "error loading texture");
}
} }
} }
// set global constants
VertexShaderManager::SetConstants(); VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants(); PixelShaderManager::SetConstants();
@ -365,5 +365,4 @@ void Flush()
shader_fail: shader_fail:
ResetBuffer(); ResetBuffer();
} }
} // namespace } // namespace

View File

@ -33,7 +33,7 @@
#include "XFMemory.h" #include "XFMemory.h"
VertexShaderCache::VSCache VertexShaderCache::vshaders; VertexShaderCache::VSCache VertexShaderCache::vshaders;
const VertexShaderCache::VSCacheEntry* VertexShaderCache::last_entry; const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
static ID3D11VertexShader* SimpleVertexShader = NULL; static ID3D11VertexShader* SimpleVertexShader = NULL;
static ID3D11VertexShader* ClearVertexShader = NULL; static ID3D11VertexShader* ClearVertexShader = NULL;
@ -83,7 +83,7 @@ void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const
// this class will load the precompiled shaders into our cache // this class will load the precompiled shaders into our cache
class VertexShaderCacheInserter : public LinearDiskCacheReader { class VertexShaderCacheInserter : public LinearDiskCacheReader {
public: public:
void Read(const u8* key, int key_size, const u8* value, int value_size) void Read(const u8 *key, int key_size, const u8 *value, int value_size)
{ {
VERTEXSHADERUID uid; VERTEXSHADERUID uid;
if (key_size != sizeof(uid)) if (key_size != sizeof(uid))
@ -177,6 +177,9 @@ void VertexShaderCache::Init()
if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX))) if (!File::Exists(File::GetUserPath(D_SHADERCACHE_IDX)))
File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX)); File::CreateDir(File::GetUserPath(D_SHADERCACHE_IDX));
SETSTAT(stats.numVertexShadersCreated, 0);
SETSTAT(stats.numVertexShadersAlive, 0);
char cache_filename[MAX_PATH]; char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id); sprintf(cache_filename, "%sdx11-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
VertexShaderCacheInserter inserter; VertexShaderCacheInserter inserter;
@ -214,8 +217,7 @@ bool VertexShaderCache::SetShader(u32 components)
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID)); memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
VSCache::iterator iter; VSCache::iterator iter = vshaders.find(uid);
iter = vshaders.find(uid);
if (iter != vshaders.end()) if (iter != vshaders.end())
{ {
iter->second.frameCount = frameCount; iter->second.frameCount = frameCount;
@ -226,7 +228,7 @@ bool VertexShaderCache::SetShader(u32 components)
return (entry.shader != NULL); return (entry.shader != NULL);
} }
const char* code = GenerateVertexShaderCode(components, API_D3D11); const char *code = GenerateVertexShaderCode(components, API_D3D11);
D3DBlob* pbytecode = NULL; D3DBlob* pbytecode = NULL;
D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode); D3D::CompileVertexShader(code, (int)strlen(code), &pbytecode);

View File

@ -52,19 +52,9 @@
#include "D3DUtil.h" #include "D3DUtil.h"
#include "W32Util/Misc.h" #include "W32Util/Misc.h"
#include "EmuWindow.h" #include "EmuWindow.h"
#include "FBManager.h" #include "FramebufferManager.h"
#include "DLCache.h" #include "DLCache.h"
#if defined(DEBUGFAST)
#define DLL_PLUGIN_NAME "Dolphin Direct3D 11 (DebugFast)"
#elif defined(_DEBUG)
#define DLL_PLUGIN_NAME "Dolphin Direct3D 11 (Debug)"
#else
#define DLL_PLUGIN_NAME "Dolphin Direct3D 11"
#endif
HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL;
SVideoInitialize g_VideoInitialize; SVideoInitialize g_VideoInitialize;
PLUGIN_GLOBALS* globals = NULL; PLUGIN_GLOBALS* globals = NULL;
@ -148,7 +138,7 @@ unsigned int Callback_PeekMessages()
} }
void UpdateFPSDisplay(const char* text) void UpdateFPSDisplay(const char *text)
{ {
char temp[512]; char temp[512];
sprintf_s(temp, 512, "SVN R%s: DX11: %s", svn_rev_str, text); sprintf_s(temp, 512, "SVN R%s: DX11: %s", svn_rev_str, text);
@ -159,7 +149,13 @@ void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{ {
_PluginInfo->Version = 0x0100; _PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_VIDEO; _PluginInfo->Type = PLUGIN_TYPE_VIDEO;
sprintf_s(_PluginInfo->Name, 100, DLL_PLUGIN_NAME); #ifdef DEBUGFAST
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11 (DebugFast)");
#elif defined _DEBUG
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11 (Debug)");
#else
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D11");
#endif
} }
void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals) void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
@ -170,7 +166,7 @@ void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
void DllAbout(HWND _hParent) void DllAbout(HWND _hParent)
{ {
MessageBoxA(NULL, "DllAbout not implemented, how did you come here? Anyway, report this to the devs.", "Error!", MB_OK); //DialogBox(g_hInstance,(LPCTSTR)IDD_ABOUT,_hParent,(DLGPROC)AboutProc);
} }
void DllConfig(void *_hParent) void DllConfig(void *_hParent)
@ -178,11 +174,12 @@ void DllConfig(void *_hParent)
DlgSettings_Show(g_hInstance, (HWND)((wxWindow *)_hParent)->GetHandle()); DlgSettings_Show(g_hInstance, (HWND)((wxWindow *)_hParent)->GetHandle());
} }
void Initialize(void* init) void Initialize(void *init)
{ {
frameCount = 0; frameCount = 0;
SVideoInitialize* _pVideoInitialize = (SVideoInitialize*)init; SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
g_VideoInitialize = *_pVideoInitialize; // Create a shortcut to _pVideoInitialize that can also update it
g_VideoInitialize = *(_pVideoInitialize);
InitXFBConvTables(); InitXFBConvTables();
g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str()); g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx11.ini").c_str());
@ -201,14 +198,17 @@ void Initialize(void* init)
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages; _pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay; _pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
// Now the window handle is written
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle; _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
OSD::AddMessage("Dolphin Direct3D 11 Video Plugin.", 5000); OSD::AddMessage("Dolphin Direct3D11 Video Plugin.", 5000);
s_PluginInitialized = true; s_PluginInitialized = true;
} }
void Video_Prepare() void Video_Prepare()
{ {
// Better be safe...
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
@ -232,24 +232,26 @@ void Video_Prepare()
PixelEngine::Init(); PixelEngine::Init();
DLCache::Init(); DLCache::Init();
// tell the host that the window is ready // Tell the host that the window is ready
g_VideoInitialize.pCoreMessage(WM_USER_CREATE); g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
} }
void Shutdown() void Shutdown()
{ {
s_PluginInitialized = false;
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
// VideoCommon // VideoCommon
DLCache::Shutdown(); DLCache::Shutdown();
Fifo_Shutdown();
CommandProcessor::Shutdown(); CommandProcessor::Shutdown();
PixelShaderManager::Shutdown(); PixelShaderManager::Shutdown();
VertexShaderManager::Shutdown(); VertexShaderManager::Shutdown();
OpcodeDecoder_Shutdown(); OpcodeDecoder_Shutdown();
VertexLoaderManager::Shutdown(); VertexLoaderManager::Shutdown();
Fifo_Shutdown();
// internal interfaces // internal interfaces
D3D::ShutdownUtils(); D3D::ShutdownUtils();
@ -263,13 +265,13 @@ void Shutdown()
s_PluginInitialized = false; s_PluginInitialized = false;
} }
void DoState(unsigned char** ptr, int mode) void DoState(unsigned char **ptr, int mode)
{ {
// clear texture cache because it might have written to RAM // Clear texture cache because it might have written to RAM
CommandProcessor::FifoCriticalEnter(); CommandProcessor::FifoCriticalEnter();
TextureCache::Invalidate(false); TextureCache::Invalidate(false);
CommandProcessor::FifoCriticalLeave(); CommandProcessor::FifoCriticalLeave();
// no need to clear shader caches // No need to clear shader caches
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
VideoCommon_DoState(p); VideoCommon_DoState(p);
} }
@ -279,6 +281,7 @@ void EmuStateChange(PLUGIN_EMUSTATE newState)
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
} }
// Enter and exit the video loop
void Video_EnterLoop() void Video_EnterLoop()
{ {
Fifo_EnterLoop(g_VideoInitialize); Fifo_EnterLoop(g_VideoInitialize);
@ -349,6 +352,7 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
} }
} }
// Run from the CPU thread (from VideoInterface.cpp)
void Video_EndField() void Video_EndField()
{ {
} }
@ -358,7 +362,8 @@ void Video_AddMessage(const char* pstr, u32 milliseconds)
OSD::AddMessage(pstr, milliseconds); OSD::AddMessage(pstr, milliseconds);
} }
void Video_Screenshot(const char* _szFilename) // Screenshot
void Video_Screenshot(const char *_szFilename)
{ {
Renderer::SetScreenshot(_szFilename); Renderer::SetScreenshot(_szFilename);
} }
@ -391,6 +396,7 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
s_accessEFBArgs.x = x; s_accessEFBArgs.x = x;
s_accessEFBArgs.y = y; s_accessEFBArgs.y = y;
s_accessEFBArgs.Data = InputData; s_accessEFBArgs.Data = InputData;
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE); Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
if (g_VideoInitialize.bOnThread) if (g_VideoInitialize.bOnThread)
@ -404,6 +410,7 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
return s_AccessEFBResult; return s_AccessEFBResult;
} }
return 0; return 0;
} }

View File

@ -16,24 +16,26 @@
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "BPFunctions.h" #include "BPFunctions.h"
#include "D3DBase.h"
#include "VideoConfig.h"
#include "Common.h" #include "Common.h"
#include "D3DBase.h"
#include "Debugger/Debugger.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "Debugger/Debugger.h" #include "VideoConfig.h"
#include "TextureConverter.h"
bool textureChanged[8]; bool textureChanged[8];
const bool renderFog = false; const bool renderFog = false;
using namespace D3D; using namespace D3D;
namespace BPFunctions namespace BPFunctions
{ {
// ----------------------------------------------
// State translation lookup tables
// Reference: Yet Another Gamecube Documentation
// ----------------------------------------------
void FlushPipeline() void FlushPipeline()
{ {
@ -80,9 +82,10 @@ void SetColorMask(const BPCmd &bp)
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const int &scaleByHalf) void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const int &scaleByHalf)
{ {
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
if (!g_ActiveConfig.bEFBCopyDisable) if (!g_ActiveConfig.bEFBCopyDisable)
{ {
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc); TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
} }
} }

View File

@ -24,22 +24,24 @@
namespace D3D namespace D3D
{ {
// Bytecode->shader. // bytecode->shader.
LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len) LPDIRECT3DVERTEXSHADER9 CreateVertexShaderFromByteCode(const u8 *bytecode, int len)
{ {
LPDIRECT3DVERTEXSHADER9 v_shader; LPDIRECT3DVERTEXSHADER9 v_shader;
HRESULT hr = D3D::dev->CreateVertexShader((DWORD *)bytecode, &v_shader); HRESULT hr = D3D::dev->CreateVertexShader((DWORD *)bytecode, &v_shader);
if (FAILED(hr)) if (FAILED(hr))
v_shader = 0; {
PanicAlert("CreateVertexShaderFromByteCode failed from %p (size %d) at %s %d\n", bytecode, len, __FILE__, __LINE__);
v_shader = NULL;
}
return v_shader; return v_shader;
} }
// Code->bytecode. // code->bytecode.
bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen) bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
{ {
//try to compile LPD3DXBUFFER shaderBuffer = NULL;
LPD3DXBUFFER shaderBuffer = 0; LPD3DXBUFFER errorBuffer = NULL;
LPD3DXBUFFER errorBuffer = 0;
HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::VertexShaderVersionString(), HRESULT hr = PD3DXCompileShader(code, len, 0, 0, "main", D3D::VertexShaderVersionString(),
0, &shaderBuffer, &errorBuffer, 0); 0, &shaderBuffer, &errorBuffer, 0);
if (FAILED(hr)) if (FAILED(hr))
@ -69,18 +71,20 @@ bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecode
return SUCCEEDED(hr) ? true : false; return SUCCEEDED(hr) ? true : false;
} }
// bytecode->shader
// Bytecode->shader.
LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len) LPDIRECT3DPIXELSHADER9 CreatePixelShaderFromByteCode(const u8 *bytecode, int len)
{ {
LPDIRECT3DPIXELSHADER9 p_shader; LPDIRECT3DPIXELSHADER9 p_shader;
HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)bytecode, &p_shader); HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)bytecode, &p_shader);
if (FAILED(hr)) if (FAILED(hr))
p_shader = 0; {
PanicAlert("CreatePixelShaderFromByteCode failed at %s %d\n", __FILE__, __LINE__);
p_shader = NULL;
}
return p_shader; return p_shader;
} }
// code->bytecode
bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen) bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodelen)
{ {
LPD3DXBUFFER shaderBuffer = 0; LPD3DXBUFFER shaderBuffer = 0;
@ -118,28 +122,32 @@ bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodel
return SUCCEEDED(hr) ? true : false; return SUCCEEDED(hr) ? true : false;
} }
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len) { LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len)
{
u8 *bytecode; u8 *bytecode;
int bytecodelen; int bytecodelen;
if (CompileVertexShader(code, len, &bytecode, &bytecodelen)) { if (CompileVertexShader(code, len, &bytecode, &bytecodelen))
{
LPDIRECT3DVERTEXSHADER9 v_shader = CreateVertexShaderFromByteCode(bytecode, len); LPDIRECT3DVERTEXSHADER9 v_shader = CreateVertexShaderFromByteCode(bytecode, len);
delete [] bytecode; delete [] bytecode;
return v_shader; return v_shader;
} else {
return 0;
} }
PanicAlert("Failed to compile and create vertex shader from %p (size %d) at %s %d\n", code, len, __FILE__, __LINE__);
return NULL;
} }
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len) { LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char* code, unsigned int len)
{
u8 *bytecode; u8 *bytecode;
int bytecodelen; int bytecodelen;
if (CompilePixelShader(code, len, &bytecode, &bytecodelen)) { if (CompilePixelShader(code, len, &bytecode, &bytecodelen))
{
LPDIRECT3DPIXELSHADER9 p_shader = CreatePixelShaderFromByteCode(bytecode, len); LPDIRECT3DPIXELSHADER9 p_shader = CreatePixelShaderFromByteCode(bytecode, len);
delete [] bytecode; delete [] bytecode;
return p_shader; return p_shader;
} else {
return 0;
} }
PanicAlert("Failed to compile and create pixel shader, %s %d\n", __FILE__, __LINE__);
return NULL;
} }
} // namespace } // namespace

View File

@ -30,5 +30,5 @@ namespace D3D
// Utility functions // Utility functions
LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len); LPDIRECT3DVERTEXSHADER9 CompileAndCreateVertexShader(const char *code, int len);
LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, int len); LPDIRECT3DPIXELSHADER9 CompileAndCreatePixelShader(const char *code, unsigned int len);
} }

View File

@ -63,9 +63,9 @@ int CD3DFont::Init()
m_fTextScale = 1.0f; // Draw fonts into texture without scaling m_fTextScale = 1.0f; // Draw fonts into texture without scaling
// Prepare to create a bitmap // Prepare to create a bitmap
int *pBitmapBits; unsigned int* pBitmapBits;
BITMAPINFO bmi; BITMAPINFO bmi;
ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER)); ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = (int)m_dwTexWidth; bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight; bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
@ -74,8 +74,8 @@ int CD3DFont::Init()
bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biBitCount = 32;
// Create a DC and a bitmap for the font // Create a DC and a bitmap for the font
HDC hDC = CreateCompatibleDC(NULL); HDC hDC = CreateCompatibleDC(NULL);
HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (VOID**)&pBitmapBits, NULL, 0); HBITMAP hbmBitmap = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
SetMapMode(hDC, MM_TEXT); SetMapMode(hDC, MM_TEXT);
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an // Create a font. By specifying ANTIALIASED_QUALITY, we might get an
@ -99,7 +99,7 @@ int CD3DFont::Init()
SetBkColor (hDC, 0); SetBkColor (hDC, 0);
SetTextAlign(hDC, TA_TOP); SetTextAlign(hDC, TA_TOP);
// Loop through all printable character and output them to the bitmap.. // Loop through all printable characters and output them to the bitmap
// Meanwhile, keep track of the corresponding tex coords for each character. // Meanwhile, keep track of the corresponding tex coords for each character.
int x = 0, y = 0; int x = 0, y = 0;
char str[2] = "\0"; char str[2] = "\0";
@ -120,10 +120,12 @@ int CD3DFont::Init()
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth; m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight; m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
x += size.cx + 3; //3 to work around annoying ij conflict (part of the j ends up with the i) x += size.cx + 3; // 3 to work around annoying ij conflict (part of the j ends up with the i)
} }
// Create a new texture for the font // Create a new texture for the font
// possible optimization: store the converted data in a buffer and fill the texture on creation.
// That way, we can use a static texture
hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC, hr = dev->CreateTexture(m_dwTexWidth, m_dwTexHeight, 1, D3DUSAGE_DYNAMIC,
D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL); D3DFMT_A4R4G4B4, D3DPOOL_DEFAULT, &m_pTexture, NULL);
if (FAILED(hr)) if (FAILED(hr))
@ -245,7 +247,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo
float invLineHeight = 1.0f / ((m_fTexCoords[0][3] - m_fTexCoords[0][1]) * m_dwTexHeight); float invLineHeight = 1.0f / ((m_fTexCoords[0][3] - m_fTexCoords[0][1]) * m_dwTexHeight);
// Fill vertex buffer // Fill vertex buffer
FONT2DVERTEX* pVertices; FONT2DVERTEX* pVertices;
int dwNumTriangles = 0L; int dwNumTriangles = 0L;
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD); m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
const char *oldstrText=strText; const char *oldstrText=strText;
@ -296,7 +298,7 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo
if (c < (' ')) if (c < (' '))
continue; continue;
c-=32; c -= 32;
float tx1 = m_fTexCoords[c][0]; float tx1 = m_fTexCoords[c][0];
float ty1 = m_fTexCoords[c][1]; float ty1 = m_fTexCoords[c][1];
float tx2 = m_fTexCoords[c][2]; float tx2 = m_fTexCoords[c][2];
@ -329,7 +331,6 @@ int CD3DFont::DrawTextScaled(float x, float y, float fXScale, float fYScale, flo
m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD); m_pVB->Lock(0, 0, (void**)&pVertices, D3DLOCK_DISCARD);
dwNumTriangles = 0; dwNumTriangles = 0;
} }
sx += w + spacing*fXScale*vpWidth; sx += w + spacing*fXScale*vpWidth;
} }

View File

@ -349,15 +349,15 @@ static void DX9DebuggerUpdateScreen()
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(NULL); D3D::dev->SetDepthStencilSurface(NULL);
D3D::dev->StretchRect(FBManager.GetEFBColorRTSurface(), NULL, D3D::dev->StretchRect(g_framebufferManager.GetEFBColorRTSurface(), NULL,
D3D::GetBackBufferSurface(), NULL, D3D::GetBackBufferSurface(), NULL,
D3DTEXF_LINEAR); D3DTEXF_LINEAR);
D3D::dev->EndScene(); D3D::dev->EndScene();
D3D::dev->Present(NULL, NULL, NULL, NULL); D3D::dev->Present(NULL, NULL, NULL, NULL);
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
D3D::dev->BeginScene(); D3D::dev->BeginScene();
} }
else else

View File

@ -145,14 +145,6 @@ void OSDMenu(WPARAM wParam)
case '3': case '3':
OSDChoice = 1; OSDChoice = 1;
// Toggle native resolution // Toggle native resolution
/*
if (!(g_Config.bNativeResolution || g_Config.b2xResolution))
g_Config.bNativeResolution = true;
else if (g_Config.bNativeResolution && Renderer::AllowCustom())
{ g_Config.bNativeResolution = false; if (Renderer::Allow2x()) {g_Config.b2xResolution = true;} }
else if (Renderer::AllowCustom())
g_Config.b2xResolution = false;
*/
OSDInternalW = D3D::GetBackBufferWidth(); OSDInternalW = D3D::GetBackBufferWidth();
OSDInternalH = D3D::GetBackBufferHeight(); OSDInternalH = D3D::GetBackBufferHeight();
break; break;
@ -224,6 +216,7 @@ HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title)
// TODO: // TODO:
// 1. Remove redundant window manipulation, // 1. Remove redundant window manipulation,
// 2. Make DX9 in fullscreen can be overlapped by other dialogs // 2. Make DX9 in fullscreen can be overlapped by other dialogs
// 3. Request window sizes which actually make the client area map to a common resolution
HWND Ret; HWND Ret;
int x=0, y=0, width=640, height=480; int x=0, y=0, width=640, height=480;
g_VideoInitialize.pRequestWindowSize(x, y, width, height); g_VideoInitialize.pRequestWindowSize(x, y, width, height);

View File

@ -26,7 +26,7 @@
#undef CHECK #undef CHECK
#define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); } #define CHECK(hr, Message, ...) if (FAILED(hr)) { PanicAlert(__FUNCTION__ "Failed in %s at line %d: " Message, __FILE__, __LINE__, __VA_ARGS__); }
FramebufferManager FBManager; FramebufferManager g_framebufferManager;
LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorRTSurface() LPDIRECT3DSURFACE9 FramebufferManager::GetEFBColorRTSurface()
{ {
@ -313,7 +313,6 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
LPDIRECT3DTEXTURE9 xfbTexture; LPDIRECT3DTEXTURE9 xfbTexture;
HRESULT hr = 0; HRESULT hr = 0;
VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight); VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight);
if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
@ -393,8 +392,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
m_virtualXFBList.push_front(newVirt); m_virtualXFBList.push_front(newVirt);
} }
// Copy EFB to XFB texture // Copy EFB data to XFB and restore render target again
if(!xfbTexture) if(!xfbTexture)
return; return;
LPDIRECT3DTEXTURE9 read_texture = GetEFBColorTexture(sourceRc); LPDIRECT3DTEXTURE9 read_texture = GetEFBColorTexture(sourceRc);

View File

@ -107,7 +107,6 @@ public:
void Destroy(); void Destroy();
void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc); void CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc);
const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount); const XFBSource** GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount);
LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc); LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc);
@ -168,6 +167,6 @@ private:
D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
}; };
extern FramebufferManager FBManager; extern FramebufferManager g_framebufferManager;
#endif #endif

View File

@ -28,4 +28,4 @@
// A global plugin specification // A global plugin specification
extern PLUGIN_GLOBALS* globals; extern PLUGIN_GLOBALS* globals;
#endif // _GLOBALS_H_ #endif // _GLOBALS_H_

View File

@ -27,7 +27,6 @@
#include "CPMemory.h" #include "CPMemory.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
class D3DVertexFormat : public NativeVertexFormat class D3DVertexFormat : public NativeVertexFormat
{ {
LPDIRECT3DVERTEXDECLARATION9 d3d_decl; LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
@ -76,12 +75,13 @@ D3DDECLTYPE VarToD3D(VarType t, int size)
D3DDECLTYPE_UNUSED, D3DDECLTYPE_UBYTE4N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT4, D3DDECLTYPE_UNUSED, D3DDECLTYPE_UBYTE4N, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT4,
}; };
D3DDECLTYPE retval = D3DDECLTYPE_UNUSED; D3DDECLTYPE retval = D3DDECLTYPE_UNUSED;
switch (size) { switch (size)
{
case 1: retval = lookup1[t]; break; case 1: retval = lookup1[t]; break;
case 2: retval = lookup2[t]; break; case 2: retval = lookup2[t]; break;
case 3: retval = lookup3[t]; break; case 3: retval = lookup3[t]; break;
case 4: retval = lookup4[t]; break; case 4: retval = lookup4[t]; break;
default: PanicAlert("VarToD3D: size wrong (%i)", size); break; default: break;
} }
if (retval == D3DDECLTYPE_UNUSED) { if (retval == D3DDECLTYPE_UNUSED) {
PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size); PanicAlert("VarToD3D: Invalid type/size combo %i , %i", (int)t, size);

View File

@ -239,14 +239,13 @@ void PixelShaderCache::Init()
char cache_filename[MAX_PATH]; char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id); sprintf(cache_filename, "%sdx9-%s-ps.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
PixelShaderCacheInserter inserter; PixelShaderCacheInserter inserter;
int read_items = g_ps_disk_cache.OpenAndRead(cache_filename, &inserter); g_ps_disk_cache.OpenAndRead(cache_filename, &inserter);
} }
// ONLY to be used during shutdown. // ONLY to be used during shutdown.
void PixelShaderCache::Clear() void PixelShaderCache::Clear()
{ {
PSCache::iterator iter = PixelShaders.begin(); for (PSCache::iterator iter = PixelShaders.begin(); iter != PixelShaders.end(); iter++)
for (; iter != PixelShaders.end(); ++iter)
iter->second.Destroy(); iter->second.Destroy();
PixelShaders.clear(); PixelShaders.clear();
@ -279,19 +278,16 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
PIXELSHADERUID uid; PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlpha); GetPixelShaderId(&uid, dstAlpha);
// Is the shader already set? // Check if the shader is already set
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount) if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
{ {
PSCache::const_iterator iter = PixelShaders.find(uid); PSCache::const_iterator iter = PixelShaders.find(uid);
if (iter != PixelShaders.end() && iter->second.shader) return (iter != PixelShaders.end() && iter->second.shader);
return true; // Sure, we're done.
else
return false; // ?? something is wrong.
} }
memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID)); memcpy(&last_pixel_shader_uid, &uid, sizeof(PIXELSHADERUID));
// Is the shader already in the cache? // Check if the shader is already in the cache
PSCache::iterator iter; PSCache::iterator iter;
iter = PixelShaders.find(uid); iter = PixelShaders.find(uid);
if (iter != PixelShaders.end()) if (iter != PixelShaders.end())
@ -311,14 +307,14 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
return false; return false;
} }
// OK, need to generate and compile it. // Need to compile a new shader
const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9,components); const char *code = GeneratePixelShaderCode(dstAlpha, API_D3D9,components);
u32 code_hash = HashAdler32((const u8 *)code, strlen(code)); u32 code_hash = HashAdler32((const u8 *)code, strlen(code));
unique_shaders.insert(code_hash); unique_shaders.insert(code_hash);
SETSTAT(stats.numUniquePixelShaders, unique_shaders.size()); SETSTAT(stats.numUniquePixelShaders, unique_shaders.size());
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) { if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
static int counter = 0; static int counter = 0;
char szTemp[MAX_PATH]; char szTemp[MAX_PATH];
@ -326,7 +322,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
SaveData(szTemp, code); SaveData(szTemp, code);
} }
#endif #endif
u8 *bytecode = 0; u8 *bytecode = 0;
int bytecodelen = 0; int bytecodelen = 0;
@ -342,7 +338,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
return false; return false;
} }
// Here we have the UID and the byte code. Insert it into the disk cache. // Insert the bytecode into the caches
g_ps_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen); g_ps_disk_cache.Append((u8 *)&uid, sizeof(uid), bytecode, bytecodelen);
g_ps_disk_cache.Sync(); g_ps_disk_cache.Sync();
@ -352,7 +348,8 @@ bool PixelShaderCache::SetShader(bool dstAlpha,u32 components)
return result; return result;
} }
bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate) { 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 // Make an entry in the table
@ -368,7 +365,7 @@ bool PixelShaderCache::InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytec
} }
INCSTAT(stats.numPixelShadersCreated); INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, (int)PixelShaders.size()); SETSTAT(stats.numPixelShadersAlive, PixelShaders.size());
if (activate) if (activate)
{ {
D3D::SetPixelShader(shader); D3D::SetPixelShader(shader);

View File

@ -51,7 +51,7 @@
#include "debugger/debugger.h" #include "debugger/debugger.h"
int s_fps=0; static int s_fps = 0;
static bool WindowResized; static bool WindowResized;
static int s_target_width; static int s_target_width;
@ -75,14 +75,14 @@ static float EFByScale;
static int s_recordWidth; static int s_recordWidth;
static int s_recordHeight; static int s_recordHeight;
static bool s_LastFrameDumped; static bool s_bLastFrameDumped;
static bool s_AVIDumping; static bool s_bAVIDumping;
static u32 s_blendMode; static u32 s_blendMode;
static u32 s_LastAA; static u32 s_LastAA;
static u32 s_LastEFBScale; static u32 s_LastEFBScale;
static bool IS_AMD; static bool IS_AMD;
static bool XFBWrited; static bool XFBWrited = false;
// used extern by other files. need to clean this up at some point. // used extern by other files. need to clean this up at some point.
int frameCount; int frameCount;
@ -120,6 +120,24 @@ static const D3DBLEND d3dDestFactors[8] =
D3DBLEND_INVDESTALPHA D3DBLEND_INVDESTALPHA
}; };
// 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
static const D3DBLENDOP d3dLogicOpop[16] = static const D3DBLENDOP d3dLogicOpop[16] =
{ {
D3DBLENDOP_ADD, D3DBLENDOP_ADD,
@ -223,7 +241,7 @@ void SetupDeviceObjects()
{ {
D3D::font.Init(); D3D::font.Init();
VertexLoaderManager::Init(); VertexLoaderManager::Init();
FBManager.Create(); g_framebufferManager.Create();
VertexShaderManager::Dirty(); VertexShaderManager::Dirty();
PixelShaderManager::Dirty(); PixelShaderManager::Dirty();
@ -243,7 +261,7 @@ void TeardownDeviceObjects()
ScreenShootMEMSurface = NULL; ScreenShootMEMSurface = NULL;
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
FBManager.Destroy(); g_framebufferManager.Destroy();
D3D::font.Shutdown(); D3D::font.Shutdown();
TextureCache::Invalidate(false); TextureCache::Invalidate(false);
VertexLoaderManager::Shutdown(); VertexLoaderManager::Shutdown();
@ -252,7 +270,8 @@ void TeardownDeviceObjects()
TextureConverter::Shutdown(); TextureConverter::Shutdown();
} }
bool Renderer::Init() // Init functions
bool Renderer::Init()
{ {
st = new char[32768]; st = new char[32768];
UpdateActiveConfig(); UpdateActiveConfig();
@ -276,6 +295,8 @@ bool Renderer::Init()
fullScreenRes, backbuffer_ms_mode, false); fullScreenRes, backbuffer_ms_mode, false);
IS_AMD = D3D::IsATIDevice(); IS_AMD = D3D::IsATIDevice();
// Decide frambuffer size
s_backbuffer_width = D3D::GetBackBufferWidth(); s_backbuffer_width = D3D::GetBackBufferWidth();
s_backbuffer_height = D3D::GetBackBufferHeight(); s_backbuffer_height = D3D::GetBackBufferHeight();
@ -323,8 +344,8 @@ bool Renderer::Init()
s_Fulltarget_width = s_target_width; s_Fulltarget_width = s_target_width;
s_Fulltarget_height = s_target_height; s_Fulltarget_height = s_target_height;
s_LastFrameDumped = false; s_bLastFrameDumped = false;
s_AVIDumping = false; s_bAVIDumping = false;
// We're not using fixed function. // We're not using fixed function.
// Let's just set the matrices to identity to be sure. // Let's just set the matrices to identity to be sure.
@ -348,8 +369,8 @@ bool Renderer::Init()
D3D::dev->SetViewport(&vp); D3D::dev->SetViewport(&vp);
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0); D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
vp.X = (s_Fulltarget_width - s_target_width) / 2; vp.X = (s_Fulltarget_width - s_target_width) / 2;
vp.Y = (s_Fulltarget_height - s_target_height) / 2; vp.Y = (s_Fulltarget_height - s_target_height) / 2;
vp.Width = s_target_width; vp.Width = s_target_width;
@ -369,28 +390,60 @@ void Renderer::Shutdown()
D3D::Present(); D3D::Present();
D3D::Close(); D3D::Close();
if (s_AVIDumping) if (s_bAVIDumping)
{ {
AVIDump::Stop(); AVIDump::Stop();
} }
delete [] st; delete [] st;
} }
int Renderer::GetTargetWidth() { return s_target_width; } // Return the rendering target width and height
int Renderer::GetTargetHeight() { return s_target_height; } int Renderer::GetTargetWidth()
int Renderer::GetFullTargetWidth() { return s_Fulltarget_width; } {
int Renderer::GetFullTargetHeight() { return s_Fulltarget_height; } return s_target_width;
float Renderer::GetTargetScaleX() { return EFBxScale; } }
float Renderer::GetTargetScaleY() { return EFByScale; }
float Renderer::GetXFBScaleX() { return xScale; } int Renderer::GetTargetHeight()
float Renderer::GetXFBScaleY() { return yScale; } {
return s_target_height;
}
int Renderer::GetFullTargetWidth()
{
return s_Fulltarget_width;
}
int Renderer::GetFullTargetHeight()
{
return s_Fulltarget_height;
}
float Renderer::GetTargetScaleX()
{
return EFBxScale;
}
float Renderer::GetTargetScaleY()
{
return EFByScale;
}
float Renderer::GetXFBScaleX()
{
return xScale;
}
float Renderer::GetXFBScaleY()
{
return yScale;
}
// Return the framebuffer size
int Renderer::GetFrameBufferWidth() int Renderer::GetFrameBufferWidth()
{ {
return s_backbuffer_width; return s_backbuffer_width;
} }
int Renderer::GetFrameBufferHeight() int Renderer::GetFrameBufferHeight()
{ {
return s_backbuffer_height; return s_backbuffer_height;
@ -399,7 +452,7 @@ int Renderer::GetFrameBufferHeight()
// Create On-Screen-Messages // Create On-Screen-Messages
void Renderer::DrawDebugText() void Renderer::DrawDebugText()
{ {
// OSD Menu messages // OSD menu messages
if (g_ActiveConfig.bOSDHotKey) if (g_ActiveConfig.bOSDHotKey)
{ {
if (OSDChoice > 0) if (OSDChoice > 0)
@ -434,9 +487,12 @@ void Renderer::DrawDebugText()
std::string OSDM3 = g_ActiveConfig.bEFBCopyDisable ? "Disabled" : std::string OSDM3 = g_ActiveConfig.bEFBCopyDisable ? "Disabled" :
g_ActiveConfig.bCopyEFBToTexture ? "To Texture" : "To RAM"; g_ActiveConfig.bCopyEFBToTexture ? "To Texture" : "To RAM";
// If there is more text than this we will have a collission // If there is more text than this we will have a collision
if (g_ActiveConfig.bShowFPS) if (g_ActiveConfig.bShowFPS)
{ T1 += "\n\n"; T2 += "\n\n"; } {
T1 += "\n\n";
T2 += "\n\n";
}
// The rows // The rows
T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str())); T0.push_back(StringFromFormat("3: Internal Resolution: %s\n", OSDM1.c_str()));
@ -504,10 +560,8 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p)
void CheckForResize() void CheckForResize()
{ {
while (EmuWindow::IsSizing()) while (EmuWindow::IsSizing())
{
Sleep(10); Sleep(10);
}
if (EmuWindow::GetParentWnd()) if (EmuWindow::GetParentWnd())
{ {
// Re-stretch window to parent window size again, if it has a parent window. // Re-stretch window to parent window size again, if it has a parent window.
@ -522,7 +576,8 @@ void CheckForResize()
GetClientRect(EmuWindow::GetWnd(), &rcWindow); GetClientRect(EmuWindow::GetWnd(), &rcWindow);
int client_width = rcWindow.right - rcWindow.left; int client_width = rcWindow.right - rcWindow.left;
int client_height = rcWindow.bottom - rcWindow.top; int client_height = rcWindow.bottom - rcWindow.top;
// Sanity check.
// Sanity check
if ((client_width != s_backbuffer_width || if ((client_width != s_backbuffer_width ||
client_height != s_backbuffer_height) && client_height != s_backbuffer_height) &&
client_width >= 4 && client_height >= 4) client_width >= 4 && client_height >= 4)
@ -539,20 +594,18 @@ void CheckForResize()
} }
} }
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
{ {
if (!fbWidth || !fbHeight) if (!fbWidth || !fbHeight)
return; return;
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight); VideoFifo_CheckSwapRequestAt(xfbAddr, fbWidth, fbHeight);
XFBWrited = true; XFBWrited = true;
// XXX: Without the VI, how would we know what kind of field this is? So // XXX: Without the VI, how would we know what kind of field this is? So
// just use progressive. // just use progressive.
if (g_ActiveConfig.bUseXFB) if (g_ActiveConfig.bUseXFB)
{ {
FBManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc); g_framebufferManager.CopyToXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
} }
else else
{ {
@ -618,7 +671,7 @@ bool Renderer::SetScissorRect()
return false; return false;
} }
void Renderer::SetColorMask() void Renderer::SetColorMask()
{ {
DWORD color_mask = 0; DWORD color_mask = 0;
if (bpmem.blendmode.alphaupdate) if (bpmem.blendmode.alphaupdate)
@ -644,18 +697,18 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
// Get the working buffer // Get the working buffer
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ? LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
FBManager.GetEFBDepthRTSurface() : FBManager.GetEFBColorRTSurface(); g_framebufferManager.GetEFBDepthRTSurface() : g_framebufferManager.GetEFBColorRTSurface();
// Get the temporal buffer to move 1pixel data // Get the temporal buffer to move 1pixel data
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ? LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
FBManager.GetEFBDepthReadSurface() : FBManager.GetEFBColorReadSurface(); g_framebufferManager.GetEFBDepthReadSurface() : g_framebufferManager.GetEFBColorReadSurface();
// Get the memory buffer that can be locked // Get the memory buffer that can be locked
LPDIRECT3DSURFACE9 pOffScreenBuffer = (type == PEEK_Z || type == POKE_Z) ? LPDIRECT3DSURFACE9 pOffScreenBuffer = (type == PEEK_Z || type == POKE_Z) ?
FBManager.GetEFBDepthOffScreenRTSurface() : FBManager.GetEFBColorOffScreenRTSurface(); g_framebufferManager.GetEFBDepthOffScreenRTSurface() : g_framebufferManager.GetEFBColorOffScreenRTSurface();
// Get the buffer format // Get the buffer format
D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ? D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ?
FBManager.GetEFBDepthRTSurfaceFormat() : FBManager.GetEFBColorRTSurfaceFormat(); g_framebufferManager.GetEFBDepthRTSurfaceFormat() : g_framebufferManager.GetEFBColorRTSurfaceFormat();
D3DFORMAT ReadBufferFormat = (type == PEEK_Z || type == POKE_Z) ? D3DFORMAT ReadBufferFormat = (type == PEEK_Z || type == POKE_Z) ?
FBManager.GetEFBDepthReadSurfaceFormat() : BufferFormat; g_framebufferManager.GetEFBDepthReadSurfaceFormat() : BufferFormat;
if (BufferFormat == D3DFMT_D24X8) if (BufferFormat == D3DFMT_D24X8)
return 0; return 0;
@ -667,8 +720,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB"); PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB");
return 0; return 0;
} }
// Get the rectangular target region covered by the EFB pixel. // Get the rectangular target region covered by the EFB pixel
EFBRectangle efbPixelRc; EFBRectangle efbPixelRc;
efbPixelRc.left = x; efbPixelRc.left = x;
efbPixelRc.top = y; efbPixelRc.top = y;
@ -700,6 +752,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
RectToLock.bottom--; RectToLock.bottom--;
if ((RectToLock.right - RectToLock.left) > 4) if ((RectToLock.right - RectToLock.left) > 4)
RectToLock.left++; RectToLock.left++;
ResetAPIState(); // Reset any game specific settings ResetAPIState(); // Reset any game specific settings
hr = D3D::dev->SetDepthStencilSurface(NULL); hr = D3D::dev->SetDepthStencilSurface(NULL);
hr = D3D::dev->SetRenderTarget(0, RBuffer); hr = D3D::dev->SetRenderTarget(0, RBuffer);
@ -727,7 +780,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
colmat[0] = colmat[5] = colmat[10] = 1.0f; colmat[0] = colmat[5] = colmat[10] = 1.0f;
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
EFBRectangle source_rect; EFBRectangle source_rect;
LPDIRECT3DTEXTURE9 read_texture = FBManager.GetEFBDepthTexture(source_rect); LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBDepthTexture(source_rect);
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
@ -742,8 +795,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
hr = D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); hr = D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
hr = D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); hr = D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
RestoreAPIState(); RestoreAPIState();
RectToLock.bottom = 4; RectToLock.bottom = 4;
RectToLock.left = 0; RectToLock.left = 0;
@ -771,8 +824,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
PanicAlert("Unable to copy data to mem buffer"); PanicAlert("Unable to copy data to mem buffer");
return 0; return 0;
} }
// The surface is good.. lock it // The surface is good.. lock it
if ((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK) if ((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
@ -780,37 +832,48 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
PanicAlert("ERROR: %s", hr == D3DERR_WASSTILLDRAWING ? "Still drawing" : hr == D3DERR_INVALIDCALL ? "Invalid call" : "w00t"); PanicAlert("ERROR: %s", hr == D3DERR_WASSTILLDRAWING ? "Still drawing" : hr == D3DERR_INVALIDCALL ? "Invalid call" : "w00t");
return 0; return 0;
} }
switch (type) {
case PEEK_Z:
{
switch (ReadBufferFormat)
{
case D3DFMT_R32F:
val = ((float*)drect.pBits)[6];
break;
default:
float ffrac = 1.0f/255.0f;
z = ((u32*)drect.pBits)[6];
val = ((float)((z>>16) & 0xFF)) * ffrac;
ffrac*= 1 / 255.0f;
val += ((float)((z>>8) & 0xFF)) * ffrac;
ffrac*= 1 / 255.0f;
val += ((float)(z & 0xFF)) * ffrac;
break;
};
z = ((u32)(val * 0xffffff));
}
break;
case PEEK_COLOR: switch (type)
z = ((u32 *)drect.pBits)[0]; {
break; case PEEK_Z:
case POKE_COLOR: {
switch (ReadBufferFormat)
{
case D3DFMT_R32F:
val = ((float*)drect.pBits)[6];
break;
default:
float ffrac = 1.0f/255.0f;
z = ((u32*)drect.pBits)[6];
val = ((float)((z>>16) & 0xFF)) * ffrac;
ffrac*= 1 / 255.0f;
val += ((float)((z>>8) & 0xFF)) * ffrac;
ffrac*= 1 / 255.0f;
val += ((float)(z & 0xFF)) * ffrac;
break;
};
z = ((u32)(val * 0xffffff));
}
break;
case POKE_Z:
// TODO: Implement
break;
case PEEK_COLOR:
z = ((u32*)drect.pBits)[0];
break;
case POKE_COLOR:
// TODO: Implement. One way is to draw a tiny pixel-sized rectangle at
// the exact location. Note: EFB pokes are susceptible to Z-buffering
// and perhaps blending.
//WARN_LOG(VIDEOINTERFACE, "This is probably some kind of software rendering");
break;
// TODO: Implement POKE_Z and POKE_COLOR // TODO: Implement POKE_Z and POKE_COLOR
default: default:
break; break;
} }
pOffScreenBuffer->UnlockRect(); pOffScreenBuffer->UnlockRect();
@ -905,10 +968,10 @@ void UpdateViewport()
{ {
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface()); D3D::dev->SetDepthStencilSurface(D3D::GetBackBufferDepthSurface());
FBManager.Destroy(); g_framebufferManager.Destroy();
FBManager.Create(); g_framebufferManager.Create();
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
} }
} }
vp.X = X; vp.X = X;
@ -978,7 +1041,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
} }
static bool RightFrame = false; static bool RightFrame = false;
// 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) void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc)
{ {
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight) if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.bUseRealXFB) || !fbWidth || !fbHeight)
@ -989,10 +1052,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// this function is called after the XFB field is changed, not after // this function is called after the XFB field is changed, not after
// EFB is copied to XFB. In this way, flickering is reduced in games // EFB is copied to XFB. In this way, flickering is reduced in games
// and seems to also give more FPS in ZTP // and seems to also give more FPS in ZTP
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2; if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0; u32 xfbCount = 0;
const XFBSource** xfbSourceList = FBManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); const XFBSource** xfbSourceList = g_framebufferManager.GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
{ {
g_VideoInitialize.pCopiedToXFB(false); g_VideoInitialize.pCopiedToXFB(false);
@ -1019,7 +1082,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
RightFrame = true; RightFrame = true;
} }
} }
// Set the backbuffer as the rendering target
// Prepare to copy the XFBs to our backbuffer
D3D::dev->SetDepthStencilSurface(NULL); D3D::dev->SetDepthStencilSurface(NULL);
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface()); D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
@ -1068,13 +1132,13 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// draw each xfb source // draw each xfb source
for (u32 i = 0; i < xfbCount; ++i) for (u32 i = 0; i < xfbCount; ++i)
{ {
xfbSource = xfbSourceList[i]; xfbSource = xfbSourceList[i];
MathUtil::Rectangle<float> sourceRc; MathUtil::Rectangle<float> sourceRc;
sourceRc.left = 0; sourceRc.left = 0;
sourceRc.top = 0; sourceRc.top = 0;
sourceRc.right = xfbSource->texWidth; sourceRc.right = xfbSource->texWidth;
sourceRc.bottom = xfbSource->texHeight; sourceRc.bottom = xfbSource->texHeight;
MathUtil::Rectangle<float> drawRc; MathUtil::Rectangle<float> drawRc;
@ -1085,11 +1149,10 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
int xfbWidth = xfbSource->srcWidth; int xfbWidth = xfbSource->srcWidth;
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2); int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
drawRc.bottom = 1.0f - 2.0f * ((hOffset) / (float)fbHeight); drawRc.bottom = 1.0f - (2.0f * (hOffset) / (float)fbHeight);
drawRc.top = 1.0f - 2.0f * ((hOffset + xfbHeight) / (float)fbHeight); drawRc.top = 1.0f - (2.0f * (hOffset + xfbHeight) / (float)fbHeight);
drawRc.left = -(xfbWidth / (float)fbWidth); drawRc.left = -(xfbWidth / (float)fbWidth);
drawRc.right = (xfbWidth / (float)fbWidth); drawRc.right = (xfbWidth / (float)fbWidth);
if (!g_ActiveConfig.bAutoScale) if (!g_ActiveConfig.bAutoScale)
{ {
@ -1117,7 +1180,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
else else
{ {
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
LPDIRECT3DTEXTURE9 read_texture = FBManager.GetEFBColorTexture(rc); LPDIRECT3DTEXTURE9 read_texture = g_framebufferManager.GetEFBColorTexture(rc);
D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode)); D3D::drawShadedTexQuad(read_texture,targetRc.AsRECT(),Renderer::GetFullTargetWidth(),Renderer::GetFullTargetHeight(),Width,Height,PixelShaderCache::GetColorCopyProgram(g_Config.iMultisampleMode),VertexShaderCache::GetSimpleVertexShader(g_Config.iMultisampleMode));
} }
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
@ -1134,7 +1197,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
vp.MinZ = 0.0f; vp.MinZ = 0.0f;
vp.MaxZ = 1.0f; vp.MaxZ = 1.0f;
D3D::dev->SetViewport(&vp); D3D::dev->SetViewport(&vp);
if(s_bScreenshot) if (s_bScreenshot)
{ {
s_criticalScreenshot.Enter(); s_criticalScreenshot.Enter();
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
@ -1153,12 +1216,12 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
if (g_ActiveConfig.bDumpFrames) if (g_ActiveConfig.bDumpFrames)
{ {
HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface); HRESULT hr = D3D::dev->GetRenderTargetData(D3D::GetBackBufferSurface(),ScreenShootMEMSurface);
if (!s_LastFrameDumped) if (!s_bLastFrameDumped)
{ {
s_recordWidth = dst_rect.GetWidth(); s_recordWidth = dst_rect.GetWidth();
s_recordHeight = dst_rect.GetHeight(); s_recordHeight = dst_rect.GetHeight();
s_AVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight); s_bAVIDumping = AVIDump::Start(EmuWindow::GetParentWnd(), s_recordWidth, s_recordHeight);
if (!s_AVIDumping) if (!s_bAVIDumping)
{ {
PanicAlert("Error dumping frames to AVI."); PanicAlert("Error dumping frames to AVI.");
} }
@ -1169,7 +1232,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
OSD::AddMessage(msg, 2000); OSD::AddMessage(msg, 2000);
} }
} }
if (s_AVIDumping) if (s_bAVIDumping)
{ {
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, dst_rect.AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
@ -1181,16 +1244,17 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
ScreenShootMEMSurface->UnlockRect(); ScreenShootMEMSurface->UnlockRect();
} }
} }
s_LastFrameDumped = true; s_bLastFrameDumped = true;
} }
else else
{ {
if (s_LastFrameDumped && s_AVIDumping) if (s_bLastFrameDumped && s_bAVIDumping)
{ {
AVIDump::Stop(); AVIDump::Stop();
s_AVIDumping = false; s_bAVIDumping = false;
OSD::AddMessage("Stop dumping frames to AVI", 2000);
} }
s_LastFrameDumped = false; s_bLastFrameDumped = false;
} }
// Finish up the current frame, print some stats // Finish up the current frame, print some stats
@ -1213,22 +1277,19 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
D3D::font.DrawTextScaled(0, 30, 20, 20, 0.0f, 0xFF00FFFF, st, false); D3D::font.DrawTextScaled(0, 30, 20, 20, 0.0f, 0xFF00FFFF, st, false);
} }
OSD::DrawMessages(); OSD::DrawMessages();
D3D::EndFrame(); D3D::EndFrame();
frameCount++; frameCount++;
DLCache::ProgressiveCleanup(); DLCache::ProgressiveCleanup();
TextureCache::Cleanup(); TextureCache::Cleanup();
// Make any new configuration settings active. // Enable any configuration changes
UpdateActiveConfig(); UpdateActiveConfig();
WindowResized = false; WindowResized = false;
CheckForResize(); CheckForResize();
bool xfbchanged = false; bool xfbchanged = false;
if (s_XFB_width != fbWidth || s_XFB_height != fbHeight) if (s_XFB_width != fbWidth || s_XFB_height != fbHeight)
{ {
xfbchanged = true; xfbchanged = true;
@ -1288,13 +1349,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
} }
else else
{ {
FBManager.Destroy(); g_framebufferManager.Destroy();
FBManager.Create(); g_framebufferManager.Create();
} }
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
} }
// Place messages on the picture, then copy it to the screen
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Count FPS. // Count FPS.
// ------------- // -------------
@ -1311,20 +1373,26 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// Begin new frame // Begin new frame
// Set default viewport and scissor, for the clear to work correctly // Set default viewport and scissor, for the clear to work correctly
// New frame
stats.ResetFrame(); stats.ResetFrame();
// Flip/present backbuffer to frontbuffer here // Flip/present backbuffer to frontbuffer here
D3D::Present(); D3D::Present();
D3D::BeginFrame(); D3D::BeginFrame();
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
UpdateViewport(); UpdateViewport();
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();
// For testing zbuffer targets.
// Renderer::SetZBufferRender();
// SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_ARB, s_FakeZTarget,
// GetTargetWidth(), GetTargetHeight());
g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB); g_VideoInitialize.pCopiedToXFB(XFBWrited || g_ActiveConfig.bUseRealXFB);
XFBWrited = false; XFBWrited = false;
} }
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
void Renderer::ResetAPIState() void Renderer::ResetAPIState()
{ {
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
@ -1365,6 +1433,7 @@ void Renderer::SetDepthMode()
} }
else else
{ {
// if the test is disabled write is disabled too
D3D::SetRenderState(D3DRS_ZENABLE, FALSE); D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // ?? D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // ??
} }

View File

@ -79,6 +79,30 @@ void TextureCache::Invalidate(bool shutdown)
HiresTextures::Shutdown(); HiresTextures::Shutdown();
} }
void TextureCache::Shutdown()
{
Invalidate(true);
FreeMemoryPages(temp, TEMP_SIZE);
temp = NULL;
}
void TextureCache::Cleanup()
{
TexCache::iterator iter = textures.begin();
while (iter != textures.end())
{
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount)
{
iter->second.Destroy(false);
iter = textures.erase(iter);
}
else
{
++iter;
}
}
}
void TextureCache::InvalidateRange(u32 start_address, u32 size) void TextureCache::InvalidateRange(u32 start_address, u32 size)
{ {
TexCache::iterator iter = textures.begin(); TexCache::iterator iter = textures.begin();
@ -90,9 +114,9 @@ void TextureCache::InvalidateRange(u32 start_address, u32 size)
iter->second.Destroy(false); iter->second.Destroy(false);
textures.erase(iter++); textures.erase(iter++);
} }
else else
{ {
++iter; ++iter;
} }
} }
} }
@ -120,53 +144,54 @@ int TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 rang
return 0; return 0;
} }
void TextureCache::Shutdown()
{
Invalidate(true);
FreeMemoryPages(temp, TEMP_SIZE);
temp = NULL;
}
void TextureCache::Cleanup()
{
TexCache::iterator iter = textures.begin();
while (iter != textures.end())
{
if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second.frameCount)
{
iter->second.Destroy(false);
textures.erase(iter++);
}
else
{
++iter;
}
}
}
TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt,bool UseNativeMips, int maxlevel) TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width, int height, int tex_format, int tlutaddr, int tlutfmt,bool UseNativeMips, int maxlevel)
{ {
// notes (about "UNsafe texture cache"):
// Have to be removed soon.
// But we keep it until the "safe" way became rock solid
// pros: it has an unique ID held by the texture data itself (@address) once cached.
// cons: it writes this unique ID in the gc RAM <- very dangerous (break MP1) and ugly
// notes (about "safe texture cache"):
// Metroids text issue (character table):
// Same addr, same GX_TF_C4 texture data but different TLUT (hence different outputs).
// That's why we have to hash the TLUT too for TLUT tex_format dependent textures (ie. GX_TF_C4, GX_TF_C8, GX_TF_C14X2).
// And since the address and tex data don't change, the key index in the cacheEntry map can't be the address but
// have to be a real unique ID.
// DONE but not satifiying yet -> may break copyEFBToTexture sometimes.
// Pokemon Colosseum text issue (plain text):
// Use a GX_TF_I4 512x512 text-flush-texture at a const address.
// The problem here was just the sparse hash on the texture. This texture is partly overwrited (what is needed only)
// so lot's of remaning old text. Thin white chars on black bg too.
// TODO: - clean this up when ready to kill old "unsafe texture cache"
// - fix the key index situation with CopyRenderTargetToTexture.
// Could happen only for GX_TF_C4, GX_TF_C8 and GX_TF_C14X2 fmt.
// Wonder if we can't use tex width&height to know if EFB might be copied to it...
// raw idea: TOCHECK if addresses are aligned we have few bits left...
if (address == 0) if (address == 0)
return NULL; return NULL;
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address); u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16; int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; //TexelSizeInNibbles(format)*width*height/16; int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format); int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
int expandedWidth = (width + bsw) & (~bsw); int expandedWidth = (width + bsw) & (~bsw);
int expandedHeight = (height + bsh) & (~bsh); int expandedHeight = (height + bsh) & (~bsh);
u64 hash_value; u64 hash_value = 0;
u32 texID = address; u32 texID = address;
u64 texHash; u64 texHash = 0;
u32 FullFormat = tex_format; u32 FullFormat = tex_format;
bool TextureisDynamic = false; bool TextureisDynamic = false;
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
u32 FullFormat = (tex_format | (tlutfmt << 16)); FullFormat = (tex_format | (tlutfmt << 16));
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures) if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
{ {
texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples); texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
{ {
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up) // WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
@ -325,7 +350,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
bool isPow2 = !((width & (width - 1)) || (height & (height - 1))); bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
entry.isNonPow2 = false; entry.isNonPow2 = false;
int TexLevels = (width > height)?width:height; int TexLevels = (width > height)?width:height;
TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : ((isPow2)? 0 : 1); TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2? 0 : 1);
if(TexLevels > (maxlevel + 1) && maxlevel > 0) if(TexLevels > (maxlevel + 1) && maxlevel > 0)
TexLevels = (maxlevel + 1); TexLevels = (maxlevel + 1);
entry.MipLevels = maxlevel; entry.MipLevels = maxlevel;
@ -364,14 +389,14 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
entry.Scaledw = width; entry.Scaledw = width;
entry.Scaledh = height; entry.Scaledh = height;
entry.fmt = FullFormat; entry.fmt = FullFormat;
if (g_ActiveConfig.bDumpTextures) if (g_ActiveConfig.bDumpTextures)
{ {
// dump texture to file // dump texture to file
char szTemp[MAX_PATH]; char szTemp[MAX_PATH];
char szDir[MAX_PATH]; char szDir[MAX_PATH];
const char* uniqueId = globals->unique_id; const char* uniqueId = globals->unique_id;
bool bCheckedDumpDir = false; static bool bCheckedDumpDir = false;
sprintf(szDir, "%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId); sprintf(szDir, "%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId);
@ -390,7 +415,7 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
} }
INCSTAT(stats.numTexturesCreated); INCSTAT(stats.numTexturesCreated);
SETSTAT(stats.numTexturesAlive, (int)textures.size()); SETSTAT(stats.numTexturesAlive, textures.size());
//Set the texture! //Set the texture!
D3D::SetTexture(stage, entry.texture); D3D::SetTexture(stage, entry.texture);
@ -434,12 +459,12 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
textures.erase(iter); textures.erase(iter);
} }
} }
if(TextureisDynamic) if (TextureisDynamic)
{ {
Scaledtex_w = tex_w; Scaledtex_w = tex_w;
Scaledtex_h = tex_h; Scaledtex_h = tex_h;
} }
if(!tex) if (!tex)
{ {
TCacheEntry entry; TCacheEntry entry;
entry.addr = address; entry.addr = address;
@ -459,7 +484,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
} }
// Make sure to resolve anything we need to read from. // Make sure to resolve anything we need to read from.
LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ? FBManager.GetEFBDepthTexture(source_rect) : FBManager.GetEFBColorTexture(source_rect); LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ? g_framebufferManager.GetEFBDepthTexture(source_rect) : g_framebufferManager.GetEFBColorTexture(source_rect);
// We have to run a pixel shader, for color conversion. // We have to run a pixel shader, for color conversion.
Renderer::ResetAPIState(); // reset any game specific settings Renderer::ResetAPIState(); // reset any game specific settings
@ -625,7 +650,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
} }
D3DFORMAT bformat = FBManager.GetEFBDepthRTSurfaceFormat(); D3DFORMAT bformat = g_framebufferManager.GetEFBDepthRTSurfaceFormat();
int SSAAMode = g_ActiveConfig.iMultisampleMode; int SSAAMode = g_ActiveConfig.iMultisampleMode;
D3D::drawShadedTexQuad( D3D::drawShadedTexQuad(
read_texture, read_texture,
@ -660,9 +685,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
D3D::SetTexture(0,NULL); D3D::SetTexture(0,NULL);
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
} }

View File

@ -156,7 +156,6 @@ void Init()
} }
CreateRgbToYuyvProgram(); CreateRgbToYuyvProgram();
CreateYuyvToRgbProgram(); CreateYuyvToRgbProgram();
} }
void Shutdown() void Shutdown()
@ -242,7 +241,7 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
if (linearFilter) if (linearFilter)
{ {
D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); D3D::ChangeSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
} }
else else
{ {
@ -256,7 +255,7 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
vp.Height = dstHeight; vp.Height = dstHeight;
vp.MinZ = 0.0f; vp.MinZ = 0.0f;
vp.MaxZ = 1.0f; vp.MaxZ = 1.0f;
hr = D3D::dev->SetViewport(&vp); hr = D3D::dev->SetViewport(&vp);
RECT SrcRect; RECT SrcRect;
SrcRect.top = sourceRc.top; SrcRect.top = sourceRc.top;
SrcRect.left = sourceRc.left; SrcRect.left = sourceRc.left;
@ -277,40 +276,31 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
D3DLOCKED_RECT drect; D3DLOCKED_RECT drect;
hr = D3D::dev->GetRenderTargetData(Rendersurf,s_texConvReadSurface); hr = D3D::dev->GetRenderTargetData(Rendersurf,s_texConvReadSurface);
if((hr = s_texConvReadSurface->LockRect(&drect, &DstRect, D3DLOCK_READONLY)) != D3D_OK) hr = s_texConvReadSurface->LockRect(&drect, &DstRect, D3DLOCK_READONLY);
int writeStride = bpmem.copyMipMapStrideChannels * 32;
if (writeStride != readStride && toTexture)
{ {
PanicAlert("ERROR: %s", hr == D3DERR_WASSTILLDRAWING ? "Still drawing" : // writing to a texture of a different size
hr == D3DERR_INVALIDCALL ? "Invalid call" : "w00t");
int readHeight = readStride / dstWidth;
int readStart = 0;
int readLoops = dstHeight / (readHeight/4); // 4 bytes per pixel
u8 *Source = (u8*)drect.pBits;
for (int i = 0; i < readLoops; i++)
{
int readDist = dstWidth*readHeight;
memcpy(destAddr,Source,readDist);
Source += readDist;
destAddr += writeStride;
}
} }
else else
{ memcpy(destAddr,drect.pBits,dstWidth*dstHeight*4);// 4 bytes per pixel
int writeStride = bpmem.copyMipMapStrideChannels * 32;
hr = s_texConvReadSurface->UnlockRect();
if (writeStride != readStride && toTexture)
{
// writing to a texture of a different size
int readHeight = readStride / dstWidth;
int readStart = 0;
int readLoops = dstHeight / (readHeight/4); // 4 bytes per pixel
u8 *Source = (u8*)drect.pBits;
for (int i = 0; i < readLoops; i++)
{
int readDist = dstWidth*readHeight;
memcpy(destAddr,Source,readDist);
Source += readDist;
destAddr += writeStride;
}
}
else
memcpy(destAddr,drect.pBits,dstWidth*dstHeight*4);// 4 bytes per pixel
hr = s_texConvReadSurface->UnlockRect();
}
} }
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
@ -335,7 +325,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
u8 *dest_ptr = Memory_GetPtr(address); u8 *dest_ptr = Memory_GetPtr(address);
LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? FBManager.GetEFBDepthTexture(source) : FBManager.GetEFBColorTexture(source); LPDIRECT3DTEXTURE9 source_texture = bFromZBuffer ? g_framebufferManager.GetEFBDepthTexture(source) : g_framebufferManager.GetEFBColorTexture(source);
int width = (source.right - source.left) >> bScaleByHalf; int width = (source.right - source.left) >> bScaleByHalf;
int height = (source.bottom - source.top) >> bScaleByHalf; int height = (source.bottom - source.top) >> bScaleByHalf;
@ -343,7 +333,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
// Invalidate any existing texture covering this memory range. // Invalidate any existing texture covering this memory range.
// TODO - don't delete the texture if it already exists, just replace the contents. // TODO - don't delete the texture if it already exists, just replace the contents.
TextureCache::InvalidateRange(address, size_in_bytes); TextureCache::InvalidateRange(address, size_in_bytes);
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1; u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1; u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
@ -383,9 +373,9 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
Renderer::ResetAPIState(); Renderer::ResetAPIState();
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight,readStride, true, bScaleByHalf > 0); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0);
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
} }
@ -454,8 +444,7 @@ u64 EncodeToRamFromTexture(u32 address,LPDIRECT3DTEXTURE9 source_texture,u32 Sou
return Hashvalue; return Hashvalue;
} }
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourceRc,u8* destAddr, int dstWidth, int dstHeight)
{ {
TextureConversionShader::SetShaderParameters( TextureConversionShader::SetShaderParameters(
(float)dstWidth, (float)dstWidth,
@ -468,9 +457,9 @@ void EncodeToRamYUYV(LPDIRECT3DTEXTURE9 srcTexture, const TargetRectangle& sourc
(float)Renderer::GetFullTargetHeight()); (float)Renderer::GetFullTargetHeight());
Renderer::ResetAPIState(); Renderer::ResetAPIState();
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
} }
@ -491,7 +480,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
LPDIRECT3DSURFACE9 Rendersurf = NULL; LPDIRECT3DSURFACE9 Rendersurf = NULL;
destTexture->GetSurfaceLevel(0,&Rendersurf); destTexture->GetSurfaceLevel(0,&Rendersurf);
D3D::dev->SetDepthStencilSurface(NULL); D3D::dev->SetDepthStencilSurface(NULL);
D3D::dev->SetRenderTarget(0, Rendersurf); D3D::dev->SetRenderTarget(0, Rendersurf);
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
@ -535,17 +524,17 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, LPDIRECT3DTEXTURE
srcWidth, srcWidth,
srcHeight, srcHeight,
s_yuyvToRgbProgram, s_yuyvToRgbProgram,
VertexShaderCache::GetSimpleVertexShader(0)); VertexShaderCache::GetSimpleVertexShader(0));
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER); D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
D3D::SetTexture(0,NULL); D3D::SetTexture(0,NULL);
D3D::dev->SetRenderTarget(0, FBManager.GetEFBColorRTSurface()); D3D::dev->SetRenderTarget(0, g_framebufferManager.GetEFBColorRTSurface());
D3D::dev->SetDepthStencilSurface(FBManager.GetEFBDepthRTSurface()); D3D::dev->SetDepthStencilSurface(g_framebufferManager.GetEFBDepthRTSurface());
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
Rendersurf->Release(); Rendersurf->Release();
s_srcTexture->Release(); s_srcTexture->Release();
} }
} // namespace } // namespace

View File

@ -81,26 +81,24 @@ void Shutdown()
delete [] LocalVBuffer; delete [] LocalVBuffer;
delete [] TIBuffer; delete [] TIBuffer;
delete [] LIBuffer; delete [] LIBuffer;
delete [] PIBuffer; delete [] PIBuffer;
ResetBuffer(); ResetBuffer();
} }
void AddIndices(int _primitive, int _numVertices) void AddIndices(int primitive, int numVertices)
{ {
switch (_primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: IndexGenerator::AddQuads(_numVertices); break; case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(_numVertices); break; case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(_numVertices); break; case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(_numVertices); break; case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(_numVertices); break; case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
case GX_DRAW_LINES: IndexGenerator::AddLineList(_numVertices); break; case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
case GX_DRAW_POINTS: IndexGenerator::AddPoints(_numVertices); break; case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
} }
} }
int GetRemainingSize() int GetRemainingSize()
{ {
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer); return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
@ -110,53 +108,54 @@ int GetRemainingVertices(int primitive)
{ {
switch (primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: case GX_DRAW_QUADS:
case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLES:
case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_STRIP:
case GX_DRAW_TRIANGLE_FAN: case GX_DRAW_TRIANGLE_FAN:
return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen())/3; return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen())/3;
case GX_DRAW_LINE_STRIP: case GX_DRAW_LINE_STRIP:
case GX_DRAW_LINES: case GX_DRAW_LINES:
return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen())/2; return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen())/2;
case GX_DRAW_POINTS: case GX_DRAW_POINTS:
return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen()); return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen());
default: return 0; default: return 0;
} }
} }
void AddVertices(int _primitive, int _numVertices) void AddVertices(int primitive, int numVertices)
{ {
if (_numVertices <= 0) if (numVertices <= 0)
return; return;
switch (_primitive)
switch (primitive)
{ {
case GX_DRAW_QUADS: case GX_DRAW_QUADS:
case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLES:
case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_STRIP:
case GX_DRAW_TRIANGLE_FAN: case GX_DRAW_TRIANGLE_FAN:
if(MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * _numVertices) if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
Flush(); Flush();
break; break;
case GX_DRAW_LINE_STRIP: case GX_DRAW_LINE_STRIP:
case GX_DRAW_LINES: case GX_DRAW_LINES:
if(MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * _numVertices) if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * numVertices)
Flush(); Flush();
break; break;
case GX_DRAW_POINTS: case GX_DRAW_POINTS:
if(MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < _numVertices) if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < numVertices)
Flush(); Flush();
break; break;
default: return; default: return;
} }
if(Flushed) if (Flushed)
{ {
IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer); IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer);
Flushed=false; Flushed=false;
} }
lastPrimitive = _primitive; lastPrimitive = primitive;
ADDSTAT(stats.thisFrame.numPrims, _numVertices); ADDSTAT(stats.thisFrame.numPrims, numVertices);
INCSTAT(stats.thisFrame.numPrimitiveJoins); INCSTAT(stats.thisFrame.numPrimitiveJoins);
AddIndices(_primitive, _numVertices); AddIndices(primitive, numVertices);
} }
inline void DumpBadShaders() inline void DumpBadShaders()
@ -179,7 +178,7 @@ inline void DumpBadShaders()
inline void Draw(int stride) inline void Draw(int stride)
{ {
if(IndexGenerator::GetNumTriangles() > 0) if (IndexGenerator::GetNumTriangles() > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_TRIANGLELIST, D3DPT_TRIANGLELIST,
@ -193,7 +192,7 @@ inline void Draw(int stride)
} }
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if(IndexGenerator::GetNumLines() > 0) if (IndexGenerator::GetNumLines() > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_LINELIST, D3DPT_LINELIST,
@ -207,7 +206,7 @@ inline void Draw(int stride)
} }
INCSTAT(stats.thisFrame.numIndexedDrawCalls); INCSTAT(stats.thisFrame.numIndexedDrawCalls);
} }
if(IndexGenerator::GetNumPoints() > 0) if (IndexGenerator::GetNumPoints() > 0)
{ {
if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( if (FAILED(D3D::dev->DrawIndexedPrimitiveUP(
D3DPT_POINTLIST, D3DPT_POINTLIST,
@ -226,47 +225,43 @@ inline void Draw(int stride)
void Flush() void Flush()
{ {
if (LocalVBuffer == s_pCurBufferPointer) return; if (LocalVBuffer == s_pCurBufferPointer) return;
if(Flushed) return; if (Flushed) return;
Flushed=true; Flushed=true;
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
DVSTARTPROFILE(); DVSTARTPROFILE();
u32 usedtextures = 0; u32 usedtextures = 0;
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) { for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevorders[i/2].getEnable(i & 1)) if (bpmem.tevorders[i / 2].getEnable(i & 1))
usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1); usedtextures |= 1 << bpmem.tevorders[i/2].getTexMap(i & 1);
}
if (bpmem.genMode.numindstages > 0) { if (bpmem.genMode.numindstages > 0)
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) { for (unsigned int i = 0; i < bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) { if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
}
}
}
for (int i = 0; i < 8; i++) for (unsigned int i = 0; i < 8; i++)
{ {
if (usedtextures & (1 << i)) { if (usedtextures & (1 << i))
{
Renderer::SetSamplerState(i & 3, i >> 2); Renderer::SetSamplerState(i & 3, i >> 2);
FourTexUnits &tex = bpmem.tex[i >> 2]; FourTexUnits &tex = bpmem.tex[i >> 2];
TextureCache::TCacheEntry* tentry = TextureCache::Load(i, TextureCache::TCacheEntry* tentry = TextureCache::Load(i,
(tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5,
tex.texImage0[i&3].width + 1, tex.texImage0[i&3].height + 1, 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.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format, tex.texTlut[i&3].tlut_format,
(tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips, (tex.texMode0[i&3].min_filter & 3) && (tex.texMode0[i&3].min_filter != 8) && g_ActiveConfig.bUseNativeMips,
(tex.texMode1[i&3].max_lod >> 4)); (tex.texMode1[i&3].max_lod >> 4));
if (tentry) { if (tentry)
{
// 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0); PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
} }
else else
{
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to load texture\n");});
ERROR_LOG(VIDEO, "error loading texture"); ERROR_LOG(VIDEO, "error loading texture");
}
} }
} }
@ -311,7 +306,5 @@ void Flush()
shader_fail: shader_fail:
ResetBuffer(); ResetBuffer();
} }
} // namespace } // namespace

View File

@ -84,16 +84,19 @@ void SetMultiVSConstant4fv(unsigned int const_number, unsigned int count, const
D3D::dev->SetVertexShaderConstantF(const_number, f, count); D3D::dev->SetVertexShaderConstantF(const_number, f, count);
} }
// this class will load the precompiled shaders into our cache
class VertexShaderCacheInserter : public LinearDiskCacheReader { class VertexShaderCacheInserter : public LinearDiskCacheReader {
public: public:
void Read(const u8 *key, int key_size, const u8 *value, int value_size) void Read(const u8 *key, int key_size, const u8 *value, int value_size)
{ {
VERTEXSHADERUID uid; VERTEXSHADERUID uid;
if (key_size != sizeof(uid)) { if (key_size != sizeof(uid))
{
ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache"); ERROR_LOG(VIDEO, "Wrong key size in vertex shader cache");
return; return;
} }
memcpy(&uid, key, key_size); memcpy(&uid, key, key_size);
VertexShaderCache::InsertByteCode(uid, value, value_size, false); VertexShaderCache::InsertByteCode(uid, value, value_size, false);
} }
}; };
@ -179,13 +182,12 @@ void VertexShaderCache::Init()
char cache_filename[MAX_PATH]; char cache_filename[MAX_PATH];
sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id); sprintf(cache_filename, "%sdx9-%s-vs.cache", File::GetUserPath(D_SHADERCACHE_IDX), globals->unique_id);
VertexShaderCacheInserter inserter; VertexShaderCacheInserter inserter;
int read_items = g_vs_disk_cache.OpenAndRead(cache_filename, &inserter); g_vs_disk_cache.OpenAndRead(cache_filename, &inserter);
} }
void VertexShaderCache::Clear() void VertexShaderCache::Clear()
{ {
VSCache::iterator iter = vshaders.begin(); for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
for (; iter != vshaders.end(); ++iter)
iter->second.Destroy(); iter->second.Destroy();
vshaders.clear(); vshaders.clear();
@ -217,16 +219,11 @@ bool VertexShaderCache::SetShader(u32 components)
VERTEXSHADERUID uid; VERTEXSHADERUID uid;
GetVertexShaderId(&uid, components); GetVertexShaderId(&uid, components);
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount) if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
{ return (vshaders[uid].shader != NULL);
if (vshaders[uid].shader)
return true;
else
return false;
}
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID)); memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
VSCache::iterator iter; VSCache::iterator iter = vshaders.find(uid);
iter = vshaders.find(uid);
if (iter != vshaders.end()) if (iter != vshaders.end())
{ {
iter->second.frameCount = frameCount; iter->second.frameCount = frameCount;

View File

@ -100,7 +100,7 @@ void *DllDebugger(void *_hParent, bool Show)
return true; return true;
} }
}; };
IMPLEMENT_APP_NO_MAIN(wxDLLApp) IMPLEMENT_APP_NO_MAIN(wxDLLApp)
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst); WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
#endif #endif
@ -148,18 +148,16 @@ void UpdateFPSDisplay(const char *text)
SetWindowText(EmuWindow::GetWnd(), temp); SetWindowText(EmuWindow::GetWnd(), temp);
} }
void GetDllInfo (PLUGIN_INFO* _PluginInfo) void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{ {
_PluginInfo->Version = 0x0100; _PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_VIDEO; _PluginInfo->Type = PLUGIN_TYPE_VIDEO;
#ifdef DEBUGFAST #ifdef DEBUGFAST
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (DebugFast)"); sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (DebugFast)");
#else #elif defined _DEBUG
#ifndef _DEBUG
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9");
#else
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (Debug)"); sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9 (Debug)");
#endif #else
sprintf_s(_PluginInfo->Name, 100, "Dolphin Direct3D9");
#endif #endif
} }
@ -197,14 +195,15 @@ void Initialize(void *init)
{ {
frameCount = 0; frameCount = 0;
SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init; SVideoInitialize *_pVideoInitialize = (SVideoInitialize*)init;
g_VideoInitialize = *_pVideoInitialize; // Create a shortcut to _pVideoInitialize that can also update it
g_VideoInitialize = *(_pVideoInitialize);
InitXFBConvTables(); InitXFBConvTables();
g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx9.ini").c_str()); g_Config.Load((std::string(File::GetUserPath(D_CONFIG_IDX)) + "gfx_dx9.ini").c_str());
g_Config.GameIniLoad(globals->game_ini); g_Config.GameIniLoad(globals->game_ini);
UpdateProjectionHack(g_Config.iPhackvalue); // DX9 projection hack could be disabled by commenting out this line UpdateProjectionHack(g_Config.iPhackvalue); // DX9 projection hack could be disabled by commenting out this line
UpdateActiveConfig(); UpdateActiveConfig();
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, _T("Loading - Please wait.")); g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, _T("Loading - Please wait."));
if (g_VideoInitialize.pWindowHandle == NULL) if (g_VideoInitialize.pWindowHandle == NULL)
{ {
@ -222,6 +221,8 @@ void Initialize(void *init)
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages; _pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay; _pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
// Now the window handle is written
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle; _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
OSD::AddMessage("Dolphin Direct3D9 Video Plugin.", 5000); OSD::AddMessage("Dolphin Direct3D9 Video Plugin.", 5000);
@ -234,10 +235,13 @@ void Video_Prepare()
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
// internal interfaces
Renderer::Init(); Renderer::Init();
TextureCache::Init(); TextureCache::Init();
BPInit();
VertexManager::Init(); VertexManager::Init();
// VideoCommon
BPInit();
Fifo_Init(); Fifo_Init();
VertexLoaderManager::Init(); VertexLoaderManager::Init();
OpcodeDecoder_Init(); OpcodeDecoder_Init();
@ -246,36 +250,45 @@ void Video_Prepare()
CommandProcessor::Init(); CommandProcessor::Init();
PixelEngine::Init(); PixelEngine::Init();
DLCache::Init(); DLCache::Init();
// Tell the host the window is ready
// Notify the core that the video plugin is ready
g_VideoInitialize.pCoreMessage(WM_USER_CREATE); g_VideoInitialize.pCoreMessage(WM_USER_CREATE);
} }
void Shutdown() void Shutdown()
{ {
s_PluginInitialized = false;
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
// VideoCommon
DLCache::Shutdown(); DLCache::Shutdown();
Fifo_Shutdown(); Fifo_Shutdown();
CommandProcessor::Shutdown(); CommandProcessor::Shutdown();
VertexManager::Shutdown();
VertexLoaderManager::Shutdown();
VertexShaderManager::Shutdown();
PixelShaderManager::Shutdown(); PixelShaderManager::Shutdown();
TextureCache::Shutdown(); VertexShaderManager::Shutdown();
OpcodeDecoder_Shutdown(); OpcodeDecoder_Shutdown();
VertexLoaderManager::Shutdown();
// internal interfaces
PixelShaderCache::Shutdown();
VertexShaderCache::Shutdown();
VertexManager::Shutdown();
TextureCache::Shutdown();
Renderer::Shutdown(); Renderer::Shutdown();
D3D::Shutdown(); D3D::Shutdown();
EmuWindow::Close(); EmuWindow::Close();
s_PluginInitialized = false;
} }
void DoState(unsigned char **ptr, int mode) { void DoState(unsigned char **ptr, int mode)
{
// Clear texture cache because it might have written to RAM // Clear texture cache because it might have written to RAM
CommandProcessor::FifoCriticalEnter(); CommandProcessor::FifoCriticalEnter();
TextureCache::Invalidate(false); TextureCache::Invalidate(false);
CommandProcessor::FifoCriticalLeave(); CommandProcessor::FifoCriticalLeave();
// No need to clear shader caches. // No need to clear shader caches
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
VideoCommon_DoState(p); VideoCommon_DoState(p);
} }
@ -285,6 +298,7 @@ void EmuStateChange(PLUGIN_EMUSTATE newState)
Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false);
} }
// Enter and exit the video loop
void Video_EnterLoop() void Video_EnterLoop()
{ {
Fifo_EnterLoop(g_VideoInitialize); Fifo_EnterLoop(g_VideoInitialize);
@ -293,11 +307,11 @@ void Video_EnterLoop()
void Video_ExitLoop() void Video_ExitLoop()
{ {
Fifo_ExitLoop(); Fifo_ExitLoop();
s_FifoShuttingDown = TRUE; s_FifoShuttingDown = TRUE;
} }
void Video_SetRendering(bool bEnabled) { void Video_SetRendering(bool bEnabled)
{
Fifo_SetRendering(bEnabled); Fifo_SetRendering(bEnabled);
} }
@ -315,7 +329,7 @@ void VideoFifo_CheckSwapRequest()
} }
} }
inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) static inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
{ {
return !((aLower >= bUpper) || (bLower >= aUpper)); return !((aLower >= bUpper) || (bLower >= aUpper));
} }
@ -335,14 +349,14 @@ void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
} }
} }
} }
// Run from the CPU thread (from VideoInterface.cpp) // Run from the CPU thread (from VideoInterface.cpp)
void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
{ {
if (s_PluginInitialized && g_ActiveConfig.bUseXFB) if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
{ {
if (g_VideoInitialize.bOnThread) if (g_VideoInitialize.bOnThread)
{ {
while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown) while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown)
@ -350,7 +364,7 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
Common::YieldCPU(); Common::YieldCPU();
} }
else else
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
s_beginFieldArgs.xfbAddr = xfbAddr; s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field; s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth; s_beginFieldArgs.fbWidth = fbWidth;
@ -360,30 +374,20 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
} }
} }
// Run from the CPU thread (from VideoInterface.cpp)
void Video_EndField() void Video_EndField()
{ {
} }
void Video_AddMessage(const char* pstr, u32 milliseconds) void Video_AddMessage(const char* pstr, u32 milliseconds)
{ {
OSD::AddMessage(pstr,milliseconds); OSD::AddMessage(pstr, milliseconds);
}
HRESULT ScreenShot(const char *File)
{
Renderer::SetScreenshot(File);
return S_OK;
} }
// Screenshot
void Video_Screenshot(const char *_szFilename) void Video_Screenshot(const char *_szFilename)
{ {
if (ScreenShot(_szFilename) != S_OK) Renderer::SetScreenshot(_szFilename);
PanicAlert("Error while capturing screen");
else {
std::string message = "Saved ";
message += _szFilename;
OSD::AddMessage(message.c_str(), 2000);
}
} }
static struct static struct
@ -406,7 +410,7 @@ void VideoFifo_CheckEFBAccess()
} }
} }
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y,u32 InputData) u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
{ {
if (s_PluginInitialized) if (s_PluginInitialized)
{ {

View File

@ -15,4 +15,4 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "stdafx.h" #include "stdafx.h"

View File

@ -23,4 +23,3 @@
#include <tchar.h> #include <tchar.h>
#include <windows.h> #include <windows.h>

View File

@ -766,11 +766,11 @@
> >
</File> </File>
<File <File
RelativePath=".\Src\TextureMngr.cpp" RelativePath=".\Src\TextureCache.cpp"
> >
</File> </File>
<File <File
RelativePath=".\Src\TextureMngr.h" RelativePath=".\Src\TextureCache.h"
> >
</File> </File>
<File <File

View File

@ -21,7 +21,7 @@
#include "VideoConfig.h" #include "VideoConfig.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "Render.h" #include "Render.h"
#include "TextureMngr.h" #include "TextureCache.h"
#include "TextureConverter.h" #include "TextureConverter.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "XFB.h" #include "XFB.h"
@ -39,6 +39,7 @@ void FlushPipeline()
{ {
VertexManager::Flush(); VertexManager::Flush();
} }
void SetGenerationMode(const BPCmd &bp) void SetGenerationMode(const BPCmd &bp)
{ {
Renderer::SetGenerationMode(); Renderer::SetGenerationMode();
@ -46,25 +47,26 @@ void SetGenerationMode(const BPCmd &bp)
void SetScissor(const BPCmd &bp) void SetScissor(const BPCmd &bp)
{ {
if (!Renderer::SetScissorRect()) Renderer::SetScissorRect();
if (bp.address == BPMEM_SCISSORBR)
ERROR_LOG(VIDEO, "bad scissor!");
} }
void SetLineWidth(const BPCmd &bp) void SetLineWidth(const BPCmd &bp)
{ {
Renderer::SetLineWidth(); Renderer::SetLineWidth();
} }
void SetDepthMode(const BPCmd &bp) void SetDepthMode(const BPCmd &bp)
{ {
Renderer::SetDepthMode(); Renderer::SetDepthMode();
} }
void SetBlendMode(const BPCmd &bp) void SetBlendMode(const BPCmd &bp)
{ {
Renderer::SetBlendMode(false); Renderer::SetBlendMode(false);
} }
void SetDitherMode(const BPCmd &bp) void SetDitherMode(const BPCmd &bp)
{ {
Renderer::SetDitherMode(); Renderer::SetDitherMode();
} }
void SetLogicOpMode(const BPCmd &bp) void SetLogicOpMode(const BPCmd &bp)
{ {
@ -73,7 +75,7 @@ void SetLogicOpMode(const BPCmd &bp)
void SetColorMask(const BPCmd &bp) void SetColorMask(const BPCmd &bp)
{ {
Renderer::SetColorMask(); Renderer::SetColorMask();
} }
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const int &scaleByHalf) void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 &copyfmt, const int &scaleByHalf)
@ -81,12 +83,15 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format) // bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
if (!g_ActiveConfig.bEFBCopyDisable) if (!g_ActiveConfig.bEFBCopyDisable)
{ {
TextureMngr::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc); TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
} }
} }
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc) void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
{ {
// it seems that the GC is able to alpha blend on color-fill
// we cant do that so if alpha is != 255 we skip it
bool colorEnable = bpmem.blendmode.colorupdate; bool colorEnable = bpmem.blendmode.colorupdate;
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate); bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
bool zEnable = bpmem.zmode.updateenable; bool zEnable = bpmem.zmode.updateenable;

View File

@ -186,22 +186,6 @@ void FramebufferManager::Shutdown()
m_virtualXFBList.clear(); m_virtualXFBList.clear();
} }
void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
{
if (g_ActiveConfig.bUseRealXFB)
copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
else
copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
}
const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
{
if (g_ActiveConfig.bUseRealXFB)
return getRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
else
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
}
GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) const GLuint FramebufferManager::GetEFBColorTexture(const EFBRectangle& sourceRc) const
{ {
if (m_msaaSamples <= 1) if (m_msaaSamples <= 1)
@ -262,6 +246,22 @@ GLuint FramebufferManager::GetEFBDepthTexture(const EFBRectangle& sourceRc) cons
} }
} }
void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
{
if (g_ActiveConfig.bUseRealXFB)
copyToRealXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
else
copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc);
}
const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount)
{
if (g_ActiveConfig.bUseRealXFB)
return getRealXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
else
return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
}
TargetRectangle FramebufferManager::ConvertEFBRectangle(const EFBRectangle& rc) const TargetRectangle FramebufferManager::ConvertEFBRectangle(const EFBRectangle& rc) const
{ {
TargetRectangle result; TargetRectangle result;
@ -274,8 +274,7 @@ TargetRectangle FramebufferManager::ConvertEFBRectangle(const EFBRectangle& rc)
return result; return result;
} }
FramebufferManager::VirtualXFBListType::iterator FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
{ {
u32 srcLower = xfbAddr; u32 srcLower = xfbAddr;
u32 srcUpper = xfbAddr + 2 * width * height; u32 srcUpper = xfbAddr + 2 * width * height;
@ -296,7 +295,7 @@ FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height)
void FramebufferManager::replaceVirtualXFB() void FramebufferManager::replaceVirtualXFB()
{ {
VirtualXFBListType::iterator it = m_virtualXFBList.begin(); VirtualXFBListType::iterator it = m_virtualXFBList.begin();
s32 srcLower = it->xfbAddr; s32 srcLower = it->xfbAddr;
s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight;
@ -311,13 +310,13 @@ void FramebufferManager::replaceVirtualXFB()
if (dstLower >= srcLower && dstUpper <= srcUpper) if (dstLower >= srcLower && dstUpper <= srcUpper)
{ {
// invalidate the data // Invalidate the data
it->xfbAddr = 0; it->xfbAddr = 0;
it->xfbHeight = 0; it->xfbHeight = 0;
it->xfbWidth = 0; it->xfbWidth = 0;
} }
else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper))
{ {
s32 upperOverlap = (srcUpper - dstLower) / lineSize; s32 upperOverlap = (srcUpper - dstLower) / lineSize;
s32 lowerOverlap = (dstUpper - srcLower) / lineSize; s32 lowerOverlap = (dstUpper - srcLower) / lineSize;
@ -338,14 +337,14 @@ void FramebufferManager::replaceVirtualXFB()
void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
{ {
u8* pXFB = Memory_GetPtr(xfbAddr); u8* xfb_in_ram = Memory_GetPtr(xfbAddr);
if (!pXFB) if (!xfb_in_ram)
{ {
WARN_LOG(VIDEO, "Tried to copy to invalid XFB address"); WARN_LOG(VIDEO, "Tried to copy to invalid XFB address");
return; return;
} }
XFB_Write(pXFB, sourceRc, fbWidth, fbHeight); XFB_Write(xfb_in_ram, sourceRc, fbWidth, fbHeight);
} }
void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc)
@ -356,7 +355,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB)
{ {
// replace the last virtual XFB // Replace the last virtual XFB
--it; --it;
} }
@ -432,7 +431,7 @@ void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight
m_virtualXFBList.push_front(newVirt); m_virtualXFBList.push_front(newVirt);
} }
// Copy EFB to XFB texture // Copy EFB data to XFB and restore render target again
#if 0 #if 0
if (m_msaaSamples <= 1) if (m_msaaSamples <= 1)

View File

@ -25,7 +25,7 @@
#include "ConfigDlg.h" #include "ConfigDlg.h"
#include "../Globals.h" #include "../Globals.h"
#include "VideoConfig.h" #include "VideoConfig.h"
#include "../TextureMngr.h" #include "../TextureCache.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "../PostProcessing.h" #include "../PostProcessing.h"
#include "Render.h" #include "Render.h"
@ -668,11 +668,11 @@ void GFXConfigDialogOGL::AdvancedSettingsChanged(wxCommandEvent& event)
case ID_TEXFMTOVERLAY: case ID_TEXFMTOVERLAY:
g_Config.bTexFmtOverlayEnable = m_TexFmtOverlay->IsChecked(); g_Config.bTexFmtOverlayEnable = m_TexFmtOverlay->IsChecked();
m_TexFmtCenter->Enable(m_TexFmtOverlay->IsChecked()); m_TexFmtCenter->Enable(m_TexFmtOverlay->IsChecked());
TextureMngr::Invalidate(false); TextureCache::Invalidate(false);
break; break;
case ID_TEXFMTCENTER: case ID_TEXFMTCENTER:
g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked(); g_Config.bTexFmtOverlayCenter = m_TexFmtCenter->IsChecked();
TextureMngr::Invalidate(false); TextureCache::Invalidate(false);
break; break;
case ID_SHOWEFBCOPYREGIONS: case ID_SHOWEFBCOPYREGIONS:
g_Config.bShowEFBCopyRegions = m_ShowEFBCopyRegions->IsChecked(); g_Config.bShowEFBCopyRegions = m_ShowEFBCopyRegions->IsChecked();

View File

@ -27,4 +27,4 @@
// A global plugin specification // A global plugin specification
extern PLUGIN_GLOBALS* globals; extern PLUGIN_GLOBALS* globals;
#endif // _GLOBALS_H_ #endif // _GLOBALS_H_

View File

@ -43,6 +43,15 @@ bool PixelShaderCache::ShaderEnabled;
static FRAGMENTSHADER* pShaderLast = NULL; static FRAGMENTSHADER* pShaderLast = NULL;
GLuint PixelShaderCache::GetDepthMatrixProgram()
{
return s_DepthMatrixProgram;
}
GLuint PixelShaderCache::GetColorMatrixProgram()
{
return s_ColorMatrixProgram;
}
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{ {
@ -174,18 +183,7 @@ void PixelShaderCache::Shutdown()
pshaders.clear(); pshaders.clear();
} }
GLuint PixelShaderCache::GetColorMatrixProgram() FRAGMENTSHADER* PixelShaderCache::SetShader(bool dstAlphaEnable,u32 components)
{
return s_ColorMatrixProgram;
}
GLuint PixelShaderCache::GetDepthMatrixProgram()
{
return s_DepthMatrixProgram;
}
FRAGMENTSHADER* PixelShaderCache::GetShader(bool dstAlphaEnable,u32 components)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
PIXELSHADERUID uid; PIXELSHADERUID uid;

View File

@ -71,7 +71,7 @@ public:
static void Init(); static void Init();
static void Shutdown(); static void Shutdown();
static FRAGMENTSHADER* GetShader(bool dstAlphaEnable,u32 components); static FRAGMENTSHADER* SetShader(bool dstAlphaEnable,u32 components);
static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram); static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
static GLuint GetColorMatrixProgram(); static GLuint GetColorMatrixProgram();

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ files = [
'BPFunctions.cpp', 'BPFunctions.cpp',
'RasterFont.cpp', 'RasterFont.cpp',
'Render.cpp', 'Render.cpp',
'TextureMngr.cpp', 'TextureCache.cpp',
'NativeVertexFormat.cpp', 'NativeVertexFormat.cpp',
'PixelShaderCache.cpp', 'PixelShaderCache.cpp',
'VertexShaderCache.cpp', 'VertexShaderCache.cpp',

View File

@ -18,9 +18,7 @@
#include <vector> #include <vector>
#include <cmath> #include <cmath>
#include "Globals.h"
#include "CommonPaths.h"
#include "StringUtil.h"
#include <fstream> #include <fstream>
#ifdef _WIN32 #ifdef _WIN32
#define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set #define _interlockedbittestandset workaround_ms_header_bug_platform_sdk6_set
@ -34,28 +32,29 @@
#undef _interlockedbittestandreset64 #undef _interlockedbittestandreset64
#endif #endif
#include "VideoConfig.h"
#include "Hash.h"
#include "Statistics.h"
#include "Profiler.h"
#include "ImageWrite.h"
#include "Render.h"
#include "MemoryUtil.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "TextureDecoder.h" #include "CommonPaths.h"
#include "TextureMngr.h" #include "FileUtil.h"
#include "FramebufferManager.h"
#include "Globals.h"
#include "Hash.h"
#include "HiresTextures.h"
#include "ImageWrite.h"
#include "MemoryUtil.h"
#include "PixelShaderCache.h" #include "PixelShaderCache.h"
#include "PixelShaderManager.h" #include "PixelShaderManager.h"
#include "VertexShaderManager.h" #include "Profiler.h"
#include "FramebufferManager.h" #include "Render.h"
#include "FileUtil.h" #include "Statistics.h"
#include "HiresTextures.h" #include "StringUtil.h"
#include "TextureCache.h"
#include "TextureConverter.h" #include "TextureConverter.h"
#include "TextureDecoder.h"
#include "VertexShaderManager.h"
#include "VideoConfig.h"
u8 *TextureMngr::temp = NULL; u8 *TextureCache::temp = NULL;
TextureMngr::TexCache TextureMngr::textures; TextureCache::TexCache TextureCache::textures;
extern int frameCount; extern int frameCount;
static u32 s_TempFramebuffer = 0; static u32 s_TempFramebuffer = 0;
@ -96,16 +95,7 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int he
return SaveTGA(filename, width, height, &data[0]); return SaveTGA(filename, width, height, &data[0]);
} }
int TextureMngr::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size) void TextureCache::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &newmode1)
{
if (addr + size_in_bytes < range_address)
return -1;
if (addr >= range_address + range_size)
return 1;
return 0;
}
void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &newmode1)
{ {
mode = newmode; mode = newmode;
mode1 = newmode1; mode1 = newmode1;
@ -134,48 +124,49 @@ void TextureMngr::TCacheEntry::SetTextureParameters(TexMode0 &newmode,TexMode1 &
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_ActiveConfig.iMaxAnisotropy)); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)(1 << g_ActiveConfig.iMaxAnisotropy));
} }
void TextureMngr::TCacheEntry::Destroy(bool shutdown) void TextureCache::TCacheEntry::Destroy(bool shutdown)
{ {
if (!texture) if (texture)
return; glDeleteTextures(1, &texture);
glDeleteTextures(1, &texture); texture = 0;
if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache) { if (!isRenderTarget && !shutdown && !g_ActiveConfig.bSafeTextureCache)
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr); {
if (ptr && *ptr == hash) u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr);
*ptr = oldpixel; if (ptr && *ptr == hash)
} *ptr = oldpixel;
texture = 0; }
} }
void TextureMngr::Init() void TextureCache::Init()
{ {
temp = (u8*)AllocateMemoryPages(TEMP_SIZE); temp = (u8*)AllocateMemoryPages(TEMP_SIZE);
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter); TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable, g_ActiveConfig.bTexFmtOverlayCenter);
HiresTextures::Init(globals->unique_id); HiresTextures::Init(globals->unique_id);
} }
void TextureMngr::Invalidate(bool shutdown) void TextureCache::Invalidate(bool shutdown)
{ {
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter) for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
iter->second.Destroy(shutdown); iter->second.Destroy(shutdown);
textures.clear(); textures.clear();
HiresTextures::Shutdown(); HiresTextures::Shutdown();
} }
void TextureMngr::Shutdown() void TextureCache::Shutdown()
{ {
Invalidate(true); Invalidate(true);
if (s_TempFramebuffer) { if (s_TempFramebuffer)
glDeleteFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer); {
s_TempFramebuffer = 0; glDeleteFramebuffersEXT(1, (GLuint *)&s_TempFramebuffer);
} s_TempFramebuffer = 0;
}
FreeMemoryPages(temp, TEMP_SIZE); FreeMemoryPages(temp, TEMP_SIZE);
temp = NULL; temp = NULL;
} }
void TextureMngr::ProgressiveCleanup() void TextureCache::Cleanup()
{ {
TexCache::iterator iter = textures.begin(); TexCache::iterator iter = textures.begin();
while (iter != textures.end()) while (iter != textures.end())
@ -186,11 +177,13 @@ void TextureMngr::ProgressiveCleanup()
textures.erase(iter++); textures.erase(iter++);
} }
else else
{
++iter; ++iter;
}
} }
} }
void TextureMngr::InvalidateRange(u32 start_address, u32 size) void TextureCache::InvalidateRange(u32 start_address, u32 size)
{ {
TexCache::iterator iter = textures.begin(); TexCache::iterator iter = textures.begin();
while (iter != textures.end()) while (iter != textures.end())
@ -201,14 +194,14 @@ void TextureMngr::InvalidateRange(u32 start_address, u32 size)
iter->second.Destroy(false); iter->second.Destroy(false);
textures.erase(iter++); textures.erase(iter++);
} }
else else
{ {
++iter; ++iter;
} }
} }
} }
void TextureMngr::MakeRangeDynamic(u32 start_address, u32 size) void TextureCache::MakeRangeDynamic(u32 start_address, u32 size)
{ {
TexCache::iterator iter = textures.begin(); TexCache::iterator iter = textures.begin();
while (iter != textures.end()) while (iter != textures.end())
@ -222,8 +215,16 @@ void TextureMngr::MakeRangeDynamic(u32 start_address, u32 size)
} }
} }
int TextureCache::TCacheEntry::IntersectsMemoryRange(u32 range_address, u32 range_size)
{
if (addr + size_in_bytes < range_address)
return -1;
if (addr >= range_address + range_size)
return 1;
return 0;
}
TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width, int height, u32 tex_format, int tlutaddr, int tlutfmt) TextureCache::TCacheEntry* TextureCache::Load(int texstage, u32 address, int width, int height, u32 tex_format, int tlutaddr, int tlutfmt)
{ {
// notes (about "UNsafe texture cache"): // notes (about "UNsafe texture cache"):
// Have to be removed soon. // Have to be removed soon.
@ -250,31 +251,32 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
// Wonder if we can't use tex width&height to know if EFB might be copied to it... // Wonder if we can't use tex width&height to know if EFB might be copied to it...
// raw idea: TOCHECK if addresses are aligned we have few bits left... // raw idea: TOCHECK if addresses are aligned we have few bits left...
if (address == 0) if (address == 0)
return NULL; return NULL;
TexMode0 &tm0 = bpmem.tex[texstage >> 2].texMode0[texstage & 3]; TexMode0 &tm0 = bpmem.tex[texstage >> 2].texMode0[texstage & 3];
TexMode1 &tm1 = bpmem.tex[texstage >> 2].texMode1[texstage & 3]; TexMode1 &tm1 = bpmem.tex[texstage >> 2].texMode1[texstage & 3];
int maxlevel = (tm1.max_lod >> 4); int maxlevel = (tm1.max_lod >> 4);
bool UseNativeMips = (tm0.min_filter & 3) && (tm0.min_filter != 8) && g_ActiveConfig.bUseNativeMips; bool UseNativeMips = (tm0.min_filter & 3) && (tm0.min_filter != 8) && g_ActiveConfig.bUseNativeMips;
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address); u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; int bsw = TexDecoder_GetBlockWidthInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; int bsh = TexDecoder_GetBlockHeightInTexels(tex_format) - 1; // TexelSizeInNibbles(format)*width*height/16;
int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format); int bsdepth = TexDecoder_GetTexelSizeInNibbles(tex_format);
int expandedWidth = (width + bsw) & (~bsw); int expandedWidth = (width + bsw) & (~bsw);
int expandedHeight = (height + bsh) & (~bsh); int expandedHeight = (height + bsh) & (~bsh);
u64 hash_value = 0; u64 hash_value = 0;
u32 texID = address; u32 texID = address;
u64 texHash = 0; u64 texHash = 0;
u32 FullFormat = tex_format; u32 FullFormat = tex_format;
bool TextureisDynamic = false; bool TextureisDynamic = false;
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
FullFormat = (tex_format | (tlutfmt << 16)); FullFormat = (tex_format | (tlutfmt << 16));
if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures) if (g_ActiveConfig.bSafeTextureCache || g_ActiveConfig.bHiresTextures || g_ActiveConfig.bDumpTextures)
{ {
texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples); texHash = GetHash64(ptr,TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format),g_ActiveConfig.iSafeTextureCache_ColorSamples);
if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2)) if ((tex_format == GX_TF_C4) || (tex_format == GX_TF_C8) || (tex_format == GX_TF_C14X2))
{ {
// WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up) // WARNING! texID != address now => may break CopyRenderTargetToTexture (cf. TODO up)
@ -300,7 +302,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
if (iter != textures.end()) if (iter != textures.end())
{ {
TCacheEntry &entry = iter->second; TCacheEntry &entry = iter->second;
if (!g_ActiveConfig.bSafeTextureCache) if (!g_ActiveConfig.bSafeTextureCache)
{ {
@ -334,63 +336,62 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
} }
} }
} }
if (((entry.isRenderTarget || entry.isDynamic) && hash_value == entry.hash && address == entry.addr)
if (((entry.isRenderTarget || entry.isDynamic) && hash_value == entry.hash && address == entry.addr)
|| ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt) && entry.MipLevels >= maxlevel)) || ((address == entry.addr) && (hash_value == entry.hash) && ((int) FullFormat == entry.fmt) && entry.MipLevels >= maxlevel))
{ {
entry.frameCount = frameCount; entry.frameCount = frameCount;
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, entry.texture); glBindTexture(GL_TEXTURE_2D, entry.texture);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
entry.SetTextureParameters(tm0,tm1); entry.SetTextureParameters(tm0,tm1);
entry.isDynamic = false; entry.isDynamic = false;
return &entry; return &entry;
} }
else else
{ {
// Let's reload the new texture data into the same texture, // Let's reload the new texture data into the same texture,
// instead of destroying it and having to create a new one. // instead of destroying it and having to create a new one.
// Might speed up movie playback very, very slightly. // Might speed up movie playback very, very slightly.
TextureisDynamic = (entry.isRenderTarget || entry.isDynamic) && !g_ActiveConfig.bCopyEFBToTexture; TextureisDynamic = (entry.isRenderTarget || entry.isDynamic) && !g_ActiveConfig.bCopyEFBToTexture;
if (((!(entry.isRenderTarget || entry.isDynamic) && width == entry.w && height == entry.h && (int)FullFormat == entry.fmt) || if (((!(entry.isRenderTarget || entry.isDynamic) && width == entry.w && height == entry.h && (int)FullFormat == entry.fmt) ||
((entry.isRenderTarget || entry.isDynamic) && entry.w == width && entry.h == height && entry.Scaledw == width && entry.Scaledh == height))) ((entry.isRenderTarget || entry.isDynamic) && entry.w == width && entry.h == height && entry.Scaledw == width && entry.Scaledh == height)))
{ {
glBindTexture(GL_TEXTURE_2D, entry.texture); glBindTexture(GL_TEXTURE_2D, entry.texture);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
entry.SetTextureParameters(tm0,tm1); entry.SetTextureParameters(tm0,tm1);
skip_texture_create = true; skip_texture_create = true;
} }
else else
{ {
entry.Destroy(false); entry.Destroy(false);
textures.erase(iter); textures.erase(iter);
} }
} }
} }
//Make an entry in the table // Make an entry in the table
TCacheEntry& entry = textures[texID]; TCacheEntry& entry = textures[texID];
entry.isDynamic = TextureisDynamic; entry.isDynamic = TextureisDynamic;
entry.isRenderTarget = false; entry.isRenderTarget = false;
PC_TexFormat dfmt = PC_TEX_FMT_NONE; PC_TexFormat pcfmt = PC_TEX_FMT_NONE;
if (g_ActiveConfig.bHiresTextures) if (g_ActiveConfig.bHiresTextures)
{ {
//Load Custom textures // Load Custom textures
char texPathTemp[MAX_PATH]; char texPathTemp[MAX_PATH];
sprintf(texPathTemp, "%s_%08x_%i", globals->unique_id, (unsigned int) texHash, tex_format); sprintf(texPathTemp, "%s_%08x_%i", globals->unique_id, (unsigned int) texHash, tex_format);
dfmt = HiresTextures::GetHiresTex(texPathTemp, &width, &height, tex_format, temp); pcfmt = HiresTextures::GetHiresTex(texPathTemp, &width, &height, tex_format, temp);
if (dfmt != PC_TEX_FMT_NONE) if (pcfmt != PC_TEX_FMT_NONE)
{ {
expandedWidth = width; expandedWidth = width;
expandedHeight = height; expandedHeight = height;
} }
} }
if (dfmt == PC_TEX_FMT_NONE) if (pcfmt == PC_TEX_FMT_NONE)
dfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt); pcfmt = TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
entry.oldpixel = ((u32 *)ptr)[0]; entry.oldpixel = ((u32 *)ptr)[0];
@ -402,8 +403,8 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
((u32 *)ptr)[0] = entry.hash; ((u32 *)ptr)[0] = entry.hash;
} }
entry.addr = address; entry.addr = address;
entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format); entry.size_in_bytes = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, tex_format);
GLenum target = GL_TEXTURE_2D; GLenum target = GL_TEXTURE_2D;
if (!skip_texture_create) { if (!skip_texture_create) {
@ -413,8 +414,8 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
bool isPow2 = !((width & (width - 1)) || (height & (height - 1))); bool isPow2 = !((width & (width - 1)) || (height & (height - 1)));
int TexLevels = (width > height)?width:height; int TexLevels = (width > height)?width:height;
TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2))+ 1 : (isPow2? 0 : 1); TexLevels = (isPow2 && UseNativeMips && (maxlevel > 0)) ? (int)(log((double)TexLevels)/log((double)2)) + 1 : (isPow2? 0 : 1);
if(TexLevels > (maxlevel + 1) && maxlevel > 0) if(TexLevels > (maxlevel + 1) && maxlevel > 0)
TexLevels = (maxlevel + 1); TexLevels = (maxlevel + 1);
entry.MipLevels = maxlevel; entry.MipLevels = maxlevel;
bool GenerateMipmaps = TexLevels > 1 || TexLevels == 0; bool GenerateMipmaps = TexLevels > 1 || TexLevels == 0;
@ -423,13 +424,13 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
int gl_iformat = 0; int gl_iformat = 0;
int gl_type = 0; int gl_type = 0;
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
if (dfmt != PC_TEX_FMT_DXT1) if (pcfmt != PC_TEX_FMT_DXT1)
{ {
switch (dfmt) switch (pcfmt)
{ {
default: default:
case PC_TEX_FMT_NONE: case PC_TEX_FMT_NONE:
PanicAlert("Invalid PC texture format %i", dfmt); PanicAlert("Invalid PC texture format %i", pcfmt);
case PC_TEX_FMT_BGRA32: case PC_TEX_FMT_BGRA32:
gl_format = GL_BGRA; gl_format = GL_BGRA;
gl_iformat = 4; gl_iformat = 4;
@ -490,12 +491,12 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
} }
else else
{ {
glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp); glTexImage2D(target, 0, gl_iformat, width, height, 0, gl_format, gl_type, temp);
} }
} }
if (expandedWidth != width) // reset if (expandedWidth != width) // reset
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} }
else else
{ {
@ -511,7 +512,7 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
} }
} }
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
if(TexLevels > 1 && dfmt != PC_TEX_FMT_NONE) if(TexLevels > 1 && pcfmt != PC_TEX_FMT_NONE)
{ {
int level = 1; int level = 1;
int mipWidth = width >> 1; int mipWidth = width >> 1;
@ -523,8 +524,8 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
u32 currentHeight = (mipHeight > 0)? mipHeight : 1; u32 currentHeight = (mipHeight > 0)? mipHeight : 1;
expandedWidth = (currentWidth + bsw) & (~bsw); expandedWidth = (currentWidth + bsw) & (~bsw);
expandedHeight = (currentHeight + bsh) & (~bsh); expandedHeight = (currentHeight + bsh) & (~bsh);
TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt); TexDecoder_Decode(temp, ptr, expandedWidth, expandedHeight, tex_format, tlutaddr, tlutfmt);
if (dfmt != PC_TEX_FMT_DXT1) if (pcfmt != PC_TEX_FMT_DXT1)
{ {
if (expandedWidth != (int)currentWidth) if (expandedWidth != (int)currentWidth)
glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth); glPixelStorei(GL_UNPACK_ROW_LENGTH, expandedWidth);
@ -543,24 +544,25 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
mipHeight >>= 1; mipHeight >>= 1;
level++; level++;
} }
} }
entry.frameCount = frameCount; entry.frameCount = frameCount;
entry.w = width; entry.w = width;
entry.h = height; entry.h = height;
entry.Scaledw = width; entry.Scaledw = width;
entry.Scaledh = height; entry.Scaledh = height;
entry.fmt = FullFormat; entry.fmt = FullFormat;
entry.SetTextureParameters(tm0,tm1); entry.SetTextureParameters(tm0,tm1);
if (g_ActiveConfig.bDumpTextures) // dump texture to file if (g_ActiveConfig.bDumpTextures)
{ {
char szTemp[MAX_PATH]; // dump texture to file
char szTemp[MAX_PATH];
char szDir[MAX_PATH]; char szDir[MAX_PATH];
const char* uniqueId = globals->unique_id; const char* uniqueId = globals->unique_id;
static bool bCheckedDumpDir = false; static bool bCheckedDumpDir = false;
sprintf(szDir,"%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId); sprintf(szDir, "%s%s", File::GetUserPath(D_DUMPTEXTURES_IDX), uniqueId);
if(!bCheckedDumpDir) if (!bCheckedDumpDir)
{ {
if (!File::Exists(szDir) || !File::IsDirectory(szDir)) if (!File::Exists(szDir) || !File::IsDirectory(szDir))
File::CreateDir(szDir); File::CreateDir(szDir);
@ -571,15 +573,14 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
sprintf(szTemp, "%s/%s_%08x_%i.tga", szDir, uniqueId, (unsigned int) texHash, tex_format); sprintf(szTemp, "%s/%s_%08x_%i.tga", szDir, uniqueId, (unsigned int) texHash, tex_format);
if (!File::Exists(szTemp)) if (!File::Exists(szTemp))
SaveTexture(szTemp, target, entry.texture, entry.w, entry.h); SaveTexture(szTemp, target, entry.texture, entry.w, entry.h);
} }
INCSTAT(stats.numTexturesCreated); INCSTAT(stats.numTexturesCreated);
SETSTAT(stats.numTexturesAlive, textures.size()); SETSTAT(stats.numTexturesAlive, textures.size());
return &entry; return &entry;
} }
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -601,7 +602,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
{ {
switch(copyfmt) switch(copyfmt)
{ {
case 0: // Z4 case 0: // Z4
case 1: // Z8 case 1: // Z8
colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1; colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1;
break; break;
@ -817,14 +818,14 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
// Unbind texture from temporary framebuffer // Unbind texture from temporary framebuffer
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
} }
if(!g_ActiveConfig.bCopyEFBToTexture) if(!g_ActiveConfig.bCopyEFBToTexture)
{ {
textures[address].hash = TextureConverter::EncodeToRamFromTexture( textures[address].hash = TextureConverter::EncodeToRamFromTexture(
address, address,
read_texture, read_texture,
xScale, xScale,
yScale, yScale,
bFromZBuffer, bFromZBuffer,
bIsIntensityFmt, bIsIntensityFmt,
copyfmt, copyfmt,
@ -836,7 +837,7 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
g_framebufferManager.SetFramebuffer(0); g_framebufferManager.SetFramebuffer(0);
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();
TextureMngr::DisableStage(0); TextureCache::DisableStage(0);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -847,14 +848,14 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
} }
} }
void TextureMngr::DisableStage(int stage) void TextureCache::DisableStage(int stage)
{ {
glActiveTexture(GL_TEXTURE0 + stage); glActiveTexture(GL_TEXTURE0 + stage);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_RECTANGLE_ARB); glDisable(GL_TEXTURE_RECTANGLE_ARB);
} }
void TextureMngr::ClearRenderTargets() void TextureCache::ClearRenderTargets()
{ {
for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter) for (TexCache::iterator iter = textures.begin(); iter != textures.end(); ++iter)
iter->second.isRenderTarget = false; iter->second.isRenderTarget = false;

View File

@ -24,7 +24,7 @@
#include "GLUtil.h" #include "GLUtil.h"
#include "BPStructs.h" #include "BPStructs.h"
class TextureMngr class TextureCache
{ {
public: public:
struct TCacheEntry struct TCacheEntry
@ -66,7 +66,7 @@ private:
public: public:
static void Init(); static void Init();
static void ProgressiveCleanup(); static void Cleanup();
static void Shutdown(); static void Shutdown();
static void Invalidate(bool shutdown); static void Invalidate(bool shutdown);
static void InvalidateRange(u32 start_address, u32 size); static void InvalidateRange(u32 start_address, u32 size);

View File

@ -20,7 +20,7 @@
#include "TextureConverter.h" #include "TextureConverter.h"
#include "TextureConversionShader.h" #include "TextureConversionShader.h"
#include "TextureMngr.h" #include "TextureCache.h"
#include "PixelShaderCache.h" #include "PixelShaderCache.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "FramebufferManager.h" #include "FramebufferManager.h"
@ -54,7 +54,7 @@ void CreateRgbToYuyvProgram()
{ {
// Output is BGRA because that is slightly faster than RGBA. // Output is BGRA because that is slightly faster than RGBA.
const char *FProgram = const char *FProgram =
"uniform samplerRECT samp0 : register(s0);\n" "uniform samplerRECT samp0 : register(s0);\n"
"void main(\n" "void main(\n"
" out float4 ocol0 : COLOR0,\n" " out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0)\n" " in float2 uv0 : TEXCOORD0)\n"
@ -78,7 +78,7 @@ void CreateRgbToYuyvProgram()
void CreateYuyvToRgbProgram() void CreateYuyvToRgbProgram()
{ {
const char *FProgram = const char *FProgram =
"uniform samplerRECT samp0 : register(s0);\n" "uniform samplerRECT samp0 : register(s0);\n"
"void main(\n" "void main(\n"
" out float4 ocol0 : COLOR0,\n" " out float4 ocol0 : COLOR0,\n"
" in float2 uv0 : TEXCOORD0)\n" " in float2 uv0 : TEXCOORD0)\n"
@ -128,7 +128,6 @@ FRAGMENTSHADER &GetOrCreateEncodingShader(u32 format)
ERROR_LOG(VIDEO, "Failed to create encoding fragment program"); ERROR_LOG(VIDEO, "Failed to create encoding fragment program");
} }
} }
return s_encodingPrograms[format]; return s_encodingPrograms[format];
} }
@ -180,7 +179,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
for (int i = 1; i < 8; ++i) for (int i = 1; i < 8; ++i)
TextureMngr::DisableStage(i); TextureCache::DisableStage(i);
// set source texture // set source texture
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@ -216,27 +215,26 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
// .. and then readback the results. // .. and then readback the results.
// TODO: make this less slow. // TODO: make this less slow.
int writeStride = bpmem.copyMipMapStrideChannels * 32; int writeStride = bpmem.copyMipMapStrideChannels * 32;
if (writeStride != readStride && toTexture) if (writeStride != readStride && toTexture)
{ {
// writing to a texture of a different size // writing to a texture of a different size
int readHeight = readStride / dstWidth; int readHeight = readStride / dstWidth;
readHeight /= 4; // 4 bytes per pixel readHeight /= 4; // 4 bytes per pixel
int readStart = 0; int readStart = 0;
int readLoops = dstHeight / readHeight; int readLoops = dstHeight / readHeight;
for (int i = 0; i < readLoops; i++) for (int i = 0; i < readLoops; i++)
{ {
glReadPixels(0, readStart, (GLsizei)dstWidth, (GLsizei)readHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr); glReadPixels(0, readStart, (GLsizei)dstWidth, (GLsizei)readHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
readStart += readHeight;
readStart += readHeight; destAddr += writeStride;
destAddr += writeStride; }
} }
} else
else glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -273,7 +271,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
// Invalidate any existing texture covering this memory range. // Invalidate any existing texture covering this memory range.
// TODO - don't delete the texture if it already exists, just replace the contents. // TODO - don't delete the texture if it already exists, just replace the contents.
TextureMngr::InvalidateRange(address, size_in_bytes); TextureCache::InvalidateRange(address, size_in_bytes);
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1; u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1; u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
@ -303,9 +301,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
scaledSource.bottom = expandedHeight; scaledSource.bottom = expandedHeight;
scaledSource.left = 0; scaledSource.left = 0;
scaledSource.right = expandedWidth / samples; scaledSource.right = expandedWidth / samples;
int cacheBytes = 32;
int cacheBytes = 32;
if ((format & 0x0f) == 6) if ((format & 0x0f) == 6)
cacheBytes = 64; cacheBytes = 64;
@ -315,12 +311,11 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
g_framebufferManager.SetFramebuffer(0); g_framebufferManager.SetFramebuffer(0);
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
TextureMngr::DisableStage(0); TextureCache::DisableStage(0);
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
} }
u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source) u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float MValueY,bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
{ {
u32 format = copyfmt; u32 format = copyfmt;
@ -341,13 +336,13 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
if (texconv_shader.glprogid == 0) if (texconv_shader.glprogid == 0)
return 0; return 0;
u8 *dest_ptr = Memory_GetPtr(address); u8 *dest_ptr = Memory_GetPtr(address);
int width = (source.right - source.left) >> bScaleByHalf; int width = (source.right - source.left) >> bScaleByHalf;
int height = (source.bottom - source.top) >> bScaleByHalf; int height = (source.bottom - source.top) >> bScaleByHalf;
int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format); int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1; u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1; u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
u16 samples = TextureConversionShader::GetEncodedSampleCount(format); u16 samples = TextureConversionShader::GetEncodedSampleCount(format);
@ -371,28 +366,25 @@ u64 EncodeToRamFromTexture(u32 address,GLuint source_texture,float MValueX,float
scaledSource.bottom = expandedHeight; scaledSource.bottom = expandedHeight;
scaledSource.left = 0; scaledSource.left = 0;
scaledSource.right = expandedWidth / samples; scaledSource.right = expandedWidth / samples;
int cacheBytes = 32;
int cacheBytes = 32;
if ((format & 0x0f) == 6) if ((format & 0x0f) == 6)
cacheBytes = 64; cacheBytes = 64;
int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format); int readStride = (expandedWidth * cacheBytes) / TexDecoder_GetBlockWidthInTexels(format);
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer); EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, readStride, true, bScaleByHalf > 0 && !bFromZBuffer);
TextureMngr::MakeRangeDynamic(address,size_in_bytes); TextureCache::MakeRangeDynamic(address,size_in_bytes);
return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples); return GetHash64(dest_ptr,size_in_bytes,g_ActiveConfig.iSafeTextureCache_ColorSamples);
} }
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* destAddr, int dstWidth, int dstHeight)
u8* destAddr, int dstWidth, int dstHeight)
{ {
Renderer::ResetAPIState(); Renderer::ResetAPIState();
EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false); EncodeToRamUsingShader(s_rgbToYuyvProgram, srcTexture, sourceRc, destAddr, dstWidth / 2, dstHeight, 0, false, false);
g_framebufferManager.SetFramebuffer(0); g_framebufferManager.SetFramebuffer(0);
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
TextureMngr::DisableStage(0); TextureCache::DisableStage(0);
Renderer::RestoreAPIState(); Renderer::RestoreAPIState();
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
} }
@ -421,7 +413,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
GL_REPORT_FBO_ERROR(); GL_REPORT_FBO_ERROR();
for (int i = 1; i < 8; ++i) for (int i = 1; i < 8; ++i)
TextureMngr::DisableStage(i); TextureCache::DisableStage(i);
// activate source texture // activate source texture
// set srcAddr as data for source texture // set srcAddr as data for source texture
@ -457,7 +449,7 @@ void DecodeToTexture(u32 xfbAddr, int srcWidth, int srcHeight, GLuint destTextur
// reset state // reset state
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
TextureMngr::DisableStage(0); TextureCache::DisableStage(0);
VertexShaderManager::SetViewportChanged(); VertexShaderManager::SetViewportChanged();

View File

@ -29,7 +29,7 @@
#include "Render.h" #include "Render.h"
#include "ImageWrite.h" #include "ImageWrite.h"
#include "BPMemory.h" #include "BPMemory.h"
#include "TextureMngr.h" #include "TextureCache.h"
#include "PixelShaderCache.h" #include "PixelShaderCache.h"
#include "PixelShaderManager.h" #include "PixelShaderManager.h"
#include "VertexShaderCache.h" #include "VertexShaderCache.h"
@ -90,6 +90,12 @@ bool Init()
return true; return true;
} }
void ResetBuffer()
{
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
s_pCurBufferPointer = LocalVBuffer;
}
void Shutdown() void Shutdown()
{ {
delete [] LocalVBuffer; delete [] LocalVBuffer;
@ -100,73 +106,67 @@ void Shutdown()
//s_nCurVBOIndex = 0; //s_nCurVBOIndex = 0;
} }
void ResetBuffer()
{
//s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers);
s_pCurBufferPointer = LocalVBuffer;
}
void AddIndices(int primitive, int numVertices) void AddIndices(int primitive, int numVertices)
{ {
switch (primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices);break; case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break;
case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices);break; case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break;
case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break; case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break;
case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break; case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break;
case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break; case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break;
case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices);break; case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break;
case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break; case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break;
} }
} }
int GetRemainingSize() int GetRemainingSize()
{ {
return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer); return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer);
} }
int GetRemainingVertices(int primitive) int GetRemainingVertices(int primitive)
{ {
switch (primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: case GX_DRAW_QUADS:
case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLES:
case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_STRIP:
case GX_DRAW_TRIANGLE_FAN: case GX_DRAW_TRIANGLE_FAN:
return (max_Index_size - IndexGenerator::GetTriangleindexLen())/3; return (max_Index_size - IndexGenerator::GetTriangleindexLen())/3;
case GX_DRAW_LINE_STRIP: case GX_DRAW_LINE_STRIP:
case GX_DRAW_LINES: case GX_DRAW_LINES:
return (max_Index_size - IndexGenerator::GetLineindexLen())/2; return (max_Index_size - IndexGenerator::GetLineindexLen())/2;
case GX_DRAW_POINTS: case GX_DRAW_POINTS:
return (max_Index_size - IndexGenerator::GetPointindexLen()); return (max_Index_size - IndexGenerator::GetPointindexLen());
default: return 0; default: return 0;
} }
} }
void AddVertices(int primitive, int numvertices) void AddVertices(int primitive, int numVertices)
{ {
if (numvertices <= 0) if (numVertices <= 0)
return; return;
(void)GL_REPORT_ERROR(); (void)GL_REPORT_ERROR();
switch (primitive) switch (primitive)
{ {
case GX_DRAW_QUADS: case GX_DRAW_QUADS:
case GX_DRAW_TRIANGLES: case GX_DRAW_TRIANGLES:
case GX_DRAW_TRIANGLE_STRIP: case GX_DRAW_TRIANGLE_STRIP:
case GX_DRAW_TRIANGLE_FAN: case GX_DRAW_TRIANGLE_FAN:
if(max_Index_size - IndexGenerator::GetTriangleindexLen() < 3 * numvertices) if(max_Index_size - IndexGenerator::GetTriangleindexLen() < 3 * numVertices)
Flush(); Flush();
break; break;
case GX_DRAW_LINE_STRIP: case GX_DRAW_LINE_STRIP:
case GX_DRAW_LINES: case GX_DRAW_LINES:
if(max_Index_size - IndexGenerator::GetLineindexLen() < 2 * numvertices) if(max_Index_size - IndexGenerator::GetLineindexLen() < 2 * numVertices)
Flush(); Flush();
break; break;
case GX_DRAW_POINTS: case GX_DRAW_POINTS:
if(max_Index_size - IndexGenerator::GetPointindexLen() < numvertices) if(max_Index_size - IndexGenerator::GetPointindexLen() < numVertices)
Flush(); Flush();
break; break;
default: return; default: return;
} }
if(Flushed) if(Flushed)
{ {
@ -174,11 +174,9 @@ void AddVertices(int primitive, int numvertices)
Flushed=false; Flushed=false;
} }
lastPrimitive = primitive; lastPrimitive = primitive;
ADDSTAT(stats.thisFrame.numPrims, numvertices); ADDSTAT(stats.thisFrame.numPrims, numVertices);
INCSTAT(stats.thisFrame.numPrimitiveJoins); INCSTAT(stats.thisFrame.numPrimitiveJoins);
AddIndices(primitive, numvertices); AddIndices(primitive, numVertices);
} }
inline void Draw() inline void Draw()
@ -203,7 +201,7 @@ inline void Draw()
void Flush() void Flush()
{ {
if (LocalVBuffer == s_pCurBufferPointer) return; if (LocalVBuffer == s_pCurBufferPointer) return;
if(Flushed) return; if (Flushed) return;
Flushed=true; Flushed=true;
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
@ -257,7 +255,7 @@ void Flush()
if (bpmem.genMode.numindstages > 0) if (bpmem.genMode.numindstages > 0)
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i)
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt); usedtextures |= 1 << bpmem.tevindref.getTexMap(bpmem.tevind[i].bt);
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
@ -265,13 +263,14 @@ void Flush()
if (usedtextures & (1 << i)) if (usedtextures & (1 << i))
{ {
glActiveTexture(GL_TEXTURE0 + i); glActiveTexture(GL_TEXTURE0 + i);
FourTexUnits &tex = bpmem.tex[i >> 2]; FourTexUnits &tex = bpmem.tex[i >> 2];
TextureMngr::TCacheEntry* tentry = TextureMngr::Load(i, (tex.texImage3[i&3].image_base/* & 0x1FFFFF*/) << 5, TextureCache::TCacheEntry* 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].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.texImage0[i&3].format, tex.texTlut[i&3].tmem_offset<<9,
tex.texTlut[i&3].tlut_format);
if (tentry) if (tentry)
{ {
// 0s are probably for no manual wrapping needed. // 0s are probably for no manual wrapping needed.
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0); PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
@ -285,12 +284,12 @@ void Flush()
} }
} }
else else
ERROR_LOG(VIDEO, "error loading tex\n"); ERROR_LOG(VIDEO, "error loading texture");
} }
} }
FRAGMENTSHADER* ps = PixelShaderCache::GetShader(false,g_nativeVertexFmt->m_components); FRAGMENTSHADER* ps = PixelShaderCache::SetShader(false,g_nativeVertexFmt->m_components);
VERTEXSHADER* vs = VertexShaderCache::GetShader(g_nativeVertexFmt->m_components); VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
// set global constants // set global constants
VertexShaderManager::SetConstants(); VertexShaderManager::SetConstants();
@ -306,7 +305,7 @@ void Flush()
// run through vertex groups again to set alpha // run through vertex groups again to set alpha
if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate) if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
{ {
ps = PixelShaderCache::GetShader(true,g_nativeVertexFmt->m_components); ps = PixelShaderCache::SetShader(true,g_nativeVertexFmt->m_components);
if (ps)PixelShaderCache::SetCurrentShader(ps->glprogid); if (ps)PixelShaderCache::SetCurrentShader(ps->glprogid);
@ -357,4 +356,3 @@ void Flush()
} }
} // namespace } // namespace

View File

@ -93,27 +93,25 @@ void VertexShaderCache::Init()
void VertexShaderCache::Shutdown() void VertexShaderCache::Shutdown()
{ {
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++) for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); ++iter)
iter->second.Destroy(); iter->second.Destroy();
vshaders.clear(); vshaders.clear();
} }
VERTEXSHADER* VertexShaderCache::GetShader(u32 components) VERTEXSHADER* VertexShaderCache::SetShader(u32 components)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
VERTEXSHADERUID uid; VERTEXSHADERUID uid;
GetVertexShaderId(&uid, components); GetVertexShaderId(&uid, components);
if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount) if (uid == last_vertex_shader_uid && vshaders[uid].frameCount == frameCount)
{
return pShaderLast; return pShaderLast;
}
memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID)); memcpy(&last_vertex_shader_uid, &uid, sizeof(VERTEXSHADERUID));
VSCache::iterator iter = vshaders.find(uid); VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end())
if (iter != vshaders.end()) { {
iter->second.frameCount = frameCount; iter->second.frameCount = frameCount;
VSCacheEntry &entry = iter->second; VSCacheEntry &entry = iter->second;
if (&entry.shader != pShaderLast) { if (&entry.shader != pShaderLast) {
@ -224,7 +222,7 @@ void VertexShaderCache::SetCurrentShader(GLuint Shader)
if (!ShaderEnabled) if (!ShaderEnabled)
{ {
glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_VERTEX_PROGRAM_ARB);
ShaderEnabled= true; ShaderEnabled= true;
} }
if (CurrentShader != Shader) if (CurrentShader != Shader)
{ {

View File

@ -61,7 +61,7 @@ public:
static void Init(); static void Init();
static void Shutdown(); static void Shutdown();
static VERTEXSHADER* GetShader(u32 components); static VERTEXSHADER* SetShader(u32 components);
static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram); static bool CompileVertexShader(VERTEXSHADER& ps, const char* pstrprogram);
static void SetCurrentShader(GLuint Shader); static void SetCurrentShader(GLuint Shader);

View File

@ -73,7 +73,7 @@ GFXConfigDialogOGL *m_ConfigFrame = NULL;
#include "GLUtil.h" #include "GLUtil.h"
#include "Fifo.h" #include "Fifo.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "TextureMngr.h" #include "TextureCache.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "VertexLoaderManager.h" #include "VertexLoaderManager.h"
@ -109,6 +109,16 @@ static volatile u32 s_doStateRequested = FALSE;
static u32 s_efbAccessRequested = FALSE; static u32 s_efbAccessRequested = FALSE;
static volatile u32 s_FifoShuttingDown = FALSE; static volatile u32 s_FifoShuttingDown = FALSE;
static volatile struct
{
u32 xfbAddr;
FieldType field;
u32 fbWidth;
u32 fbHeight;
} s_beginFieldArgs;
static volatile EFBAccessType s_AccessEFBType;
bool IsD3D() bool IsD3D()
{ {
return false; return false;
@ -191,7 +201,8 @@ void Initialize(void *init)
// Now the window handle is written // Now the window handle is written
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle; _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
OSD::AddMessage("Dolphin OpenGL Video Plugin", 5000); OSD::AddMessage("Dolphin Direct3D9 Video Plugin.", 5000);
s_PluginInitialized = true;
} }
static volatile struct static volatile struct
@ -207,7 +218,7 @@ static void check_DoState() {
{ {
#endif #endif
// Clear all caches that touch RAM // Clear all caches that touch RAM
TextureMngr::Invalidate(false); TextureCache::Invalidate(false);
VertexLoaderManager::MarkAllDirty(); VertexLoaderManager::MarkAllDirty();
PointerWrap p(s_doStateArgs.ptr, s_doStateArgs.mode); PointerWrap p(s_doStateArgs.ptr, s_doStateArgs.mode);
@ -259,14 +270,14 @@ void Video_Prepare(void)
exit(1); exit(1);
} }
s_swapRequested = FALSE;
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
CommandProcessor::Init(); CommandProcessor::Init();
PixelEngine::Init(); PixelEngine::Init();
TextureMngr::Init(); TextureCache::Init();
BPInit(); BPInit();
VertexManager::Init(); VertexManager::Init();
@ -289,14 +300,13 @@ void Video_Prepare(void)
INFO_LOG(VIDEO, "Video plugin initialized."); INFO_LOG(VIDEO, "Video plugin initialized.");
} }
void Shutdown(void) void Shutdown()
{ {
s_PluginInitialized = false; s_PluginInitialized = false;
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_swapRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE;
DLCache::Shutdown(); DLCache::Shutdown();
Fifo_Shutdown(); Fifo_Shutdown();
PostProcessing::Shutdown(); PostProcessing::Shutdown();
@ -310,7 +320,7 @@ void Shutdown(void)
PixelShaderManager::Shutdown(); PixelShaderManager::Shutdown();
PixelShaderCache::Shutdown(); PixelShaderCache::Shutdown();
VertexManager::Shutdown(); VertexManager::Shutdown();
TextureMngr::Shutdown(); TextureCache::Shutdown();
OpcodeDecoder_Shutdown(); OpcodeDecoder_Shutdown();
Renderer::Shutdown(); Renderer::Shutdown();
OpenGL_Shutdown(); OpenGL_Shutdown();
@ -325,35 +335,14 @@ void Video_EnterLoop()
void Video_ExitLoop() void Video_ExitLoop()
{ {
Fifo_ExitLoop(); Fifo_ExitLoop();
s_FifoShuttingDown = TRUE; s_FifoShuttingDown = TRUE;
} }
// Screenshot and screen message
void Video_Screenshot(const char *_szFilename)
{
Renderer::SetScreenshot(_szFilename);
}
void Video_AddMessage(const char* pstr, u32 milliseconds)
{
OSD::AddMessage(pstr, milliseconds);
}
void Video_SetRendering(bool bEnabled) void Video_SetRendering(bool bEnabled)
{ {
Fifo_SetRendering(bEnabled); Fifo_SetRendering(bEnabled);
} }
static volatile struct
{
u32 xfbAddr;
FieldType field;
u32 fbWidth;
u32 fbHeight;
} s_beginFieldArgs;
// Run from the graphics thread (from Fifo.cpp) // Run from the graphics thread (from Fifo.cpp)
void VideoFifo_CheckSwapRequest() void VideoFifo_CheckSwapRequest()
{ {
@ -388,14 +377,14 @@ void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
} }
} }
} }
// Run from the CPU thread (from VideoInterface.cpp) // Run from the CPU thread (from VideoInterface.cpp)
void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
{ {
if (s_PluginInitialized && g_ActiveConfig.bUseXFB) if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
{ {
if (g_VideoInitialize.bOnThread) if (g_VideoInitialize.bOnThread)
{ {
while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown) while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown)
@ -403,7 +392,7 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
Common::YieldCPU(); Common::YieldCPU();
} }
else else
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
s_beginFieldArgs.xfbAddr = xfbAddr; s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field; s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth; s_beginFieldArgs.fbWidth = fbWidth;
@ -418,6 +407,17 @@ void Video_EndField()
{ {
} }
void Video_AddMessage(const char* pstr, u32 milliseconds)
{
OSD::AddMessage(pstr, milliseconds);
}
// Screenshot
void Video_Screenshot(const char *_szFilename)
{
Renderer::SetScreenshot(_szFilename);
}
static struct static struct
{ {
EFBAccessType type; EFBAccessType type;
@ -446,6 +446,7 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
s_accessEFBArgs.x = x; s_accessEFBArgs.x = x;
s_accessEFBArgs.y = y; s_accessEFBArgs.y = y;
s_accessEFBArgs.Data = InputData; s_accessEFBArgs.Data = InputData;
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE); Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
if (g_VideoInitialize.bOnThread) if (g_VideoInitialize.bOnThread)
@ -496,7 +497,7 @@ void Video_PixelEngineWrite32(const u32 _Data, const u32 _Address)
PixelEngine::Write32(_Data, _Address); PixelEngine::Write32(_Data, _Address);
} }
void Video_GatherPipeBursted(void) inline void Video_GatherPipeBursted(void)
{ {
CommandProcessor::GatherPipeBursted(); CommandProcessor::GatherPipeBursted();
} }

View File

@ -15,4 +15,4 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "stdafx.h" #include "stdafx.h"

View File

@ -1,4 +1,4 @@
// Copyright (C) 2003 Dolphin Project.. // Copyright (C) 2003 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -23,4 +23,3 @@
#include <tchar.h> #include <tchar.h>
#include <windows.h> #include <windows.h>