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

View File

@ -24,6 +24,7 @@
#endif #endif
#include "Common.h" #include "Common.h"
#include "FileUtil.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "DynamicLibrary.h" #include "DynamicLibrary.h"
@ -32,7 +33,6 @@ DynamicLibrary::DynamicLibrary()
library = 0; library = 0;
} }
std::string GetLastErrorAsString() std::string GetLastErrorAsString()
{ {
#ifdef _WIN32 #ifdef _WIN32
@ -64,13 +64,11 @@ std::string GetLastErrorAsString()
#endif #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
/* Loading means loading the dll with LoadLibrary() to get an instance to the dll. // before opening the Config and Debugging windows from Plugin.cpp and
This is done when Dolphin is started to determine which dlls are good, and // before opening the dll for running the emulation in Video_...cpp in Core.
before opening the Config and Debugging windows from Plugin.cpp and // Since this is fairly slow, TODO: think about implementing some sort of cache.
before opening the dll for running the emulation in Video_...cpp in Core. */
// -----------------------
int DynamicLibrary::Load(const char* filename) int DynamicLibrary::Load(const char* filename)
{ {
if (!filename || strlen(filename) == 0) if (!filename || strlen(filename) == 0)
@ -80,7 +78,6 @@ int DynamicLibrary::Load(const char* filename)
return 0; return 0;
} }
LOG(MASTER_LOG, "Trying to load library %s", filename); LOG(MASTER_LOG, "Trying to load library %s", filename);
if (IsLoaded()) if (IsLoaded())
{ {
LOG(MASTER_LOG, "Trying to load already loaded library %s", filename); 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); library = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
#endif #endif
if (!library) { if (!library)
{
LOG(MASTER_LOG, "Error loading DLL %s: %s", filename, GetLastErrorAsString().c_str()); LOG(MASTER_LOG, "Error loading DLL %s: %s", 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()); PanicAlert("Error loading DLL %s: %s\n", filename, GetLastErrorAsString().c_str());
}
return 0; return 0;
} }
@ -108,20 +113,16 @@ int DynamicLibrary::Unload()
{ {
int retval; int retval;
if (!IsLoaded()) { 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()); PanicAlert("Error unloading DLL %s: not loaded", library_file.c_str());
return 0; return 0;
} }
#ifdef _WIN32 #ifdef _WIN32
retval = FreeLibrary(library); retval = FreeLibrary(library);
#else #else
retval = dlclose(library)?0:1; retval = dlclose(library)?0:1;
#endif #endif
if (!retval) { 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(), PanicAlert("Error unloading DLL %s: %s", library_file.c_str(),
GetLastErrorAsString().c_str()); GetLastErrorAsString().c_str());
} }
@ -135,8 +136,8 @@ void* DynamicLibrary::Get(const char* funcname) const
void* retval; void* retval;
if (!library) 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 #ifdef _WIN32
retval = GetProcAddress(library, funcname); retval = GetProcAddress(library, funcname);

View File

@ -24,16 +24,16 @@
#include <string> #include <string>
// Abstracts the (few) differences between dynamically loading DLLs under Windows
// and .so / .dylib under Linux/MacOSX.
class DynamicLibrary class DynamicLibrary
{ {
public: public:
DynamicLibrary(); DynamicLibrary();
int Load(const char *filename); int Load(const char *filename);
int Unload(); int Unload();
void *Get(const char *funcname) const; void *Get(const char *funcname) const;
bool IsLoaded() const { return library != 0; }
bool IsLoaded() const {return(library != 0);}
private: private:
std::string library_file; std::string library_file;

View File

@ -24,13 +24,13 @@ bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no);
static MsgAlertHandler msg_handler = DefaultMsgHandler; static MsgAlertHandler msg_handler = DefaultMsgHandler;
void RegisterMsgAlertHandler(MsgAlertHandler handler) { void RegisterMsgAlertHandler(MsgAlertHandler handler)
{
msg_handler = handler; msg_handler = handler;
} }
bool MsgAlert(const char* caption, bool yes_no, bool MsgAlert(const char* caption, bool yes_no, const char* format, ...)
const char* format, ...) { {
char buffer[2048]; char buffer[2048];
va_list args; va_list args;
bool ret = false; bool ret = false;
@ -40,7 +40,8 @@ bool MsgAlert(const char* caption, bool yes_no,
LOG(MASTER_LOG, "%s: %s", caption, buffer); LOG(MASTER_LOG, "%s: %s", caption, buffer);
if (msg_handler) { if (msg_handler)
{
ret = msg_handler(caption, buffer, yes_no); ret = msg_handler(caption, buffer, yes_no);
} }
@ -48,9 +49,8 @@ bool MsgAlert(const char* caption, bool yes_no,
return ret; return ret;
} }
bool DefaultMsgHandler(const char* caption, const char* text, bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no)
bool yes_no) { {
#ifdef _WIN32 #ifdef _WIN32
if (yes_no) if (yes_no)
return IDYES == MessageBox(0, text, caption, return IDYES == MessageBox(0, text, caption,

View File

@ -74,7 +74,7 @@ CEXIIPL::CEXIIPL() :
} }
else 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"); pStream = fopen(FONT_SJIS_FILE, "rb");
@ -89,7 +89,8 @@ CEXIIPL::CEXIIPL() :
} }
else 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)); memcpy(m_pIPL, iplver, sizeof(iplver));
@ -120,7 +121,6 @@ CEXIIPL::~CEXIIPL()
if (m_count > 0) if (m_count > 0)
{ {
m_szBuffer[m_count] = 0x00; m_szBuffer[m_count] = 0x00;
//MessageBox(NULL, m_szBuffer, "last message", MB_OK);
} }
if (m_pIPL != NULL) if (m_pIPL != NULL)
@ -130,19 +130,19 @@ CEXIIPL::~CEXIIPL()
} }
// SRAM // SRAM
FILE* pStream = NULL; FILE *file = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb");
pStream = fopen(Core::GetStartupParameter().m_strSRAM.c_str(), "wb"); if (file)
if (pStream != NULL)
{ {
fwrite(m_SRAM, 1, 64, pStream); fwrite(m_SRAM, 1, 64, file);
fclose(pStream); fclose(file);
} }
} }
void CEXIIPL::SetCS(int _iCS) void CEXIIPL::SetCS(int _iCS)
{ {
if (_iCS) if (_iCS)
{ // cs transition to high {
// cs transition to high
m_uPosition = 0; m_uPosition = 0;
} }
} }

