just a bunch of random code cleanup i did on the train bored, plus a d3d implementation of NativeVertexFormat which isn't actually used yet.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1658 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard
2008-12-25 15:56:36 +00:00
parent 3fd665502e
commit dcc48d6c41
28 changed files with 948 additions and 679 deletions
+21 -20
View File
@@ -24,6 +24,7 @@
#endif
#include "Common.h"
#include "FileUtil.h"
#include "StringUtil.h"
#include "DynamicLibrary.h"
@@ -32,11 +33,10 @@ DynamicLibrary::DynamicLibrary()
library = 0;
}
std::string GetLastErrorAsString()
{
#ifdef _WIN32
LPVOID lpMsgBuf = 0;
LPVOID lpMsgBuf = 0;
DWORD error = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
@@ -64,13 +64,11 @@ std::string GetLastErrorAsString()
#endif
}
// ------------------------------------------------------------------
/* Loading means loading the dll with LoadLibrary() to get an instance to the dll.
This is done when Dolphin is started to determine which dlls are good, and
before opening the Config and Debugging windows from Plugin.cpp and
before opening the dll for running the emulation in Video_...cpp in Core. */
// -----------------------
// Loading means loading the dll with LoadLibrary() to get an instance to the dll.
// This is done when Dolphin is started to determine which dlls are good, and
// before opening the Config and Debugging windows from Plugin.cpp and
// before opening the dll for running the emulation in Video_...cpp in Core.
// Since this is fairly slow, TODO: think about implementing some sort of cache.
int DynamicLibrary::Load(const char* filename)
{
if (!filename || strlen(filename) == 0)
@@ -80,7 +78,6 @@ int DynamicLibrary::Load(const char* filename)
return 0;
}
LOG(MASTER_LOG, "Trying to load library %s", filename);
if (IsLoaded())
{
LOG(MASTER_LOG, "Trying to load already loaded library %s", filename);
@@ -93,9 +90,17 @@ int DynamicLibrary::Load(const char* filename)
library = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
#endif
if (!library) {
if (!library)
{
LOG(MASTER_LOG, "Error loading DLL %s: %s", filename, GetLastErrorAsString().c_str());
PanicAlert("Error loading DLL %s: %s\n", filename, GetLastErrorAsString().c_str());
if (File::Exists(filename))
{
PanicAlert("Error loading DLL %s: %s\n\nAre you missing SDL.DLL or another file that this plugin may depend on?", filename, GetLastErrorAsString().c_str());
}
else
{
PanicAlert("Error loading DLL %s: %s\n", filename, GetLastErrorAsString().c_str());
}
return 0;
}
@@ -108,11 +113,9 @@ int DynamicLibrary::Unload()
{
int retval;
if (!IsLoaded()) {
LOG(MASTER_LOG, "Error unloading DLL %s: not loaded", library_file.c_str());
PanicAlert("Error unloading DLL %s: not loaded", library_file.c_str());
return 0;
}
#ifdef _WIN32
retval = FreeLibrary(library);
@@ -120,8 +123,6 @@ int DynamicLibrary::Unload()
retval = dlclose(library)?0:1;
#endif
if (!retval) {
LOG(MASTER_LOG, "Error unloading DLL %s: %s", library_file.c_str(),
GetLastErrorAsString().c_str());
PanicAlert("Error unloading DLL %s: %s", library_file.c_str(),
GetLastErrorAsString().c_str());
}
@@ -135,8 +136,8 @@ void* DynamicLibrary::Get(const char* funcname) const
void* retval;
if (!library)
{
LOG(MASTER_LOG, "Can't find function %s - Library not loaded.");
PanicAlert("Can't find function %s - Library not loaded.");
PanicAlert("Can't find function %s - Library not loaded.");
return NULL;
}
#ifdef _WIN32
retval = GetProcAddress(library, funcname);
@@ -145,8 +146,8 @@ void* DynamicLibrary::Get(const char* funcname) const
#endif
if (!retval) {
LOG(MASTER_LOG, "Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
PanicAlert("Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
LOG(MASTER_LOG, "Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
PanicAlert("Symbol %s missing in %s (error: %s)\n", funcname, library_file.c_str(), GetLastErrorAsString().c_str());
}
return retval;
+12 -12
View File
@@ -24,23 +24,23 @@
#include <string>
// Abstracts the (few) differences between dynamically loading DLLs under Windows
// and .so / .dylib under Linux/MacOSX.
class DynamicLibrary
{
public:
public:
DynamicLibrary();
int Load(const char *filename);
int Unload();
void *Get(const char *funcname) const;
bool IsLoaded() const { return library != 0; }
DynamicLibrary();
int Load(const char* filename);
int Unload();
void* Get(const char* funcname) const;
bool IsLoaded() const {return(library != 0);}
private:
std::string library_file;
private:
std::string library_file;
#ifdef _WIN32
HINSTANCE library;
HINSTANCE library;
#else
void* library;
void *library;
#endif
};
+29 -29
View File
@@ -24,44 +24,44 @@ bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no);
static MsgAlertHandler msg_handler = DefaultMsgHandler;
void RegisterMsgAlertHandler(MsgAlertHandler handler) {
msg_handler = handler;
void RegisterMsgAlertHandler(MsgAlertHandler handler)
{
msg_handler = handler;
}
bool MsgAlert(const char* caption, bool yes_no,
const char* format, ...) {
char buffer[2048];
va_list args;
bool ret = false;
bool MsgAlert(const char* caption, bool yes_no, const char* format, ...)
{
char buffer[2048];
va_list args;
bool ret = false;
va_start(args, format);
CharArrayFromFormatV(buffer, 2048, format, args);
va_start(args, format);
CharArrayFromFormatV(buffer, 2048, format, args);
LOG(MASTER_LOG, "%s: %s", caption, buffer);
LOG(MASTER_LOG, "%s: %s", caption, buffer);
if (msg_handler) {
ret = msg_handler(caption, buffer, yes_no);
}
va_end(args);
return ret;
if (msg_handler)
{
ret = msg_handler(caption, buffer, yes_no);
}
va_end(args);
return ret;
}
bool DefaultMsgHandler(const char* caption, const char* text,
bool yes_no) {
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no)
{
#ifdef _WIN32
if (yes_no)
return IDYES == MessageBox(0, text, caption,
MB_ICONQUESTION | MB_YESNO);
else {
MessageBox(0, text, caption, MB_ICONWARNING);
return true;
}
if (yes_no)
return IDYES == MessageBox(0, text, caption,
MB_ICONQUESTION | MB_YESNO);
else {
MessageBox(0, text, caption, MB_ICONWARNING);
return true;
}
#else
printf("%s\n", text);
return true;
printf("%s\n", text);
return true;
#endif
}
+9 -9
View File
@@ -74,7 +74,7 @@ CEXIIPL::CEXIIPL() :
}
else
{
PanicAlert("Error: failed to load font_ansi.bin. Fonts may bug");
PanicAlert("Error: failed to load font_ansi.bin.\nFonts in a few games may not work, or crash the game.");
}
pStream = fopen(FONT_SJIS_FILE, "rb");
@@ -89,7 +89,8 @@ CEXIIPL::CEXIIPL() :
}
else
{
PanicAlert("Error: failed to load font_sjis.bin. Fonts may bug");
// Heh, BIOS fonts don't really work in JAP games anyway ... we get bogus characters.
PanicAlert("Error: failed to load font_sjis.bin.\nFonts in a few Japanese games may not work or crash the game.");
}
memcpy(m_pIPL, iplver, sizeof(iplver));
@@ -120,7 +121,6 @@ CEXIIPL::~CEXIIPL()
if (m_count > 0)
{
m_szBuffer[m_count] = 0x00;
//MessageBox(NULL, m_szBuffer, "last message", MB_OK);
}
if (m_pIPL != NULL)
@@ -130,19 +130,19 @@ CEXIIPL::~CEXIIPL()
}
// SRAM
FILE* pStream = NULL;
pStream = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb");
if (pStream != NULL)
FILE *file = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb");
if (file)
{
fwrite(m_SRAM, 1, 64, pStream);
fclose(pStream);
fwrite(m_SRAM, 1, 64, file);
fclose(file);
}
}
void CEXIIPL::SetCS(int _iCS)
{
if (_iCS)
{ // cs transition to high
{
// cs transition to high
m_uPosition = 0;
}
}
+1 -4
View File
@@ -63,10 +63,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0];
if (accessType == 8) //Rule out DEP
{
if (PowerPC::state == PowerPC::CPU_POWERDOWN)
return EXCEPTION_CONTINUE_SEARCH;
MessageBox(0, _T("Tried to execute code that's not marked executable. This is likely a JIT bug.\n"), 0, 0);
return EXCEPTION_CONTINUE_SEARCH;
return (DWORD)EXCEPTION_CONTINUE_SEARCH;
}
//Where in the x86 code are we?
+8 -5
View File
@@ -58,7 +58,7 @@ CPluginManager::~CPluginManager()
// ----------------------------------------
// Create list of avaliable plugins
// Create list of available plugins
// -------------
void CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
{
@@ -145,10 +145,11 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
//int ret = PluginVideo::LoadPlugin(_rFilename);
//int ret = PluginDSP::LoadPlugin(_rFilename);
if(Type)
if (Type)
{
//Common::CPlugin::Debug((HWND)_Parent);
if(!PluginVideo::IsLoaded()) PluginVideo::LoadPlugin(_rFilename);
if (!PluginVideo::IsLoaded())
PluginVideo::LoadPlugin(_rFilename);
PluginVideo::Debug((HWND)_Parent, Show);
}
else
@@ -162,7 +163,6 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
//m_DllDebugger(NULL);
}
// ----------------------------------------
// Get dll info
// -------------
@@ -179,6 +179,9 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
Common::CPlugin::Release();
}
/*
The DLL loading code provides enough error messages already. Possibly make some return codes
and handle messages here instead?
else
{
if (!File::Exists(_rFileName)) {
@@ -186,7 +189,7 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
} else {
PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName);
}
}
}*/
}
@@ -89,14 +89,16 @@ struct PortableVertexDeclaration
// all the data loading code must always be made compatible.
class NativeVertexFormat
{
u8* m_compiledCode;
PortableVertexDeclaration vtx_decl;
public:
NativeVertexFormat();
~NativeVertexFormat();
protected:
NativeVertexFormat() {}
void Initialize(const PortableVertexDeclaration &vtx_decl);
void SetupVertexPointers() const;
public:
virtual ~NativeVertexFormat() {}
virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0;
virtual void SetupVertexPointers() const = 0;
static NativeVertexFormat *Create();
// TODO: move these in under private:
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.
+8
View File
@@ -20,8 +20,16 @@
#include "Common.h"
// This must be called once before calling the two conversion functions
// below.
void InitXFBConvTables();
// These implementations could likely be made considerably faster by
// reducing precision so that intermediate calculations are done in
// 15-bit precision instead of 32-bit. However, this would complicate
// the code and since we have a GPU implementation too, there really
// isn't much point.
// Converts 4:2:2 YUV (YUYV) data to 32-bit RGBA data.
void ConvertFromXFB(u32 *dst, const u8* _pXFB, int width, int height);
@@ -1201,6 +1201,10 @@
RelativePath=".\Src\DecodedVArray.h"
>
</File>
<File
RelativePath=".\Src\NativeVertexFormat.cpp"
>
</File>
<File
RelativePath=".\Src\OpcodeDecoding.cpp"
>
@@ -1273,6 +1277,14 @@
RelativePath=".\Src\PixelShader.h"
>
</File>
<File
RelativePath=".\Src\PixelShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\PixelShaderManager.h"
>
</File>
<File
RelativePath=".\Src\Render.cpp"
>
@@ -1281,14 +1293,6 @@
RelativePath=".\Src\Render.h"
>
</File>
<File
RelativePath=".\Src\ShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\ShaderManager.h"
>
</File>
<File
RelativePath=".\Src\TextureCache.cpp"
>
@@ -1317,6 +1321,14 @@
RelativePath=".\Src\VertexShader.h"
>
</File>
<File
RelativePath=".\Src\VertexShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexShaderManager.h"
>
</File>
</Filter>
<Filter
Name="D3D"
@@ -0,0 +1,145 @@
// Copyright (C) 2003-2008 Dolphin Project.
// 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
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "D3DBase.h"
#include "Profiler.h"
#include "x64Emitter.h"
#include "ABI.h"
#include "MemoryUtil.h"
#include "VertexShader.h"
#include "CPMemory.h"
#include "NativeVertexFormat.h"
class D3DVertexFormat : public NativeVertexFormat
{
PortableVertexDeclaration vtx_decl;
LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
public:
D3DVertexFormat();
~D3DVertexFormat();
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
virtual void SetupVertexPointers() const;
};
NativeVertexFormat *NativeVertexFormat::Create()
{
return new D3DVertexFormat();
}
D3DVertexFormat::D3DVertexFormat() : d3d_decl(NULL)
{
}
D3DVertexFormat::~D3DVertexFormat()
{
if (d3d_decl)
{
d3d_decl->Release();
d3d_decl = NULL;
}
}
D3DDECLTYPE VarToD3D(VarType t)
{
static const D3DDECLTYPE lookup[5] =
{
D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT3,
};
return lookup[t];
}
// TODO: Ban signed bytes as normals - not likely that ATI supports them natively.
// We probably won't see much of a speed loss, and any speed loss will be regained anyway
// when we finally compile display lists.
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{
D3DVERTEXELEMENT9 *elems = new D3DVERTEXELEMENT9[32];
memset(elems, 0, sizeof(D3DVERTEXELEMENT9) * 32);
// There's only one stream and it's 0, so the above memset takes care of that - no need to set Stream.
// Same for method.
// So, here we go. First position:
int elem_idx = 0;
elems[elem_idx].Offset = 0; // Positions are always first, at position 0.
elems[elem_idx].Type = D3DDECLTYPE_FLOAT3;
elems[elem_idx].Usage = D3DDECLUSAGE_POSITION;
++elem_idx;
for (int i = 0; i < 3; i++)
{
if (_vtx_decl.normal_offset[i] >= 0)
{
elems[elem_idx].Offset = _vtx_decl.normal_offset[i];
elems[elem_idx].Type = VarToD3D(_vtx_decl.normal_gl_type);
elems[elem_idx].Usage = D3DDECLUSAGE_NORMAL;
elems[elem_idx].UsageIndex = i;
++elem_idx;
}
}
for (int i = 0; i < 2; i++)
{
if (_vtx_decl.color_offset[i] >= 0)
{
elems[elem_idx].Offset = _vtx_decl.color_offset[i];
elems[elem_idx].Type = VarToD3D(_vtx_decl.color_gl_type);
elems[elem_idx].Usage = D3DDECLUSAGE_COLOR;
elems[elem_idx].UsageIndex = i;
++elem_idx;
}
}
for (int i = 0; i < 8; i++)
{
if (_vtx_decl.texcoord_offset[i] >= 0)
{
elems[elem_idx].Offset = _vtx_decl.texcoord_offset[i];
elems[elem_idx].Type = VarToD3D(_vtx_decl.texcoord_gl_type[i]);
elems[elem_idx].Usage = D3DDECLUSAGE_TEXCOORD;
elems[elem_idx].UsageIndex = i;
++elem_idx;
}
}
if (vtx_decl.posmtx_offset != -1)
{
// glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)vtx_decl.posmtx_offset);
elems[elem_idx].Offset = _vtx_decl.posmtx_offset;
elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES;
elems[elem_idx].UsageIndex = 0;
++elem_idx;
}
if (FAILED(D3D::dev->CreateVertexDeclaration(elems, &d3d_decl)))
{
PanicAlert("Failed to create D3D vertex declaration!");
return;
}
}
void D3DVertexFormat::SetupVertexPointers() const
{
D3D::dev->SetVertexDeclaration(d3d_decl);
}
@@ -33,7 +33,8 @@
#include "TransformEngine.h"
#include "OpcodeDecoding.h"
#include "TextureCache.h"
#include "ShaderManager.h"
#include "VertexShaderManager.h"
#include "PixelShaderManager.h"
#include "BPStructs.h"
#include "XFStructs.h"
@@ -1,218 +1,134 @@
// Copyright (C) 2003-2008 Dolphin Project.
// 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
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "D3DBase.h"
#include "Statistics.h"
#include "Utils.h"
#include "Profiler.h"
#include "ShaderManager.h"
#include "VertexLoader.h"
#include "BPMemory.h"
#include "XFMemory.h"
//I hope we don't get too many hash collisions :p
//all these magic numbers are primes, it should help a bit
tevhash GetCurrentTEV()
{
u32 hash = bpmem.genMode.numindstages + bpmem.genMode.numtevstages*11 + bpmem.genMode.numtexgens*8*17;
for (int i = 0; i < (int)bpmem.genMode.numtevstages+1; i++)
{
hash = _rotl(hash,3) ^ (bpmem.combiners[i].colorC.hex*13);
hash = _rotl(hash,7) ^ ((bpmem.combiners[i].alphaC.hex&0xFFFFFFFC)*3);
hash = _rotl(hash,9) ^ xfregs.texcoords[i].texmtxinfo.projection*451;
}
for (int i = 0; i < (int)bpmem.genMode.numtevstages/2+1; i++)
{
hash = _rotl(hash,13) ^ (bpmem.tevorders[i].hex*7);
}
for (int i = 0; i < 8; i++)
{
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap1;
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap2;
}
hash ^= bpmem.dstalpha.enable ^ 0xc0debabe;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp0*7;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp1*13;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.logic*11;
return hash;
}
PShaderCache::PSCache PShaderCache::pshaders;
VShaderCache::VSCache VShaderCache::vshaders;
void PShaderCache::Init()
{
}
void PShaderCache::Shutdown()
{
PSCache::iterator iter = pshaders.begin();
for (;iter!=pshaders.end();iter++)
iter->second.Destroy();
pshaders.clear();
}
void PShaderCache::SetShader()
{
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
static LPDIRECT3DPIXELSHADER9 lastShader = 0;
DVSTARTPROFILE();
tevhash currentHash = GetCurrentTEV();
PSCache::iterator iter;
iter = pshaders.find(currentHash);
if (iter != pshaders.end())
{
iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader)
{
D3D::dev->SetPixelShader(entry.shader);
lastShader = entry.shader;
}
return;
}
const char *code = GeneratePixelShader();
LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePShader(code, int(strlen(code)));
if (shader)
{
//Make an entry in the table
PSCacheEntry newentry;
newentry.shader = shader;
newentry.frameCount = frameCount;
pshaders[currentHash] = newentry;
}
D3D::dev->SetPixelShader(shader);
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
}
void PShaderCache::Cleanup()
{
PSCache::iterator iter;
iter = pshaders.begin();
while (iter != pshaders.end())
{
PSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount-30)
{
entry.Destroy();
iter = pshaders.erase(iter);
}
else
{
iter++;
}
}
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
}
void VShaderCache::Init()
{
}
void VShaderCache::Shutdown()
{
VSCache::iterator iter = vshaders.begin();
for (; iter != vshaders.end(); iter++)
iter->second.Destroy();
vshaders.clear();
}
void VShaderCache::SetShader()
{
static LPDIRECT3DVERTEXSHADER9 shader = NULL;
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
if (shader) {
//D3D::dev->SetVertexShader(shader);
return;
}
static LPDIRECT3DVERTEXSHADER9 lastShader = 0;
DVSTARTPROFILE();
tevhash currentHash = GetCurrentTEV();
VSCache::iterator iter;
iter = vshaders.find(currentHash);
if (iter != vshaders.end())
{
iter->second.frameCount=frameCount;
VSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader)
{
D3D::dev->SetVertexShader(entry.shader);
lastShader = entry.shader;
}
return;
}
const char *code = GenerateVertexShader();
shader = D3D::CompileVShader(code, int(strlen(code)));
if (shader)
{
//Make an entry in the table
VSCacheEntry entry;
entry.shader = shader;
entry.frameCount=frameCount;
vshaders[currentHash] = entry;
}
D3D::dev->SetVertexShader(shader);
INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
}
void VShaderCache::Cleanup()
{
for (VSCache::iterator iter=vshaders.begin(); iter!=vshaders.end();)
{
VSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount - 30)
{
entry.Destroy();
iter = vshaders.erase(iter);
}
else
{
++iter;
}
}
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
}
// Copyright (C) 2003-2008 Dolphin Project.
// 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
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "D3DBase.h"
#include "Statistics.h"
#include "Utils.h"
#include "Profiler.h"
#include "PixelShaderManager.h"
#include "VertexLoader.h"
#include "BPMemory.h"
#include "XFMemory.h"
PShaderCache::PSCache PShaderCache::pshaders;
//I hope we don't get too many hash collisions :p
//all these magic numbers are primes, it should help a bit
tevhash GetCurrentTEV()
{
u32 hash = bpmem.genMode.numindstages + bpmem.genMode.numtevstages*11 + bpmem.genMode.numtexgens*8*17;
for (int i = 0; i < (int)bpmem.genMode.numtevstages+1; i++)
{
hash = _rotl(hash,3) ^ (bpmem.combiners[i].colorC.hex*13);
hash = _rotl(hash,7) ^ ((bpmem.combiners[i].alphaC.hex&0xFFFFFFFC)*3);
hash = _rotl(hash,9) ^ xfregs.texcoords[i].texmtxinfo.projection*451;
}
for (int i = 0; i < (int)bpmem.genMode.numtevstages/2+1; i++)
{
hash = _rotl(hash,13) ^ (bpmem.tevorders[i].hex*7);
}
for (int i = 0; i < 8; i++)
{
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap1;
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap2;
}
hash ^= bpmem.dstalpha.enable ^ 0xc0debabe;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp0*7;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp1*13;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.logic*11;
return hash;
}
void PShaderCache::Init()
{
}
void PShaderCache::Shutdown()
{
PSCache::iterator iter = pshaders.begin();
for (;iter!=pshaders.end();iter++)
iter->second.Destroy();
pshaders.clear();
}
void PShaderCache::SetShader()
{
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
static LPDIRECT3DPIXELSHADER9 lastShader = 0;
DVSTARTPROFILE();
tevhash currentHash = GetCurrentTEV();
PSCache::iterator iter;
iter = pshaders.find(currentHash);
if (iter != pshaders.end())
{
iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader)
{
D3D::dev->SetPixelShader(entry.shader);
lastShader = entry.shader;
}
return;
}
const char *code = GeneratePixelShader();
LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePShader(code, int(strlen(code)));
if (shader)
{
//Make an entry in the table
PSCacheEntry newentry;
newentry.shader = shader;
newentry.frameCount = frameCount;
pshaders[currentHash] = newentry;
}
D3D::dev->SetPixelShader(shader);
INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
}
void PShaderCache::Cleanup()
{
PSCache::iterator iter;
iter = pshaders.begin();
while (iter != pshaders.end())
{
PSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount-30)
{
entry.Destroy();
iter = pshaders.erase(iter);
}
else
{
iter++;
}
}
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
}
@@ -1,97 +1,64 @@
// Copyright (C) 2003-2008 Dolphin Project.
// 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
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#pragma once
#include "D3DBase.h"
#include <map>
#include "PixelShader.h"
#include "VertexShader.h"
typedef u32 tevhash;
tevhash GetCurrentTEV();
class PShaderCache
{
struct PSCacheEntry
{
LPDIRECT3DPIXELSHADER9 shader;
//CGPShader shader;
int frameCount;
PSCacheEntry()
{
shader=0;
frameCount=0;
}
void Destroy()
{
if (shader)
shader->Release();
}
};
typedef std::map<tevhash,PSCacheEntry> PSCache;
static PSCache pshaders;
public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader();
};
class VShaderCache
{
struct VSCacheEntry
{
LPDIRECT3DVERTEXSHADER9 shader;
//CGVShader shader;
int frameCount;
VSCacheEntry()
{
shader=0;
frameCount=0;
}
void Destroy()
{
if (shader)
shader->Release();
}
};
typedef std::map<tevhash,VSCacheEntry> VSCache;
static VSCache vshaders;
public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader();
};
void InitCG();
void ShutdownCG();
// Copyright (C) 2003-2008 Dolphin Project.
// 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
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _PIXELSHADERMANAGER_H
#define _PIXELSHADERMANAGER_H
#include "D3DBase.h"
#include <map>
#include "PixelShader.h"
#include "VertexShader.h"
typedef u32 tevhash;
tevhash GetCurrentTEV();
class PShaderCache
{
struct PSCacheEntry
{
LPDIRECT3DPIXELSHADER9 shader;
//CGPShader shader;
int frameCount;
PSCacheEntry()
{
shader = 0;
frameCount = 0;
}
void Destroy()
{
if (shader)
shader->Release();
}
};
typedef std::map<tevhash, PSCacheEntry> PSCache;
static PSCache pshaders;
public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader();
};
#endif // _PIXELSHADERMANAGER_H
+23 -30
View File
@@ -29,7 +29,8 @@
#include "XFStructs.h"
#include "D3DPostprocess.h"
#include "D3DUtil.h"
#include "ShaderManager.h"
#include "VertexShaderManager.h"
#include "PixelShaderManager.h"
#include "TextureCache.h"
#include "Utils.h"
#include "EmuWindow.h"
@@ -171,7 +172,8 @@ void Renderer::ReinitView()
xScale = width/640.0f;
yScale = height/480.0f;
RECT rc = {
RECT rc =
{
(LONG)(m_x*xScale), (LONG)(m_y*yScale), (LONG)(m_width*xScale), (LONG)(m_height*yScale)
};
}
@@ -198,24 +200,24 @@ void Renderer::SwapBuffers(void)
{
char st[2048];
char *p = st;
p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated);
p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive);
p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated);
p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive);
p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated);
p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive);
p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled);
p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated);
p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive);
p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims);
p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims);
p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads);
p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads);
p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads);
p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
p+=sprintf(p,"textures created: %i\n",stats.numTexturesCreated);
p+=sprintf(p,"textures alive: %i\n",stats.numTexturesAlive);
p+=sprintf(p,"pshaders created: %i\n",stats.numPixelShadersCreated);
p+=sprintf(p,"pshaders alive: %i\n",stats.numPixelShadersAlive);
p+=sprintf(p,"vshaders created: %i\n",stats.numVertexShadersCreated);
p+=sprintf(p,"vshaders alive: %i\n",stats.numVertexShadersAlive);
p+=sprintf(p,"dlists called: %i\n",stats.numDListsCalled);
p+=sprintf(p,"dlists created: %i\n",stats.numDListsCreated);
p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);
p+=sprintf(p,"XF loads: %i\n",stats.thisFrame.numXFLoads);
p+=sprintf(p,"XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
p+=sprintf(p,"CP loads: %i\n",stats.thisFrame.numCPLoads);
p+=sprintf(p,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
p+=sprintf(p,"BP loads: %i\n",stats.thisFrame.numBPLoads);
p+=sprintf(p,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false);
@@ -270,7 +272,7 @@ void Renderer::SwapBuffers(void)
u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB;
// clearColor |= 0x003F003F;
// D3D::BeginFrame(true,clearColor,1.0f);
D3D::BeginFrame(false,clearColor,1.0f);
D3D::BeginFrame(false, clearColor, 1.0f);
// D3D::EnableAlphaToCoverage();
Postprocess::BeginFrame();
@@ -280,15 +282,6 @@ void Renderer::SwapBuffers(void)
D3D::font.SetRenderStates(); //compatibility with low end cards
}
void Renderer::Flush(void)
{
// render the rest of the vertex buffer
//only to be used for debugging purposes
//D3D::EndFrame();
//D3D::BeginFrame(false,0);
}
void Renderer::SetViewport(float* _Viewport)
{
Viewport* pViewport = (Viewport*)_Viewport;
+8 -10
View File
@@ -44,17 +44,15 @@ public:
static void Init(SVideoInitialize &_VideoInitialize);
static void Shutdown();
// initialize opengl standard values (like view port)
static void Initialize(void);
// must be called if the window size has changed
static void ReinitView(void);
//
// --- Render Functions ---
//
static void SwapBuffers(void);
static void Flush(void);
static float GetXScale(){return xScale;}
static float GetYScale(){return yScale;}
static float GetXScale() {return xScale;}
static float GetYScale() {return yScale;}
static void SetScissorBox(RECT &rc);
static void SetViewport(float* _Viewport);
@@ -108,8 +106,8 @@ public:
* @param pVertexStreamZeroData User memory pointer to the vertex data.
* @param VertexStreamZeroStride The number of bytes of data for each vertex.
*/
static void DrawPrimitiveUP( D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount,
const void* pVertexStreamZeroData, UINT VertexStreamZeroStride );
static void DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount,
const void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
/**
* Renders a sequence of non indexed, geometric primitives of the specified type from the current set of data input streams.
@@ -117,7 +115,7 @@ public:
* @param StartVertex Index of the first vertex to load.
* @param PrimitiveCount Number of primitives to render.
*/
static void DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount );
static void DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
};
#endif // __H_RENDER__
@@ -27,7 +27,8 @@
#include "IndexGenerator.h"
#include "BPStructs.h"
#include "XFStructs.h"
#include "ShaderManager.h"
#include "VertexShaderManager.h"
#include "PixelShaderManager.h"
#include "Utils.h"
using namespace D3D;
@@ -0,0 +1,110 @@
// Copyright (C) 2003-2008 Dolphin Project.
// 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
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <map>
#include "D3DBase.h"
#include "Statistics.h"
#include "Utils.h"
#include "Profiler.h"
#include "VertexShaderManager.h"
#include "VertexLoader.h"
#include "BPMemory.h"
#include "XFMemory.h"
VShaderCache::VSCache VShaderCache::vshaders;
void VShaderCache::Init()
{
}
void VShaderCache::Shutdown()
{
VSCache::iterator iter = vshaders.begin();
for (; iter != vshaders.end(); iter++)
iter->second.Destroy();
vshaders.clear();
}
void VShaderCache::SetShader()
{
static LPDIRECT3DVERTEXSHADER9 shader = NULL;
if (D3D::GetShaderVersion() < 2)
return; // we are screwed
if (shader) {
//D3D::dev->SetVertexShader(shader);
return;
}
static LPDIRECT3DVERTEXSHADER9 lastShader = 0;
DVSTARTPROFILE();
u32 currentHash = 0x1337; // GetCurrentTEV();
VSCache::iterator iter;
iter = vshaders.find(currentHash);
if (iter != vshaders.end())
{
iter->second.frameCount=frameCount;
VSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader)
{
D3D::dev->SetVertexShader(entry.shader);
lastShader = entry.shader;
}
return;
}
const char *code = GenerateVertexShader();
shader = D3D::CompileVShader(code, int(strlen(code)));
if (shader)
{
//Make an entry in the table
VSCacheEntry entry;
entry.shader = shader;
entry.frameCount=frameCount;
vshaders[currentHash] = entry;
}
D3D::dev->SetVertexShader(shader);
INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
}
void VShaderCache::Cleanup()
{
for (VSCache::iterator iter=vshaders.begin(); iter!=vshaders.end();)
{
VSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount - 30)
{
entry.Destroy();
iter = vshaders.erase(iter);
}
else
{
++iter;
}
}
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
}
@@ -0,0 +1,57 @@
// Copyright (C) 2003-2008 Dolphin Project.
// 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
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _VERTEXSHADERMANAGER_H
#define _VERTEXSHADERMANAGER_H
#include "D3DBase.h"
#include <map>
#include "PixelShader.h"
#include "VertexShader.h"
class VShaderCache
{
struct VSCacheEntry
{
LPDIRECT3DVERTEXSHADER9 shader;
int frameCount;
VSCacheEntry()
{
shader = 0;
frameCount = 0;
}
void Destroy()
{
if (shader)
shader->Release();
}
};
typedef std::map<u32, VSCacheEntry> VSCache;
static VSCache vshaders;
public:
static void Init();
static void Cleanup();
static void Shutdown();
static void SetShader();
};
#endif // _VERTEXSHADERMANAGER_H
@@ -461,12 +461,12 @@ void BPWritten(int addr, int changes, int newval)
}
else {
// EFB to XFB
if(g_Config.bUseXFB)
if (g_Config.bUseXFB)
{
// the number of lines copied is determined by the y scale * source efb height
float yScale = bpmem.dispcopyyscale / 256.0f;
float xfbLines = bpmem.copyTexSrcWH.y + 1.0f * yScale;
XFB_Write(Memory_GetPtr(bpmem.copyTexDest<<5), multirc, (bpmem.copyMipMapStrideChannels << 4), (int)xfbLines);
XFB_Write(Memory_GetPtr(bpmem.copyTexDest << 5), multirc, (bpmem.copyMipMapStrideChannels << 4), (int)xfbLines);
}
else
{
@@ -140,7 +140,6 @@ void UpdateFPSDisplay(const char *text)
char temp[512];
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
OpenGL_SetWindowText(temp);
}
// =======================================================================================
@@ -148,9 +147,9 @@ void UpdateFPSDisplay(const char *text)
bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight)
{
int _twidth, _theight;
if(g_Config.bFullscreen)
if (g_Config.bFullscreen)
{
if(strlen(g_Config.iFSResolution) > 1)
if (strlen(g_Config.iFSResolution) > 1)
{
sscanf(g_Config.iFSResolution, "%dx%d", &_twidth, &_theight);
}
@@ -162,7 +161,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
}
else // Going Windowed
{
if(strlen(g_Config.iWindowedRes) > 1)
if (strlen(g_Config.iWindowedRes) > 1)
{
sscanf(g_Config.iWindowedRes, "%dx%d", &_twidth, &_theight);
}
@@ -189,7 +188,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
float FactorH = 480.0f / (float)nBackbufferHeight;
float Max = (FactorW < FactorH) ? FactorH : FactorW;
if(g_Config.bStretchToFit)
if (g_Config.bStretchToFit)
{
MValueX = 1.0f / FactorW;
MValueY = 1.0f / FactorH;
@@ -608,7 +607,7 @@ void OpenGL_Update()
int height = rcWindow.bottom - rcWindow.top;
if (EmuWindow::GetParentWnd() != 0)
::MoveWindow(EmuWindow::GetWnd(), 0,0,width,height, FALSE);
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
nBackbufferWidth = width;
nBackbufferHeight = height;

Some files were not shown because too many files have changed in this diff Show More