View File

@ -63,10 +63,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0]; int accessType = (int)pPtrs->ExceptionRecord->ExceptionInformation[0];
if (accessType == 8) //Rule out DEP if (accessType == 8) //Rule out DEP
{ {
if (PowerPC::state == PowerPC::CPU_POWERDOWN) return (DWORD)EXCEPTION_CONTINUE_SEARCH;
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;
} }
//Where in the x86 code are we? //Where in the x86 code are we?

View File

@ -58,7 +58,7 @@ CPluginManager::~CPluginManager()
// ---------------------------------------- // ----------------------------------------
// Create list of avaliable plugins // Create list of available plugins
// ------------- // -------------
void CPluginManager::ScanForPlugins(wxWindow* _wxWindow) void CPluginManager::ScanForPlugins(wxWindow* _wxWindow)
{ {
@ -148,7 +148,8 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
if (Type) if (Type)
{ {
//Common::CPlugin::Debug((HWND)_Parent); //Common::CPlugin::Debug((HWND)_Parent);
if(!PluginVideo::IsLoaded()) PluginVideo::LoadPlugin(_rFilename); if (!PluginVideo::IsLoaded())
PluginVideo::LoadPlugin(_rFilename);
PluginVideo::Debug((HWND)_Parent, Show); PluginVideo::Debug((HWND)_Parent, Show);
} }
else else
@ -162,7 +163,6 @@ void CPluginManager::OpenDebug(void* _Parent, const char *_rFilename, bool Type,
//m_DllDebugger(NULL); //m_DllDebugger(NULL);
} }
// ---------------------------------------- // ----------------------------------------
// Get dll info // Get dll info
// ------------- // -------------
@ -179,6 +179,9 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
Common::CPlugin::Release(); Common::CPlugin::Release();
} }
/*
The DLL loading code provides enough error messages already. Possibly make some return codes
and handle messages here instead?
else else
{ {
if (!File::Exists(_rFileName)) { if (!File::Exists(_rFileName)) {
@ -186,7 +189,7 @@ CPluginInfo::CPluginInfo(const char *_rFileName)
} else { } else {
PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName); PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName);
} }
} }*/
} }

View File

@ -89,14 +89,16 @@ struct PortableVertexDeclaration
// all the data loading code must always be made compatible. // all the data loading code must always be made compatible.
class NativeVertexFormat class NativeVertexFormat
{ {
u8* m_compiledCode; protected:
PortableVertexDeclaration vtx_decl; NativeVertexFormat() {}
public:
NativeVertexFormat();
~NativeVertexFormat();
void Initialize(const PortableVertexDeclaration &vtx_decl); public:
void SetupVertexPointers() const; virtual ~NativeVertexFormat() {}
virtual void Initialize(const PortableVertexDeclaration &vtx_decl) = 0;
virtual void SetupVertexPointers() const = 0;
static NativeVertexFormat *Create();
// TODO: move these in under private: // TODO: move these in under private:
u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present. u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present.

View File

@ -20,8 +20,16 @@
#include "Common.h" #include "Common.h"
// This must be called once before calling the two conversion functions
// below.
void InitXFBConvTables(); 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. // Converts 4:2:2 YUV (YUYV) data to 32-bit RGBA data.
void ConvertFromXFB(u32 *dst, const u8* _pXFB, int width, int height); void ConvertFromXFB(u32 *dst, const u8* _pXFB, int width, int height);

View File

@ -1201,6 +1201,10 @@
RelativePath=".\Src\DecodedVArray.h" RelativePath=".\Src\DecodedVArray.h"
> >
</File> </File>
<File
RelativePath=".\Src\NativeVertexFormat.cpp"
>
</File>
<File <File
RelativePath=".\Src\OpcodeDecoding.cpp" RelativePath=".\Src\OpcodeDecoding.cpp"
> >
@ -1273,6 +1277,14 @@
RelativePath=".\Src\PixelShader.h" RelativePath=".\Src\PixelShader.h"
> >
</File> </File>
<File
RelativePath=".\Src\PixelShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\PixelShaderManager.h"
>
</File>
<File <File
RelativePath=".\Src\Render.cpp" RelativePath=".\Src\Render.cpp"
> >
@ -1281,14 +1293,6 @@
RelativePath=".\Src\Render.h" RelativePath=".\Src\Render.h"
> >
</File> </File>
<File
RelativePath=".\Src\ShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\ShaderManager.h"
>
</File>
<File <File
RelativePath=".\Src\TextureCache.cpp" RelativePath=".\Src\TextureCache.cpp"
> >
@ -1317,6 +1321,14 @@
RelativePath=".\Src\VertexShader.h" RelativePath=".\Src\VertexShader.h"
> >
</File> </File>
<File
RelativePath=".\Src\VertexShaderManager.cpp"
>
</File>
<File
RelativePath=".\Src\VertexShaderManager.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="D3D" Name="D3D"

View File

@ -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);
}

View File

@ -33,7 +33,8 @@
#include "TransformEngine.h" #include "TransformEngine.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "ShaderManager.h" #include "VertexShaderManager.h"
#include "PixelShaderManager.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"

View File

@ -19,12 +19,14 @@
#include "Statistics.h" #include "Statistics.h"
#include "Utils.h" #include "Utils.h"
#include "Profiler.h" #include "Profiler.h"
#include "ShaderManager.h" #include "PixelShaderManager.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "BPMemory.h" #include "BPMemory.h"
#include "XFMemory.h" #include "XFMemory.h"
PShaderCache::PSCache PShaderCache::pshaders;
//I hope we don't get too many hash collisions :p //I hope we don't get too many hash collisions :p
//all these magic numbers are primes, it should help a bit //all these magic numbers are primes, it should help a bit
tevhash GetCurrentTEV() tevhash GetCurrentTEV()
@ -53,9 +55,6 @@ tevhash GetCurrentTEV()
} }
PShaderCache::PSCache PShaderCache::pshaders;
VShaderCache::VSCache VShaderCache::vshaders;
void PShaderCache::Init() void PShaderCache::Init()
{ {
@ -133,86 +132,3 @@ void PShaderCache::Cleanup()
} }
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size()); 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());
}

View File

@ -15,7 +15,8 @@
// 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/
#pragma once #ifndef _PIXELSHADERMANAGER_H
#define _PIXELSHADERMANAGER_H
#include "D3DBase.h" #include "D3DBase.h"
@ -27,7 +28,6 @@ typedef u32 tevhash;
tevhash GetCurrentTEV(); tevhash GetCurrentTEV();
class PShaderCache class PShaderCache
{ {
struct PSCacheEntry struct PSCacheEntry
@ -61,37 +61,4 @@ public:
}; };
#endif // _PIXELSHADERMANAGER_H
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();

View File

@ -29,7 +29,8 @@
#include "XFStructs.h" #include "XFStructs.h"
#include "D3DPostprocess.h" #include "D3DPostprocess.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "ShaderManager.h" #include "VertexShaderManager.h"
#include "PixelShaderManager.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "Utils.h" #include "Utils.h"
#include "EmuWindow.h" #include "EmuWindow.h"
@ -171,7 +172,8 @@ void Renderer::ReinitView()
xScale = width/640.0f; xScale = width/640.0f;
yScale = height/480.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) (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 st[2048];
char *p = st; char *p = st;
p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated); p+=sprintf(p,"textures created: %i\n",stats.numTexturesCreated);
p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive); p+=sprintf(p,"textures alive: %i\n",stats.numTexturesAlive);
p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated); p+=sprintf(p,"pshaders created: %i\n",stats.numPixelShadersCreated);
p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive); p+=sprintf(p,"pshaders alive: %i\n",stats.numPixelShadersAlive);
p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated); p+=sprintf(p,"vshaders created: %i\n",stats.numVertexShadersCreated);
p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive); p+=sprintf(p,"vshaders alive: %i\n",stats.numVertexShadersAlive);
p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled); p+=sprintf(p,"dlists called: %i\n",stats.numDListsCalled);
p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated); p+=sprintf(p,"dlists created: %i\n",stats.numDListsCreated);
p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive); p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims); p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins); p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims); p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);
p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads); p+=sprintf(p,"XF loads: %i\n",stats.thisFrame.numXFLoads);
p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL); p+=sprintf(p,"XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads); p+=sprintf(p,"CP loads: %i\n",stats.thisFrame.numCPLoads);
p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL); p+=sprintf(p,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads); p+=sprintf(p,"BP loads: %i\n",stats.thisFrame.numBPLoads);
p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL); p+=sprintf(p,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false); D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false);
@ -280,15 +282,6 @@ void Renderer::SwapBuffers(void)
D3D::font.SetRenderStates(); //compatibility with low end cards 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) void Renderer::SetViewport(float* _Viewport)
{ {
Viewport* pViewport = (Viewport*)_Viewport; Viewport* pViewport = (Viewport*)_Viewport;

View File

@ -44,15 +44,13 @@ public:
static void Init(SVideoInitialize &_VideoInitialize); static void Init(SVideoInitialize &_VideoInitialize);
static void Shutdown(); static void Shutdown();
// initialize opengl standard values (like view port)
static void Initialize(void); static void Initialize(void);
// must be called if the window size has changed // must be called if the window size has changed
static void ReinitView(void); static void ReinitView(void);
//
// --- Render Functions ---
//
static void SwapBuffers(void); static void SwapBuffers(void);
static void Flush(void);
static float GetXScale() {return xScale;} static float GetXScale() {return xScale;}
static float GetYScale() {return yScale;} static float GetYScale() {return yScale;}

View File

@ -27,7 +27,8 @@
#include "IndexGenerator.h" #include "IndexGenerator.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "ShaderManager.h" #include "VertexShaderManager.h"
#include "PixelShaderManager.h"
#include "Utils.h" #include "Utils.h"
using namespace D3D; using namespace D3D;

View File

@ -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());
}

View File

@ -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

View File

@ -140,7 +140,6 @@ void UpdateFPSDisplay(const char *text)
char temp[512]; char temp[512];
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text); sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
OpenGL_SetWindowText(temp); OpenGL_SetWindowText(temp);
} }
// ======================================================================================= // =======================================================================================

View File

@ -38,6 +38,17 @@
#define DEBUG_LOG(...) #define DEBUG_LOG(...)
#endif #endif
enum {
EFB_WIDTH = 640,
EFB_HEIGHT = 528,
};
enum {
XFB_WIDTH = 640,
XFB_HEIGHT = 480, // 528 is max height ... ? or 538?
// TODO: figure out what to do with PAL
};
void DebugLog(const char* _fmt, ...); void DebugLog(const char* _fmt, ...);
void __Log(const char *format, ...); void __Log(const char *format, ...);
void __Log(int type, const char *format, ...); void __Log(int type, const char *format, ...);

View File

@ -48,7 +48,25 @@ DECLARE_IMPORT(glColorPointer);
DECLARE_IMPORT(glTexCoordPointer); DECLARE_IMPORT(glTexCoordPointer);
#endif #endif
NativeVertexFormat::NativeVertexFormat() class GLVertexFormat : public NativeVertexFormat
{
u8 *m_compiledCode;
PortableVertexDeclaration vtx_decl;
public:
GLVertexFormat();
~GLVertexFormat();
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
virtual void SetupVertexPointers() const;
};
NativeVertexFormat *NativeVertexFormat::Create()
{
return new GLVertexFormat();
}
GLVertexFormat::GLVertexFormat()
{ {
#ifdef USE_JIT #ifdef USE_JIT
m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false); m_compiledCode = (u8 *)AllocateExecutableMemory(COMPILED_CODE_SIZE, false);
@ -58,7 +76,7 @@ NativeVertexFormat::NativeVertexFormat()
#endif #endif
} }
NativeVertexFormat::~NativeVertexFormat() GLVertexFormat::~GLVertexFormat()
{ {
#ifdef USE_JIT #ifdef USE_JIT
FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE); FreeMemoryPages(m_compiledCode, COMPILED_CODE_SIZE);
@ -72,7 +90,7 @@ inline GLuint VarToGL(VarType t)
return lookup[t]; return lookup[t];
} }
void NativeVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) void GLVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{ {
using namespace Gen; using namespace Gen;
@ -148,7 +166,7 @@ void NativeVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
this->vtx_decl = _vtx_decl; this->vtx_decl = _vtx_decl;
} }
void NativeVertexFormat::SetupVertexPointers() const { void GLVertexFormat::SetupVertexPointers() const {
// Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to // Cast a pointer to compiled code to a pointer to a function taking no parameters, through a (void *) cast first to
// get around type checking errors, and call it. // get around type checking errors, and call it.
#ifdef USE_JIT #ifdef USE_JIT

View File

@ -43,17 +43,17 @@
#include "VertexLoader.h" #include "VertexLoader.h"
#include "XFB.h" #include "XFB.h"
#include "Timer.h" #include "Timer.h"
#include "Logging/Logging.h" // for Logging()
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
#include "Debugger/Debugger.h" // for the CDebugger class #include "Debugger/Debugger.h" // for the CDebugger class
#endif #endif
#include "Logging/Logging.h" // for Logging()
#ifdef _WIN32 #ifdef _WIN32
#include "OS/Win32.h" #include "OS/Win32.h"
#else #else
#endif #endif
//#define USE_AA
#define AA_AMMOUNT 16
struct MESSAGE struct MESSAGE
{ {
MESSAGE() {} MESSAGE() {}
@ -63,31 +63,39 @@ struct MESSAGE
}; };
CGcontext g_cgcontext; CGcontext g_cgcontext;
CGprofile g_cgvProf, g_cgfProf; CGprofile g_cgvProf;
CGprofile g_cgfProf;
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
extern CDebugger* m_frame; // the debugging class extern CDebugger* m_frame; // the debugging class
#endif #endif
static int g_MaxTexWidth = 0, g_MaxTexHeight = 0;
static RasterFont* s_pfont = NULL; static RasterFont* s_pfont = NULL;
static std::list<MESSAGE> s_listMsgs; static std::list<MESSAGE> s_listMsgs;
static bool s_bFullscreen = false; static bool s_bFullscreen = false;
static bool s_bOutputCgErrors = true; static bool s_bOutputCgErrors = true;
static int nZBufferRender = 0; // if > 0, then using zbuffer render static int nZBufferRender = 0; // if > 0, then use zbuffer render, and count down.
static u32 s_uFramebuffer = 0;
static u32 s_RenderTargets[1] = {0}, s_DepthTarget = 0, s_ZBufferTarget = 0; // A framebuffer is a set of render targets: a color and a z buffer. They can be either RenderBuffers or Textures.
static GLuint s_uFramebuffer = 0;
// The size of these should be a (not necessarily even) multiple of the EFB size, 640x528, but isn't.
static GLuint s_RenderTarget = 0;
static GLuint s_DepthTarget = 0;
static GLuint s_ZBufferTarget = 0;
static bool s_bATIDrawBuffers = false;
static bool s_bHaveStencilBuffer = false;
static bool s_bATIDrawBuffers = false, s_bHaveStencilBuffer = false;
static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal; static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal;
static int s_nCurTarget = 0;
bool g_bBlendLogicOp = false; bool g_bBlendLogicOp = false;
int frameCount; int frameCount;
void HandleCgError(CGcontext ctx, CGerror err, void *appdata); void HandleCgError(CGcontext ctx, CGerror err, void *appdata);
bool Renderer::Create2() bool Renderer::Init()
{ {
bool bSuccess = true; bool bSuccess = true;
GLenum err = GL_NO_ERROR; GLenum err = GL_NO_ERROR;
@ -154,8 +162,11 @@ bool Renderer::Create2()
#endif #endif
// check the max texture width and height // check the max texture width and height
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&g_MaxTexWidth); GLint max_texture_size;
g_MaxTexHeight = g_MaxTexWidth; glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&max_texture_size);
if (max_texture_size < 1024) {
ERROR_LOG("GL_MAX_TEXTURE_SIZE too small at %i - must be at least 1024", max_texture_size);
}
GL_REPORT_ERROR(); GL_REPORT_ERROR();
if (err != GL_NO_ERROR) bSuccess = false; if (err != GL_NO_ERROR) bSuccess = false;
@ -171,13 +182,16 @@ bool Renderer::Create2()
_assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); _assert_(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
// The size of the framebuffer targets should really NOT be the size of the OpenGL viewport.
// The EFB is larger than 640x480 - in fact, it's 640x528, give or take a couple of lines.
// So the below is wrong.
int nBackbufferWidth = (int)OpenGL_GetWidth(); int nBackbufferWidth = (int)OpenGL_GetWidth();
int nBackbufferHeight = (int)OpenGL_GetHeight(); int nBackbufferHeight = (int)OpenGL_GetHeight();
// create the framebuffer targets // Create the framebuffer target
glGenTextures(ARRAYSIZE(s_RenderTargets), (GLuint *)s_RenderTargets); glGenTextures(1, (GLuint *)&s_RenderTarget);
for(u32 i = 0; i < ARRAYSIZE(s_RenderTargets); ++i) {
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[i]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
// initialize to default // initialize to default
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, nBackbufferWidth, nBackbufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, nBackbufferWidth, nBackbufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -189,18 +203,11 @@ bool Renderer::Create2()
} }
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#ifdef USE_AA
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_RenderTargets[i]);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, AA_AMMOUNT, GL_RGBA, nBackbufferWidth, nBackbufferHeight);
#endif
}
s_nCurTarget = 0;
GL_REPORT_ERROR(); GL_REPORT_ERROR();
int nMaxMRT = 0; int nMaxMRT = 0;
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *)&nMaxMRT); glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, (GLint *)&nMaxMRT);
if (nMaxMRT > 1) { if (nMaxMRT > 1) {
// create zbuffer target // create zbuffer target
glGenTextures(1, (GLuint *)&s_ZBufferTarget); glGenTextures(1, (GLuint *)&s_ZBufferTarget);
@ -216,20 +223,12 @@ bool Renderer::Create2()
} }
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#ifdef USE_AA
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_ZBufferTarget);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, AA_AMMOUNT, GL_RGBA, nBackbufferWidth, nBackbufferHeight);
#endif
} }
// create the depth buffer // create the depth buffer
glGenRenderbuffersEXT(1, (GLuint *)&s_DepthTarget); glGenRenderbuffersEXT(1, (GLuint *)&s_DepthTarget);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_DepthTarget);
#ifdef USE_AA
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, AA_AMMOUNT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight);
#else
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, nBackbufferWidth, nBackbufferHeight);
#endif
if (glGetError() != GL_NO_ERROR) { if (glGetError() != GL_NO_ERROR) {
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, nBackbufferWidth, nBackbufferHeight);
@ -241,15 +240,9 @@ bool Renderer::Create2()
GL_REPORT_ERROR(); GL_REPORT_ERROR();
// set as render targets // set as render targets
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[s_nCurTarget], 0 ); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget);
#ifdef USE_AA
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_RenderTargets[s_nCurTarget]);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_RenderTargets[s_nCurTarget]);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, s_DepthTarget);
#endif
GL_REPORT_ERROR(); GL_REPORT_ERROR();
if (s_ZBufferTarget != 0) { if (s_ZBufferTarget != 0) {
@ -278,9 +271,6 @@ bool Renderer::Create2()
s_pfont = new RasterFont(); s_pfont = new RasterFont();
SetAA(g_Config.iMultisampleMode);
GL_REPORT_ERROR();
// load the effect, find the best profiles (if any) // load the effect, find the best profiles (if any)
if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) { if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) {
ERROR_LOG("arbvp1 not supported\n"); ERROR_LOG("arbvp1 not supported\n");
@ -292,7 +282,7 @@ bool Renderer::Create2()
} }
g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX); g_cgvProf = cgGLGetLatestProfile(CG_GL_VERTEX);
g_cgfProf = cgGLGetLatestProfile(CG_GL_FRAGMENT);//CG_PROFILE_ARBFP1; g_cgfProf = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLSetOptimalOptions(g_cgvProf); cgGLSetOptimalOptions(g_cgvProf);
cgGLSetOptimalOptions(g_cgfProf); cgGLSetOptimalOptions(g_cgfProf);
@ -317,10 +307,9 @@ bool Renderer::Create2()
return false; return false;
} }
//glEnable(GL_POLYGON_OFFSET_FILL); s_RenderMode = Renderer::RM_Normal;
//glEnable(GL_POLYGON_OFFSET_LINE);
//glPolygonOffset(0, 1); if (!InitializeGL())
if (!Initialize())
return false; return false;
XFB_Init(); XFB_Init();
@ -334,26 +323,25 @@ void Renderer::Shutdown(void)
XFB_Shutdown(); XFB_Shutdown();
if (g_cgcontext != 0) { if (g_cgcontext) {
cgDestroyContext(g_cgcontext); cgDestroyContext(g_cgcontext);
g_cgcontext = 0; g_cgcontext = 0;
} }
if (s_RenderTarget) {
if (s_RenderTargets[0]) { glDeleteTextures(1, &s_RenderTarget);
glDeleteTextures(ARRAYSIZE(s_RenderTargets), (GLuint *)s_RenderTargets); s_RenderTarget = 0;
memset(s_RenderTargets, 0, sizeof(s_RenderTargets));
} }
if (s_DepthTarget) { if (s_DepthTarget) {
glDeleteRenderbuffersEXT(1, (GLuint *)&s_DepthTarget); s_DepthTarget = 0; glDeleteRenderbuffersEXT(1, &s_DepthTarget);
s_DepthTarget = 0;
} }
if (s_uFramebuffer != 0) { if (s_uFramebuffer) {
glDeleteFramebuffersEXT( 1, (GLuint *)&s_uFramebuffer); glDeleteFramebuffersEXT(1, &s_uFramebuffer);
s_uFramebuffer = 0; s_uFramebuffer = 0;
} }
} }
bool Renderer::InitializeGL()
bool Renderer::Initialize()
{ {
glStencilFunc(GL_ALWAYS, 0, 0); glStencilFunc(GL_ALWAYS, 0, 0);
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
@ -394,8 +382,6 @@ bool Renderer::Initialize()
glClientActiveTexture(GL_TEXTURE0); glClientActiveTexture(GL_TEXTURE0);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
s_RenderMode = Renderer::RM_Normal;
GLenum err = GL_NO_ERROR; GLenum err = GL_NO_ERROR;
GL_REPORT_ERROR(); GL_REPORT_ERROR();
@ -455,11 +441,6 @@ void Renderer::RenderText(const char* pstr, int left, int top, u32 color)
s_pfont->printMultilineText(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight,0,nBackbufferWidth,nBackbufferHeight); s_pfont->printMultilineText(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight,0,nBackbufferWidth,nBackbufferHeight);
} }
void Renderer::SetAA(int aa)
{
}
void Renderer::ReinitView(int nNewWidth, int nNewHeight) void Renderer::ReinitView(int nNewWidth, int nNewHeight)
{ {
int oldscreen = s_bFullscreen; int oldscreen = s_bFullscreen;
@ -499,6 +480,7 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight)
OpenGL_SetSize(nNewWidth > 16 ? nNewWidth : 16, OpenGL_SetSize(nNewWidth > 16 ? nNewWidth : 16,
nNewHeight > 16 ? nNewHeight : 16); nNewHeight > 16 ? nNewHeight : 16);
} }
int Renderer::GetTargetWidth() int Renderer::GetTargetWidth()
{ {
return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth()); return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth());
@ -514,24 +496,32 @@ bool Renderer::CanBlendLogicOp()
return g_bBlendLogicOp; return g_bBlendLogicOp;
} }
void Renderer::SetRenderTarget(u32 targ) void Renderer::SetRenderTarget(GLuint targ)
{ {
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, targ!=0?targ:s_RenderTargets[s_nCurTarget], 0 ); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,
targ != 0 ? targ : s_RenderTarget, 0);
} }
void Renderer::SetDepthTarget(u32 targ) void Renderer::SetDepthTarget(GLuint targ)
{ {
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, targ != 0 ? targ : s_DepthTarget ); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
targ != 0 ? targ : s_DepthTarget);
} }
void Renderer::SetFramebuffer(u32 fb) void Renderer::SetFramebuffer(GLuint fb)
{ {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb != 0 ? fb : s_uFramebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
fb != 0 ? fb : s_uFramebuffer);
} }
u32 Renderer::GetRenderTarget() GLuint Renderer::GetRenderTarget()
{ {
return s_RenderTargets[s_nCurTarget]; return s_RenderTarget;
}
GLuint Renderer::GetZBufferTarget()
{
return nZBufferRender > 0 ? s_ZBufferTarget : 0;
} }
void Renderer::ResetGLState() void Renderer::ResetGLState()
@ -571,8 +561,6 @@ void Renderer::SetColorMask()
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
} }
// =======================================================================================
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg() // Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
// case 0x52 > SetScissorRect() // case 0x52 > SetScissorRect()
// --------------- // ---------------
@ -581,7 +569,6 @@ void Renderer::SetColorMask()
// bpmem.scissorTL.x, y = 342x342 // bpmem.scissorTL.x, y = 342x342
// bpmem.scissorBR.x, y = 981x821 // bpmem.scissorBR.x, y = 981x821
// Renderer::GetTargetHeight() = the fixed ini file setting // Renderer::GetTargetHeight() = the fixed ini file setting
// ---------------
bool Renderer::SetScissorRect() bool Renderer::SetScissorRect()
{ {
int xoff = bpmem.scissorOffset.x * 2 - 342; int xoff = bpmem.scissorOffset.x * 2 - 342;
@ -624,7 +611,6 @@ bool Renderer::SetScissorRect()
return false; return false;
} }
bool Renderer::IsUsingATIDrawBuffers() bool Renderer::IsUsingATIDrawBuffers()
{ {
return s_bATIDrawBuffers; return s_bATIDrawBuffers;
@ -670,14 +656,17 @@ void Renderer::FlushZBufferAlphaToTarget()
glStencilFunc(GL_EQUAL, 1, 0xff); glStencilFunc(GL_EQUAL, 1, 0xff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// TODO: This code should not have to bother with stretchtofit checking -
// all necessary scale initialization should be done elsewhere.
// TODO: Investigate BlitFramebufferEXT.
if (g_Config.bStretchToFit) if (g_Config.bStretchToFit)
{ {
//TODO: Do Correctly in a bit //TODO: Do Correctly in a bit
float FactorW = (float)640 / (float)OpenGL_GetWidth(); float FactorW = 640.f / (float)OpenGL_GetWidth();
float FactorH = (float)480 / (float)OpenGL_GetHeight(); float FactorH = 480.f / (float)OpenGL_GetHeight();
float Max = (FactorW < FactorH) ? FactorH : FactorW; float Max = (FactorW < FactorH) ? FactorH : FactorW;
float Temp = 1 / Max; float Temp = 1.0f / Max;
FactorW *= Temp; FactorW *= Temp;
FactorH *= Temp; FactorH *= Temp;
@ -686,8 +675,7 @@ void Renderer::FlushZBufferAlphaToTarget()
glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-FactorW,FactorH); glTexCoord2f(0, (float)GetTargetHeight()); glVertex2f(-FactorW,FactorH);
glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(FactorW,FactorH); glTexCoord2f((float)GetTargetWidth(), (float)GetTargetHeight()); glVertex2f(FactorW,FactorH);
glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(FactorW,-FactorH); glTexCoord2f((float)GetTargetWidth(), 0); glVertex2f(FactorW,-FactorH);
glEnd();
__Log("%d, %d", FactorW, FactorH);
} }
else else
{ {
@ -696,8 +684,8 @@ void Renderer::FlushZBufferAlphaToTarget()
glTexCoord2f(0, (float)(GetTargetHeight())); glVertex2f(-1,1); glTexCoord2f(0, (float)(GetTargetHeight())); glVertex2f(-1,1);
glTexCoord2f((float)(GetTargetWidth()), (float)(GetTargetHeight())); glVertex2f(1,1); glTexCoord2f((float)(GetTargetWidth()), (float)(GetTargetHeight())); glVertex2f(1,1);
glTexCoord2f((float)(GetTargetWidth()), 0); glVertex2f(1,-1); glTexCoord2f((float)(GetTargetWidth()), 0); glVertex2f(1,-1);
}
glEnd(); glEnd();
}
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -774,11 +762,6 @@ Renderer::RenderMode Renderer::GetRenderMode()
return s_RenderMode; return s_RenderMode;
} }
u32 Renderer::GetZBufferTarget()
{
return nZBufferRender > 0 ? s_ZBufferTarget : 0;
}
void Renderer::Swap(const TRectangle& rc) void Renderer::Swap(const TRectangle& rc)
{ {
OpenGL_Update(); // just updates the render window position and the backbuffer size OpenGL_Update(); // just updates the render window position and the backbuffer size
@ -787,22 +770,27 @@ void Renderer::Swap(const TRectangle& rc)
Renderer::SetRenderMode(Renderer::RM_Normal); Renderer::SetRenderMode(Renderer::RM_Normal);
// render to the real buffer now #if 0
#ifdef USE_AA // Not working?
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_RenderTargets[0]); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_uFramebuffer);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
glBlitFramebufferEXT(0, 0, 640, 480, 0, 0, OpenGL_GetWidth(), OpenGL_GetHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
#else #else
// render to the real buffer now
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer
#endif
glViewport(OpenGL_GetXoff(), OpenGL_GetYoff(), (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight()); glViewport(OpenGL_GetXoff(), OpenGL_GetYoff(), (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
ResetGLState(); ResetGLState();
// texture map s_RenderTargets[s_curtarget] onto the main buffer // texture map s_RenderTargets[s_curtarget] onto the main buffer
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTargets[s_nCurTarget]); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s_RenderTarget);
TextureMngr::EnableTexRECT(0); TextureMngr::EnableTexRECT(0);
// disable all other stages // disable all other stages
for(int i = 1; i < 8; ++i) TextureMngr::DisableStage(i); for (int i = 1; i < 8; ++i)
TextureMngr::DisableStage(i);
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -822,12 +810,6 @@ void Renderer::Swap(const TRectangle& rc)
SwapBuffers(); SwapBuffers();
RestoreGLState(); RestoreGLState();
#ifdef USE_AA
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, s_RenderTargets[s_nCurTarget]);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
glBlitFramebufferEXT(0, 0, nBackbufferWidth, nBackbufferHeight, 0, 0, nBackbufferWidth, nBackbufferHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
#endif #endif
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
@ -854,40 +836,37 @@ void Renderer::SwapBuffers()
// Write logging data to debugger // Write logging data to debugger
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if (m_frame) if (m_frame)
{
Logging(0); Logging(0);
}
#endif #endif
if (g_Config.bOverlayStats) { if (g_Config.bOverlayStats) {
char st[2048]; char st[2048];
char *p = st; char *p = st;
if (g_Config.bShowFPS) if (g_Config.bShowFPS)
p+=sprintf(p, "FPS: %d\n", s_fps); // So it shows up before the stats and doesn't make anyting ugly p+=sprintf(p, "FPS: %d\n", s_fps); // So it shows up before the stats and doesn't make anyting ugly
p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated); p+=sprintf(p,"textures created: %i\n",stats.numTexturesCreated);
p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive); p+=sprintf(p,"textures alive: %i\n",stats.numTexturesAlive);
p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated); p+=sprintf(p,"pshaders created: %i\n",stats.numPixelShadersCreated);
p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive); p+=sprintf(p,"pshaders alive: %i\n",stats.numPixelShadersAlive);
p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated); p+=sprintf(p,"vshaders created: %i\n",stats.numVertexShadersCreated);
p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive); p+=sprintf(p,"vshaders alive: %i\n",stats.numVertexShadersAlive);
p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled); p+=sprintf(p,"dlists called: %i\n",stats.numDListsCalled);
p+=sprintf(p,"Num dlists called (frame): %i\n",stats.thisFrame.numDListsCalled); p+=sprintf(p,"dlists called(f): %i\n",stats.thisFrame.numDListsCalled);
// not used. // not used.
//p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated); //p+=sprintf(p,"dlists created: %i\n",stats.numDListsCreated);
//p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive); //p+=sprintf(p,"dlists alive: %i\n",stats.numDListsAlive);
//p+=sprintf(p,"Num strip joins: %i\n",stats.numJoins); //p+=sprintf(p,"strip joins: %i\n",stats.numJoins);
p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims); p+=sprintf(p,"primitives: %i\n",stats.thisFrame.numPrims);
p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins); p+=sprintf(p,"primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
p+=sprintf(p,"Num buffer splits: %i\n",stats.thisFrame.numBufferSplits); p+=sprintf(p,"buffer splits: %i\n",stats.thisFrame.numBufferSplits);
p+=sprintf(p,"Num draw calls: %i\n",stats.thisFrame.numDrawCalls); p+=sprintf(p,"draw calls: %i\n",stats.thisFrame.numDrawCalls);
p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims); p+=sprintf(p,"primitives (DL): %i\n",stats.thisFrame.numDLPrims);
p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads); p+=sprintf(p,"XF loads: %i\n",stats.thisFrame.numXFLoads);
p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL); p+=sprintf(p,"XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads); p+=sprintf(p,"CP loads: %i\n",stats.thisFrame.numCPLoads);
p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL); p+=sprintf(p,"CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads); p+=sprintf(p,"BP loads: %i\n",stats.thisFrame.numBPLoads);
p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL); p+=sprintf(p,"BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
p+=sprintf(p,"Num vertex loaders: %i\n",stats.numVertexLoaders); p+=sprintf(p,"vertex loaders: %i\n",stats.numVertexLoaders);
std::string text = st; std::string text = st;
VertexLoaderManager::AppendListToString(&text); VertexLoaderManager::AppendListToString(&text);
@ -928,13 +907,14 @@ void Renderer::SwapBuffers()
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
//clean out old stuff from caches //clean out old stuff from caches
frameCount++;
PixelShaderMngr::Cleanup(); PixelShaderMngr::Cleanup();
TextureMngr::Cleanup(); TextureMngr::Cleanup();
frameCount++;
// New frame // New frame
stats.ResetFrame(); stats.ResetFrame();
// Render to the framebuffer.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
if (nZBufferRender > 0) { if (nZBufferRender > 0) {

View File

@ -15,6 +15,55 @@
// 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/
// How the non-true-XFB mode COULD work:
//
// The game renders to the EFB:
//
// ----------------------+
// | |
// | |
// | |
// | |
// | |
// | | efb_height
// | |
// | |
// | - - - - - - - - - - |
// | |
// +---------------------+
// efb_width
//
// At XFB blit time, the top 640-xxx X XXX part of the above buffer (size dotted below),
// should be stretch blitted into the inner rectangle of the window:
// +-----------------------------------------+
// | | | |
// | | . | |
// | | | |
// | | . | |
// | | | |
// | | . | | OpenGL_Height()
// | | | |
// | | . | |
// | | - - - - - - - - - - | |
// | | \ | |
// +-------+---------------------------------+
// OpenGL_Width()
//
//
// efb_width and efb_height can even be adjusted so that the last blit will result
// in a 1:1 rather than a stretch. That would require creating a bigger efb from the
// start though.
//
// The above is not how it works today.
/*
int win_w = OpenGL_Width();
int win_h = OpenGL_Height();
int blit_w_640 = last_xfb_specified_width;
int blit_h_640 = last_xfb_specified_height;
*/
#ifndef GCOGL_RENDER #ifndef GCOGL_RENDER
#define GCOGL_RENDER #define GCOGL_RENDER
@ -37,20 +86,19 @@ public:
{ {
RM_Normal=0, // normal target as color0, ztarget as color1 RM_Normal=0, // normal target as color0, ztarget as color1
RM_ZBufferOnly, // zbuffer as color0 RM_ZBufferOnly, // zbuffer as color0
RM_ZBufferAlpha // zbuffer as color0, also will dump alpha info to regular target once mode is switched RM_ZBufferAlpha, // zbuffer as color0, also will dump alpha info to regular target once mode is switched
// use stencil buffer to indicate what pixels were written // use stencil buffer to indicate what pixels were written
}; };
static bool Create2(); static bool Init();
static void Shutdown(); static void Shutdown();
// initialize opengl standard values (like viewport) // initialize opengl standard values (like viewport)
static bool Initialize(); static bool InitializeGL();
static void AddMessage(const char* str, u32 ms); static void AddMessage(const char* str, u32 ms);
static void ProcessMessages(); // draw the current messages on the screen static void ProcessMessages(); // draw the current messages on the screen
static void RenderText(const char* pstr, int left, int top, u32 color); static void RenderText(const char* pstr, int left, int top, u32 color);
static void SetAA(int aa); // sets the anti-aliasing level
static void ReinitView(int nNewWidth, int nNewHeight); static void ReinitView(int nNewWidth, int nNewHeight);
@ -65,7 +113,7 @@ public:
static bool HaveStencilBuffer(); static bool HaveStencilBuffer();
static void SetZBufferRender(); // sets rendering of the zbuffer using MRTs static void SetZBufferRender(); // sets rendering of the zbuffer using MRTs
static u32 GetZBufferTarget(); static GLuint GetZBufferTarget();
static void SetColorMask(); static void SetColorMask();
static bool SetScissorRect(); static bool SetScissorRect();
@ -73,10 +121,12 @@ public:
static void SetRenderMode(RenderMode mode); static void SetRenderMode(RenderMode mode);
static RenderMode GetRenderMode(); static RenderMode GetRenderMode();
static void SetRenderTarget(u32 targ); // if targ is 0, sets to original render target static void SetRenderTarget(GLuint targ); // if targ is 0, sets to original render target
static void SetDepthTarget(u32 targ); static void SetDepthTarget(GLuint targ);
static void SetFramebuffer(u32 fb);
static u32 GetRenderTarget(); static void SetFramebuffer(GLuint fb);
static GLuint GetRenderTarget();
// Finish up the current frame, print some stats // Finish up the current frame, print some stats
static void Swap(const TRectangle& rc); static void Swap(const TRectangle& rc);

View File

@ -120,7 +120,7 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr)
m_numLoadedVertices = 0; m_numLoadedVertices = 0;
m_VertexSize = 0; m_VertexSize = 0;
m_numPipelineStages = 0; m_numPipelineStages = 0;
m_NativeFmt = new NativeVertexFormat(); m_NativeFmt = NativeVertexFormat::Create();
loop_counter = 0; loop_counter = 0;
VertexLoader_Normal::Init(); VertexLoader_Normal::Init();

View File

@ -348,6 +348,7 @@ void VertexShaderMngr::SetConstants()
// [3] = xorig + width/2 + 342 // [3] = xorig + width/2 + 342
// [4] = yorig + height/2 + 342 // [4] = yorig + height/2 + 342
// [5] = 16777215 * farz // [5] = 16777215 * farz
/*INFO_LOG("view: topleft=(%f,%f), wh=(%f,%f), z=(%f,%f)\n", /*INFO_LOG("view: topleft=(%f,%f), wh=(%f,%f), z=(%f,%f)\n",
rawViewport[3]-rawViewport[0]-342, rawViewport[4]+rawViewport[1]-342, rawViewport[3]-rawViewport[0]-342, rawViewport[4]+rawViewport[1]-342,
2 * rawViewport[0], 2 * rawViewport[1], 2 * rawViewport[0], 2 * rawViewport[1],
@ -363,6 +364,7 @@ void VertexShaderMngr::SetConstants()
int overfl; int overfl;
int xoffs = 0, yoffs = 0; int xoffs = 0, yoffs = 0;
int wid, hei, actualWid, actualHei; int wid, hei, actualWid, actualHei;
int winw = OpenGL_GetWidth(); int winw = OpenGL_GetWidth();
int winh = OpenGL_GetHeight(); int winh = OpenGL_GetHeight();
float ratio = (float)winw / (float)winh / fourThree; float ratio = (float)winw / (float)winh / fourThree;
@ -421,6 +423,7 @@ void VertexShaderMngr::SetConstants()
Renderer::GetTargetHeight()-((int)(xfregs.rawViewport[4]-xfregs.rawViewport[1]-342-scissorYOff)) * MValueY, Renderer::GetTargetHeight()-((int)(xfregs.rawViewport[4]-xfregs.rawViewport[1]-342-scissorYOff)) * MValueY,
abs((int)(2 * xfregs.rawViewport[0])) * MValueX, abs((int)(2 * xfregs.rawViewport[1])) * MValueY); abs((int)(2 * xfregs.rawViewport[0])) * MValueX, abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
} }
glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f); glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f);
} }

View File

@ -30,8 +30,6 @@
#define XFB_USE_SHADERS 1 #define XFB_USE_SHADERS 1
enum { enum {
XFB_WIDTH = 640,
XFB_HEIGHT = 480, // 528 is max height.
XFB_BUF_HEIGHT = 538, //480, XFB_BUF_HEIGHT = 538, //480,
// TODO: figure out what to do with PAL // TODO: figure out what to do with PAL
}; };
@ -145,10 +143,9 @@ void XFB_Shutdown()
void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt) void XFB_Write(u8 *xfb_in_ram, const TRectangle& sourceRc, u32 dstWd, u32 dstHt)
{ {
Renderer::SetRenderMode(Renderer::RM_Normal); Renderer::SetRenderMode(Renderer::RM_Normal);
Renderer::ResetGLState(); Renderer::ResetGLState();
// switch to XFB frame buffer // Switch to XFB frame buffer.
Renderer::SetFramebuffer(s_xfbFrameBuffer); Renderer::SetFramebuffer(s_xfbFrameBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_xfbRenderBuffer); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_xfbRenderBuffer); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, s_xfbRenderBuffer);

View File

@ -262,8 +262,8 @@ void Video_DoState(unsigned char **ptr, int mode) {
void Video_Prepare(void) void Video_Prepare(void)
{ {
OpenGL_MakeCurrent(); OpenGL_MakeCurrent();
if (!Renderer::Create2()) { if (!Renderer::Init()) {
g_VideoInitialize.pLog("Renderer::Create2 failed\n", TRUE); g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE);
PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info"); PanicAlert("Can't create opengl renderer. You might be missing some required opengl extensions, check the logs for more info");
exit(1); exit(1);
} }